aigens

API documentation

Everything you do on the aigens website can be done from a script: write a script from an idea, create episodes, generate character images, render, download videos, and make trending videos. Limits are the same as on the website; a few actions are priced differently, see Pricing for API calls.

Contents
  1. 1. Base URL and keys
  2. 2. General conventions
  3. 3. Pricing for API calls
  4. 4. Making an episode, step by step
  5. 5. Trending videos
  6. 6. Common endpoints
  7. 7. Limits
  8. 8. Error codes

1. Base URL and keys

Base URL: https://aigens.app. Create a key on the API page in the studio, then send it with every request in the Authorization header:

curl https://aigens.app/api/me \
  -H "Authorization: Bearer aig_YOUR_KEY"
  • A key is shown only once, when it is created. If you lose it, revoke it and create a new one; each account can have up to 5 keys.
  • A key can do everything the account can, including spending spirit stones. Never put a key in code that runs in a browser or in a public repository.
  • Keys cannot be used to create or revoke keys, or for admin endpoints.

2. General conventions

  • Requests and responses are JSON (except file uploads, which use multipart forms).
  • Errors return an HTTP status of 400 or above with { "error": "human-readable message", "code": "CODE" }. The message follows your Accept-Language header (Vietnamese by default). The code field is present when the error is one of the predefined kinds.
  • Common statuses: 401 wrong or revoked key; 402 not enough spirit stones; 409 the action can't be done right now (a scene is rendering, a character has no image: CAST_NOT_READY); 422 the script doesn't match the format, with a list of issues per scene.
  • Rate limits per account: reads (GET) 120 per minute, writes (POST, PATCH, DELETE) 20 per minute. Going over returns 429 with "code": "RATE_LIMITED" and a Retry-After header (seconds to wait). Sending a wrong key many times in a row blocks you for one minute.
  • Three actions spend spirit stones: writing a script from an idea, sending scenes to render, and sending a trending video. Failed runs are refunded automatically.
  • Rendering runs in the background. Polling the status every 5 to 15 seconds is enough.

3. Pricing for API calls

When you call with an API key, content-generating actions have their own prices: rendering scenes and trending videos cost the website price times 150%, rounded up. First-time offers (your first video, your first trending run) are only available on the website; API calls don't get the discount and don't use it up either.

ActionOn the websiteVia the API
Write a script from an idea (each time)free2 spirit stones
Render one scene (including redos)5 spirit stones8 spirit stones
One trending video20 spirit stones30 spirit stones
Create episodes, character images, stitching, reading datafreefree

Current prices are always in GET /api/me, under pricing.api. The quote in GET /api/episodes/{id} already uses API prices when you call with a key. Every charge returns charged; the spirit stone ledger adds "(API)". A failed script draft is refunded right away.

4. Making an episode, step by step

The six steps below match the steps you click through on the website. A complete, runnable version is in the Python example at the top of this page.

Step 1. The system writes a script from your idea (free)

curl -X POST https://aigens.app/api/episodes/draft \
  -H "Authorization: Bearer $AIGENS_KEY" -H "Content-Type: application/json" \
  -d '{"idea": "The Tortoise and the Hare race a second time, with a surprise ending.", "sceneCount": 5, "voiceGender": "female"}'

# Returns: { "json": "<JSON prompt string>", "issues": [] }

A JSON prompt has the shape { title, style, characters: [{ key, name, description }], scenes: [{ prompt, voice }] }. You can edit it before creating the episode, or write the whole JSON yourself and skip this step. Whenever a character appears in a scene, that scene's prompt must mention the character's exact key.

Step 2. Create the episode (free)

curl -X POST https://aigens.app/api/episodes \
  -H "Authorization: Bearer $AIGENS_KEY" -H "Content-Type: application/json" \
  -d '{"json": "<JSON prompt string from step 1>", "aspect": "9:16", "voiceGender": "female", "captions": true}'

# Returns: { "id": "<episode id>" }

Step 3. Character images (free)

Read the episode to get its characters, request an image for each one, wait until the status becomes pending_review, then approve it. If you have your own image, upload it instead of generating one; uploaded images are approved right away.

curl https://aigens.app/api/episodes/$EPISODE -H "Authorization: Bearer $AIGENS_KEY"
# episode.cast: [{ "id": "...", "key": "character_tho", "status": "no_image" }, ...]

curl -X POST https://aigens.app/api/characters/episode/$CHARACTER/image   -H "Authorization: Bearer $AIGENS_KEY"
curl -X POST https://aigens.app/api/characters/episode/$CHARACTER/approve -H "Authorization: Bearer $AIGENS_KEY"

# Or use your own image:
curl -X POST https://aigens.app/api/characters/episode/$CHARACTER/upload \
  -H "Authorization: Bearer $AIGENS_KEY" -F "image=@hare.jpg;type=image/jpeg"

Step 4. Render (spends spirit stones)

curl -X POST https://aigens.app/api/episodes/$EPISODE/render \
  -H "Authorization: Bearer $AIGENS_KEY" -H "Content-Type: application/json" -d '{}'

# Returns: { "charged": 50, "scenes": 5, "balance": 450 }

The amount to be charged is in quote.total when you read the episode. To redo a few scenes, send {"sceneIds": ["<scene id>"]}.

Step 5. Wait for rendering and stitching

Read the episode again until episode.status is done. In automatic stitch mode, the system stitches as soon as the last scene is finished.

waiting_castSome characters don't have an approved image yet
validatedReady to render
renderingRendering scenes. If no rendering accounts are available, the episode stays in this state until one frees up, without an error
stitchingAll scenes are done; stitching
doneThe full episode video is ready
partialSome scenes failed. Failed scenes were refunded; resend them with sceneIds

Step 6. Download the video

curl -L -o episode.mp4 https://aigens.app/api/episodes/$EPISODE/download -H "Authorization: Bearer $AIGENS_KEY"

Videos are kept for a limited time (see keepDays in /api/me). After that the video is deleted; the script and characters stay.

6. Common endpoints

GET/api/meAccount, spirit stone balance, current prices and limits
GET/api/voicesReader voices you can pick for an episode in one video language (language, e.g. ?language=en-US; vi-VN by default): id, name, gender, language, style, sampleUrl (sample clip link, may be null); plus languages: every video language that has voices
POST/api/episodes/draftThe system writes a script (JSON prompt) from an idea: idea (up to 2,000 characters), sceneCount, language (the video language: the title, character names and voiceover are written in it; defaults to the voice's language, then vi-VN), voiceId or voiceGender, projectId. SPENDS SPIRIT STONES when called with an API key (refunded if no script could be written); returns charged
POST/api/episodesCreate an episode from a JSON prompt: json, idea, aspect (9:16 or 16:9), language (the video language, must match the voice's language; defaults to the voice's language, then vi-VN), voiceId (the id of a voice from GET /api/voices) or voiceGender (male by default, or female: the first voice of that gender in the video language), speed (1, 1.1 by default, 1.2, 1.25, 1.5), outputResolution (720p by default, or 1080p: the final video's resolution; stitching 1080p takes longer), captions, stitchMode (auto or review), projectId, autoCharacterImages (true by default: queue image generation for characters without an image; false if you upload your own). Free
GET/api/episodesList episodes: limit, offset, projectId or loose=1
GET/api/episodes/{id}One episode: status, characters, each scene, plus a price quote (quote)
PATCH/api/episodes/{id}Change the title, style, aspect ratio, captions, stitch mode, speed (speed), final video resolution (outputResolution), reader voice (voiceId or voiceGender, in the episode's video language; locked once a scene has been sent to render)
DELETE/api/episodes/{id}Delete the episode
POST/api/characters/episode/{id}/imageRequest an image for one of the episode's characters. Free, with a daily regeneration quota
POST/api/characters/episode/{id}/uploadUpload your own image for a character: multipart form, field image. Approved right away
POST/api/characters/episode/{id}/approveApprove a character image
PATCH/api/scenes/{id}Edit the image prompt or voiceover of a scene that hasn't been sent to render
POST/api/episodes/{id}/renderRender and SPEND SPIRIT STONES. No body: every draft scene. sceneIds: redo those scenes
POST/api/episodes/{id}/stitchStitch, or re-stitch, into one video. Free
GET/api/scenes/{id}/videoRedirects to a scene's video; add ?download=1 to download it
GET/api/episodes/{id}/downloadRedirects to the download link of the full episode video
GET/api/trendsYour trending videos, your balance, and terms: the next run's price and the number of seconds used
POST/api/trendsSend a trending video and SPEND SPIRIT STONES: multipart form, kind (video type, swap_character by default: replace the character), character (image) plus video (file) or url (TikTok link)
GET/api/trends/{id}/videoRedirects to the result video; add ?download=1 to download it
GET/api/walletBalance and spirit stone ledger

7. Limits

Rate limits apply only to calls with an API key and are counted per minute for each account (all keys of an account share them):

  • Reads (GET): 120 per minute.
  • Writes (POST, PATCH, DELETE): 20 per minute.
  • Sending a wrong key 20 times within a minute from the same IP address blocks every key from that IP until the minute is over.
  • Over the limit: HTTP 429, { "code": "RATE_LIMITED", "retryAfter": 37 }, with the headers Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining.

Content limits currently in effect (the same as on the website; the latest numbers are always in GET /api/me, under limits):

Scenes per episodeup to 10
Length of each scene10 to 10 seconds
Voiceover per scene15 to 45 words
Image prompt per sceneup to 2000 characters
Prompt sent per sceneup to 4000 characters, including the style and the descriptions of the characters in the scene
Charactersup to 20 per episode, 5 per scene
Regenerating character images300 times a day for the whole account (the first image of a character doesn't count)
Uploaded character imagesup to 8 MB
Trending videosuses the first 30 seconds; source videos up to 60 seconds and 80 MB; character images up to 8 MB
Video retentionstitched videos are kept 3 days; scenes of an unstitched episode are kept 7 days

8. Error codes

Every error returns JSON { "error": "human-readable message", "code": "CODE" }. Rely on code when it is present to handle errors in your script; the wording in error may change.

HTTP statuses

400The data sent is wrong or missing (parameters, file too large, wrong format).
401Missing, wrong or revoked key.
402Not enough spirit stones for this action.
403Not allowed: the account is blocked, or the action is only available when logged in on the website (managing API keys, admin).
404Not found, or it doesn't belong to your account.
409Can't be done right now because of the current state (a scene is rendering, a character has no image, the episode is stitching…). See code.
422The script doesn't match the format or exceeds a limit, with a list of issues per scene.
429Over the rate limit (RATE_LIMITED) or out of character image regenerations for today (DAILY_LIMIT).
500Server error. Try again later; if it keeps happening, email contact@lin.vn.
503The server isn't ready yet.

Values of code

BAD_IMAGE_PATH400Invalid image file.
BAD_OUTPUT_RESOLUTION400Video resolution must be 720p or 1080p.
BAD_SPEED400Video speed must be between 0.5x and 2x.
BAD_TREND_KIND400Invalid trending video type.
CHARACTER_KEY_OVERLAP400This character key is part of (or contains) another key. Rename it so they can't be confused.
DUPLICATE_SCENE400The scene list contains duplicates.
LANGUAGE_NOT_AVAILABLE400There is no voice for this video language yet.
NO_SCENES400No scenes selected to send.
ORDER_MISMATCH400The episode list doesn't match the project.
PROMPT_REQUIRED400The scene has no prompt yet.
VOICE_LANGUAGE_MISMATCH400The voice is not in the video's language.
VOICE_NOT_FOUND400This voice does not exist or is turned off.
INSUFFICIENT_BALANCE402Not enough spirit stones.
BLOCKED403This account is locked.
CHARACTER_NOT_FOUND404Character not found.
EPISODE_NOT_FOUND404Episode not found.
IMAGE_NOT_FOUND404This character image was not found.
PROFILE_NOT_FOUND404Account not found.
PROJECT_NOT_FOUND404Project not found.
SCENE_NOT_FOUND404Scene not found.
TREND_NOT_FOUND404Video not found.
ASPECT_LOCKED409The aspect ratio is locked once a scene has been sent to render.
CAST_LOCKED409An episode using this character is creating scenes or stitching, so its image can't be changed yet. Wait for it to finish, then try again.
CAST_NOT_READY409A character in this scene has no approved image. Generate or upload an image and approve it before creating the video.
CHARACTER_BUSY409The character image is being generated.
CHARACTER_CONFLICT409The episode and the project have different images for the same character. Choose which one to keep.
CHARACTER_EXISTS409This character key already exists.
CHARACTER_LIMIT409The episode already has the maximum number of characters.
CHARACTER_NOT_REVIEWABLE409The character has no image waiting for review.
LAST_SCENE409An episode must keep at least one scene.
PROJECT_BUSY409The project still has work running (rendering scenes, drawing characters or stitching). Wait for it to finish, then delete.
SCENE_BUSY409The scene is queued or rendering, so it can't be changed right now.
SCENE_NOT_REVIEWABLE409This scene is not ready for review yet.
SCENES_NOT_APPROVED409Some scenes haven't been approved.
SCENES_NOT_READY409Some scenes haven't finished rendering.
STITCH_BUSY409The episode is being stitched.
STITCH_UP_TO_DATE409The current stitched video is already up to date.
TREND_BUSY409The video is being rendered and can't be deleted yet.
VOICE_LOCKED409The voice is locked once a scene has been sent to render.
DAILY_LIMIT429You've used all of today's character image regenerations.
RATE_LIMITED429The API key's rate limit was exceeded. Wait the number of seconds in retryAfter (or the Retry-After header), then call again.