Generations (jobs)
POST/api/v1/jobs/estimatescope jobs:read
Computes the exact price in credits and the generation time, and returns a signed quote valid for 1 hour. Nothing is charged. Pass the quote to POST /jobs to lock the price.
JSON body
| Field | Type | Description |
|---|
brief | object | The full video briefrequired |
brief.subject | string | Video subject, in one sentence (3 to 200 characters).required |
brief.input | object (variants) | Content source: { kind: "idea" } (the script is written for you), { kind: "script", text } (your exact text, 4,000 chars max) or { kind: "document", text, sourceName } (facts to respect, 40,000 chars max).Default: {"kind":"idea"} |
brief.audience | "beginner" | "dev" | "ops" | "decision-maker" | Target audience: beginner, dev, ops or decision-maker.Default: "dev" |
brief.length | "short" | "standard" | "full" | Length: short (45–60 s), standard (90–120 s) or full (150–180 s).Default: "standard" |
brief.language | "fr" | "en" | Narration language: en (English, default) or fr (French).Default: "en" |
brief.voice | string | Narrator voice (see GET /catalog): George, Sarah, Daniel, Brian, Lily, Alice, Will, Matilda. Every voice speaks both languages.Default: "George" |
brief.look | object (variants) | Visual style: { mode: "preset", preset: "clean" | "night" | "toon" }, { mode: "brand" } (brand colors, brand field required) or { mode: "custom", description } (Studio plan).Default: {"mode":"preset"} |
brief.brand | object | Brand shown: name (24 chars), site, colors (1 to 3 #RRGGBB colors), logo ("asset:<id>" returned by POST /assets). |
brief.brand.name | string | Brand name (24 characters max).required |
brief.brand.site | string | Website shown at the end of the video (40 characters max). |
brief.brand.colors | string[] | 1 to 3 hex colors #RRGGBB.required |
brief.brand.logo | string | Logo: "asset:<id>" returned by POST /assets. |
brief.notes | object | Instructions: mustShow (up to 10 things to show), avoid (things to avoid), keyMoment, free (free text).Default: {"mustShow":[],"avoid":[]} |
brief.notes.mustShow | string[] | Things that must be shown (10 max, 80 chars each).Default: [] |
brief.notes.avoid | string[] | Things to avoid (10 max).Default: [] |
brief.notes.keyMoment | string | The key moment to highlight. |
brief.notes.free | string | Free-form instructions (1,000 characters max). |
brief.mascot | boolean | Adds an animated presenter.Default: false |
brief.tier | "standard" | "studio" | standard, or studio (higher quality, +300 credits, Studio plan).Default: "standard" |
brief.dimension | "2d" | "3d" | 2d (flat motion design, default) or 3d (perspective, volume, depth and camera moves).Default: "2d" |
brief.threeD | "none" | "signature" | Legacy, ignored: use dimension.Default: "none" |
voiceMode | "draft" | "final" | final = licensed voice (paid plans), draft = free draft voice. Default: final on paid plans. |
curl -X POST https://motiongist.com/api/v1/jobs/estimate \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"brief": {
"subject": "How a CDN works",
"input": {
"kind": "idea"
},
"audience": "dev",
"length": "standard",
"language": "en",
"voice": "George",
"look": {
"mode": "preset",
"preset": "night"
},
"notes": {
"mustShow": [
"edge cache",
"latency"
],
"avoid": []
}
}
}'
{
"data": {
"total": 847,
"lines": [
{
"label": "Standard video (90–120 s)",
"credits": 700
},
{
"label": "Final voice (1,470 characters)",
"credits": 147
}
],
"quote": "eyJ3cyI6IjQ…(signed quote, pass it back unchanged)…",
"quoteExpiresAt": "2026-10-23T10:12:00.000Z",
"voiceMode": "final",
"isRevision": false,
"balance": 29153,
"allowed": true,
"blockers": [],
"overdraft": false,
"eta": {
"minutesMin": 4,
"minutesMax": 8
}
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: VALIDATION_ERROR (400)
POST/api/v1/jobsscope jobs:write
Charges the credits and queues the generation. With a quote, the price is guaranteed (and refused if the brief changed); without a quote, the server recomputes the price. 202 response: then poll GET /jobs/{id} or subscribe to webhooks.
JSON body
| Field | Type | Description |
|---|
brief | object | Video brief (one-shot: a project is created for it). Or projectId. |
brief.subject | string | Video subject, in one sentence (3 to 200 characters).required |
brief.input | object (variants) | Content source: { kind: "idea" } (the script is written for you), { kind: "script", text } (your exact text, 4,000 chars max) or { kind: "document", text, sourceName } (facts to respect, 40,000 chars max).Default: {"kind":"idea"} |
brief.audience | "beginner" | "dev" | "ops" | "decision-maker" | Target audience: beginner, dev, ops or decision-maker.Default: "dev" |
brief.length | "short" | "standard" | "full" | Length: short (45–60 s), standard (90–120 s) or full (150–180 s).Default: "standard" |
brief.language | "fr" | "en" | Narration language: en (English, default) or fr (French).Default: "en" |
brief.voice | string | Narrator voice (see GET /catalog): George, Sarah, Daniel, Brian, Lily, Alice, Will, Matilda. Every voice speaks both languages.Default: "George" |
brief.look | object (variants) | Visual style: { mode: "preset", preset: "clean" | "night" | "toon" }, { mode: "brand" } (brand colors, brand field required) or { mode: "custom", description } (Studio plan).Default: {"mode":"preset"} |
brief.brand | object | Brand shown: name (24 chars), site, colors (1 to 3 #RRGGBB colors), logo ("asset:<id>" returned by POST /assets). |
brief.brand.name | string | Brand name (24 characters max).required |
brief.brand.site | string | Website shown at the end of the video (40 characters max). |
brief.brand.colors | string[] | 1 to 3 hex colors #RRGGBB.required |
brief.brand.logo | string | Logo: "asset:<id>" returned by POST /assets. |
brief.notes | object | Instructions: mustShow (up to 10 things to show), avoid (things to avoid), keyMoment, free (free text).Default: {"mustShow":[],"avoid":[]} |
brief.notes.mustShow | string[] | Things that must be shown (10 max, 80 chars each).Default: [] |
brief.notes.avoid | string[] | Things to avoid (10 max).Default: [] |
brief.notes.keyMoment | string | The key moment to highlight. |
brief.notes.free | string | Free-form instructions (1,000 characters max). |
brief.mascot | boolean | Adds an animated presenter.Default: false |
brief.tier | "standard" | "studio" | standard, or studio (higher quality, +300 credits, Studio plan).Default: "standard" |
brief.dimension | "2d" | "3d" | 2d (flat motion design, default) or 3d (perspective, volume, depth and camera moves).Default: "2d" |
brief.threeD | "none" | "signature" | Legacy, ignored: use dimension.Default: "none" |
projectId | uuid | Existing project to generate (alternative to brief) |
quote | string | Signed quote returned by POST /jobs/estimate. Guarantees the price; without a quote, the server recomputes the price. |
title | string | Title (120 characters max). Default: the subject. |
voiceMode | "draft" | "final" | final = licensed voice (paid plans), draft = free draft voice. Default: final on paid plans. |
curl -X POST https://motiongist.com/api/v1/jobs \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"brief": {
"subject": "How a CDN works",
"input": {
"kind": "idea"
},
"audience": "dev",
"length": "standard",
"language": "en",
"voice": "George",
"look": {
"mode": "preset",
"preset": "night"
},
"notes": {
"mustShow": [
"edge cache",
"latency"
],
"avoid": []
}
},
"quote": "eyJ3cyI6IjQ…(signed quote, pass it back unchanged)…"
}'
{
"data": {
"job": {
"id": "7f3c2a10-5b1e-4c8a-9d2f-0e6b4a1c9d55",
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"status": "queued",
"stage": "script",
"stageLabel": "Script",
"progress": 0,
"detail": null,
"stages": {},
"voiceMode": "final",
"isRevision": false,
"credits": 847,
"queuePosition": 1,
"cancellable": true,
"error": null,
"videoId": null,
"attempt": 1,
"source": "api",
"queuedAt": "2026-10-23T09:12:04.000Z",
"startedAt": null,
"finishedAt": null
},
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"queuePosition": 1
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: VALIDATION_ERROR (400), QUOTE_INVALID (400), INSUFFICIENT_CREDITS (402), PLAN_REQUIRED (403), RATE_LIMITED (429)
GET/api/v1/jobsscope jobs:read
Generations of the workspace, newest first, with cursor pagination.
Parameters
| Name | In | Type | Description |
|---|
limit | query | integer | Number of items (1 to 100, default 20) |
cursor | query | string | Cursor returned in nextCursor, for the next page |
status | query | string | Filter, one or more comma-separated values: queued, running, succeeded, failed, cancelled |
since | query | date-time | Only generations created after this date (ISO 8601) |
curl https://motiongist.com/api/v1/jobs \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"items": [
{
"id": "7f3c2a10-5b1e-4c8a-9d2f-0e6b4a1c9d55",
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"status": "running",
"stage": "storyboard",
"stageLabel": "Storyboard",
"progress": 46,
"detail": "Scene 4/9",
"stages": {},
"voiceMode": "final",
"isRevision": false,
"credits": 847,
"queuePosition": 0,
"cancellable": true,
"error": null,
"videoId": null,
"attempt": 1,
"source": "api",
"queuedAt": "2026-10-23T09:12:04.000Z",
"startedAt": "2026-10-23T09:12:09.000Z",
"finishedAt": null
}
],
"nextCursor": "2026-10-23T09:12:04.000Z"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
GET/api/v1/jobs/{id}scope jobs:read
Status, stage (script, voice, storyboard, review, render), progress in %, queue position, error if any, and videoId once finished. Poll every 5 to 10 seconds at most.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Generation idrequired |
curl https://motiongist.com/api/v1/jobs/7f3c2a10-5b1e-4c8a-9d2f-0e6b4a1c9d55 \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"id": "7f3c2a10-5b1e-4c8a-9d2f-0e6b4a1c9d55",
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"status": "succeeded",
"stage": "done",
"stageLabel": "Ready",
"progress": 100,
"detail": null,
"stages": {},
"voiceMode": "final",
"isRevision": false,
"credits": 847,
"queuePosition": 0,
"cancellable": false,
"error": null,
"videoId": "c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f",
"attempt": 1,
"source": "api",
"queuedAt": "2026-10-23T09:12:04.000Z",
"startedAt": "2026-10-23T09:12:09.000Z",
"finishedAt": "2026-10-23T09:19:41.000Z"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404)
POST/api/v1/jobs/{id}/cancelscope jobs:write
Cancels a generation as long as rendering has not started. Queued: cancelled immediately and credits refunded. Running: the engine is asked to stop, the refund follows.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Generation idrequired |
curl -X POST https://motiongist.com/api/v1/jobs/7f3c2a10-5b1e-4c8a-9d2f-0e6b4a1c9d55/cancel \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"id": "7f3c2a10-5b1e-4c8a-9d2f-0e6b4a1c9d55",
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"status": "cancelled",
"stage": "storyboard",
"stageLabel": "Storyboard",
"progress": 46,
"detail": "Scene 4/9",
"stages": {},
"voiceMode": "final",
"isRevision": false,
"credits": 847,
"queuePosition": 0,
"cancellable": false,
"error": null,
"videoId": null,
"attempt": 1,
"source": "api",
"queuedAt": "2026-10-23T09:12:04.000Z",
"startedAt": "2026-10-23T09:12:09.000Z",
"finishedAt": null
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), NOT_CANCELLABLE (409)
Post copy, sharing & publishing
GET/api/v1/videos/{id}/post-copyscope videos:read
Title, description and hashtags for YouTube, TikTok, Instagram and LinkedIn, in the video language and within each platform limit (limits are returned). Generated on the first call, then stored. caption is the text actually posted (description + hashtags).
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Video idrequired |
curl https://motiongist.com/api/v1/videos/c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f/post-copy \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"language": "en",
"generatedAt": "2026-10-23T09:20:00.000Z",
"platforms": {
"youtube": {
"title": "How a CDN works in 60 seconds #shorts",
"description": "Your files, next to your visitors.\n\nFollow for more explainers.",
"hashtags": [
"cdn",
"webdev",
"shorts"
],
"caption": "Your files, next to your visitors.\n\nFollow for more explainers.\n\n#cdn #webdev #shorts",
"limits": {
"title": 100,
"caption": 5000,
"hashtags": 15
}
}
}
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404)
POST/api/v1/videos/{id}/post-copyscope videos:write
Rewrites the copy (all platforms or some), optionally in another language. Free, limited to 60 AI calls per hour per workspace.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Video idrequired |
JSON body
| Field | Type | Description |
|---|
language | "en" | "fr" | Write it in this language (default: the current one, else the video language) |
platforms | enum[] | Only these platforms (the others are kept) |
curl -X POST https://motiongist.com/api/v1/videos/c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f/post-copy \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"language": "en",
"platforms": [
"tiktok"
]
}'
{
"data": {
"language": "en",
"generatedAt": "2026-10-23T09:20:00.000Z",
"platforms": {
"youtube": {
"title": "How a CDN works in 60 seconds #shorts",
"description": "Your files, next to your visitors.\n\nFollow for more explainers.",
"hashtags": [
"cdn",
"webdev",
"shorts"
],
"caption": "Your files, next to your visitors.\n\nFollow for more explainers.\n\n#cdn #webdev #shorts",
"limits": {
"title": 100,
"caption": 5000,
"hashtags": 15
}
}
}
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), RATE_LIMITED (429)
PATCH/api/v1/videos/{id}/post-copyscope videos:write
Replaces the given platforms. Text over a platform limit is refused (VALIDATION_ERROR), never cut. Hashtags are given without #.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Video idrequired |
JSON body
| Field | Type | Description |
|---|
language | "en" | "fr" | Narration language: en (English, default) or fr (French). |
platforms | object | required |
platforms.youtube | object | |
platforms.youtube.title | string | required |
platforms.youtube.description | string | required |
platforms.youtube.hashtags | string[] | required |
platforms.tiktok | object | |
platforms.tiktok.title | string | required |
platforms.tiktok.description | string | required |
platforms.tiktok.hashtags | string[] | required |
platforms.instagram | object | |
platforms.instagram.title | string | required |
platforms.instagram.description | string | required |
platforms.instagram.hashtags | string[] | required |
platforms.linkedin | object | |
platforms.linkedin.title | string | required |
platforms.linkedin.description | string | required |
platforms.linkedin.hashtags | string[] | required |
curl -X PATCH https://motiongist.com/api/v1/videos/c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f/post-copy \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platforms": {
"tiktok": {
"title": "How a CDN works",
"description": "Your files, next to your visitors.",
"hashtags": [
"webdev",
"cdn"
]
}
}
}'
{
"data": {
"language": "en",
"generatedAt": "2026-10-23T09:20:00.000Z",
"platforms": {
"youtube": {
"title": "How a CDN works in 60 seconds #shorts",
"description": "Your files, next to your visitors.\n\nFollow for more explainers.",
"hashtags": [
"cdn",
"webdev",
"shorts"
],
"caption": "Your files, next to your visitors.\n\nFollow for more explainers.\n\n#cdn #webdev #shorts",
"limits": {
"title": 100,
"caption": 5000,
"hashtags": 15
}
}
}
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), VALIDATION_ERROR (400)
GET/api/v1/videos/{id}/sharescope videos:read
Public share page of the video: link (unlisted, noindex), embed code, button, download, branding and view count. enabled=false means no public link.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Video idrequired |
curl https://motiongist.com/api/v1/videos/c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f/share \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"enabled": true,
"token": "Xq3vR8kP2mWz7tLa",
"url": "https://motiongist.com/v/Xq3vR8kP2mWz7tLa",
"embedUrl": "https://motiongist.com/embed/Xq3vR8kP2mWz7tLa",
"embedCode": "<iframe src=\"https://motiongist.com/embed/Xq3vR8kP2mWz7tLa\" …></iframe>",
"cta": {
"label": "Book a demo",
"url": "https://example.com/demo"
},
"allowDownload": false,
"showBranding": true,
"brandingForced": false,
"views": 128,
"createdAt": "2026-10-23T09:25:00.000Z"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404)
PATCH/api/v1/videos/{id}/sharescope videos:write
enabled=true creates the link (kept across updates); enabled=false revokes it for good (turning it back on creates a new link). cta adds a button (http/https URL). The free plan always shows the "Made with Motiongist" badge.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Video idrequired |
JSON body
| Field | Type | Description |
|---|
enabled | boolean | required |
cta | object (variants) | |
allowDownload | boolean | |
showBranding | boolean | |
curl -X PATCH https://motiongist.com/api/v1/videos/c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f/share \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"cta": {
"label": "Book a demo",
"url": "https://example.com/demo"
},
"allowDownload": false
}'
{
"data": {
"enabled": true,
"token": "Xq3vR8kP2mWz7tLa",
"url": "https://motiongist.com/v/Xq3vR8kP2mWz7tLa",
"embedUrl": "https://motiongist.com/embed/Xq3vR8kP2mWz7tLa",
"embedCode": "<iframe src=\"https://motiongist.com/embed/Xq3vR8kP2mWz7tLa\" …></iframe>",
"cta": {
"label": "Book a demo",
"url": "https://example.com/demo"
},
"allowDownload": false,
"showBranding": true,
"brandingForced": false,
"views": 128,
"createdAt": "2026-10-23T09:25:00.000Z"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), VALIDATION_ERROR (400)
GET/api/v1/social-accountsscope videos:read
YouTube, TikTok, Instagram and LinkedIn accounts connected by the workspace members in the web app (/app/publishing; connecting needs a browser). platforms tells which platforms this server can publish to.
curl https://motiongist.com/api/v1/social-accounts \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"items": [
{
"id": "01970d2c-55aa-7c1e-9d0b-3e4f5a6b7c8d",
"provider": "youtube",
"name": "Motiongist Demo",
"avatarUrl": null,
"status": "active",
"simulated": false,
"connectedAt": "2026-10-20T14:02:00.000Z",
"updatedAt": "2026-10-20T14:02:00.000Z"
}
],
"platforms": [
{
"id": "youtube",
"available": true,
"mode": "live"
}
]
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
GET/api/v1/postsscope videos:read
Posts of the workspace, filtered by scheduled date (from, to), status or video.
Parameters
| Name | In | Type | Description |
|---|
from | query | date-time | Scheduled at or after (ISO 8601 with offset) |
to | query | date-time | Scheduled at or before |
status | query | string | scheduled, publishing, published, failed or cancelled |
videoId | query | uuid | Only the posts of this video |
limit | query | integer | Number of items (1 to 500, default 100) |
curl https://motiongist.com/api/v1/posts \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"items": [
{
"id": "01970d2c-77cc-7e3a-8f1b-5a6b7c8d9e0f",
"videoId": "c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f",
"videoTitle": "How a CDN works",
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"accountId": "01970d2c-55aa-7c1e-9d0b-3e4f5a6b7c8d",
"accountName": "Motiongist Demo",
"provider": "youtube",
"status": "scheduled",
"scheduledAt": "2026-10-30T16:30:00.000Z",
"publishedAt": null,
"copy": {
"title": "How a CDN works in 60 seconds #shorts",
"description": "Your files, next to your visitors.\n\nFollow for more explainers.",
"hashtags": [
"cdn",
"webdev",
"shorts"
]
},
"caption": "Your files, next to your visitors.\n\nFollow for more explainers.\n\n#cdn #webdev #shorts",
"options": {},
"externalId": null,
"externalUrl": null,
"error": null,
"attempts": 0,
"createdAt": "2026-10-23T09:30:00.000Z"
}
]
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
POST/api/v1/postsscope videos:write
Queues a video for a connected account, now (scheduledAt omitted) or at scheduledAt (up to 1 year ahead). Uses the video post copy for the platform unless copy is given. Costs no credits. The worker publishes within seconds of the date, retries temporary errors (after 1 min, 5 min, 30 min) and emits post.published or post.failed.
JSON body
| Field | Type | Description |
|---|
videoId | uuid | required |
accountId | uuid | required |
scheduledAt | object (variants) | |
copy | object | |
copy.title | string | required |
copy.description | string | required |
copy.hashtags | string[] | required |
options | object | |
options.privacy | "public" | "unlisted" | "private" | |
options.simulate | "transient" | "permanent" | "auth" | |
curl -X POST https://motiongist.com/api/v1/posts \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"videoId": "c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f",
"accountId": "01970d2c-55aa-7c1e-9d0b-3e4f5a6b7c8d",
"scheduledAt": "2026-10-30T17:30:00+01:00"
}'
{
"data": {
"id": "01970d2c-77cc-7e3a-8f1b-5a6b7c8d9e0f",
"videoId": "c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f",
"videoTitle": "How a CDN works",
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"accountId": "01970d2c-55aa-7c1e-9d0b-3e4f5a6b7c8d",
"accountName": "Motiongist Demo",
"provider": "youtube",
"status": "scheduled",
"scheduledAt": "2026-10-30T16:30:00.000Z",
"publishedAt": null,
"copy": {
"title": "How a CDN works in 60 seconds #shorts",
"description": "Your files, next to your visitors.\n\nFollow for more explainers.",
"hashtags": [
"cdn",
"webdev",
"shorts"
]
},
"caption": "Your files, next to your visitors.\n\nFollow for more explainers.\n\n#cdn #webdev #shorts",
"options": {},
"externalId": null,
"externalUrl": null,
"error": null,
"attempts": 0,
"createdAt": "2026-10-23T09:30:00.000Z"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), VALIDATION_ERROR (400)
GET/api/v1/posts/{id}scope videos:read
Status of a post; externalUrl once published, error when it failed.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Post idrequired |
curl https://motiongist.com/api/v1/posts/01970d2c-77cc-7e3a-8f1b-5a6b7c8d9e0f \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"id": "01970d2c-77cc-7e3a-8f1b-5a6b7c8d9e0f",
"videoId": "c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f",
"videoTitle": "How a CDN works",
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"accountId": "01970d2c-55aa-7c1e-9d0b-3e4f5a6b7c8d",
"accountName": "Motiongist Demo",
"provider": "youtube",
"status": "published",
"scheduledAt": "2026-10-30T16:30:00.000Z",
"publishedAt": "2026-10-30T16:30:08.000Z",
"copy": {
"title": "How a CDN works in 60 seconds #shorts",
"description": "Your files, next to your visitors.\n\nFollow for more explainers.",
"hashtags": [
"cdn",
"webdev",
"shorts"
]
},
"caption": "Your files, next to your visitors.\n\nFollow for more explainers.\n\n#cdn #webdev #shorts",
"options": {},
"externalId": "dQw4w9WgXcQ",
"externalUrl": "https://www.youtube.com/shorts/dQw4w9WgXcQ",
"error": null,
"attempts": 0,
"createdAt": "2026-10-23T09:30:00.000Z"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404)
PATCH/api/v1/posts/{id}scope videos:write
Moves a scheduled post, or re-queues a failed or cancelled one (attempts reset).
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Post idrequired |
JSON body
| Field | Type | Description |
|---|
scheduledAt | object (variants) | New time (ISO 8601 with offset); null = nowrequired |
curl -X PATCH https://motiongist.com/api/v1/posts/01970d2c-77cc-7e3a-8f1b-5a6b7c8d9e0f \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"scheduledAt": "2026-10-31T09:00:00+01:00"
}'
{
"data": {
"id": "01970d2c-77cc-7e3a-8f1b-5a6b7c8d9e0f",
"videoId": "c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f",
"videoTitle": "How a CDN works",
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"accountId": "01970d2c-55aa-7c1e-9d0b-3e4f5a6b7c8d",
"accountName": "Motiongist Demo",
"provider": "youtube",
"status": "scheduled",
"scheduledAt": "2026-10-30T16:30:00.000Z",
"publishedAt": null,
"copy": {
"title": "How a CDN works in 60 seconds #shorts",
"description": "Your files, next to your visitors.\n\nFollow for more explainers.",
"hashtags": [
"cdn",
"webdev",
"shorts"
]
},
"caption": "Your files, next to your visitors.\n\nFollow for more explainers.\n\n#cdn #webdev #shorts",
"options": {},
"externalId": null,
"externalUrl": null,
"error": null,
"attempts": 0,
"createdAt": "2026-10-23T09:30:00.000Z"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), CONFLICT (409), VALIDATION_ERROR (400)
DELETE/api/v1/posts/{id}scope videos:write
Cancels a post that has not started publishing (CONFLICT otherwise).
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Post idrequired |
curl -X DELETE https://motiongist.com/api/v1/posts/01970d2c-77cc-7e3a-8f1b-5a6b7c8d9e0f \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"id": "01970d2c-77cc-7e3a-8f1b-5a6b7c8d9e0f",
"videoId": "c4d5e6f7-1a2b-4c3d-8e9f-0a1b2c3d4e5f",
"videoTitle": "How a CDN works",
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"accountId": "01970d2c-55aa-7c1e-9d0b-3e4f5a6b7c8d",
"accountName": "Motiongist Demo",
"provider": "youtube",
"status": "cancelled",
"scheduledAt": "2026-10-30T16:30:00.000Z",
"publishedAt": null,
"copy": {
"title": "How a CDN works in 60 seconds #shorts",
"description": "Your files, next to your visitors.\n\nFollow for more explainers.",
"hashtags": [
"cdn",
"webdev",
"shorts"
]
},
"caption": "Your files, next to your visitors.\n\nFollow for more explainers.\n\n#cdn #webdev #shorts",
"options": {},
"externalId": null,
"externalUrl": null,
"error": null,
"attempts": 0,
"createdAt": "2026-10-23T09:30:00.000Z"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), CONFLICT (409)
Projects
GET/api/v1/projectsscope jobs:read
Projects (studio drafts) of the workspace, most recently updated first.
Parameters
| Name | In | Type | Description |
|---|
limit | query | integer | Number of items (1 to 100, default 20) |
cursor | query | string | Cursor returned in nextCursor, for the next page |
status | query | string | draft, queued, generating, ready or failed |
q | query | string | Search in the title |
curl https://motiongist.com/api/v1/projects \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"items": [
{
"id": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"title": "How a CDN works",
"status": "draft",
"draft": {
"subject": "How a CDN works",
"inputKind": "script",
"audience": "dev",
"length": "standard",
"language": "en",
"voice": "George",
"look": {
"mode": "preset",
"preset": "night"
},
"notes": {
"mustShow": [],
"avoid": []
},
"mascot": false,
"tier": "standard",
"format": "9:16",
"captions": true,
"music": true
},
"script": "Your site takes 3 seconds to load in Tokyo? The problem isn’t your server. It’s the distance…",
"narration": null,
"latestJobId": null,
"latestVideoId": null,
"source": "api",
"createdAt": "2026-10-23T09:02:11.000Z",
"updatedAt": "2026-10-23T09:04:37.000Z",
"url": "https://motiongist.com/app/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b"
}
],
"nextCursor": "2026-10-23T09:12:04.000Z"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
POST/api/v1/projectsscope jobs:write
Creates a draft, like in the studio: settings, script, voice preview, then estimate and generate. Handy for an agent that iterates with the user before paying. The project also shows up in the web studio.
JSON body
| Field | Type | Description |
|---|
title | string | Title (120 characters max). Default: the subject. |
script | string | Exact text to narrate. Without a script, POST /projects/{id}/script writes one. |
draft | object | Project settings: subject, audience, length, language (en or fr), voice, look, brand, notes… |
draft.subject | string | Video subject. |
draft.inputKind | "idea" | "script" | "url" | "document" | idea, script, url or document. |
draft.sourceText | string | Source text (document, web page) whose facts must be used. |
draft.sourceName | string | |
draft.sourceUrl | string | |
draft.audience | "beginner" | "dev" | "ops" | "decision-maker" | Target audience: beginner, dev, ops or decision-maker. |
draft.length | "short" | "standard" | "full" | Length: short (45–60 s), standard (90–120 s) or full (150–180 s). |
draft.language | "fr" | "en" | Narration language: en (English, default) or fr (French). |
draft.voice | string | Narrator voice (see GET /catalog): George, Sarah, Daniel, Brian, Lily, Alice, Will, Matilda. Every voice speaks both languages. |
draft.look | object (variants) | Visual style: { mode: "preset", preset: "clean" | "night" | "toon" }, { mode: "brand" } (brand colors, brand field required) or { mode: "custom", description } (Studio plan). |
draft.brand | object | Brand shown: name (24 chars), site, colors (1 to 3 #RRGGBB colors), logo ("asset:<id>" returned by POST /assets). |
draft.brand.name | string | Brand name (24 characters max).required |
draft.brand.site | string | Website shown at the end of the video (40 characters max). |
draft.brand.colors | string[] | 1 to 3 hex colors #RRGGBB.required |
draft.brand.logo | string | Logo: "asset:<id>" returned by POST /assets. |
draft.notes | object | Instructions: mustShow (up to 10 things to show), avoid (things to avoid), keyMoment, free (free text). |
draft.notes.mustShow | string[] | Things that must be shown (10 max, 80 chars each). |
draft.notes.avoid | string[] | Things to avoid (10 max). |
draft.notes.keyMoment | string | The key moment to highlight. |
draft.notes.free | string | Free-form instructions (1,000 characters max). |
draft.mascot | boolean | Adds an animated presenter. |
draft.tier | "standard" | "studio" | standard, or studio (higher quality, +300 credits, Studio plan). |
draft.dimension | "2d" | "3d" | 2d (flat motion design, default) or 3d (perspective, volume, depth and camera moves). |
draft.format | "9:16" | "16:9" | Format: 9:16 (vertical) or 16:9. |
draft.captions | boolean | Burned-in captions. |
draft.music | boolean | Background music. |
curl -X POST https://motiongist.com/api/v1/projects \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"draft": {
"subject": "How a CDN works",
"length": "standard",
"language": "en",
"voice": "George",
"look": {
"mode": "preset",
"preset": "night"
}
}
}'
{
"data": {
"id": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"title": "How a CDN works",
"status": "draft",
"draft": {
"subject": "How a CDN works",
"inputKind": "script",
"audience": "dev",
"length": "standard",
"language": "en",
"voice": "George",
"look": {
"mode": "preset",
"preset": "night"
},
"notes": {
"mustShow": [],
"avoid": []
},
"mascot": false,
"tier": "standard",
"format": "9:16",
"captions": true,
"music": true
},
"script": "Your site takes 3 seconds to load in Tokyo? The problem isn’t your server. It’s the distance…",
"narration": null,
"latestJobId": null,
"latestVideoId": null,
"source": "api",
"createdAt": "2026-10-23T09:02:11.000Z",
"updatedAt": "2026-10-23T09:04:37.000Z",
"url": "https://motiongist.com/app/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: VALIDATION_ERROR (400)
GET/api/v1/projects/{id}scope jobs:read
Settings, script, narration preview, latest generation and latest video of the project.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
curl https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"id": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"title": "How a CDN works",
"status": "draft",
"draft": {
"subject": "How a CDN works",
"inputKind": "script",
"audience": "dev",
"length": "standard",
"language": "en",
"voice": "George",
"look": {
"mode": "preset",
"preset": "night"
},
"notes": {
"mustShow": [],
"avoid": []
},
"mascot": false,
"tier": "standard",
"format": "9:16",
"captions": true,
"music": true
},
"script": "Your site takes 3 seconds to load in Tokyo? The problem isn’t your server. It’s the distance…",
"narration": null,
"latestJobId": null,
"latestVideoId": null,
"source": "api",
"createdAt": "2026-10-23T09:02:11.000Z",
"updatedAt": "2026-10-23T09:04:37.000Z",
"url": "https://motiongist.com/app/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404)
PATCH/api/v1/projects/{id}scope jobs:write
Updates the title, the script (null to clear it) or part of the settings (merged with the existing ones). Any change invalidates the previous quote.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
JSON body
| Field | Type | Description |
|---|
title | string | Title (120 characters max). Default: the subject. |
script | object (variants) | |
draft | object | |
draft.subject | string | Video subject. |
draft.inputKind | "idea" | "script" | "url" | "document" | idea, script, url or document. |
draft.sourceText | string | Source text (document, web page) whose facts must be used. |
draft.sourceName | string | |
draft.sourceUrl | string | |
draft.audience | "beginner" | "dev" | "ops" | "decision-maker" | Target audience: beginner, dev, ops or decision-maker. |
draft.length | "short" | "standard" | "full" | Length: short (45–60 s), standard (90–120 s) or full (150–180 s). |
draft.language | "fr" | "en" | Narration language: en (English, default) or fr (French). |
draft.voice | string | Narrator voice (see GET /catalog): George, Sarah, Daniel, Brian, Lily, Alice, Will, Matilda. Every voice speaks both languages. |
draft.look | object (variants) | Visual style: { mode: "preset", preset: "clean" | "night" | "toon" }, { mode: "brand" } (brand colors, brand field required) or { mode: "custom", description } (Studio plan). |
draft.brand | object | Brand shown: name (24 chars), site, colors (1 to 3 #RRGGBB colors), logo ("asset:<id>" returned by POST /assets). |
draft.brand.name | string | Brand name (24 characters max).required |
draft.brand.site | string | Website shown at the end of the video (40 characters max). |
draft.brand.colors | string[] | 1 to 3 hex colors #RRGGBB.required |
draft.brand.logo | string | Logo: "asset:<id>" returned by POST /assets. |
draft.notes | object | Instructions: mustShow (up to 10 things to show), avoid (things to avoid), keyMoment, free (free text). |
draft.notes.mustShow | string[] | Things that must be shown (10 max, 80 chars each). |
draft.notes.avoid | string[] | Things to avoid (10 max). |
draft.notes.keyMoment | string | The key moment to highlight. |
draft.notes.free | string | Free-form instructions (1,000 characters max). |
draft.mascot | boolean | Adds an animated presenter. |
draft.tier | "standard" | "studio" | standard, or studio (higher quality, +300 credits, Studio plan). |
draft.dimension | "2d" | "3d" | 2d (flat motion design, default) or 3d (perspective, volume, depth and camera moves). |
draft.format | "9:16" | "16:9" | Format: 9:16 (vertical) or 16:9. |
draft.captions | boolean | Burned-in captions. |
draft.music | boolean | Background music. |
curl -X PATCH https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"draft": {
"voice": "Sarah",
"length": "short"
}
}'
{
"data": {
"id": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"title": "How a CDN works",
"status": "draft",
"draft": {
"subject": "How a CDN works",
"inputKind": "script",
"audience": "dev",
"length": "standard",
"language": "en",
"voice": "George",
"look": {
"mode": "preset",
"preset": "night"
},
"notes": {
"mustShow": [],
"avoid": []
},
"mascot": false,
"tier": "standard",
"format": "9:16",
"captions": true,
"music": true
},
"script": "Your site takes 3 seconds to load in Tokyo? The problem isn’t your server. It’s the distance…",
"narration": null,
"latestJobId": null,
"latestVideoId": null,
"source": "api",
"createdAt": "2026-10-23T09:02:11.000Z",
"updatedAt": "2026-10-23T09:04:37.000Z",
"url": "https://motiongist.com/app/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), VALIDATION_ERROR (400)
DELETE/api/v1/projects/{id}scope jobs:write
Deletes the project and its videos. Refused (409) while a generation is running.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
curl -X DELETE https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"id": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"deleted": true
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), CONFLICT (409)
POST/api/v1/projects/{id}/scriptscope jobs:write
Writes a narrated script (hook, one idea per sentence, recap) from the project subject or source document, in the project language, and saves it to the project. Free, limited to 60 AI calls per hour per workspace.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
JSON body
| Field | Type | Description |
|---|
topic | string | Topic to cover (default: the project subject) |
tone | string | Desired tone, e.g. "funny and direct" |
curl -X POST https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b/script \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"tone": "direct, with a touch of humor"
}'
{
"data": {
"title": "How a CDN works",
"script": "Your site takes 3 seconds to load in Tokyo? The problem isn’t your server. It’s the distance…",
"words": 246,
"seconds": 100,
"source": "llm",
"project": {
"id": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"title": "How a CDN works",
"status": "draft",
"draft": {
"subject": "How a CDN works",
"inputKind": "script",
"audience": "dev",
"length": "standard",
"language": "en",
"voice": "George",
"look": {
"mode": "preset",
"preset": "night"
},
"notes": {
"mustShow": [],
"avoid": []
},
"mascot": false,
"tier": "standard",
"format": "9:16",
"captions": true,
"music": true
},
"script": "Your site takes 3 seconds to load in Tokyo? The problem isn’t your server. It’s the distance…",
"narration": null,
"latestJobId": null,
"latestVideoId": null,
"source": "api",
"createdAt": "2026-10-23T09:02:11.000Z",
"updatedAt": "2026-10-23T09:04:37.000Z",
"url": "https://motiongist.com/app/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b"
}
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), VALIDATION_ERROR (400), RATE_LIMITED (429)
POST/api/v1/projects/{id}/narrationscope jobs:write
Synthesizes the script with the chosen voice so you can listen before generating. Free, cached as long as the text and the voice do not change. Returns an audio URL valid for 15 minutes.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
curl -X POST https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b/narration \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"narration": {
"assetId": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
"voice": "George",
"provider": "edge",
"seconds": 98.4,
"words": 246
},
"audioUrl": "https://motiongist.com/api/files/narrations/…"
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), VALIDATION_ERROR (400), RATE_LIMITED (429)
GET/api/v1/projects/{id}/storyboardscope jobs:read
The scene plan of the project: status (none, planning, ready, failed) and scenes (id, stage, narration, intent). After a render it is the storyboard of the latest video; dirty lists the scenes the next render rebuilds.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
curl https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b/storyboard \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"supported": true,
"status": "ready",
"source": "engine",
"basedOnVideoId": null,
"dirty": [],
"planJob": null,
"error": null,
"updatedAt": "2026-10-23T09:14:00.000Z",
"plan": {
"title": "How a CDN works",
"look": "night",
"presenter": false,
"scenes": [
{
"id": "s1",
"stage": "hero",
"narration": "Your site lives on one server. Your visitors live everywhere.",
"intent": "A single server in Virginia, dots of visitors light up around the globe."
},
{
"id": "s2",
"stage": "graph",
"narration": "A CDN keeps copies of it close to every visitor.",
"intent": "Edge servers pop up on each continent on “copies”, lines shorten on “close”."
},
{
"id": "s3",
"stage": "split",
"narration": "Pages load faster, and your server breathes.",
"intent": "Left: stopwatch 800 → 40 ms. Right: CPU gauge drops."
}
]
}
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404)
POST/api/v1/projects/{id}/storyboardscope jobs:write
Optional and free: the engine plans the video scene by scene in about a minute, so the user can review it before paying for a render. Poll GET until status is ready. The render then follows the storyboard exactly.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
curl -X POST https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b/storyboard \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"jobId": "7f3c2a10-5b1e-4c8a-9d2f-0e6b4a1c9d55",
"reused": false,
"storyboard": {
"supported": true,
"status": "planning",
"source": "engine",
"basedOnVideoId": null,
"dirty": [],
"planJob": null,
"error": null,
"updatedAt": "2026-10-23T09:14:00.000Z",
"plan": null
}
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), CONFLICT (409), RATE_LIMITED (429)
PATCH/api/v1/projects/{id}/storyboardscope jobs:write
Replaces the ordered scene list (3 to 24 scenes). Keep the id of existing scenes, omit it for new ones. Edited scenes are rebuilt on the next render; untouched scenes of a rendered video keep their visuals. Estimate again afterwards.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
JSON body
| Field | Type | Description |
|---|
title | string | Title (120 characters max). Default: the subject. |
scenes | object[] | required |
curl -X PATCH https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b/storyboard \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"scenes": [
{
"id": "s1",
"narration": "A CDN keeps copies of your site close to every visitor.",
"intent": "World map, servers light up on “close”."
},
{
"narration": "New scene without id.",
"intent": "Stopwatch drops from 800 to 40 ms."
},
{
"id": "s3",
"narration": "Faster pages, lighter servers.",
"intent": "Two gauges move in opposite directions."
}
]
}'
{
"data": {
"supported": true,
"status": "ready",
"source": "engine",
"basedOnVideoId": null,
"dirty": [],
"planJob": null,
"error": null,
"updatedAt": "2026-10-23T09:14:00.000Z",
"plan": {
"title": "How a CDN works",
"look": "night",
"presenter": false,
"scenes": [
{
"id": "s1",
"stage": "hero",
"narration": "Your site lives on one server. Your visitors live everywhere.",
"intent": "A single server in Virginia, dots of visitors light up around the globe."
},
{
"id": "s2",
"stage": "graph",
"narration": "A CDN keeps copies of it close to every visitor.",
"intent": "Edge servers pop up on each continent on “copies”, lines shorten on “close”."
},
{
"id": "s3",
"stage": "split",
"narration": "Pages load faster, and your server breathes.",
"intent": "Left: stopwatch 800 → 40 ms. Right: CPU gauge drops."
}
]
}
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), CONFLICT (409), VALIDATION_ERROR (400)
POST/api/v1/projects/{id}/storyboard/regeneratescope jobs:write
Marks scenes to be rebuilt on the next render even though their text did not change (new take on the visuals). The other scenes are reused as they are.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
JSON body
| Field | Type | Description |
|---|
sceneIds | string[] | required |
curl -X POST https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b/storyboard/regenerate \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"sceneIds": [
"s2"
]
}'
{
"data": {
"supported": true,
"status": "ready",
"source": "engine",
"basedOnVideoId": null,
"dirty": [
"s2"
],
"planJob": null,
"error": null,
"updatedAt": "2026-10-23T09:14:00.000Z",
"plan": {
"title": "How a CDN works",
"look": "night",
"presenter": false,
"scenes": [
{
"id": "s1",
"stage": "hero",
"narration": "Your site lives on one server. Your visitors live everywhere.",
"intent": "A single server in Virginia, dots of visitors light up around the globe."
},
{
"id": "s2",
"stage": "graph",
"narration": "A CDN keeps copies of it close to every visitor.",
"intent": "Edge servers pop up on each continent on “copies”, lines shorten on “close”."
},
{
"id": "s3",
"stage": "split",
"narration": "Pages load faster, and your server breathes.",
"intent": "Left: stopwatch 800 → 40 ms. Right: CPU gauge drops."
}
]
}
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), CONFLICT (409), VALIDATION_ERROR (400)
DELETE/api/v1/projects/{id}/storyboardscope jobs:write
Removes the storyboard: the engine plans the scenes itself during the next render.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
curl -X DELETE https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b/storyboard \
-H "X-API-Key: $MOTIONGIST_API_KEY"
{
"data": {
"supported": true,
"status": "none",
"source": "engine",
"basedOnVideoId": null,
"dirty": [],
"planJob": null,
"error": null,
"updatedAt": "2026-10-23T09:14:00.000Z",
"plan": null
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404)
POST/api/v1/projects/{id}/estimatescope jobs:read
Exact price in credits for the current state of the project, and a signed quote valid for 1 hour. A new version of an already generated project is billed as a revision (50% of the base price).
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
JSON body
| Field | Type | Description |
|---|
voiceMode | "draft" | "final" | final = licensed voice (paid plans), draft = free draft voice. Default: final on paid plans. |
curl -X POST https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b/estimate \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"voiceMode": "final"
}'
{
"data": {
"total": 847,
"lines": [
{
"label": "Standard video (90–120 s)",
"credits": 700
},
{
"label": "Final voice (1,470 characters)",
"credits": 147
}
],
"quote": "eyJ3cyI6IjQ…(signed quote, pass it back unchanged)…",
"quoteExpiresAt": "2026-10-23T10:12:00.000Z",
"voiceMode": "final",
"isRevision": false,
"balance": 29153,
"allowed": true,
"blockers": [],
"overdraft": false,
"eta": {
"minutesMin": 4,
"minutesMax": 8
}
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), VALIDATION_ERROR (400)
POST/api/v1/projects/{id}/generatescope jobs:write
Starts the generation at the quoted price. The quote is required: if it expired or the project changed since the estimate, the response is QUOTE_INVALID and you need to estimate again.
Parameters
| Name | In | Type | Description |
|---|
id | path | uuid | Project idrequired |
JSON body
| Field | Type | Description |
|---|
quote | string | Signed quote returned by POST /projects/{id}/estimate (valid 1 h)required |
curl -X POST https://motiongist.com/api/v1/projects/2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b/generate \
-H "X-API-Key: $MOTIONGIST_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"quote": "eyJ3cyI6IjQ…(signed quote, pass it back unchanged)…"
}'
{
"data": {
"job": {
"id": "7f3c2a10-5b1e-4c8a-9d2f-0e6b4a1c9d55",
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"status": "queued",
"stage": "storyboard",
"stageLabel": "Storyboard",
"progress": 0,
"detail": "Scene 4/9",
"stages": {},
"voiceMode": "final",
"isRevision": false,
"credits": 847,
"queuePosition": 0,
"cancellable": true,
"error": null,
"videoId": null,
"attempt": 1,
"source": "api",
"queuedAt": "2026-10-23T09:12:04.000Z",
"startedAt": "2026-10-23T09:12:09.000Z",
"finishedAt": null
},
"projectId": "2b9e4d71-8c0a-4f3e-a6b5-1d2c3e4f5a6b",
"queuePosition": 1
},
"requestId": "req_3f9a1c2e7b8d4a60"
}
Possible errors: NOT_FOUND (404), QUOTE_INVALID (400), INSUFFICIENT_CREDITS (402), PLAN_REQUIRED (403)