Quick Start

Submit your first export request in about five minutes.

Prerequisites

  • An active Indream API key.
  • node >= 18 or python >= 3.10 for SDK examples.
  • A minimal editor JSON payload.

Step 1: Prepare a Minimal Editor State

{
  "timebaseTicksPerSecond": 240000,
  "compositionWidth": 1920,
  "compositionHeight": 1080,
  "outputRatio": "16:9",
  "globalBackground": {
    "type": "none"
  },
  "brandRuntime": {
    "brandId": null,
    "logoX": 50,
    "logoY": 50,
    "managedItemIds": [],
    "managedAssetIds": [],
    "introShiftInFrames": 0,
    "overlayTrackId": null,
    "underlayTrackId": null
  },
  "tracks": [
    {
      "id": "HSbB",
      "items": ["CYON"],
      "hidden": false,
      "muted": false
    }
  ],
  "assets": {},
  "items": {
    "CYON": {
      "id": "CYON",
      "type": "text",
      "text": "Hello World",
      "color": "#ffffff",
      "top": { "value": 492, "keyframes": [] },
      "left": { "value": 755, "keyframes": [] },
      "width": { "value": 411, "keyframes": [] },
      "height": { "value": 96, "keyframes": [] },
      "scaleX": { "value": 1, "keyframes": [] },
      "scaleY": { "value": 1, "keyframes": [] },
      "align": "center",
      "opacity": { "value": 1, "keyframes": [] },
      "rotation": { "value": 0, "keyframes": [] },
      "fontFamily": "Roboto",
      "fontSize": 80,
      "lineHeight": 1.2,
      "letterSpacing": 0,
      "resizeOnEdit": true,
      "direction": "ltr",
      "fontStyle": {
        "variant": "normal",
        "weight": "400"
      },
      "isDraggingInTimeline": false,
      "strokeWidth": 0,
      "strokeColor": "#000000",
      "background": null,
      "startTicks": 0,
      "durationTicks": 336000
    }
  },
  "transitions": {},
  "deletedAssets": []
}

Optional keyframe example (left/top/opacity):

{
  "left": {
    "value": 120,
    "keyframes": [
      { "timeTicks": 0, "value": 120 },
      { "timeTicks": 240000, "value": 560 }
    ]
  },
  "top": {
    "value": 80,
    "keyframes": [
      { "timeTicks": 0, "value": 80 },
      { "timeTicks": 240000, "value": 140 }
    ]
  },
  "opacity": {
    "value": 1,
    "keyframes": [
      { "timeTicks": 0, "value": 1 },
      { "timeTicks": 240000, "value": 0.7 }
    ]
  }
}

Step 2: Validate Before Create

curl -X POST "https://api.indream.ai/v1/editor/validate" \
  -H "x-api-key: <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"editorState": {"compositionWidth": 1280}}'

If validation fails, fix the fields in errors[] before creating a task.

Step 3: Create Export Task

curl -X POST "https://api.indream.ai/v1/exports" \
  -H "x-api-key: <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "editorState": { "...": "..." },
    "ratio": "9:16",
    "scale": 0.6,
    "fps": 30,
    "format": "mp4"
  }'

Your account can have at most 2 active export tasks (PENDING/PROCESSING/PAUSED) at a time. If that limit is exceeded, create returns 422 OPEN_API_EXPORT_CONCURRENCY_LIMIT_EXCEEDED.

Step 4: Poll Task Status

curl "https://api.indream.ai/v1/exports/<TASK_ID>" \
  -H "x-api-key: <YOUR_API_KEY>"

You can also filter list results by creator key:

curl "https://api.indream.ai/v1/exports?pageSize=20&createdByApiKeyId=<API_KEY_ID>" \
  -H "x-api-key: <YOUR_API_KEY>"

Wait until status becomes one of the terminal states:

  • COMPLETED: use outputUrl
  • FAILED or CANCELED: inspect error

outputUrl is temporary and usually expires in 1-3 days. Save the file to your own server as soon as possible.

Project Workflow

If you need autosave, reusable uploads, or multiple exports from the same draft, use a project-based workflow:

  1. create a project with POST /v1/projects
  2. upload files through POST /v1/uploads
  3. persist changes with POST /v1/projects/{projectId}/sync
  4. export the saved project with POST /v1/projects/{projectId}/exports

See Projects and Assets for the full flow.

Node.js Client Example

import { IndreamClient } from '@indreamai/client'

const client = new IndreamClient({ apiKey: process.env.INDREAM_API_KEY! })

const task = await client.exports.create({
  editorState,
  ratio: '9:16',
  scale: 0.6,
  fps: 30,
  format: 'mp4',
})

const done = await client.exports.wait(task.taskId, {
  timeoutMs: 10 * 60 * 1000,
  pollIntervalMs: 2000,
})

console.log(done.status, done.outputUrl)

Python Client Example

from indream import IndreamClient

client = IndreamClient(api_key="<YOUR_API_KEY>")

created = client.exports.create(
    {
        "editorState": editor_state,
        "ratio": "9:16",
        "scale": 0.6,
        "fps": 30,
        "format": "mp4",
    }
)

done = client.exports.wait(created.task_id, timeout=600, poll_interval=2)
print(done.status, done.output_url)

Failure Handling Checklist

  • Retry only 429 and 5xx responses.
  • Do not retry invalid payloads until corrected.
  • For idempotent create retries, you can pass SDK idempotencyKey (or Idempotency-Key header) and keep it stable.

Last updated on

On this page