Skip to content

Stories

Stories generate multi-scene illustrated narratives with consistent characters and style. Your AI assistant composes the storyboard and manages the workflow on your behalf.

Because generating multiple scenes takes time, stories use an async workflow.

  1. Submit a storyboard: JSON with characters, scenes, and optionally locations and a style (see What goes in a storyboard).
  2. Receive HTTP 202 with a job_id and poll_url (the full GET /v1/jobs/{job_id} URL).
  3. Poll until status is completed or failed.
  4. Download the scene images and the character and location reference images.

Stories need a model that can make multi-scene stories (supports_multiturn in GET /v1/models): today gemini and gemini-pro. Without model, Depicta uses your default model if it can, otherwise gemini. Other models return 422 model_not_capable.

  • characters (required, 1 to 10): a name, an appearance, and optionally a reference_url to an image to match. Depicta makes a reference portrait of each character before the first scene.
  • scenes (required, 2 to 10): a prompt for each. Say in the prompt who is in the scene, where it happens, and any change in how someone looks.
  • locations (optional, up to 10): a name plus a description or a reference_url. Before the first scene, Depicta makes one image of each described location (each one is charged like any other image) or fetches your reference image. Every location stays in view for all scenes. Scenes aren’t tied to a location, so name the place in the scene prompt.
  • style (up to 200 characters), setting, prompt, aspect_ratio and image_size apply to the whole story. Every scene uses the story’s aspect_ratio.

Character and location names are short labels: up to 60 characters of letters (any script), digits, spaces and - _ ' ’ . , · ・ ׳ ་, with no space at the start or end.

Everything you write in a storyboard, names and style included, goes through the content check.

Terminal window
depicta story run storyboard.json

The CLI polls automatically (every 3 seconds) and downloads all scene images when done. It waits up to 45 minutes (--timeout, in seconds), because a busy service can queue a story for up to 30 minutes before it starts.

If the wait runs out, or you press Ctrl+C, the CLI tells you the story is still running and will be charged when it completes, with its job ID: don’t resubmit it. Check on it with:

Terminal window
depicta story status <job_id>
  • A timeout doesn’t stop the story. If the CLI or your own polling gives up, the story keeps running and is charged when it finishes. Check on it with depicta story status <job_id> or GET /v1/jobs/{id}. Don’t submit it again: both stories would run, and both would be charged.
  • Busy service. A story can wait up to 30 minutes before its first scene (status processing, 0 scenes done). If it can’t start in that time, it fails with service_unavailable and nothing is charged.
  • Up to 3 stories in progress. Another one gets 429 rate_limit_exceeded with a Retry-After header.
Terminal window
curl -X POST https://api.depicta.ai/v1/generate/story \
-H "Authorization: Bearer dpct_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d @storyboard.json
{
"job_id": "a1b2c3d4-e5f6-7890-abcd-ef0123456789",
"status": "pending",
"poll_url": "https://api.depicta.ai/v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef0123456789"
}
{
"job_id": "a1b2c3d4-...",
"status": "completed",
"scenes_completed": 4,
"scenes_total": 4,
"created_at": "2026-10-15T09:00:00Z",
"started_at": "2026-10-15T09:00:01Z",
"completed_at": "2026-10-15T09:04:30Z",
"result": {
"model": "google/gemini-3.1-flash-image",
"title": "The Library of Aria",
"scenes": [
{
"scene": 1,
"title": "Aria enters the library",
"image_url": "https://media.depicta.ai/...",
"expires_at": "2026-10-15T10:04:30Z",
"image_hash": "sha256...",
"formats": {
"png": {"url": "https://media.depicta.ai/...", "format": "png"},
"jpeg": {"url": "https://media.depicta.ai/...", "format": "jpeg"},
"webp": {"url": "https://media.depicta.ai/...", "format": "webp"}
}
}
],
"characters": [
{"name": "Aria", "reference_url": "https://media.depicta.ai/...", "expires_at": "2026-10-15T10:04:30Z"}
],
"locations": [
{"name": "library", "reference_url": "https://media.depicta.ai/...", "expires_at": "2026-10-15T10:04:30Z"}
],
"cost_eur": "0.420000",
"balance_eur": "9.580000"
}
}

cost_eur is the total for the whole story, in credits (EUR, excluding VAT; VAT is added when you buy credits). balance_eur is what you have left.

{
"job_id": "a1b2c3d4-...",
"status": "failed",
"error": {
"code": "service_unavailable",
"message": "..."
}
}

A failed job says why in error.code, and error.message says what happened and what to do. A story job can fail with:

error.code Meaning
model_refused The model returned no image
upstream_error The model rejected the request; retrying it unchanged fails
upstream_unavailable The model was unavailable
generation_failed, story_generation_failed Generation failed
post_generation_failed An image was generated but could not be finished
service_unavailable The story could not start in time
timeout The story ran past the maximum time
internal_error Unexpected server error
abandoned The job never finished
delivery_failed Generated and charged, but not delivered