Quick Start
Submit your first export request in about five minutes.
Prerequisites
- An active Indream API key.
node >= 18orpython >= 3.10for 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: useoutputUrlFAILEDorCANCELED: inspecterror
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:
- create a project with
POST /v1/projects - upload files through
POST /v1/uploads - persist changes with
POST /v1/projects/{projectId}/sync - 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
429and5xxresponses. - Do not retry invalid payloads until corrected.
- For idempotent create retries, you can pass SDK
idempotencyKey(orIdempotency-Keyheader) and keep it stable.
Last updated on