{"openapi":"3.1.0","info":{"title":"GPT-Video API","version":"1","description":"GPT-Video turns long videos into short vertical clips. This is its REST API.\n\nAuthenticate every request with an API key: `Authorization: Bearer gvk_...`. Keys are created in the GPT-Video app.\n\nErrors share one body, `{ \"error\": { \"code\", \"message\", \"hint\", \"requestId\", \"details\" } }`. The `code` says what to do next; the HTTP status is only its class.\n\nSend the same request again only after a code listed in `x-retryable`, after the seconds in `Retry-After` when the answer has it, and with the same Idempotency-Key.\n\nA POST that spends (credits, or an export from the daily allowance) needs an `Idempotency-Key` header; retrying with the same key never spends twice.\n\n`x-scope` is the scope an API key needs for an operation. When it needs more than one, `x-scopes` lists all of them. `x-bonus-credits` is the number of API bonus credits an operation uses when the API bonus pays for it, besides its daily allowance. An operation that spends credits uses the same number of API bonus credits when the API bonus pays for it.\n\nWebhooks send events to an address you add on the Developers page of the GPT-Video app, at /app/developers, signed as Standard Webhooks describes. An event tells you that something changed. Call get_job or get_export to read its current state."},"servers":[{"url":"https://api.gpt-video.com/v1"}],"security":[{"apiKey":[]}],"tags":[{"name":"account","description":"Account and credits"},{"name":"uploads","description":"Uploads"},{"name":"assets","description":"Videos and transcripts"},{"name":"projects","description":"Projects and analysis"},{"name":"clips","description":"Clips"},{"name":"compositions","description":"Compositions and captions"},{"name":"exports","description":"Exports"},{"name":"studio","description":"Formats"},{"name":"tools","description":"Tools"},{"name":"editing","description":"Timeline editing"},{"name":"assistant","description":"Editor Assistant"},{"name":"jobs","description":"Jobs"},{"name":"reference","description":"Settings and voice list"},{"name":"webhooks","description":"Webhooks"}],"paths":{"/me":{"get":{"operationId":"get_me","summary":"Get the current key","description":"Returns the API key in use, its scopes and the plan of the account it belongs to.\n\nCall this first to check that a key works and what it may do, before you upload or spend anything. It returns the id of the key that made the request, its scopes and the plan of its account. It changes nothing and uses no credits.","tags":["account"],"parameters":[],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"object","properties":{"id":{"type":"string","description":"The id of the API key that made the request. It starts with mck_; the secret itself is never shown again."},"scopes":{"type":"array","items":{"type":"string","enum":["clips:read","clips:write","spend"]},"description":"What the key may do: clips:read reads, clips:write changes things, spend uses credits or the daily export allowance (analyses and exports)."}},"required":["id","scopes"],"description":"The API key that made the request."},"account":{"type":"object","properties":{"plan":{"type":"string","enum":["free","starter","creator","studio","unlimited"],"description":"The plan of the account the key belongs to."}},"required":["plan"],"description":"The account the key belongs to."}},"required":["key","account"]},"examples":{"example1":{"summary":"Check a key before using it","value":{"key":{"id":"mck_5f2c9e1a7b3d8046","scopes":["clips:read","clips:write","spend"]},"account":{"plan":"creator"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/credits":{"get":{"operationId":"get_credits","summary":"Get the credit balance","description":"Returns the credits the account can spend now, split between this month's plan credits and the top-up, the API bonus, and today's daily limits.\n\nCall this before you start an analysis or an export, to know whether the account can pay for it. remaining is what a charge can use right now, as long as planRequired is false: this month's plan credits first, then the top-up. Through the API, the plan credits and the top-up are spent only on the Creator and Studio plans. On any other plan a call through the API spends only the API bonus, and a charge the bonus cannot pay answers PLAN_REQUIRED. The plan credits start again from included on the 1st of each month (UTC) and are not carried over. Top-up credits you bought do not expire. Credits that the GPT-Video app granted to a new account without a purchase expire after a set number of days and are spent only in the app. planRequired is true when the account must choose a plan in the GPT-Video app before it can spend its credits. The API bonus is shown apart, in bonus, and is not part of remaining: while it is active, a call through the API spends the bonus first, even when planRequired is true. Exports, Editor Assistant turns, tool runs and fake text scripts have daily limits, shown in dailyLimits. To see how the balance moved, call list_ledger_entries.","tags":["account"],"parameters":[],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["free","starter","creator","studio","unlimited"],"description":"The plan of the account."},"planRequired":{"type":"boolean","description":"true when the account must choose a plan before it can spend its credits or export; reading works either way. While bonus.status is active, a call through the API still spends the bonus. It does not say whether the API may spend the plan credits: only the Creator and Studio plans can."},"credits":{"type":"object","properties":{"period":{"type":"string","description":"The calendar month the plan credits belong to, as YYYY-MM (UTC)."},"periodEndsAt":{"type":"string","description":"When the month ends and the plan credits start again from included: the 1st of the next month at 00:00 UTC."},"included":{"type":"integer","description":"How many credits the plan gives each month."},"remaining":{"type":"integer","description":"How many credits a charge can use right now: remainingFromPlan plus topUp. While planRequired is true, these credits cannot be spent, even when this is above 0. Through the API, they can be spent only on the Creator and Studio plans. The API bonus is not part of it: see bonus."},"remainingFromPlan":{"type":"integer","description":"What is left of this month's plan credits, never below 0. They are spent first."},"topUp":{"type":"integer","description":"Credits on top of the plan, never below 0. They are spent after the plan credits. Credits you bought do not expire. Credits that the GPT-Video app granted to a new account without a purchase expire after a set number of days and are spent only in the app."}},"required":["period","periodEndsAt","included","remaining","remainingFromPlan","topUp"],"description":"The plan credits and the top-up of the account. Analyses are paid in credits."},"bonus":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","enum":["active","used_up","expired","paused","cancelled"],"description":"active: calls through the API spend it now. used_up: no credits are left. expired: expiresAt has passed, and what was left can no longer be spent. paused: it cannot be spent for now; resumesAt says when it starts again. cancelled: it was cancelled, as the API terms allow for a bonus obtained by misuse."},"granted":{"type":"integer","description":"How many credits the bonus gave."},"remaining":{"type":"integer","description":"How many bonus credits are left, never below 0. They can be spent only while status is active."},"grantedAt":{"type":"string","description":"When the bonus was given."},"expiresAt":{"type":"string","description":"When the bonus ends. Bonus credits left after this time are lost."},"resumesAt":{"type":["string","null"],"description":"When a paused bonus can be spent again: the next 00:00 UTC, when the bonus has reached today's spending limit. null in every other case, also when it was paused with no set end."}},"required":["status","granted","remaining","grantedAt","expiresAt","resumesAt"]},{"type":"null"}],"description":"The API bonus: credits given once to the account for using the API. It is not part of remaining. While status is active, a call through the API that costs credits spends the bonus before the plan credits and the top-up, even when planRequired is true; on any plan but Creator and Studio the bonus also pays for exports, Editor Assistant turns, tool runs and fake text scripts, within its own daily limits. A charge the bonus cannot cover in full is never split: on the Creator and Studio plans the plan pays it, and on any other plan it is refused. Every account can receive the bonus, whatever its plan. Calls from the GPT-Video app never spend it. null when the account never received one."},"dailyLimits":{"type":"object","properties":{"resetsAt":{"type":"string","description":"When the daily limits start again: the next 00:00 UTC."},"exports":{"type":"object","properties":{"limit":{"type":"integer","description":"How many exports can start each day through the API. On the Creator and Studio plans, the plan's limit. On any other plan, the API bonus's limit while the bonus is active (the account's own limit when it is lower), and 0 when the bonus is not active."},"used":{"type":"integer","description":"How many exports started today, from the API and from the GPT-Video app."},"remaining":{"type":"integer","description":"How many more exports can start today, never below 0."}},"required":["limit","used","remaining"],"description":"Exports use no credits: they count against this daily limit."},"assistantTurns":{"type":"object","properties":{"limit":{"type":"integer","description":"How many Editor Assistant turns can start each day through the API. On the Creator and Studio plans, the plan's limit. On any other plan, the API bonus's limit while the bonus is active (the account's own limit when it is lower), and 0 when the bonus is not active."},"used":{"type":"integer","description":"How many Editor Assistant turns started today, from the API and from the GPT-Video app."},"remaining":{"type":"integer","description":"How many more Editor Assistant turns can start today, never below 0."}},"required":["limit","used","remaining"],"description":"Turns of the Editor Assistant."},"toolRuns":{"type":"object","properties":{"limit":{"type":"integer","description":"How many tool runs can start each day through the API. On the Creator and Studio plans, the plan's limit. On any other plan, the API bonus's limit while the bonus is active (the account's own limit when it is lower), and 0 when the bonus is not active."},"used":{"type":"integer","description":"How many tool runs started today, from the API and from the GPT-Video app."},"remaining":{"type":"integer","description":"How many more tool runs can start today, never below 0."}},"required":["limit","used","remaining"],"description":"Tool runs: voiceovers, audio separations and brainstorms."},"fakeTextScripts":{"type":"object","properties":{"limit":{"type":"integer","description":"How many fake text scripts can start each day through the API. On the Creator and Studio plans, the plan's limit. On any other plan, the API bonus's limit while the bonus is active (the account's own limit when it is lower), and 0 when the bonus is not active."},"used":{"type":"integer","description":"How many fake text scripts started today, from the API and from the GPT-Video app."},"remaining":{"type":"integer","description":"How many more fake text scripts can start today, never below 0."}},"required":["limit","used","remaining"],"description":"Fake text scripts: a story written by the model, or a request for the voices of a story."},"assistantTurnsThroughApi":{"anyOf":[{"type":"object","properties":{"limit":{"type":"integer","description":"How many Editor Assistant turns can start through the API each day: a fifth of the plan's assistantTurns limit, rounded up."},"used":{"type":"integer","description":"How many turns started through the API today."},"remaining":{"type":"integer","description":"How many more turns can start through the API today, never below 0. Each of them also needs room in assistantTurns."}},"required":["limit","used","remaining"]},{"type":"null"}],"description":"On the Creator and Studio plans, the part of assistantTurns that calls through the API may use. null on any other plan: its turns through the API are paid by the API bonus and counted in assistantTurns."}},"required":["resetsAt","exports","assistantTurns","toolRuns","fakeTextScripts","assistantTurnsThroughApi"],"description":"The limits that count per day instead of per month."}},"required":["plan","planRequired","credits","bonus","dailyLimits"]},"examples":{"example1":{"summary":"Check the balance before an analysis","value":{"plan":"creator","planRequired":false,"credits":{"period":"2026-09","periodEndsAt":"2026-10-01T00:00:00.000Z","included":800,"remaining":1020,"remainingFromPlan":770,"topUp":250},"bonus":null,"dailyLimits":{"resetsAt":"2026-09-02T00:00:00.000Z","exports":{"limit":100,"used":1,"remaining":99},"assistantTurns":{"limit":500,"used":12,"remaining":488},"toolRuns":{"limit":100,"used":2,"remaining":98},"fakeTextScripts":{"limit":100,"used":0,"remaining":100},"assistantTurnsThroughApi":{"limit":100,"used":4,"remaining":96}}}},"example2":{"summary":"Check the balance with the API bonus","value":{"plan":"free","planRequired":true,"credits":{"period":"2026-09","periodEndsAt":"2026-10-01T00:00:00.000Z","included":0,"remaining":0,"remainingFromPlan":0,"topUp":0},"bonus":{"status":"active","granted":50,"remaining":47,"grantedAt":"2026-09-01T08:00:00.000Z","expiresAt":"2026-10-01T08:00:00.000Z","resumesAt":null},"dailyLimits":{"resetsAt":"2026-09-02T00:00:00.000Z","exports":{"limit":5,"used":1,"remaining":4},"assistantTurns":{"limit":20,"used":1,"remaining":19},"toolRuns":{"limit":10,"used":0,"remaining":10},"fakeTextScripts":{"limit":10,"used":0,"remaining":10},"assistantTurnsThroughApi":null}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/credits/ledger":{"get":{"operationId":"list_ledger_entries","summary":"List the credit movements","description":"Lists every movement of the spendable credit balance and of the API bonus, newest first: charges, refunds, top-ups and corrections.\n\nUse this to explain the balance that get_credits shows: what was charged and for which project, what came back, what was bought. Movements come newest first; send nextCursor as cursor to read older ones. Filter with period to read one calendar month; top-ups and their reversals belong to no month, so a period filter leaves them out. A movement the API bonus paid has credits 0, and fromBonus says how much the bonus moved; receiving the bonus is not a movement. The history starts when the ledger was turned on, and opening_balance movements sum up what came before. The balance that counts is the one of get_credits.","tags":["account"],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many items to return, from 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"description":"How many items to return, from 1 to 100. Defaults to 20.","default":20}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page. Leave it out to get the first page.","schema":{"type":"string","minLength":1,"maxLength":512}},{"name":"period","in":"query","required":false,"description":"Only the movements that count on this calendar month, as YYYY-MM. Movements of the top-up alone (a top-up, its reversal, its opening balance) never match, because they belong to no month.","schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The id of the movement. It starts with lgr_."},"kind":{"type":"string","enum":["charge","refund","top_up","top_up_reversal","plan_change","adjustment","opening_balance"],"description":"What moved the balance: charge spent credits; refund gave credits back for work that was not done or an action you undid; top_up added credits you bought; top_up_reversal took back a top-up that was refunded or disputed; plan_change corrected the month after a change of plan; adjustment is any other correction; opening_balance is the balance the history starts from."},"operation":{"anyOf":[{"type":"string","enum":["analysis","editing","generation","export","assistant","tool","fake_text"]},{"type":"null"}],"description":"What a charge paid for, and for a refund to the API bonus what the refunded charge had paid for: analysis finds the clips of a video, editing adds a clip to an edit, generation makes a video with a model, export renders a composition to a file, assistant is a turn of the Editor Assistant, tool is a voiceover, an audio separation or a brainstorm, fake_text writes a fake text story or makes its voices. null when the movement names no purchase."},"credits":{"type":"integer","description":"How the spendable balance changed: negative when credits were spent, positive when they came in. credits is fromPlan plus fromTopUp; fromBonus moves only the API bonus, so a movement the bonus paid has credits 0."},"fromPlan":{"type":"integer","description":"The part of credits that moved the plan credits of period."},"fromTopUp":{"type":"integer","description":"The part of credits that moved the top-up."},"fromBonus":{"type":"integer","description":"How the API bonus changed: negative when the bonus paid, positive when credits went back to it. 0 when the bonus was not involved. Receiving the bonus is not a movement: get_credits shows it."},"projectId":{"type":["string","null"],"description":"The project the movement is about, when it is about one; always null for generation."},"source":{"type":"string","enum":["app","api","system"],"description":"Where the movement came from: app is the GPT-Video app, api is a call with a key or from a connected assistant, system is everything else, such as a purchase or a plan change."},"keyId":{"type":["string","null"],"description":"The id of the API key that made the call, when a key made it, also through an assistant set up with a key. It starts with mck_. null otherwise: the GPT-Video app, a purchase, or an assistant connected without a key."},"period":{"type":["string","null"],"description":"The calendar month the movement counts on, as YYYY-MM; null for a movement of the top-up alone (a top-up, its reversal, its opening balance), which belongs to no month."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","operation","credits","fromPlan","fromTopUp","fromBonus","projectId","source","keyId","period","createdAt"]},"description":"The items of this page."},"hasMore":{"type":"boolean","description":"true when there are more items after this page."},"nextCursor":{"type":["string","null"],"description":"Send it as cursor to get the next page. It is null on the last page."}},"required":["data","hasMore","nextCursor"]},"examples":{"example1":{"summary":"List the latest credit movements","value":{"data":[{"id":"lgr_9b1e4c7a2d5f40e8a316","kind":"charge","operation":"analysis","credits":-30,"fromPlan":-30,"fromTopUp":0,"fromBonus":0,"projectId":"prj_7c2e9a4f1b3d4e8096a5","source":"api","keyId":"mck_5f2c9e1a7b3d8046","period":"2026-09","createdAt":"2026-09-01T09:10:00.000Z"},{"id":"lgr_2c8f0a6e4b1d47c9e5a0","kind":"top_up","operation":null,"credits":250,"fromPlan":0,"fromTopUp":250,"fromBonus":0,"projectId":null,"source":"system","keyId":null,"period":null,"createdAt":"2026-09-01T08:30:00.000Z"}],"hasMore":false,"nextCursor":null}},"example2":{"summary":"List the movements of one month","value":{"data":[{"id":"lgr_9b1e4c7a2d5f40e8a316","kind":"charge","operation":"analysis","credits":-30,"fromPlan":-30,"fromTopUp":0,"fromBonus":0,"projectId":"prj_7c2e9a4f1b3d4e8096a5","source":"api","keyId":"mck_5f2c9e1a7b3d8046","period":"2026-09","createdAt":"2026-09-01T09:10:00.000Z"}],"hasMore":false,"nextCursor":null}},"example3":{"summary":"List what the API bonus paid","value":{"data":[{"id":"lgr_5d8a2f0c7e1b46a9d3c7","kind":"charge","operation":"export","credits":0,"fromPlan":0,"fromTopUp":0,"fromBonus":-1,"projectId":null,"source":"api","keyId":"mck_5f2c9e1a7b3d8046","period":"2026-09","createdAt":"2026-09-01T09:42:00.000Z"},{"id":"lgr_0f6c3b9e2a7d41f8c5b1","kind":"charge","operation":"assistant","credits":0,"fromPlan":0,"fromTopUp":0,"fromBonus":-2,"projectId":null,"source":"api","keyId":"mck_5f2c9e1a7b3d8046","period":"2026-09","createdAt":"2026-09-01T09:40:00.000Z"}],"hasMore":false,"nextCursor":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/uploads":{"post":{"operationId":"create_upload","summary":"Start an upload","description":"Opens an upload for a video file and says how many parts to send and how big each one is.\n\nUse it to send a video from your computer or server. Send the name of the file and its exact size; the answer says how many parts to send and how big each one is. Then send every part with upload_part, in any order and in parallel, and finish with complete_upload, which turns the file into an asset you can analyze. Only MP4, MOV, MKV, WebM, AVI and MPEG-TS video files are accepted, up to 8 GB, and the file counts toward the storage of the account. A video in another format, such as MPG, FLV, WMV or OGV, is refused before the upload opens: convert it to MP4 or MOV first. Send an Idempotency-Key: a retry with the same key returns the same upload instead of opening a second one.","tags":["uploads"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":255,"description":"The name of the file, such as interview.mp4. It is shown in the app, and its extension gives the type when contentType is missing."},"sizeBytes":{"type":"integer","minimum":1,"maximum":8589934592,"description":"The exact size of the file in bytes, up to 8 GB."},"contentType":{"type":"string","minLength":3,"maxLength":255,"description":"The type of the file, such as video/mp4. Leave it out, or send application/octet-stream, to use the extension of filename."}},"required":["filename","sizeBytes"],"additionalProperties":false}}}},"responses":{"201":{"description":"Created","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"upload":{"type":"object","properties":{"id":{"type":"string","description":"The upload id. It starts with upl_."},"filename":{"type":"string","description":"The name of the file as it will be shown, without any folder in it."},"contentType":{"type":"string","description":"The type of the file, such as video/mp4."},"sizeBytes":{"type":"integer","description":"The size of the whole file, in bytes."},"partSizeBytes":{"type":"integer","description":"The size of every part except the last one, in bytes."},"partCount":{"type":"integer","description":"How many parts the file is split into. Parts are numbered from 1 to partCount."},"receivedParts":{"type":"array","items":{"type":"integer"},"description":"The numbers of the parts that arrived whole, in order."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"expiresAt":{"type":"string","description":"When the upload is removed if nothing arrives before then. Every part that arrives moves it later."}},"required":["id","filename","contentType","sizeBytes","partSizeBytes","partCount","receivedParts","createdAt","expiresAt"]}},"required":["upload"]},"examples":{"example1":{"summary":"Start the upload of a 20 MB video","value":{"upload":{"id":"upl_9c4e1a7d2b5f4e6083b1","filename":"keynote.mp4","contentType":"video/mp4","sizeBytes":20971520,"partSizeBytes":8388608,"partCount":3,"receivedParts":[],"createdAt":"2026-09-01T10:30:00.000Z","expiresAt":"2026-09-01T16:30:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The file counts toward the storage of the account.","x-stability":"beta"}},"/uploads/{uploadId}/parts/{partNumber}":{"put":{"operationId":"upload_part","summary":"Send a part of an upload","description":"Sends one part of an upload as raw bytes, and returns the parts received so far.\n\nSend the bytes of the part as the body, with Content-Type: application/octet-stream and no JSON around them. Every part is exactly partSizeBytes long except the last one, which holds the rest of the file. Parts are numbered from 1 to partCount and can be sent in any order and in parallel; sending a part again replaces it. When receivedParts lists every part, call complete_upload. A part sent while the upload is being completed is refused, and so is a part that was still arriving when complete_upload started: send it again, then complete the upload again.","tags":["uploads"],"parameters":[{"name":"uploadId","in":"path","required":true,"description":"The id of the upload, as create_upload returned it.","schema":{"type":"string","pattern":"^upl_[0-9a-f]{20}$","description":"The id of the upload, as create_upload returned it."}},{"name":"partNumber","in":"path","required":true,"description":"The number of the part, from 1 to the partCount of the upload.","schema":{"type":"integer","minimum":1,"maximum":1024,"description":"The number of the part, from 1 to the partCount of the upload."}}],"requestBody":{"required":true,"description":"The bytes of one part, at most 8388608 bytes. Every part is exactly partSizeBytes long except the last one, which holds the rest of the file.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"upload":{"type":"object","properties":{"id":{"type":"string","description":"The upload id. It starts with upl_."},"filename":{"type":"string","description":"The name of the file as it will be shown, without any folder in it."},"contentType":{"type":"string","description":"The type of the file, such as video/mp4."},"sizeBytes":{"type":"integer","description":"The size of the whole file, in bytes."},"partSizeBytes":{"type":"integer","description":"The size of every part except the last one, in bytes."},"partCount":{"type":"integer","description":"How many parts the file is split into. Parts are numbered from 1 to partCount."},"receivedParts":{"type":"array","items":{"type":"integer"},"description":"The numbers of the parts that arrived whole, in order."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"expiresAt":{"type":"string","description":"When the upload is removed if nothing arrives before then. Every part that arrives moves it later."}},"required":["id","filename","contentType","sizeBytes","partSizeBytes","partCount","receivedParts","createdAt","expiresAt"]}},"required":["upload"]},"examples":{"example1":{"summary":"Send the first part","value":{"upload":{"id":"upl_5d2a8f1e6c3b4079e0a1","filename":"keynote.mp4","contentType":"video/mp4","sizeBytes":20971520,"partSizeBytes":8388608,"partCount":3,"receivedParts":[1],"createdAt":"2026-09-01T10:30:00.000Z","expiresAt":"2026-09-01T16:31:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/uploads/{uploadId}":{"get":{"operationId":"get_upload","summary":"Get an upload","description":"Returns an open upload with the parts that arrived and the time it expires.\n\nUse it to resume after a lost connection or a restart: send again only the parts that are not in receivedParts, then call complete_upload. Only open uploads exist here; an upload that was completed, cancelled or removed for inactivity is not found, and the asset of a completed upload is read with get_asset.","tags":["uploads"],"parameters":[{"name":"uploadId","in":"path","required":true,"description":"The id of the upload, as create_upload returned it.","schema":{"type":"string","pattern":"^upl_[0-9a-f]{20}$","description":"The id of the upload, as create_upload returned it."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"upload":{"type":"object","properties":{"id":{"type":"string","description":"The upload id. It starts with upl_."},"filename":{"type":"string","description":"The name of the file as it will be shown, without any folder in it."},"contentType":{"type":"string","description":"The type of the file, such as video/mp4."},"sizeBytes":{"type":"integer","description":"The size of the whole file, in bytes."},"partSizeBytes":{"type":"integer","description":"The size of every part except the last one, in bytes."},"partCount":{"type":"integer","description":"How many parts the file is split into. Parts are numbered from 1 to partCount."},"receivedParts":{"type":"array","items":{"type":"integer"},"description":"The numbers of the parts that arrived whole, in order."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"expiresAt":{"type":"string","description":"When the upload is removed if nothing arrives before then. Every part that arrives moves it later."}},"required":["id","filename","contentType","sizeBytes","partSizeBytes","partCount","receivedParts","createdAt","expiresAt"]}},"required":["upload"]},"examples":{"example1":{"summary":"Check which parts arrived","value":{"upload":{"id":"upl_e7b04c92a15d4f36b8c7","filename":"teaser.mp4","contentType":"video/mp4","sizeBytes":4096,"partSizeBytes":8388608,"partCount":1,"receivedParts":[1],"createdAt":"2026-09-01T10:40:00.000Z","expiresAt":"2026-09-01T16:41:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"},"delete":{"operationId":"cancel_upload","summary":"Cancel an upload","description":"Cancels an open upload and deletes the parts sent so far.\n\nUse it when you will not finish an upload: its parts are deleted and it no longer counts among your uploads in progress, so a new one can start. An upload that is being completed cannot be cancelled. Cancelling an upload that was already completed, cancelled or removed answers not found.","tags":["uploads"],"parameters":[{"name":"uploadId","in":"path","required":true,"description":"The id of the upload, as create_upload returned it.","schema":{"type":"string","pattern":"^upl_[0-9a-f]{20}$","description":"The id of the upload, as create_upload returned it."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"uploadId":{"type":"string","description":"The id of the upload that was cancelled."},"cancelled":{"type":"boolean","const":true,"description":"Always true: a cancel that could not happen is an error."}},"required":["uploadId","cancelled"]},"examples":{"example1":{"summary":"Cancel an upload","value":{"uploadId":"upl_5d2a8f1e6c3b4079e0a1","cancelled":true}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/uploads/{uploadId}/complete":{"post":{"operationId":"complete_upload","summary":"Complete an upload","description":"Turns an upload whose parts all arrived into an asset that a project can use as its source.\n\nCall it once receivedParts lists every part. The file is checked and becomes an asset; pass its id to create_project to analyze it. If parts are missing, nothing changes and the answer names them. The first bytes of the file are checked before anything else: only MP4, MOV, MKV, WebM, AVI and MPEG-TS files go on. A playlist (M3U8), a DASH manifest, a web page or any other text file is refused, and the upload stays open: cancel it with cancel_upload. If the file passes that check but cannot be read as a video, the upload also stays open with all its parts: call complete_upload again, or cancel it. After a success the upload no longer exists, so a retry without an Idempotency-Key answers not found; send a key, and a retry with the same key returns the same asset.","tags":["uploads"],"parameters":[{"name":"uploadId","in":"path","required":true,"description":"The id of the upload, as create_upload returned it.","schema":{"type":"string","pattern":"^upl_[0-9a-f]{20}$","description":"The id of the upload, as create_upload returned it."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200,"description":"The title of the video in the app. Leave it out to use the name of the file without its extension."}},"additionalProperties":false}}}},"responses":{"201":{"description":"Created","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"asset":{"type":"object","properties":{"id":{"type":"string","description":"The asset id. It starts with ast_."},"kind":{"type":"string","enum":["video","audio","image","font","other"]},"title":{"type":"string"},"filename":{"type":["string","null"],"description":"The name of the file as it was uploaded, when there was one."},"origin":{"type":"string","enum":["upload","link","converted","export","voice","separated"],"description":"upload was sent by you, link was imported from a link, converted is a playable copy made for the analysis, export is the file of an export, voice is the audio of a voiceover, separated is the audio an audio separation kept."},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer"},"durationSec":{"type":["number","null"]},"width":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The width as the video is shown, rotation applied."},"height":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The height as the video is shown, rotation applied."},"fps":{"type":["number","null"]},"hasAudio":{"type":["boolean","null"]},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"deletesAt":{"type":["string","null"],"description":"The first time the file may be deleted to free space: files are kept for a limited time. null when nothing deletes it."}},"required":["id","kind","title","filename","origin","mimeType","sizeBytes","durationSec","width","height","fps","hasAudio","createdAt","deletesAt"],"description":"The new asset. Its id is what create_project takes as sourceAssetId."}},"required":["asset"]},"examples":{"example1":{"summary":"Complete an upload","value":{"asset":{"id":"ast_5b0e7c3a9d1f4286b7e4","kind":"video","title":"Product teaser","filename":"teaser.mp4","origin":"upload","mimeType":"video/mp4","sizeBytes":4096,"durationSec":42.5,"width":1920,"height":1080,"fps":30,"hasAudio":true,"createdAt":"2026-09-01T10:42:00.000Z","deletesAt":null}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. Analyzing the video later is what uses credits.","x-stability":"beta"}},"/assets":{"get":{"operationId":"list_assets","summary":"List your videos","description":"Lists the videos you uploaded or imported, newest first, a page at a time.\n\nUse it to find the video to analyze: any of these ids can be the source of a project. The list holds the videos that came from you, through complete_upload, import_asset or the GPT-Video app. Files the service makes from them, such as converted copies and exports, are not listed; get_asset reads them by id. Use search to find a video by its title.","tags":["assets"],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many items to return, from 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"description":"How many items to return, from 1 to 100. Defaults to 20.","default":20}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page. Leave it out to get the first page.","schema":{"type":"string","minLength":1,"maxLength":512}},{"name":"search","in":"query","required":false,"description":"Return only the videos whose title contains this text, ignoring case.","schema":{"type":"string","minLength":1,"maxLength":200}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The asset id. It starts with ast_."},"kind":{"type":"string","enum":["video","audio","image","font","other"]},"title":{"type":"string"},"filename":{"type":["string","null"],"description":"The name of the file as it was uploaded, when there was one."},"origin":{"type":"string","enum":["upload","link","converted","export","voice","separated"],"description":"upload was sent by you, link was imported from a link, converted is a playable copy made for the analysis, export is the file of an export, voice is the audio of a voiceover, separated is the audio an audio separation kept."},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer"},"durationSec":{"type":["number","null"]},"width":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The width as the video is shown, rotation applied."},"height":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The height as the video is shown, rotation applied."},"fps":{"type":["number","null"]},"hasAudio":{"type":["boolean","null"]},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"deletesAt":{"type":["string","null"],"description":"The first time the file may be deleted to free space: files are kept for a limited time. null when nothing deletes it."}},"required":["id","kind","title","filename","origin","mimeType","sizeBytes","durationSec","width","height","fps","hasAudio","createdAt","deletesAt"]},"description":"The items of this page."},"hasMore":{"type":"boolean","description":"true when there are more items after this page."},"nextCursor":{"type":["string","null"],"description":"Send it as cursor to get the next page. It is null on the last page."}},"required":["data","hasMore","nextCursor"]},"examples":{"example1":{"summary":"List your videos","value":{"data":[{"id":"ast_8e21b0d94c6f4a17b358","kind":"video","title":"Product demo","filename":"demo.mp4","origin":"upload","mimeType":"video/mp4","sizeBytes":50331648,"durationSec":120,"width":1920,"height":1080,"fps":30,"hasAudio":true,"createdAt":"2026-09-01T09:05:00.000Z","deletesAt":"2026-09-08T09:05:00.000Z"},{"id":"ast_3f9a1c7e5b2d4086a1c4","kind":"video","title":"Interview with a founder","filename":"interview.mp4","origin":"upload","mimeType":"video/mp4","sizeBytes":734003200,"durationSec":1800,"width":1920,"height":1080,"fps":30,"hasAudio":true,"createdAt":"2026-09-01T09:00:00.000Z","deletesAt":null}],"hasMore":false,"nextCursor":null}},"example2":{"summary":"List your videos one at a time","value":{"data":[{"id":"ast_8e21b0d94c6f4a17b358","kind":"video","title":"Product demo","filename":"demo.mp4","origin":"upload","mimeType":"video/mp4","sizeBytes":50331648,"durationSec":120,"width":1920,"height":1080,"fps":30,"hasAudio":true,"createdAt":"2026-09-01T09:05:00.000Z","deletesAt":"2026-09-08T09:05:00.000Z"}],"hasMore":true,"nextCursor":"eyJrIjp7ImNyZWF0ZWRBdCI6IjIwMjYtMDktMDFUMDk6MDU6MDAuMDAwWiIsImlkIjoiYXN0XzhlMjFiMGQ5NGM2ZjRhMTdiMzU4In0sInYiOjF9"}},"example3":{"summary":"Get the next page","value":{"data":[{"id":"ast_3f9a1c7e5b2d4086a1c4","kind":"video","title":"Interview with a founder","filename":"interview.mp4","origin":"upload","mimeType":"video/mp4","sizeBytes":734003200,"durationSec":1800,"width":1920,"height":1080,"fps":30,"hasAudio":true,"createdAt":"2026-09-01T09:00:00.000Z","deletesAt":null}],"hasMore":false,"nextCursor":null}},"example4":{"summary":"Find a video by its title","value":{"data":[{"id":"ast_8e21b0d94c6f4a17b358","kind":"video","title":"Product demo","filename":"demo.mp4","origin":"upload","mimeType":"video/mp4","sizeBytes":50331648,"durationSec":120,"width":1920,"height":1080,"fps":30,"hasAudio":true,"createdAt":"2026-09-01T09:05:00.000Z","deletesAt":"2026-09-08T09:05:00.000Z"}],"hasMore":false,"nextCursor":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/assets/{assetId}":{"get":{"operationId":"get_asset","summary":"Get an asset","description":"Returns one file: a video you uploaded, its converted copy, or the file of an export.\n\nUse it to read the size, length and dimensions of a file, and when it may be deleted. Files are kept for a limited time; see deletesAt. After an analysis the sourceAssetId of a project can point to the converted copy of its video, whose id starts with ast_n: this operation reads that copy too.","tags":["assets"],"parameters":[{"name":"assetId","in":"path","required":true,"description":"The id of the asset. It starts with ast_, or with ast_n for the converted copy an analysis makes.","schema":{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$","description":"The id of the asset. It starts with ast_, or with ast_n for the converted copy an analysis makes."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"asset":{"type":"object","properties":{"id":{"type":"string","description":"The asset id. It starts with ast_."},"kind":{"type":"string","enum":["video","audio","image","font","other"]},"title":{"type":"string"},"filename":{"type":["string","null"],"description":"The name of the file as it was uploaded, when there was one."},"origin":{"type":"string","enum":["upload","link","converted","export","voice","separated"],"description":"upload was sent by you, link was imported from a link, converted is a playable copy made for the analysis, export is the file of an export, voice is the audio of a voiceover, separated is the audio an audio separation kept."},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer"},"durationSec":{"type":["number","null"]},"width":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The width as the video is shown, rotation applied."},"height":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The height as the video is shown, rotation applied."},"fps":{"type":["number","null"]},"hasAudio":{"type":["boolean","null"]},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"deletesAt":{"type":["string","null"],"description":"The first time the file may be deleted to free space: files are kept for a limited time. null when nothing deletes it."}},"required":["id","kind","title","filename","origin","mimeType","sizeBytes","durationSec","width","height","fps","hasAudio","createdAt","deletesAt"]}},"required":["asset"]},"examples":{"example1":{"summary":"Read a video you uploaded","value":{"asset":{"id":"ast_3f9a1c7e5b2d4086a1c4","kind":"video","title":"Interview with a founder","filename":"interview.mp4","origin":"upload","mimeType":"video/mp4","sizeBytes":734003200,"durationSec":1800,"width":1920,"height":1080,"fps":30,"hasAudio":true,"createdAt":"2026-09-01T09:00:00.000Z","deletesAt":null}}},"example2":{"summary":"Read the file of an export","value":{"asset":{"id":"ast_c47d2e8a19b54f06d2e1","kind":"video","title":"Paid before the product","filename":null,"origin":"export","mimeType":"video/mp4","sizeBytes":18874368,"durationSec":30,"width":1080,"height":1920,"fps":30,"hasAudio":true,"createdAt":"2026-09-01T10:15:00.000Z","deletesAt":"2026-09-15T10:15:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/assets/{assetId}/transcript":{"get":{"operationId":"get_transcript","summary":"Get the transcript of a video","description":"Returns the words of a video with their times, as speech recognition heard them.\n\nA video is transcribed when a project that uses it as its source is analyzed, and the transcript is kept afterwards. This is the raw transcript: corrections made in the GPT-Video editor are not in it. While the analysis that makes it is running the answer is NOT_READY, and a video that no analysis has used answers CONFLICT.","tags":["assets"],"parameters":[{"name":"assetId","in":"path","required":true,"description":"The id of the asset. It starts with ast_, or with ast_n for the converted copy an analysis makes.","schema":{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$","description":"The id of the asset. It starts with ast_, or with ast_n for the converted copy an analysis makes."}},{"name":"words","in":"query","required":false,"description":"false leaves out the list of words and returns the segments alone, which is much shorter; words is then an empty list. Defaults to true.","schema":{"type":"boolean","description":"false leaves out the list of words and returns the segments alone, which is much shorter; words is then an empty list. Defaults to true."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"transcript":{"type":"object","properties":{"assetId":{"type":"string","description":"The asset that was asked for."},"language":{"type":"string","description":"The language of the speech, as a two-letter code such as en."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"words":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string"},"startSec":{"type":"number","description":"When the word starts, in seconds from the start of the video."},"endSec":{"type":"number","description":"When the word ends, in seconds from the start of the video."},"confidence":{"type":["number","null"],"description":"How sure the recognition is of this word, from 0 to 1; null when it did not say."}},"required":["text","startSec","endSec","confidence"]},"description":"Every word, in the order it is spoken."},"segments":{"type":"array","items":{"type":"object","properties":{"startSec":{"type":"number"},"endSec":{"type":"number"},"text":{"type":"string"}},"required":["startSec","endSec","text"]},"description":"The words grouped into stretches of speech."}},"required":["assetId","language","createdAt","words","segments"]}},"required":["transcript"]},"examples":{"example1":{"summary":"Read the transcript of a video","value":{"transcript":{"assetId":"ast_3f9a1c7e5b2d4086a1c4","language":"en","createdAt":"2026-09-01T09:20:00.000Z","words":[{"text":"the","startSec":118,"endSec":118.35,"confidence":0.94},{"text":"first","startSec":118.4,"endSec":118.75,"confidence":0.94},{"text":"customer","startSec":118.8,"endSec":119.15,"confidence":0.94}],"segments":[{"startSec":118,"endSec":152,"text":"the first customer paid us before we had a product"}]}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, NOT_READY","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["NOT_READY"]},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/assets/import":{"post":{"operationId":"import_asset","summary":"Import a video from a link","description":"Downloads a video file from a direct link and adds it to your videos.\n\nSend a direct link to a video file, such as an MP4 or MOV file on your own storage or CDN. The download runs in the background: the answer is a job, and when the job is done its assetId is the new video, ready to be the source of a project. Links to web pages, such as YouTube or TikTok videos, are refused, and so are links to private networks. Importing needs the Creator or Studio plan or the API bonus; it uses no credits, and the file counts toward the storage of your account. An imported video is kept like an upload: it may be deleted after a while if no project uses it, and get_asset gives the date in deletesAt. Send an Idempotency-Key: the same request sent again returns the same job instead of downloading the file twice.\n\nImporting from a link is not available yet.","x-available":false,"tags":["assets"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"A direct link to a video file, http or https. Links to pages such as YouTube or TikTok are refused."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"The title of the new video. Without it, the name of the file at the link is used."}},"required":["url"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","description":"The job id. It starts with job_."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does. analysis finds the clips of an Auto Clip project, or prepares a Vibe Editing project. build makes the video of a split screen, streamer or Reddit story project. export renders a composition to a file. framing follows the face in a clip. import brings in a video from a link. story writes the story of a fake text project. voices makes the voices of a fake text story. tool runs a voiceover, an audio separation or a brainstorm. assistant_turn is one turn of the Editor Assistant."},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the job is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the job failed or stopped, in one sentence; null otherwise."},"projectId":{"type":["string","null"],"description":"The project the job works on, when it has one."},"compositionId":{"type":["string","null"],"description":"The composition the job works on, when it has one."},"exportId":{"type":["string","null"],"description":"The export this job renders, for an export job; null otherwise."},"assetId":{"type":["string","null"],"description":"The video an import job brought in, once the job is done; null for every other job, and when that video no longer exists or cannot be used through the API."},"toolRunId":{"type":["string","null"],"description":"The tool run a tool job carries out, to read with get_tool_run; null for every other job."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn an assistant_turn job carries out, to read with get_assistant_turn; null for every other job."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"startedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","kind","status","progress","errorMessage","projectId","compositionId","exportId","assetId","toolRunId","turnId","createdAt","startedAt","finishedAt"]}},"required":["job"]},"examples":{"example1":{"summary":"Import a video from a link","value":{"job":{"id":"job_5b0e7c2a9d4f6e1b3a8c","kind":"import","status":"queued","progress":0,"errorMessage":null,"projectId":null,"compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T11:20:00.000Z","startedAt":null,"finishedAt":null}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED, UNSUPPORTED_SOURCE_URL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The file counts toward the storage of your account.","x-stability":"beta"}},"/projects":{"get":{"operationId":"list_projects","summary":"List projects","description":"Returns the projects of the account, the most recently created first, one page at a time.\n\nUse it to find a project you created before, or to see what is already in the account. Each project carries its status, its source video and its settings, so you can tell which ones are ready and which still need settings. Projects made in the GPT-Video app are listed too. To read one project with its running analysis, call get_project.","tags":["projects"],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many items to return, from 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"description":"How many items to return, from 1 to 100. Defaults to 20.","default":20}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page. Leave it out to get the first page.","schema":{"type":"string","minLength":1,"maxLength":512}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]},"description":"The items of this page."},"hasMore":{"type":"boolean","description":"true when there are more items after this page."},"nextCursor":{"type":["string","null"],"description":"Send it as cursor to get the next page. It is null on the last page."}},"required":["data","hasMore","nextCursor"]},"examples":{"example1":{"summary":"List the projects","value":{"data":[{"id":"prj_1d8b6e0c47a24f93b1c2","kind":"autoclip","title":"Weekly podcast","status":"draft","sourceAssetId":null,"compositionId":null,"settings":{"language":null,"clipCount":5,"minDurationSec":null,"maxDurationSec":null,"objective":"educational","captionStyle":null,"reframe":null,"instructions":null,"vocabulary":null},"missingSettings":["language","minDurationSec","maxDurationSec","captionStyle","reframe"],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"errorMessage":null,"createdAt":"2026-09-01T09:50:00.000Z","updatedAt":"2026-09-01T09:50:00.000Z"},{"id":"prj_7c2e9a4f1b3d4e8096a5","kind":"autoclip","title":"Founder interview","status":"ready","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","compositionId":null,"settings":{"language":"en","clipCount":3,"minDurationSec":15,"maxDurationSec":60,"objective":"viral","captionStyle":"word-pop","reframe":"face","instructions":null,"vocabulary":null},"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"errorMessage":null,"createdAt":"2026-09-01T09:10:00.000Z","updatedAt":"2026-09-01T09:40:00.000Z"}],"hasMore":false,"nextCursor":null}},"example2":{"summary":"Ask for one project per page","value":{"data":[{"id":"prj_1d8b6e0c47a24f93b1c2","kind":"autoclip","title":"Weekly podcast","status":"draft","sourceAssetId":null,"compositionId":null,"settings":{"language":null,"clipCount":5,"minDurationSec":null,"maxDurationSec":null,"objective":"educational","captionStyle":null,"reframe":null,"instructions":null,"vocabulary":null},"missingSettings":["language","minDurationSec","maxDurationSec","captionStyle","reframe"],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"errorMessage":null,"createdAt":"2026-09-01T09:50:00.000Z","updatedAt":"2026-09-01T09:50:00.000Z"}],"hasMore":true,"nextCursor":"eyJrIjp7ImNyZWF0ZWRBdCI6IjIwMjYtMDktMDFUMDk6NTA6MDAuMDAwWiIsImlkIjoicHJqXzFkOGI2ZTBjNDdhMjRmOTNiMWMyIn0sInYiOjF9"}},"example3":{"summary":"Read the next page","value":{"data":[{"id":"prj_7c2e9a4f1b3d4e8096a5","kind":"autoclip","title":"Founder interview","status":"ready","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","compositionId":null,"settings":{"language":"en","clipCount":3,"minDurationSec":15,"maxDurationSec":60,"objective":"viral","captionStyle":"word-pop","reframe":"face","instructions":null,"vocabulary":null},"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"errorMessage":null,"createdAt":"2026-09-01T09:10:00.000Z","updatedAt":"2026-09-01T09:40:00.000Z"}],"hasMore":false,"nextCursor":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"},"post":{"operationId":"create_project","summary":"Create a project","description":"Creates an Auto Clip project on a video you uploaded, with the settings you choose.\n\nCall it after complete_upload, with the id of the video it returned. The source video is chosen here and only here: to analyze another video, create another project. You can set the settings now or later with update_project; every setting listed in missingSettings must be chosen before analyze_project. Nothing is analyzed and no credits are used until you call analyze_project. Send an Idempotency-Key: a retry without one creates a second project.","tags":["projects"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sourceAssetId":{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$","description":"The video to analyze: the asset id that complete_upload returned. It cannot be changed later."},"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"A name for the project. Leave it out to get a default name."},"settings":{"type":"object","properties":{"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"clipCount":{"type":"integer","minimum":1,"maximum":100,"description":"How many clips the analysis proposes. From 1 to 100."},"minDurationSec":{"type":"number","minimum":5,"maximum":180,"description":"The shortest clip the analysis may propose, in seconds. From 5 to 180, and not longer than maxDurationSec when the analysis starts."},"maxDurationSec":{"type":"number","minimum":10,"maximum":300,"description":"The longest clip the analysis may propose, in seconds. From 10 to 300."},"objective":{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"],"description":"What the clips should be good at. get_setting_options lists every objective with what it means."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like."},"reframe":{"type":"string","enum":["face","center"],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame."},"instructions":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. At most 2000 characters; null removes them."},"vocabulary":{"anyOf":[{"type":"string","maxLength":311},{"type":"null"}],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. At most 311 characters; null removes it."}},"additionalProperties":false,"description":"Auto Clip settings. A field you leave out is left as it is, and every one can be set later with update_project."}},"required":["sourceAssetId"],"additionalProperties":false}}}},"responses":{"201":{"description":"Created","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Create a project on an uploaded video","value":{"project":{"id":"prj_27dd3348d28146ce5a3a","kind":"autoclip","title":"Product demo clips","status":"draft","sourceAssetId":"ast_8e21b0d94c6f4a17b358","compositionId":null,"settings":{"language":"en","clipCount":5,"minDurationSec":20,"maxDurationSec":45,"objective":"howto","captionStyle":"bold-karaoke","reframe":"face","instructions":null,"vocabulary":null},"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"errorMessage":null,"createdAt":"2026-09-01T11:00:00.000Z","updatedAt":"2026-09-01T11:00:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The analysis is charged when you call analyze_project.","x-stability":"beta"}},"/projects/{projectId}":{"get":{"operationId":"get_project","summary":"Get a project","description":"Returns one project with its status, settings, missing settings and the analysis running on it.\n\nUse it to check whether a project is ready to analyze (missingSettings is empty), whether an analysis is running (analysisJobId), and why the last analysis failed (errorMessage). To wait for an analysis, follow its job with get_job.","tags":["projects"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."},"analysisJobId":{"type":["string","null"],"description":"The job of the analysis running on the project now, to follow with get_job; null when none is running."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt","analysisJobId"]}},"required":["project"]},"examples":{"example1":{"summary":"Read a project","value":{"project":{"id":"prj_7c2e9a4f1b3d4e8096a5","kind":"autoclip","title":"Founder interview","status":"ready","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","compositionId":null,"settings":{"language":"en","clipCount":3,"minDurationSec":15,"maxDurationSec":60,"objective":"viral","captionStyle":"word-pop","reframe":"face","instructions":null,"vocabulary":null},"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"errorMessage":null,"createdAt":"2026-09-01T09:10:00.000Z","updatedAt":"2026-09-01T09:40:00.000Z","analysisJobId":null}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"},"patch":{"operationId":"update_project","summary":"Update a project","description":"Renames an Auto Clip project or changes its settings, leaving every field you do not send as it was.\n\nUse it to choose the settings listed in missingSettings, or to change them before the next analysis. Only the fields you send change. The source video cannot be changed: sending sourceAssetId is refused, and to analyze another video you create another project. Settings changed while an analysis is waiting to start are used by that analysis; the price depends only on the source video.","tags":["projects"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"The new name of the project."},"settings":{"type":"object","properties":{"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"clipCount":{"type":"integer","minimum":1,"maximum":100,"description":"How many clips the analysis proposes. From 1 to 100."},"minDurationSec":{"type":"number","minimum":5,"maximum":180,"description":"The shortest clip the analysis may propose, in seconds. From 5 to 180, and not longer than maxDurationSec when the analysis starts."},"maxDurationSec":{"type":"number","minimum":10,"maximum":300,"description":"The longest clip the analysis may propose, in seconds. From 10 to 300."},"objective":{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"],"description":"What the clips should be good at. get_setting_options lists every objective with what it means."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like."},"reframe":{"type":"string","enum":["face","center"],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame."},"instructions":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. At most 2000 characters; null removes them."},"vocabulary":{"anyOf":[{"type":"string","maxLength":311},{"type":"null"}],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. At most 311 characters; null removes it."}},"additionalProperties":false,"description":"Auto Clip settings. A field you leave out is left as it is, and every one can be set later with update_project."}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Choose the settings a draft is missing","value":{"project":{"id":"prj_1d8b6e0c47a24f93b1c2","kind":"autoclip","title":"Weekly podcast","status":"draft","sourceAssetId":null,"compositionId":null,"settings":{"language":"en","clipCount":5,"minDurationSec":20,"maxDurationSec":45,"objective":"educational","captionStyle":"bold-karaoke","reframe":"face","instructions":null,"vocabulary":null},"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"errorMessage":null,"createdAt":"2026-09-01T09:50:00.000Z","updatedAt":"2026-09-01T11:05:00.000Z"}}},"example2":{"summary":"Rename a project and remove its instructions","value":{"project":{"id":"prj_7c2e9a4f1b3d4e8096a5","kind":"autoclip","title":"Founder interview, part one","status":"ready","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","compositionId":null,"settings":{"language":"en","clipCount":3,"minDurationSec":15,"maxDurationSec":60,"objective":"viral","captionStyle":"word-pop","reframe":"face","instructions":null,"vocabulary":null},"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"errorMessage":null,"createdAt":"2026-09-01T09:10:00.000Z","updatedAt":"2026-09-01T11:05:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/{projectId}/analyze":{"post":{"operationId":"analyze_project","summary":"Analyze a project","description":"Starts the analysis that transcribes the source video and finds its clips, and returns the job to follow.\n\nCall it when missingSettings is empty; estimate_analysis gives the price first. The answer is 202 with the job of the analysis: follow it with get_job, and when it is done list the clips with list_clips. If an analysis of the project is already running, you get that job back and nothing is charged (reused is true). Retrying with the same Idempotency-Key never charges twice: if the first attempt was charged, the retry answers what it paid and who paid it (paidWith). Analyzing a project again replaces its proposed and rejected clips and keeps the accepted ones.","tags":["projects"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","description":"The job id. It starts with job_."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does. analysis finds the clips of an Auto Clip project, or prepares a Vibe Editing project. build makes the video of a split screen, streamer or Reddit story project. export renders a composition to a file. framing follows the face in a clip. import brings in a video from a link. story writes the story of a fake text project. voices makes the voices of a fake text story. tool runs a voiceover, an audio separation or a brainstorm. assistant_turn is one turn of the Editor Assistant."},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the job is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the job failed or stopped, in one sentence; null otherwise."},"projectId":{"type":["string","null"],"description":"The project the job works on, when it has one."},"compositionId":{"type":["string","null"],"description":"The composition the job works on, when it has one."},"exportId":{"type":["string","null"],"description":"The export this job renders, for an export job; null otherwise."},"assetId":{"type":["string","null"],"description":"The video an import job brought in, once the job is done; null for every other job, and when that video no longer exists or cannot be used through the API."},"toolRunId":{"type":["string","null"],"description":"The tool run a tool job carries out, to read with get_tool_run; null for every other job."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn an assistant_turn job carries out, to read with get_assistant_turn; null for every other job."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"startedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","kind","status","progress","errorMessage","projectId","compositionId","exportId","assetId","toolRunId","turnId","createdAt","startedAt","finishedAt"]},"creditsCharged":{"type":"integer","minimum":0,"description":"The credits this request was charged: the price for a new analysis, 0 when an analysis already running was returned."},"reused":{"type":"boolean","description":"true when an analysis of the project was already running and this is its job, charged to nobody again."},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["job","creditsCharged","reused","paidWith"]},"examples":{"example1":{"summary":"Analyze a project","value":{"job":{"id":"job_b582bc8315e372bf9ba3","kind":"analysis","status":"queued","progress":0,"errorMessage":null,"projectId":"prj_7c2e9a4f1b3d4e8096a5","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T11:10:00.000Z","startedAt":null,"finishedAt":null},"creditsCharged":30,"reused":false,"paidWith":"plan"}},"example2":{"summary":"An analysis that is already running","value":{"job":{"id":"job_6c1e8b4a2f0d4a97e3b5","kind":"analysis","status":"running","progress":0.4,"errorMessage":null,"projectId":"prj_7c2e9a4f1b3d4e8096a5","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T09:11:00.000Z","startedAt":"2026-09-01T09:12:00.000Z","finishedAt":null},"creditsCharged":0,"reused":true,"paidWith":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED, SOURCE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"One credit per started minute of source video, charged when the analysis starts and not returned if it fails. Analyzing again is a new analysis and is charged again.","x-stability":"beta"}},"/projects/{projectId}/analyze/estimate":{"post":{"operationId":"estimate_analysis","summary":"Estimate the credits of an analysis or a build","description":"Estimate the credits of an analysis, a build or the preparation of an edit, and who would pay them, without starting anything.\n\nCall it before analyze_project, before the build of a split screen, streamer or Reddit story project, or before preparing a Vibe Editing project, to show the price and to check that the account can pay it. It refuses for the same reasons the start would (no source video, settings still to choose, a video that no longer exists), so a project it accepts is ready to start, and the price it gives is the one the start charges. The price of an analysis depends only on the length of the source video, never on the settings: when the user only wants the price of an Auto Clip project with settings still to choose, choose them with update_project (get_setting_options lists the values) and estimate again, and tell the user they can change them before analyze_project. payer says who would pay now: the plan or the API bonus. When the same work is already running, creditsToCharge is 0, runningJobId is its job, payer is null and enough is true, even when planRequired is true. Fake text projects have no price here: their story and voices use the daily fake text allowance. Nothing is charged or changed.","tags":["projects"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"estimate":{"type":"object","properties":{"credits":{"type":"integer","description":"The price of a new analysis, build or preparation of this project, in credits."},"creditsToCharge":{"type":"integer","description":"What the start would charge now: the price, or 0 when the same work is already running."},"sourceDurationSec":{"type":"number","description":"The length of video the price is computed on, in seconds: the source, or the main and the background video of a split screen together. 0 when the price does not depend on a video, as for a Reddit story."},"runningJobId":{"type":["string","null"],"description":"The job of the analysis or build already running on the project; null when none is."},"creditsAvailable":{"type":"integer","description":"The credits of the plan the account can spend now: what is left of the plan this month plus top-up credits. Through the API they can be spent only on the Creator and Studio plans. The API bonus is not in it: see payer and bonusRemaining."},"planRequired":{"type":"boolean","description":"true when the account must choose a plan in the GPT-Video app before it can spend its credits. While the API bonus is active, a call through the API spends it even when planRequired is true. It does not say whether the API may spend the plan credits: only the Creator and Studio plans can."},"enough":{"type":"boolean","description":"true when the start would not be refused for credits or plan, that is when payer is not null. Always true while the same work is running, because that job is returned and nothing is charged."},"payer":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who would pay the start now: plan is the credits of the account's plan, api_bonus is the API bonus. null when the start would be refused for credits or plan, and when the same work is already running and nothing would be charged."},"bonusRemaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The credits left in the API bonus, 0 once it is used up, expired or cancelled; null when the account never had one."}},"required":["credits","creditsToCharge","sourceDurationSec","runningJobId","creditsAvailable","planRequired","enough","payer","bonusRemaining"]}},"required":["estimate"]},"examples":{"example1":{"summary":"Price an analysis before starting it","value":{"estimate":{"credits":30,"creditsToCharge":30,"sourceDurationSec":1800,"runningJobId":null,"creditsAvailable":640,"planRequired":false,"enough":true,"payer":"plan","bonusRemaining":null}}},"example2":{"summary":"An analysis already running costs nothing","value":{"estimate":{"credits":30,"creditsToCharge":0,"sourceDurationSec":1800,"runningJobId":"job_6c1e8b4a2f0d4a97e3b5","creditsAvailable":640,"planRequired":false,"enough":true,"payer":null,"bonusRemaining":null}}},"example3":{"summary":"Price the build of a split screen video","value":{"estimate":{"credits":31,"creditsToCharge":31,"sourceDurationSec":1860,"runningJobId":null,"creditsAvailable":640,"planRequired":false,"enough":true,"payer":"plan","bonusRemaining":null}}},"example4":{"summary":"Price the build of a Reddit story","value":{"estimate":{"credits":1,"creditsToCharge":1,"sourceDurationSec":0,"runningJobId":null,"creditsAvailable":640,"planRequired":false,"enough":true,"payer":"plan","bonusRemaining":null}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"SOURCE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/{projectId}/clips":{"get":{"operationId":"list_clips","summary":"List the clips of a project","description":"Returns the clips an analysis found in a project, in the order the analysis ranked them.\n\nCall this when the analysis of a project is done, to see the clips it found: where each one sits in the source video, its title and hook, and a score explained factor by factor. Filter by status to see only the clips still waiting for a decision. Analyzing the project again replaces the proposed and rejected clips with new ones, with new ids, and keeps the accepted ones; a cursor issued before that answers CONFLICT, and you start again without it. Accept a clip with accept_clip to get a composition you can export. Works on Auto Clip projects only.","tags":["clips"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The id of the project, as create_project returns it.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The id of the project, as create_project returns it."}},{"name":"status","in":"query","required":false,"description":"Only the clips with this status. Leave it out to get every clip.","schema":{"type":"string","enum":["proposed","accepted","rejected"]}},{"name":"limit","in":"query","required":false,"description":"How many items to return, from 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"description":"How many items to return, from 1 to 100. Defaults to 20.","default":20}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page. Leave it out to get the first page.","schema":{"type":"string","minLength":1,"maxLength":512}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The clip id. It starts with cnd_."},"projectId":{"type":"string","description":"The project the clip was found in."},"sourceAssetId":{"type":"string","description":"The source video the clip is cut from."},"status":{"type":"string","enum":["proposed","accepted","rejected"],"description":"proposed is waiting for a decision, accepted has a composition, rejected was set aside and can be restored."},"rank":{"type":"integer","description":"The place of the clip in the project, from 0, in the order the analysis ranked the clips. A new analysis puts the accepted clips it keeps first."},"startSec":{"type":"number","description":"Where the clip starts in the source video, in seconds."},"endSec":{"type":"number","description":"Where the clip ends in the source video, in seconds."},"durationSec":{"type":"number","description":"How long the clip is, in seconds."},"title":{"type":"string","description":"A short title for the clip."},"hook":{"type":"string","description":"What the first seconds of the clip promise the viewer."},"summary":{"type":"string","description":"What the clip is about, in a sentence or two."},"reason":{"type":"string","description":"Why this moment was picked."},"score":{"type":"number","minimum":0,"maximum":100,"description":"A priority score from 0 to 100, explained factor by factor in scoreBreakdown. It ranks the clips of a project against each other; it is not a probability of going viral."},"scoreBreakdown":{"type":"array","items":{"type":"object","properties":{"factor":{"type":"string","enum":["hook","payoff","clarity","emotion","novelty","selfContained","quotability","dialogue"],"description":"Which quality of the clip this entry judges."},"label":{"type":"string","description":"The name of the factor, as the GPT-Video app shows it."},"score":{"type":"number","minimum":0,"maximum":10,"description":"How the clip does on this factor, from 0 to 10."},"note":{"type":"string","description":"Why the clip got this score on this factor."}},"required":["factor","label","score","note"]},"description":"One entry per factor of the score. Factors are added over time, so an older clip can have fewer entries: read each entry by its factor, never by its position."},"tags":{"type":"array","items":{"type":"string"},"description":"Topics of the clip."},"transcriptExcerpt":{"type":"string","description":"What is said in the clip, taken from the transcript."},"social":{"type":"object","properties":{"title":{"type":"string"},"caption":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"}}},"required":["title","caption","hashtags"],"description":"A suggested title, caption and hashtags for posting the clip."},"compositionId":{"type":["string","null"],"description":"The composition made when the clip was accepted; null until then."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","sourceAssetId","status","rank","startSec","endSec","durationSec","title","hook","summary","reason","score","scoreBreakdown","tags","transcriptExcerpt","social","compositionId","createdAt"]},"description":"The items of this page."},"hasMore":{"type":"boolean","description":"true when there are more items after this page."},"nextCursor":{"type":["string","null"],"description":"Send it as cursor to get the next page. It is null on the last page."}},"required":["data","hasMore","nextCursor"]},"examples":{"example1":{"summary":"List the clips of a project","value":{"data":[{"id":"cnd_9e04a6c3d12b4f78a5b9","projectId":"prj_7c2e9a4f1b3d4e8096a5","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","summary":"The founder explains how the first customer paid before the product existed.","reason":"A clear claim in the first seconds and a result at the end.","tags":["startups","sales"],"createdAt":"2026-09-01T09:40:00.000Z","status":"accepted","rank":0,"startSec":120,"endSec":150,"durationSec":30,"title":"Paid before the product","hook":"They paid us before we had a product","score":87.5,"scoreBreakdown":[{"factor":"hook","label":"Hook (first 3 seconds)","score":9,"note":"Opens on a concrete claim."},{"factor":"payoff","label":"Payoff / ending","score":8,"note":"Ends on the result."},{"factor":"clarity","label":"Clarity","score":7,"note":"One idea, said plainly."},{"factor":"emotion","label":"Emotion","score":9,"note":"The speaker sounds surprised."},{"factor":"novelty","label":"Novelty / surprise","score":8,"note":"Not the usual advice."},{"factor":"selfContained","label":"Self-contained","score":7,"note":"Needs no context."},{"factor":"quotability","label":"Quotability","score":9,"note":"Has a line people repeat."},{"factor":"dialogue","label":"Dialogue (back-and-forth)","score":8,"note":"A single speaker."}],"transcriptExcerpt":"before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that","social":{"title":"Paid before the product","caption":"How a first customer paid before there was a product.","hashtags":["#startup","#founder"]},"compositionId":"cmp_4e8c2a6f09d14b73a1e5"},{"id":"cnd_2b7f4e91a0c84d35e6f0","projectId":"prj_7c2e9a4f1b3d4e8096a5","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","summary":"The founder explains how the first customer paid before the product existed.","reason":"A clear claim in the first seconds and a result at the end.","tags":["startups","sales"],"createdAt":"2026-09-01T09:40:00.000Z","status":"proposed","rank":1,"startSec":300,"endSec":330,"durationSec":30,"title":"The first customer","hook":"Our first customer changed everything","score":81,"scoreBreakdown":[{"factor":"hook","label":"Hook (first 3 seconds)","score":8,"note":"Opens on a concrete claim."},{"factor":"payoff","label":"Payoff / ending","score":7,"note":"Ends on the result."},{"factor":"clarity","label":"Clarity","score":6,"note":"One idea, said plainly."},{"factor":"emotion","label":"Emotion","score":8,"note":"The speaker sounds surprised."},{"factor":"novelty","label":"Novelty / surprise","score":7,"note":"Not the usual advice."},{"factor":"selfContained","label":"Self-contained","score":6,"note":"Needs no context."},{"factor":"quotability","label":"Quotability","score":8,"note":"Has a line people repeat."},{"factor":"dialogue","label":"Dialogue (back-and-forth)","score":7,"note":"A single speaker."}],"transcriptExcerpt":"before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that","social":{"title":"The first customer","caption":"How a first customer paid before there was a product.","hashtags":["#startup","#founder"]},"compositionId":null},{"id":"cnd_6a3d1f8e0b574c29d4e3","projectId":"prj_7c2e9a4f1b3d4e8096a5","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","summary":"The founder explains how the first customer paid before the product existed.","reason":"A clear claim in the first seconds and a result at the end.","tags":["startups","sales"],"createdAt":"2026-09-01T09:40:00.000Z","status":"rejected","rank":2,"startSec":600,"endSec":640,"durationSec":40,"title":"Team habits","hook":"What our team does every morning","score":64,"scoreBreakdown":[{"factor":"hook","label":"Hook (first 3 seconds)","score":6,"note":"Opens on a concrete claim."},{"factor":"payoff","label":"Payoff / ending","score":5,"note":"Ends on the result."},{"factor":"clarity","label":"Clarity","score":4,"note":"One idea, said plainly."},{"factor":"emotion","label":"Emotion","score":6,"note":"The speaker sounds surprised."},{"factor":"novelty","label":"Novelty / surprise","score":5,"note":"Not the usual advice."},{"factor":"selfContained","label":"Self-contained","score":4,"note":"Needs no context."},{"factor":"quotability","label":"Quotability","score":6,"note":"Has a line people repeat."},{"factor":"dialogue","label":"Dialogue (back-and-forth)","score":5,"note":"A single speaker."}],"transcriptExcerpt":"before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer","social":{"title":"Team habits","caption":"How a first customer paid before there was a product.","hashtags":["#startup","#founder"]},"compositionId":null}],"hasMore":false,"nextCursor":null}},"example2":{"summary":"Only the clips waiting for a decision","value":{"data":[{"id":"cnd_2b7f4e91a0c84d35e6f0","projectId":"prj_7c2e9a4f1b3d4e8096a5","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","summary":"The founder explains how the first customer paid before the product existed.","reason":"A clear claim in the first seconds and a result at the end.","tags":["startups","sales"],"createdAt":"2026-09-01T09:40:00.000Z","status":"proposed","rank":1,"startSec":300,"endSec":330,"durationSec":30,"title":"The first customer","hook":"Our first customer changed everything","score":81,"scoreBreakdown":[{"factor":"hook","label":"Hook (first 3 seconds)","score":8,"note":"Opens on a concrete claim."},{"factor":"payoff","label":"Payoff / ending","score":7,"note":"Ends on the result."},{"factor":"clarity","label":"Clarity","score":6,"note":"One idea, said plainly."},{"factor":"emotion","label":"Emotion","score":8,"note":"The speaker sounds surprised."},{"factor":"novelty","label":"Novelty / surprise","score":7,"note":"Not the usual advice."},{"factor":"selfContained","label":"Self-contained","score":6,"note":"Needs no context."},{"factor":"quotability","label":"Quotability","score":8,"note":"Has a line people repeat."},{"factor":"dialogue","label":"Dialogue (back-and-forth)","score":7,"note":"A single speaker."}],"transcriptExcerpt":"before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that","social":{"title":"The first customer","caption":"How a first customer paid before there was a product.","hashtags":["#startup","#founder"]},"compositionId":null}],"hasMore":false,"nextCursor":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/clips/{clipId}":{"get":{"operationId":"get_clip","summary":"Get a clip","description":"Returns one clip with its place in the source video, its score and the copy suggested for posting it.\n\nUse it to read a clip again after list_clips, for example to check its status before you accept or reject it. Analyzing the project again removes the proposed and rejected clips, so their ids then answer NOT_FOUND; accepted clips are kept with their ids.","tags":["clips"],"parameters":[{"name":"clipId","in":"path","required":true,"description":"The id of the clip, as list_clips returns it.","schema":{"type":"string","pattern":"^cnd_[0-9a-f]{20}$","description":"The id of the clip, as list_clips returns it."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"clip":{"type":"object","properties":{"id":{"type":"string","description":"The clip id. It starts with cnd_."},"projectId":{"type":"string","description":"The project the clip was found in."},"sourceAssetId":{"type":"string","description":"The source video the clip is cut from."},"status":{"type":"string","enum":["proposed","accepted","rejected"],"description":"proposed is waiting for a decision, accepted has a composition, rejected was set aside and can be restored."},"rank":{"type":"integer","description":"The place of the clip in the project, from 0, in the order the analysis ranked the clips. A new analysis puts the accepted clips it keeps first."},"startSec":{"type":"number","description":"Where the clip starts in the source video, in seconds."},"endSec":{"type":"number","description":"Where the clip ends in the source video, in seconds."},"durationSec":{"type":"number","description":"How long the clip is, in seconds."},"title":{"type":"string","description":"A short title for the clip."},"hook":{"type":"string","description":"What the first seconds of the clip promise the viewer."},"summary":{"type":"string","description":"What the clip is about, in a sentence or two."},"reason":{"type":"string","description":"Why this moment was picked."},"score":{"type":"number","minimum":0,"maximum":100,"description":"A priority score from 0 to 100, explained factor by factor in scoreBreakdown. It ranks the clips of a project against each other; it is not a probability of going viral."},"scoreBreakdown":{"type":"array","items":{"type":"object","properties":{"factor":{"type":"string","enum":["hook","payoff","clarity","emotion","novelty","selfContained","quotability","dialogue"],"description":"Which quality of the clip this entry judges."},"label":{"type":"string","description":"The name of the factor, as the GPT-Video app shows it."},"score":{"type":"number","minimum":0,"maximum":10,"description":"How the clip does on this factor, from 0 to 10."},"note":{"type":"string","description":"Why the clip got this score on this factor."}},"required":["factor","label","score","note"]},"description":"One entry per factor of the score. Factors are added over time, so an older clip can have fewer entries: read each entry by its factor, never by its position."},"tags":{"type":"array","items":{"type":"string"},"description":"Topics of the clip."},"transcriptExcerpt":{"type":"string","description":"What is said in the clip, taken from the transcript."},"social":{"type":"object","properties":{"title":{"type":"string"},"caption":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"}}},"required":["title","caption","hashtags"],"description":"A suggested title, caption and hashtags for posting the clip."},"compositionId":{"type":["string","null"],"description":"The composition made when the clip was accepted; null until then."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","sourceAssetId","status","rank","startSec","endSec","durationSec","title","hook","summary","reason","score","scoreBreakdown","tags","transcriptExcerpt","social","compositionId","createdAt"]}},"required":["clip"]},"examples":{"example1":{"summary":"Get a clip","value":{"clip":{"id":"cnd_2b7f4e91a0c84d35e6f0","projectId":"prj_7c2e9a4f1b3d4e8096a5","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","summary":"The founder explains how the first customer paid before the product existed.","reason":"A clear claim in the first seconds and a result at the end.","tags":["startups","sales"],"createdAt":"2026-09-01T09:40:00.000Z","status":"proposed","rank":1,"startSec":300,"endSec":330,"durationSec":30,"title":"The first customer","hook":"Our first customer changed everything","score":81,"scoreBreakdown":[{"factor":"hook","label":"Hook (first 3 seconds)","score":8,"note":"Opens on a concrete claim."},{"factor":"payoff","label":"Payoff / ending","score":7,"note":"Ends on the result."},{"factor":"clarity","label":"Clarity","score":6,"note":"One idea, said plainly."},{"factor":"emotion","label":"Emotion","score":8,"note":"The speaker sounds surprised."},{"factor":"novelty","label":"Novelty / surprise","score":7,"note":"Not the usual advice."},{"factor":"selfContained","label":"Self-contained","score":6,"note":"Needs no context."},{"factor":"quotability","label":"Quotability","score":8,"note":"Has a line people repeat."},{"factor":"dialogue","label":"Dialogue (back-and-forth)","score":7,"note":"A single speaker."}],"transcriptExcerpt":"before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that","social":{"title":"The first customer","caption":"How a first customer paid before there was a product.","hashtags":["#startup","#founder"]},"compositionId":null}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/clips/{clipId}/accept":{"post":{"operationId":"accept_clip","summary":"Accept a clip","description":"Accepts a clip and returns the composition made from it, the vertical video you can export.\n\nAccepting turns the clip into a composition: the vertical video cut from the source, with captions and the hook. It uses no credits. Accepting a clip that is already accepted returns its composition again, so a retry is safe; a rejected clip can be accepted too. The framing is computed after the accept: until it is done the composition shows framing.status tracking with the job in framing.jobId, and create_export answers NOT_READY. Follow it with get_composition. Works on clips of Auto Clip projects only.","tags":["clips"],"parameters":[{"name":"clipId","in":"path","required":true,"description":"The id of the clip, as list_clips returns it.","schema":{"type":"string","pattern":"^cnd_[0-9a-f]{20}$","description":"The id of the clip, as list_clips returns it."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"clip":{"type":"object","properties":{"id":{"type":"string","description":"The clip id. It starts with cnd_."},"projectId":{"type":"string","description":"The project the clip was found in."},"sourceAssetId":{"type":"string","description":"The source video the clip is cut from."},"status":{"type":"string","enum":["proposed","accepted","rejected"],"description":"proposed is waiting for a decision, accepted has a composition, rejected was set aside and can be restored."},"rank":{"type":"integer","description":"The place of the clip in the project, from 0, in the order the analysis ranked the clips. A new analysis puts the accepted clips it keeps first."},"startSec":{"type":"number","description":"Where the clip starts in the source video, in seconds."},"endSec":{"type":"number","description":"Where the clip ends in the source video, in seconds."},"durationSec":{"type":"number","description":"How long the clip is, in seconds."},"title":{"type":"string","description":"A short title for the clip."},"hook":{"type":"string","description":"What the first seconds of the clip promise the viewer."},"summary":{"type":"string","description":"What the clip is about, in a sentence or two."},"reason":{"type":"string","description":"Why this moment was picked."},"score":{"type":"number","minimum":0,"maximum":100,"description":"A priority score from 0 to 100, explained factor by factor in scoreBreakdown. It ranks the clips of a project against each other; it is not a probability of going viral."},"scoreBreakdown":{"type":"array","items":{"type":"object","properties":{"factor":{"type":"string","enum":["hook","payoff","clarity","emotion","novelty","selfContained","quotability","dialogue"],"description":"Which quality of the clip this entry judges."},"label":{"type":"string","description":"The name of the factor, as the GPT-Video app shows it."},"score":{"type":"number","minimum":0,"maximum":10,"description":"How the clip does on this factor, from 0 to 10."},"note":{"type":"string","description":"Why the clip got this score on this factor."}},"required":["factor","label","score","note"]},"description":"One entry per factor of the score. Factors are added over time, so an older clip can have fewer entries: read each entry by its factor, never by its position."},"tags":{"type":"array","items":{"type":"string"},"description":"Topics of the clip."},"transcriptExcerpt":{"type":"string","description":"What is said in the clip, taken from the transcript."},"social":{"type":"object","properties":{"title":{"type":"string"},"caption":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"}}},"required":["title","caption","hashtags"],"description":"A suggested title, caption and hashtags for posting the clip."},"compositionId":{"type":["string","null"],"description":"The composition made when the clip was accepted; null until then."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","sourceAssetId","status","rank","startSec","endSec","durationSec","title","hook","summary","reason","score","scoreBreakdown","tags","transcriptExcerpt","social","compositionId","createdAt"]},"composition":{"type":"object","properties":{"id":{"type":"string","description":"The composition id. It starts with cmp_."},"projectId":{"type":"string"},"clipId":{"type":["string","null"],"description":"The clip this composition was made from, when it comes from a clip."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"]},"title":{"type":"string"},"revision":{"type":"integer","description":"Grows by one at every change; an export renders one revision."},"durationSec":{"type":"number"},"width":{"type":"integer"},"height":{"type":"integer"},"fps":{"type":"integer"},"source":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"},"startSec":{"type":"number"},"endSec":{"type":"number"}},"required":["assetId","startSec","endSec"]},{"type":"null"}],"description":"The part of the source video this composition shows: filled for Auto Clip and streamer compositions, null for every other kind, and when the video no longer exists or cannot be used through the API."},"hook":{"type":["string","null"],"description":"The hook text shown at the start: filled for Auto Clip compositions only, null for every other kind."},"captions":{"anyOf":[{"type":"object","properties":{"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},"wordCount":{"type":"integer"}},"required":["style","wordCount"]},{"type":"null"}],"description":"The caption style and how many words the captions have; null without captions."},"framing":{"type":"object","properties":{"status":{"type":"string","enum":["tracked","centered","tracking","none"]},"jobId":{"type":["string","null"]}},"required":["status","jobId"],"description":"How the video follows the speaker: tracked follows the face, centered keeps the middle, tracking is still being computed by the job in jobId, none has no source video to frame."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","clipId","kind","title","revision","durationSec","width","height","fps","source","hook","captions","framing","createdAt","updatedAt"]}},"required":["clip","composition"]},"examples":{"example1":{"summary":"Accept a proposed clip","value":{"clip":{"id":"cnd_2b7f4e91a0c84d35e6f0","projectId":"prj_7c2e9a4f1b3d4e8096a5","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","summary":"The founder explains how the first customer paid before the product existed.","reason":"A clear claim in the first seconds and a result at the end.","tags":["startups","sales"],"createdAt":"2026-09-01T09:40:00.000Z","status":"accepted","rank":1,"startSec":300,"endSec":330,"durationSec":30,"title":"The first customer","hook":"Our first customer changed everything","score":81,"scoreBreakdown":[{"factor":"hook","label":"Hook (first 3 seconds)","score":8,"note":"Opens on a concrete claim."},{"factor":"payoff","label":"Payoff / ending","score":7,"note":"Ends on the result."},{"factor":"clarity","label":"Clarity","score":6,"note":"One idea, said plainly."},{"factor":"emotion","label":"Emotion","score":8,"note":"The speaker sounds surprised."},{"factor":"novelty","label":"Novelty / surprise","score":7,"note":"Not the usual advice."},{"factor":"selfContained","label":"Self-contained","score":6,"note":"Needs no context."},{"factor":"quotability","label":"Quotability","score":8,"note":"Has a line people repeat."},{"factor":"dialogue","label":"Dialogue (back-and-forth)","score":7,"note":"A single speaker."}],"transcriptExcerpt":"before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that","social":{"title":"The first customer","caption":"How a first customer paid before there was a product.","hashtags":["#startup","#founder"]},"compositionId":"cmp_b18e4f2a6c0d4973e5a1"},"composition":{"id":"cmp_b18e4f2a6c0d4973e5a1","projectId":"prj_7c2e9a4f1b3d4e8096a5","clipId":"cnd_2b7f4e91a0c84d35e6f0","kind":"autoclip","title":"The first customer","revision":0,"durationSec":30,"width":1080,"height":1920,"fps":30,"source":{"assetId":"ast_3f9a1c7e5b2d4086a1c4","startSec":300,"endSec":330},"hook":"Our first customer changed everything","captions":{"style":"word-pop","wordCount":75},"framing":{"status":"tracking","jobId":"job_4f0a9c2e7d1b4e3a86c5"},"createdAt":"2026-09-01T10:30:00.000Z","updatedAt":"2026-09-01T10:30:00.000Z"}}},"example2":{"summary":"Accept a clip that is already accepted","value":{"clip":{"id":"cnd_9e04a6c3d12b4f78a5b9","projectId":"prj_7c2e9a4f1b3d4e8096a5","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","summary":"The founder explains how the first customer paid before the product existed.","reason":"A clear claim in the first seconds and a result at the end.","tags":["startups","sales"],"createdAt":"2026-09-01T09:40:00.000Z","status":"accepted","rank":0,"startSec":120,"endSec":150,"durationSec":30,"title":"Paid before the product","hook":"They paid us before we had a product","score":87.5,"scoreBreakdown":[{"factor":"hook","label":"Hook (first 3 seconds)","score":9,"note":"Opens on a concrete claim."},{"factor":"payoff","label":"Payoff / ending","score":8,"note":"Ends on the result."},{"factor":"clarity","label":"Clarity","score":7,"note":"One idea, said plainly."},{"factor":"emotion","label":"Emotion","score":9,"note":"The speaker sounds surprised."},{"factor":"novelty","label":"Novelty / surprise","score":8,"note":"Not the usual advice."},{"factor":"selfContained","label":"Self-contained","score":7,"note":"Needs no context."},{"factor":"quotability","label":"Quotability","score":9,"note":"Has a line people repeat."},{"factor":"dialogue","label":"Dialogue (back-and-forth)","score":8,"note":"A single speaker."}],"transcriptExcerpt":"before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that","social":{"title":"Paid before the product","caption":"How a first customer paid before there was a product.","hashtags":["#startup","#founder"]},"compositionId":"cmp_4e8c2a6f09d14b73a1e5"},"composition":{"id":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","clipId":"cnd_9e04a6c3d12b4f78a5b9","kind":"autoclip","title":"Paid before the product","revision":0,"durationSec":30,"width":1080,"height":1920,"fps":30,"source":{"assetId":"ast_3f9a1c7e5b2d4086a1c4","startSec":120,"endSec":150},"hook":"They paid us before we had a product","captions":{"style":"word-pop","wordCount":75},"framing":{"status":"centered","jobId":null},"createdAt":"2026-09-01T10:00:00.000Z","updatedAt":"2026-09-01T10:00:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The export of the composition uses the daily export allowance.","x-stability":"beta"}},"/clips/{clipId}/reject":{"post":{"operationId":"reject_clip","summary":"Reject a clip","description":"Sets a proposed clip aside, so it no longer counts among the clips waiting for a decision.\n\nUse it to separate the clips you do not want from the ones still to review. A rejected clip stays in the project with status rejected, and restore_clip brings it back. Rejecting a clip that is already rejected changes nothing and answers the clip. An accepted clip cannot be rejected, because it has a composition: the answer is CONFLICT. Analyzing the project again removes the rejected clips. Works on clips of Auto Clip projects only.","tags":["clips"],"parameters":[{"name":"clipId","in":"path","required":true,"description":"The id of the clip, as list_clips returns it.","schema":{"type":"string","pattern":"^cnd_[0-9a-f]{20}$","description":"The id of the clip, as list_clips returns it."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"clip":{"type":"object","properties":{"id":{"type":"string","description":"The clip id. It starts with cnd_."},"projectId":{"type":"string","description":"The project the clip was found in."},"sourceAssetId":{"type":"string","description":"The source video the clip is cut from."},"status":{"type":"string","enum":["proposed","accepted","rejected"],"description":"proposed is waiting for a decision, accepted has a composition, rejected was set aside and can be restored."},"rank":{"type":"integer","description":"The place of the clip in the project, from 0, in the order the analysis ranked the clips. A new analysis puts the accepted clips it keeps first."},"startSec":{"type":"number","description":"Where the clip starts in the source video, in seconds."},"endSec":{"type":"number","description":"Where the clip ends in the source video, in seconds."},"durationSec":{"type":"number","description":"How long the clip is, in seconds."},"title":{"type":"string","description":"A short title for the clip."},"hook":{"type":"string","description":"What the first seconds of the clip promise the viewer."},"summary":{"type":"string","description":"What the clip is about, in a sentence or two."},"reason":{"type":"string","description":"Why this moment was picked."},"score":{"type":"number","minimum":0,"maximum":100,"description":"A priority score from 0 to 100, explained factor by factor in scoreBreakdown. It ranks the clips of a project against each other; it is not a probability of going viral."},"scoreBreakdown":{"type":"array","items":{"type":"object","properties":{"factor":{"type":"string","enum":["hook","payoff","clarity","emotion","novelty","selfContained","quotability","dialogue"],"description":"Which quality of the clip this entry judges."},"label":{"type":"string","description":"The name of the factor, as the GPT-Video app shows it."},"score":{"type":"number","minimum":0,"maximum":10,"description":"How the clip does on this factor, from 0 to 10."},"note":{"type":"string","description":"Why the clip got this score on this factor."}},"required":["factor","label","score","note"]},"description":"One entry per factor of the score. Factors are added over time, so an older clip can have fewer entries: read each entry by its factor, never by its position."},"tags":{"type":"array","items":{"type":"string"},"description":"Topics of the clip."},"transcriptExcerpt":{"type":"string","description":"What is said in the clip, taken from the transcript."},"social":{"type":"object","properties":{"title":{"type":"string"},"caption":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"}}},"required":["title","caption","hashtags"],"description":"A suggested title, caption and hashtags for posting the clip."},"compositionId":{"type":["string","null"],"description":"The composition made when the clip was accepted; null until then."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","sourceAssetId","status","rank","startSec","endSec","durationSec","title","hook","summary","reason","score","scoreBreakdown","tags","transcriptExcerpt","social","compositionId","createdAt"]}},"required":["clip"]},"examples":{"example1":{"summary":"Reject a proposed clip","value":{"clip":{"id":"cnd_2b7f4e91a0c84d35e6f0","projectId":"prj_7c2e9a4f1b3d4e8096a5","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","summary":"The founder explains how the first customer paid before the product existed.","reason":"A clear claim in the first seconds and a result at the end.","tags":["startups","sales"],"createdAt":"2026-09-01T09:40:00.000Z","status":"rejected","rank":1,"startSec":300,"endSec":330,"durationSec":30,"title":"The first customer","hook":"Our first customer changed everything","score":81,"scoreBreakdown":[{"factor":"hook","label":"Hook (first 3 seconds)","score":8,"note":"Opens on a concrete claim."},{"factor":"payoff","label":"Payoff / ending","score":7,"note":"Ends on the result."},{"factor":"clarity","label":"Clarity","score":6,"note":"One idea, said plainly."},{"factor":"emotion","label":"Emotion","score":8,"note":"The speaker sounds surprised."},{"factor":"novelty","label":"Novelty / surprise","score":7,"note":"Not the usual advice."},{"factor":"selfContained","label":"Self-contained","score":6,"note":"Needs no context."},{"factor":"quotability","label":"Quotability","score":8,"note":"Has a line people repeat."},{"factor":"dialogue","label":"Dialogue (back-and-forth)","score":7,"note":"A single speaker."}],"transcriptExcerpt":"before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that","social":{"title":"The first customer","caption":"How a first customer paid before there was a product.","hashtags":["#startup","#founder"]},"compositionId":null}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/clips/{clipId}/restore":{"post":{"operationId":"restore_clip","summary":"Restore a rejected clip","description":"Brings a rejected clip back among the proposed clips, with the same id.\n\nUse it to undo reject_clip: the clip goes back to status proposed, waiting for a decision. Restoring a clip that is already proposed changes nothing and answers the clip. An accepted clip cannot be restored, and the answer is CONFLICT. Works on clips of Auto Clip projects only.","tags":["clips"],"parameters":[{"name":"clipId","in":"path","required":true,"description":"The id of the clip, as list_clips returns it.","schema":{"type":"string","pattern":"^cnd_[0-9a-f]{20}$","description":"The id of the clip, as list_clips returns it."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"clip":{"type":"object","properties":{"id":{"type":"string","description":"The clip id. It starts with cnd_."},"projectId":{"type":"string","description":"The project the clip was found in."},"sourceAssetId":{"type":"string","description":"The source video the clip is cut from."},"status":{"type":"string","enum":["proposed","accepted","rejected"],"description":"proposed is waiting for a decision, accepted has a composition, rejected was set aside and can be restored."},"rank":{"type":"integer","description":"The place of the clip in the project, from 0, in the order the analysis ranked the clips. A new analysis puts the accepted clips it keeps first."},"startSec":{"type":"number","description":"Where the clip starts in the source video, in seconds."},"endSec":{"type":"number","description":"Where the clip ends in the source video, in seconds."},"durationSec":{"type":"number","description":"How long the clip is, in seconds."},"title":{"type":"string","description":"A short title for the clip."},"hook":{"type":"string","description":"What the first seconds of the clip promise the viewer."},"summary":{"type":"string","description":"What the clip is about, in a sentence or two."},"reason":{"type":"string","description":"Why this moment was picked."},"score":{"type":"number","minimum":0,"maximum":100,"description":"A priority score from 0 to 100, explained factor by factor in scoreBreakdown. It ranks the clips of a project against each other; it is not a probability of going viral."},"scoreBreakdown":{"type":"array","items":{"type":"object","properties":{"factor":{"type":"string","enum":["hook","payoff","clarity","emotion","novelty","selfContained","quotability","dialogue"],"description":"Which quality of the clip this entry judges."},"label":{"type":"string","description":"The name of the factor, as the GPT-Video app shows it."},"score":{"type":"number","minimum":0,"maximum":10,"description":"How the clip does on this factor, from 0 to 10."},"note":{"type":"string","description":"Why the clip got this score on this factor."}},"required":["factor","label","score","note"]},"description":"One entry per factor of the score. Factors are added over time, so an older clip can have fewer entries: read each entry by its factor, never by its position."},"tags":{"type":"array","items":{"type":"string"},"description":"Topics of the clip."},"transcriptExcerpt":{"type":"string","description":"What is said in the clip, taken from the transcript."},"social":{"type":"object","properties":{"title":{"type":"string"},"caption":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"}}},"required":["title","caption","hashtags"],"description":"A suggested title, caption and hashtags for posting the clip."},"compositionId":{"type":["string","null"],"description":"The composition made when the clip was accepted; null until then."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","sourceAssetId","status","rank","startSec","endSec","durationSec","title","hook","summary","reason","score","scoreBreakdown","tags","transcriptExcerpt","social","compositionId","createdAt"]}},"required":["clip"]},"examples":{"example1":{"summary":"Restore a rejected clip","value":{"clip":{"id":"cnd_6a3d1f8e0b574c29d4e3","projectId":"prj_7c2e9a4f1b3d4e8096a5","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","summary":"The founder explains how the first customer paid before the product existed.","reason":"A clear claim in the first seconds and a result at the end.","tags":["startups","sales"],"createdAt":"2026-09-01T09:40:00.000Z","status":"proposed","rank":2,"startSec":600,"endSec":640,"durationSec":40,"title":"Team habits","hook":"What our team does every morning","score":64,"scoreBreakdown":[{"factor":"hook","label":"Hook (first 3 seconds)","score":6,"note":"Opens on a concrete claim."},{"factor":"payoff","label":"Payoff / ending","score":5,"note":"Ends on the result."},{"factor":"clarity","label":"Clarity","score":4,"note":"One idea, said plainly."},{"factor":"emotion","label":"Emotion","score":6,"note":"The speaker sounds surprised."},{"factor":"novelty","label":"Novelty / surprise","score":5,"note":"Not the usual advice."},{"factor":"selfContained","label":"Self-contained","score":4,"note":"Needs no context."},{"factor":"quotability","label":"Quotability","score":6,"note":"Has a line people repeat."},{"factor":"dialogue","label":"Dialogue (back-and-forth)","score":5,"note":"A single speaker."}],"transcriptExcerpt":"before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer","social":{"title":"Team habits","caption":"How a first customer paid before there was a product.","hashtags":["#startup","#founder"]},"compositionId":null}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/compositions/{compositionId}":{"get":{"operationId":"get_composition","summary":"Get a composition","description":"Returns a composition: the vertical video made from a clip, with its size, captions, hook and framing.\n\nUse it after accept_clip to follow the framing: while framing.status is tracking, the face is still being followed by the job in framing.jobId, and create_export answers NOT_READY until it is done. Every change to the composition adds one to revision, the finished framing included, and an export renders the composition as it is when its render starts, and a finished export says which revision it rendered. Compositions of other kinds of project are shown too: source is filled for Auto Clip and streamer compositions, hook for Auto Clip compositions only.","tags":["compositions"],"parameters":[{"name":"compositionId","in":"path","required":true,"description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project.","schema":{"type":"string","pattern":"^cmp_[0-9a-f]{20}$","description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"composition":{"type":"object","properties":{"id":{"type":"string","description":"The composition id. It starts with cmp_."},"projectId":{"type":"string"},"clipId":{"type":["string","null"],"description":"The clip this composition was made from, when it comes from a clip."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"]},"title":{"type":"string"},"revision":{"type":"integer","description":"Grows by one at every change; an export renders one revision."},"durationSec":{"type":"number"},"width":{"type":"integer"},"height":{"type":"integer"},"fps":{"type":"integer"},"source":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"},"startSec":{"type":"number"},"endSec":{"type":"number"}},"required":["assetId","startSec","endSec"]},{"type":"null"}],"description":"The part of the source video this composition shows: filled for Auto Clip and streamer compositions, null for every other kind, and when the video no longer exists or cannot be used through the API."},"hook":{"type":["string","null"],"description":"The hook text shown at the start: filled for Auto Clip compositions only, null for every other kind."},"captions":{"anyOf":[{"type":"object","properties":{"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},"wordCount":{"type":"integer"}},"required":["style","wordCount"]},{"type":"null"}],"description":"The caption style and how many words the captions have; null without captions."},"framing":{"type":"object","properties":{"status":{"type":"string","enum":["tracked","centered","tracking","none"]},"jobId":{"type":["string","null"]}},"required":["status","jobId"],"description":"How the video follows the speaker: tracked follows the face, centered keeps the middle, tracking is still being computed by the job in jobId, none has no source video to frame."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","clipId","kind","title","revision","durationSec","width","height","fps","source","hook","captions","framing","createdAt","updatedAt"]}},"required":["composition"]},"examples":{"example1":{"summary":"Get a composition","value":{"composition":{"id":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","clipId":"cnd_9e04a6c3d12b4f78a5b9","kind":"autoclip","title":"Paid before the product","revision":0,"durationSec":30,"width":1080,"height":1920,"fps":30,"source":{"assetId":"ast_3f9a1c7e5b2d4086a1c4","startSec":120,"endSec":150},"hook":"They paid us before we had a product","captions":{"style":"word-pop","wordCount":75},"framing":{"status":"centered","jobId":null},"createdAt":"2026-09-01T10:00:00.000Z","updatedAt":"2026-09-01T10:00:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"},"delete":{"operationId":"delete_composition","summary":"Delete a composition","description":"Deletes the composition of an Auto Clip clip, and the clip goes back to proposed.\n\nUse it to undo an accept_clip: the composition goes away and its clip is proposed again, ready to be accepted later as a new composition. Exports of a deleted composition can no longer be read; download them first. A composition that is being exported is refused until the export finishes. A DELETE sent again after a timeout answers NOT_FOUND when the first one went through: read the clip with get_clip to know. Works on compositions of Auto Clip clips only.","tags":["compositions"],"parameters":[{"name":"compositionId","in":"path","required":true,"description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project.","schema":{"type":"string","pattern":"^cmp_[0-9a-f]{20}$","description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"compositionId":{"type":"string","description":"The id of the composition that was deleted."},"deleted":{"type":"boolean","const":true},"clip":{"type":"object","properties":{"id":{"type":"string","description":"The clip id. It starts with cnd_."},"projectId":{"type":"string","description":"The project the clip was found in."},"sourceAssetId":{"type":"string","description":"The source video the clip is cut from."},"status":{"type":"string","enum":["proposed","accepted","rejected"],"description":"proposed is waiting for a decision, accepted has a composition, rejected was set aside and can be restored."},"rank":{"type":"integer","description":"The place of the clip in the project, from 0, in the order the analysis ranked the clips. A new analysis puts the accepted clips it keeps first."},"startSec":{"type":"number","description":"Where the clip starts in the source video, in seconds."},"endSec":{"type":"number","description":"Where the clip ends in the source video, in seconds."},"durationSec":{"type":"number","description":"How long the clip is, in seconds."},"title":{"type":"string","description":"A short title for the clip."},"hook":{"type":"string","description":"What the first seconds of the clip promise the viewer."},"summary":{"type":"string","description":"What the clip is about, in a sentence or two."},"reason":{"type":"string","description":"Why this moment was picked."},"score":{"type":"number","minimum":0,"maximum":100,"description":"A priority score from 0 to 100, explained factor by factor in scoreBreakdown. It ranks the clips of a project against each other; it is not a probability of going viral."},"scoreBreakdown":{"type":"array","items":{"type":"object","properties":{"factor":{"type":"string","enum":["hook","payoff","clarity","emotion","novelty","selfContained","quotability","dialogue"],"description":"Which quality of the clip this entry judges."},"label":{"type":"string","description":"The name of the factor, as the GPT-Video app shows it."},"score":{"type":"number","minimum":0,"maximum":10,"description":"How the clip does on this factor, from 0 to 10."},"note":{"type":"string","description":"Why the clip got this score on this factor."}},"required":["factor","label","score","note"]},"description":"One entry per factor of the score. Factors are added over time, so an older clip can have fewer entries: read each entry by its factor, never by its position."},"tags":{"type":"array","items":{"type":"string"},"description":"Topics of the clip."},"transcriptExcerpt":{"type":"string","description":"What is said in the clip, taken from the transcript."},"social":{"type":"object","properties":{"title":{"type":"string"},"caption":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"}}},"required":["title","caption","hashtags"],"description":"A suggested title, caption and hashtags for posting the clip."},"compositionId":{"type":["string","null"],"description":"The composition made when the clip was accepted; null until then."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","sourceAssetId","status","rank","startSec","endSec","durationSec","title","hook","summary","reason","score","scoreBreakdown","tags","transcriptExcerpt","social","compositionId","createdAt"],"description":"The clip of the composition, proposed again."}},"required":["compositionId","deleted","clip"]},"examples":{"example1":{"summary":"Delete the composition of a clip","value":{"compositionId":"cmp_1e710123e428fb030a18","deleted":true,"clip":{"id":"cnd_8e77645e55cc8ea02336","projectId":"prj_7c2e9a4f1b3d4e8096a5","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","status":"proposed","rank":3,"startSec":900,"endSec":935,"durationSec":35,"title":"Selling the idea first","hook":"Sell it before you build it","summary":"The founder explains how the first customer paid before the product existed.","reason":"A clear claim in the first seconds and a result at the end.","score":78,"scoreBreakdown":[{"factor":"hook","label":"Hook (first 3 seconds)","score":8,"note":"Opens on a concrete claim."},{"factor":"payoff","label":"Payoff / ending","score":7,"note":"Ends on the result."},{"factor":"clarity","label":"Clarity","score":6,"note":"One idea, said plainly."},{"factor":"emotion","label":"Emotion","score":8,"note":"The speaker sounds surprised."},{"factor":"novelty","label":"Novelty / surprise","score":7,"note":"Not the usual advice."},{"factor":"selfContained","label":"Self-contained","score":6,"note":"Needs no context."},{"factor":"quotability","label":"Quotability","score":8,"note":"Has a line people repeat."},{"factor":"dialogue","label":"Dialogue (back-and-forth)","score":7,"note":"A single speaker."}],"tags":["startups","sales"],"transcriptExcerpt":"before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had","social":{"title":"Selling the idea first","caption":"How a first customer paid before there was a product.","hashtags":["#startup","#founder"]},"compositionId":null,"createdAt":"2026-09-01T09:40:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/compositions/{compositionId}/captions":{"get":{"operationId":"get_composition_captions","summary":"Get the captions of a composition","description":"Returns the captions of a composition as an SRT or WebVTT file, inside a JSON answer.\n\nUse it to post the captions as a separate file next to the exported video. The text follows the composition as it is now, and an export made earlier can differ: compare compositionRevision with the revision of a finished export (status done) to know they match. Lines break where they break on screen, and words keep the case they were typed in. A composition with no words to caption answers CONFLICT. Works on compositions of every kind of project.","tags":["compositions"],"parameters":[{"name":"compositionId","in":"path","required":true,"description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project.","schema":{"type":"string","pattern":"^cmp_[0-9a-f]{20}$","description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project."}},{"name":"format","in":"query","required":false,"description":"srt for SubRip, vtt for WebVTT. Defaults to srt.","schema":{"type":"string","enum":["srt","vtt"],"default":"srt"}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"captions":{"type":"object","properties":{"format":{"type":"string","enum":["srt","vtt"],"description":"The format of text."},"mimeType":{"type":"string","description":"The media type to save text with, character set included."},"compositionRevision":{"type":"integer","description":"The revision of the composition the text was written from."},"text":{"type":"string","description":"The whole subtitle file, ready to save."}},"required":["format","mimeType","compositionRevision","text"]}},"required":["captions"]},"examples":{"example1":{"summary":"Get the captions as SRT","value":{"captions":{"format":"srt","mimeType":"text/plain; charset=utf-8","compositionRevision":0,"text":"1\n00:00:00,000 --> 00:00:01,600\nbefore we had a\n\n2\n00:00:01,600 --> 00:00:02,800\nproduct and that\n\n3\n00:00:02,800 --> 00:00:04,000\nchanged everything for\n\n4\n00:00:04,000 --> 00:00:05,600\nour team the first\n\n5\n00:00:05,600 --> 00:00:06,800\ncustomer paid us\n\n6\n00:00:06,800 --> 00:00:08,400\nbefore we had a\n\n7\n00:00:08,400 --> 00:00:09,600\nproduct and that\n\n8\n00:00:09,600 --> 00:00:10,800\nchanged everything for\n\n9\n00:00:10,800 --> 00:00:12,400\nour team the first\n\n10\n00:00:12,400 --> 00:00:13,600\ncustomer paid us\n\n11\n00:00:13,600 --> 00:00:15,200\nbefore we had a\n\n12\n00:00:15,200 --> 00:00:16,400\nproduct and that\n\n13\n00:00:16,400 --> 00:00:17,600\nchanged everything for\n\n14\n00:00:17,600 --> 00:00:19,200\nour team the first\n\n15\n00:00:19,200 --> 00:00:20,400\ncustomer paid us\n\n16\n00:00:20,400 --> 00:00:22,000\nbefore we had a\n\n17\n00:00:22,000 --> 00:00:23,200\nproduct and that\n\n18\n00:00:23,200 --> 00:00:24,400\nchanged everything for\n\n19\n00:00:24,400 --> 00:00:26,000\nour team the first\n\n20\n00:00:26,000 --> 00:00:27,200\ncustomer paid us\n\n21\n00:00:27,200 --> 00:00:28,800\nbefore we had a\n\n22\n00:00:28,800 --> 00:00:30,000\nproduct and that\n"}}},"example2":{"summary":"Get the captions as WebVTT","value":{"captions":{"format":"vtt","mimeType":"text/vtt; charset=utf-8","compositionRevision":0,"text":"WEBVTT\n\n00:00:00.000 --> 00:00:01.600\nbefore we had a\n\n00:00:01.600 --> 00:00:02.800\nproduct and that\n\n00:00:02.800 --> 00:00:04.000\nchanged everything for\n\n00:00:04.000 --> 00:00:05.600\nour team the first\n\n00:00:05.600 --> 00:00:06.800\ncustomer paid us\n\n00:00:06.800 --> 00:00:08.400\nbefore we had a\n\n00:00:08.400 --> 00:00:09.600\nproduct and that\n\n00:00:09.600 --> 00:00:10.800\nchanged everything for\n\n00:00:10.800 --> 00:00:12.400\nour team the first\n\n00:00:12.400 --> 00:00:13.600\ncustomer paid us\n\n00:00:13.600 --> 00:00:15.200\nbefore we had a\n\n00:00:15.200 --> 00:00:16.400\nproduct and that\n\n00:00:16.400 --> 00:00:17.600\nchanged everything for\n\n00:00:17.600 --> 00:00:19.200\nour team the first\n\n00:00:19.200 --> 00:00:20.400\ncustomer paid us\n\n00:00:20.400 --> 00:00:22.000\nbefore we had a\n\n00:00:22.000 --> 00:00:23.200\nproduct and that\n\n00:00:23.200 --> 00:00:24.400\nchanged everything for\n\n00:00:24.400 --> 00:00:26.000\nour team the first\n\n00:00:26.000 --> 00:00:27.200\ncustomer paid us\n\n00:00:27.200 --> 00:00:28.800\nbefore we had a\n\n00:00:28.800 --> 00:00:30.000\nproduct and that\n"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/{projectId}/compositions":{"get":{"operationId":"list_compositions","summary":"List the compositions of a project","description":"Lists the compositions of a project, the newest first, a page at a time.\n\nUse it to find the composition of a project of any kind: an Auto Clip project has one for each accepted clip, and a split screen, streamer, Reddit story, fake text or Vibe Editing project has one, which is also its compositionId. Then read it with get_composition, change it with edit_composition or export it with create_export. Pass the nextCursor of a page to get the next one.","tags":["compositions"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The id of the project, as create_project returns it.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The id of the project, as create_project returns it."}},{"name":"limit","in":"query","required":false,"description":"How many items to return, from 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"description":"How many items to return, from 1 to 100. Defaults to 20.","default":20}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page. Leave it out to get the first page.","schema":{"type":"string","minLength":1,"maxLength":512}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The composition id. It starts with cmp_."},"projectId":{"type":"string"},"clipId":{"type":["string","null"],"description":"The clip this composition was made from, when it comes from a clip."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"]},"title":{"type":"string"},"revision":{"type":"integer","description":"Grows by one at every change; an export renders one revision."},"durationSec":{"type":"number"},"width":{"type":"integer"},"height":{"type":"integer"},"fps":{"type":"integer"},"source":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"},"startSec":{"type":"number"},"endSec":{"type":"number"}},"required":["assetId","startSec","endSec"]},{"type":"null"}],"description":"The part of the source video this composition shows: filled for Auto Clip and streamer compositions, null for every other kind, and when the video no longer exists or cannot be used through the API."},"hook":{"type":["string","null"],"description":"The hook text shown at the start: filled for Auto Clip compositions only, null for every other kind."},"captions":{"anyOf":[{"type":"object","properties":{"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},"wordCount":{"type":"integer"}},"required":["style","wordCount"]},{"type":"null"}],"description":"The caption style and how many words the captions have; null without captions."},"framing":{"type":"object","properties":{"status":{"type":"string","enum":["tracked","centered","tracking","none"]},"jobId":{"type":["string","null"]}},"required":["status","jobId"],"description":"How the video follows the speaker: tracked follows the face, centered keeps the middle, tracking is still being computed by the job in jobId, none has no source video to frame."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","clipId","kind","title","revision","durationSec","width","height","fps","source","hook","captions","framing","createdAt","updatedAt"]},"description":"The items of this page."},"hasMore":{"type":"boolean","description":"true when there are more items after this page."},"nextCursor":{"type":["string","null"],"description":"Send it as cursor to get the next page. It is null on the last page."}},"required":["data","hasMore","nextCursor"]},"examples":{"example1":{"summary":"List the compositions of an Auto Clip project","value":{"data":[{"id":"cmp_1e710123e428fb030a18","projectId":"prj_7c2e9a4f1b3d4e8096a5","clipId":"cnd_8e77645e55cc8ea02336","kind":"autoclip","title":"Selling the idea first","revision":0,"durationSec":35,"width":1080,"height":1920,"fps":30,"source":{"assetId":"ast_3f9a1c7e5b2d4086a1c4","startSec":900,"endSec":935},"hook":"Sell it before you build it","captions":{"style":"word-pop","wordCount":87},"framing":{"status":"centered","jobId":null},"createdAt":"2026-09-01T10:02:00.000Z","updatedAt":"2026-09-01T10:02:00.000Z"},{"id":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","clipId":"cnd_9e04a6c3d12b4f78a5b9","kind":"autoclip","title":"Paid before the product","revision":0,"durationSec":30,"width":1080,"height":1920,"fps":30,"source":{"assetId":"ast_3f9a1c7e5b2d4086a1c4","startSec":120,"endSec":150},"hook":"They paid us before we had a product","captions":{"style":"word-pop","wordCount":75},"framing":{"status":"centered","jobId":null},"createdAt":"2026-09-01T10:00:00.000Z","updatedAt":"2026-09-01T10:00:00.000Z"}],"hasMore":false,"nextCursor":null}},"example2":{"summary":"Find the composition of a split screen project","value":{"data":[{"id":"cmp_cc26cb47fd6004aa5fba","projectId":"prj_9cf6ba9cd17fd89cf513","clipId":null,"kind":"splitscreen","title":"Founder interview, split","revision":0,"durationSec":1800,"width":1080,"height":1920,"fps":30,"source":null,"hook":null,"captions":{"style":"bold-karaoke","wordCount":380},"framing":{"status":"none","jobId":null},"createdAt":"2026-08-31T21:46:00.000Z","updatedAt":"2026-08-31T21:46:00.000Z"}],"hasMore":false,"nextCursor":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/compositions/{compositionId}/edit":{"post":{"operationId":"edit_composition","summary":"Edit a composition","description":"Changes the title, hook, captions, start and end, or music volume of a composition.\n\nSend only the fields to change, with the revision you read; at least one field is needed. A change that leaves everything as it was answers with changed empty and the same revision, and writes nothing. trim moves the start and the end on the source video, and the captions move with them; it works on Auto Clip and streamer compositions, and the hook on Auto Clip compositions only. Captions, title and music volume work on Auto Clip, streamer, split screen and Reddit story compositions. A composition of a Vibe Editing or fake text project is changed with the operations of its kind, and the answer says which. Some changes are refused because the video would not work: a clip shorter than 3 seconds or longer than 180, captions over the face of a clip that follows it, a caption line too wide for the video, a hook of more than 12 words. The revision also grows when a job changes the composition, such as the framing a trim computes again.","tags":["compositions"],"parameters":[{"name":"compositionId","in":"path","required":true,"description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project.","schema":{"type":"string","pattern":"^cmp_[0-9a-f]{20}$","description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedRevision":{"type":"integer","minimum":0,"description":"The revision of the composition you read with get_composition. If the composition changed since, the request answers CONFLICT and changes nothing."},"title":{"type":"string","minLength":1,"maxLength":200,"pattern":"\\S","description":"The new title of the composition, from 1 to 200 characters."},"hook":{"anyOf":[{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S"},{"type":"null"}],"description":"Auto Clip only: the text shown over the first 2 seconds, up to 120 characters and 12 words. null removes it."},"captions":{"type":"object","properties":{"enabled":{"type":"boolean","description":"false removes the captions. true adds them back from the transcript when the composition has none."},"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style, as get_setting_options lists them."},"options":{"type":"object","properties":{"fontFamily":{"type":"string","enum":["Montserrat","Anton","System"],"description":"The typeface of the captions."},"fontSize":{"type":"integer","minimum":20,"maximum":200,"description":"The size of the caption text, from 20 to 200."},"yPercent":{"type":"number","minimum":0,"maximum":100,"description":"Where the captions sit, from 0 at the top to 100 at the bottom."},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","description":"The color of the words, as #RRGGBB."},"highlightColor":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","description":"The color of the word being spoken, as #RRGGBB."},"maxWordsPerGroup":{"type":"integer","minimum":1,"maximum":12,"description":"How many words are on screen at once, at most, from 1 to 12."},"maxCharsPerGroup":{"type":"integer","minimum":4,"maximum":80,"description":"How many characters are on screen at once, at most, from 4 to 80."},"uppercase":{"type":"boolean","description":"true shows the captions in capital letters."},"maxGapSec":{"type":"number","minimum":0.1,"maximum":5,"description":"The longest pause, in seconds, inside one group of words on screen, from 0.1 to 5."}},"additionalProperties":false,"description":"The caption options to change. A field you leave out stays as it is."}},"additionalProperties":false,"description":"The captions to change. Captions added to a composition that has none are made from the transcript of its video."},"trim":{"type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"The new start, in seconds of the source video."},"endSec":{"type":"number","exclusiveMinimum":0,"description":"The new end, in seconds of the source video."}},"additionalProperties":false,"description":"Auto Clip and streamer only: the start and end on the source video. A value you leave out stays as it is."},"musicVolume":{"type":"number","minimum":0,"maximum":2,"description":"The volume of the music: 0 is muted, 1 is normal, 2 is double."}},"required":["expectedRevision"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"composition":{"type":"object","properties":{"id":{"type":"string","description":"The composition id. It starts with cmp_."},"projectId":{"type":"string"},"clipId":{"type":["string","null"],"description":"The clip this composition was made from, when it comes from a clip."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"]},"title":{"type":"string"},"revision":{"type":"integer","description":"Grows by one at every change; an export renders one revision."},"durationSec":{"type":"number"},"width":{"type":"integer"},"height":{"type":"integer"},"fps":{"type":"integer"},"source":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"},"startSec":{"type":"number"},"endSec":{"type":"number"}},"required":["assetId","startSec","endSec"]},{"type":"null"}],"description":"The part of the source video this composition shows: filled for Auto Clip and streamer compositions, null for every other kind, and when the video no longer exists or cannot be used through the API."},"hook":{"type":["string","null"],"description":"The hook text shown at the start: filled for Auto Clip compositions only, null for every other kind."},"captions":{"anyOf":[{"type":"object","properties":{"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},"wordCount":{"type":"integer"}},"required":["style","wordCount"]},{"type":"null"}],"description":"The caption style and how many words the captions have; null without captions."},"framing":{"type":"object","properties":{"status":{"type":"string","enum":["tracked","centered","tracking","none"]},"jobId":{"type":["string","null"]}},"required":["status","jobId"],"description":"How the video follows the speaker: tracked follows the face, centered keeps the middle, tracking is still being computed by the job in jobId, none has no source video to frame."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","clipId","kind","title","revision","durationSec","width","height","fps","source","hook","captions","framing","createdAt","updatedAt"]},"changed":{"type":"array","items":{"type":"string","enum":["title","hook","captions","trim","musicVolume"]},"description":"The fields whose value is now different. Empty when the request changed nothing: then nothing was written and the revision is the one you sent."},"notes":{"type":"array","items":{"type":"string"},"description":"What else happened, or why a field changed nothing, one sentence each."}},"required":["composition","changed","notes"]},"examples":{"example1":{"summary":"Change the title and the caption style","value":{"composition":{"id":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","clipId":"cnd_9e04a6c3d12b4f78a5b9","kind":"autoclip","title":"They paid before the product existed","revision":1,"durationSec":30,"width":1080,"height":1920,"fps":30,"source":{"assetId":"ast_3f9a1c7e5b2d4086a1c4","startSec":120,"endSec":150},"hook":"They paid us before we had a product","captions":{"style":"boxed","wordCount":75},"framing":{"status":"centered","jobId":null},"createdAt":"2026-09-01T10:00:00.000Z","updatedAt":"2026-09-01T11:10:00.000Z"},"changed":["title","captions"],"notes":[]}},"example2":{"summary":"A change that changes nothing","value":{"composition":{"id":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","clipId":"cnd_9e04a6c3d12b4f78a5b9","kind":"autoclip","title":"Paid before the product","revision":0,"durationSec":30,"width":1080,"height":1920,"fps":30,"source":{"assetId":"ast_3f9a1c7e5b2d4086a1c4","startSec":120,"endSec":150},"hook":"They paid us before we had a product","captions":{"style":"word-pop","wordCount":75},"framing":{"status":"centered","jobId":null},"createdAt":"2026-09-01T10:00:00.000Z","updatedAt":"2026-09-01T10:00:00.000Z"},"changed":[],"notes":[]}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/compositions/{compositionId}/captions/replace":{"post":{"operationId":"replace_caption_words","summary":"Correct words in the captions","description":"Replaces words in the captions of a composition, such as a name the transcript got wrong.\n\nEach replacement finds its word without minding capitals or punctuation, and keeps the punctuation of the word it replaces. With occurrence, only that occurrence of the word changes, counting from 1; without it, every one does. A word that is not in the captions is listed in notFound with up to three similar words, and nothing is written when no word was found. Send the revision you read; up to 30 replacements a request. Works on Auto Clip, streamer, split screen and Reddit story compositions; the captions of a Vibe Editing project are corrected with apply_timeline_operations.","tags":["compositions"],"parameters":[{"name":"compositionId","in":"path","required":true,"description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project.","schema":{"type":"string","pattern":"^cmp_[0-9a-f]{20}$","description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedRevision":{"type":"integer","minimum":0,"description":"The revision of the composition you read with get_composition. If the composition changed since, the request answers CONFLICT and changes nothing."},"replacements":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","minLength":1,"maxLength":200,"description":"The word to find, compared without capitals or punctuation."},"to":{"type":"string","minLength":1,"maxLength":200,"description":"The text to write in its place."},"occurrence":{"type":"integer","minimum":1,"description":"Which occurrence of the word to replace, counting from 1. Leave it out to replace every one."}},"required":["from","to"],"additionalProperties":false},"minItems":1,"maxItems":30,"description":"The words to replace, from 1 to 30. When two replacements find the same word, the first one wins it."}},"required":["expectedRevision","replacements"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"composition":{"type":"object","properties":{"id":{"type":"string","description":"The composition id. It starts with cmp_."},"projectId":{"type":"string"},"clipId":{"type":["string","null"],"description":"The clip this composition was made from, when it comes from a clip."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"]},"title":{"type":"string"},"revision":{"type":"integer","description":"Grows by one at every change; an export renders one revision."},"durationSec":{"type":"number"},"width":{"type":"integer"},"height":{"type":"integer"},"fps":{"type":"integer"},"source":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"},"startSec":{"type":"number"},"endSec":{"type":"number"}},"required":["assetId","startSec","endSec"]},{"type":"null"}],"description":"The part of the source video this composition shows: filled for Auto Clip and streamer compositions, null for every other kind, and when the video no longer exists or cannot be used through the API."},"hook":{"type":["string","null"],"description":"The hook text shown at the start: filled for Auto Clip compositions only, null for every other kind."},"captions":{"anyOf":[{"type":"object","properties":{"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},"wordCount":{"type":"integer"}},"required":["style","wordCount"]},{"type":"null"}],"description":"The caption style and how many words the captions have; null without captions."},"framing":{"type":"object","properties":{"status":{"type":"string","enum":["tracked","centered","tracking","none"]},"jobId":{"type":["string","null"]}},"required":["status","jobId"],"description":"How the video follows the speaker: tracked follows the face, centered keeps the middle, tracking is still being computed by the job in jobId, none has no source video to frame."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","clipId","kind","title","revision","durationSec","width","height","fps","source","hook","captions","framing","createdAt","updatedAt"]},"replaced":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string"},"count":{"type":"integer"}},"required":["from","count"]},"description":"Every replacement that found its word, with how many words it changed."},"notFound":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string"},"similar":{"type":"array","items":{"type":"string"}}},"required":["from","similar"]},"description":"Every replacement that found no word, with up to three similar words of the captions."}},"required":["composition","replaced","notFound"]},"examples":{"example1":{"summary":"Correct a word everywhere","value":{"composition":{"id":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","clipId":"cnd_9e04a6c3d12b4f78a5b9","kind":"autoclip","title":"Paid before the product","revision":1,"durationSec":30,"width":1080,"height":1920,"fps":30,"source":{"assetId":"ast_3f9a1c7e5b2d4086a1c4","startSec":120,"endSec":150},"hook":"They paid us before we had a product","captions":{"style":"word-pop","wordCount":75},"framing":{"status":"centered","jobId":null},"createdAt":"2026-09-01T10:00:00.000Z","updatedAt":"2026-09-01T11:10:00.000Z"},"replaced":[{"from":"customer","count":4}],"notFound":[]}},"example2":{"summary":"A word that is not in the captions","value":{"composition":{"id":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","clipId":"cnd_9e04a6c3d12b4f78a5b9","kind":"autoclip","title":"Paid before the product","revision":0,"durationSec":30,"width":1080,"height":1920,"fps":30,"source":{"assetId":"ast_3f9a1c7e5b2d4086a1c4","startSec":120,"endSec":150},"hook":"They paid us before we had a product","captions":{"style":"word-pop","wordCount":75},"framing":{"status":"centered","jobId":null},"createdAt":"2026-09-01T10:00:00.000Z","updatedAt":"2026-09-01T10:00:00.000Z"},"replaced":[],"notFound":[{"from":"costumer","similar":["customer"]}]}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/compositions/{compositionId}/reframe":{"post":{"operationId":"reframe_composition","summary":"Frame a composition again","description":"Computes the vertical framing of a composition again, following the face or keeping the center.\n\nIt starts a framing job and answers 202 with it; follow it with get_job, or read framing in get_composition. face follows the face of the speaker, center keeps the middle of the video. When a framing job is already running on the composition, the answer is that job with reused true, and nothing new starts. Works on Auto Clip and streamer compositions; a Vibe Editing project changes its framing with the set_reframe operation of apply_timeline_operations. An export started while the framing runs answers NOT_READY.","tags":["compositions"],"parameters":[{"name":"compositionId","in":"path","required":true,"description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project.","schema":{"type":"string","pattern":"^cmp_[0-9a-f]{20}$","description":"The id of the composition: accept_clip returns it for a clip, and list_compositions or the project's compositionId give it for the other kinds of project."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["face","center"],"description":"face follows the face of the speaker, center keeps the middle of the video."}},"required":["mode"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","description":"The job id. It starts with job_."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does. analysis finds the clips of an Auto Clip project, or prepares a Vibe Editing project. build makes the video of a split screen, streamer or Reddit story project. export renders a composition to a file. framing follows the face in a clip. import brings in a video from a link. story writes the story of a fake text project. voices makes the voices of a fake text story. tool runs a voiceover, an audio separation or a brainstorm. assistant_turn is one turn of the Editor Assistant."},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the job is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the job failed or stopped, in one sentence; null otherwise."},"projectId":{"type":["string","null"],"description":"The project the job works on, when it has one."},"compositionId":{"type":["string","null"],"description":"The composition the job works on, when it has one."},"exportId":{"type":["string","null"],"description":"The export this job renders, for an export job; null otherwise."},"assetId":{"type":["string","null"],"description":"The video an import job brought in, once the job is done; null for every other job, and when that video no longer exists or cannot be used through the API."},"toolRunId":{"type":["string","null"],"description":"The tool run a tool job carries out, to read with get_tool_run; null for every other job."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn an assistant_turn job carries out, to read with get_assistant_turn; null for every other job."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"startedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","kind","status","progress","errorMessage","projectId","compositionId","exportId","assetId","toolRunId","turnId","createdAt","startedAt","finishedAt"]},"reused":{"type":"boolean","description":"true when a framing job was already running on the composition and this is that job."}},"required":["job","reused"]},"examples":{"example1":{"summary":"Follow the face","value":{"job":{"id":"job_4e8a2c6f0b3d49a7e1c5","kind":"framing","status":"queued","progress":0,"errorMessage":null,"projectId":"prj_7c2e9a4f1b3d4e8096a5","compositionId":"cmp_4e8c2a6f09d14b73a1e5","exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T11:10:00.000Z","startedAt":null,"finishedAt":null},"reused":false}},"example2":{"summary":"A framing that is already running","value":{"job":{"id":"job_4e8a2c6f0b3d49a7e1c5","kind":"framing","status":"queued","progress":0,"errorMessage":null,"projectId":"prj_7c2e9a4f1b3d4e8096a5","compositionId":"cmp_4e8c2a6f09d14b73a1e5","exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T11:10:00.000Z","startedAt":null,"finishedAt":null},"reused":true}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/compositions/{compositionId}/exports":{"post":{"operationId":"create_export","summary":"Export a composition","description":"Starts rendering a composition to an MP4 file and returns the export to follow.\n\nCall this when a composition is ready to become a video file. It answers 202 at once with the export, queued, and a Location to follow; read it with get_export (with ?wait= to hold the request) until it is done, then download the file from its downloadUrl. The export renders the composition as it is when its render starts: a change saved while it waits in the queue is in the file, and a change saved after that is not. Once it is done, its revision says which revision the file holds. Every composition can be exported: of an Auto Clip clip, of a split screen, streamer, Reddit story or fake text project, or of a Vibe Editing edit. A composition that uses a file the API cannot use (one the GPT-Video app put in it) is refused before anything is used. An account that is not on the Creator or Studio plan exports through the API bonus, which pays for exports up to a fixed length (see the FAQ); a longer one answers PLAN_REQUIRED. paidWith says who paid this request. While the face framing of the clip is still being computed the call answers NOT_READY: wait the seconds in Retry-After and send it again. Asking again while the same revision is exporting returns that export and uses nothing. Always send an Idempotency-Key, the same one on every retry: a retry of the same request never uses a second export, and if the first try stopped before the render started, the retry starts it, with the composition as it is at the retry. This answer never carries a download link; get_export does.","tags":["exports"],"parameters":[{"name":"compositionId","in":"path","required":true,"description":"The composition to export, as accept_clip or get_composition returned it. It starts with cmp_.","schema":{"type":"string","pattern":"^cmp_[0-9a-f]{20}$","description":"The composition to export, as accept_clip or get_composition returned it. It starts with cmp_."}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"export":{"type":"object","properties":{"id":{"type":"string","description":"The export id. It starts with rnd_."},"compositionId":{"type":"string","description":"The composition this export renders."},"projectId":{"type":"string","description":"The project of the composition."},"jobId":{"type":["string","null"],"description":"The job that renders this export, to read with get_job. It starts with job_; null while the export has no job yet."},"revision":{"type":"integer","description":"The revision of the composition in this export. The render reads the composition when it starts, so a change saved while the export waits in the queue is in the file. Until the export is done this is the revision it was asked at; once it is done it is the revision the file holds."},"status":{"type":"string","enum":["queued","rendering","done","failed","cancelled"],"description":"queued and rendering are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the export is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"For a failed or cancelled export, a short message that says what happened; null otherwise."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"When the export ended, done or not; null while it is still working."},"file":{"anyOf":[{"type":"object","properties":{"mimeType":{"type":"string"},"sizeBytes":{"type":"integer"},"durationSec":{"type":["number","null"]},"width":{"anyOf":[{"type":"integer"},{"type":"null"}]},"height":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["mimeType","sizeBytes","durationSec","width","height"]},{"type":"null"}],"description":"The exported MP4, once the export is done; null before. It stays described after the file is deleted (see fileDeletedAt)."},"downloadUrl":{"type":["string","null"],"description":"A link that downloads the MP4 with no API key, for 15 minutes and for this file only. Only get_export and list_exports give one, once the export is done and while the file is kept; every read gives a new link. create_export always answers null."},"downloadUrlExpiresAt":{"type":["string","null"],"description":"When downloadUrl stops working; null when there is no link."},"fileDeletesAt":{"type":["string","null"],"description":"The first time the MP4 may be deleted to free space: export files are kept for a limited time. null when nothing deletes it, and once it is deleted."},"fileDeletedAt":{"type":["string","null"],"description":"When the MP4 was deleted to free space; export the composition again for a new file. null while the file is kept."}},"required":["id","compositionId","projectId","jobId","revision","status","progress","errorMessage","createdAt","finishedAt","file","downloadUrl","downloadUrlExpiresAt","fileDeletesAt","fileDeletedAt"]},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["export","paidWith"]},"examples":{"example1":{"summary":"Export a composition","value":{"export":{"id":"rnd_6d0f2a8c4e1b47a9c3f5","compositionId":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","jobId":"job_8c3f1e5a9d2b4f7c06e1","revision":0,"status":"queued","progress":0,"errorMessage":null,"createdAt":"2026-09-01T11:00:00.000Z","finishedAt":null,"file":null,"downloadUrl":null,"downloadUrlExpiresAt":null,"fileDeletesAt":null,"fileDeletedAt":null},"paidWith":"plan"}},"example2":{"summary":"Export a split screen video","value":{"export":{"id":"rnd_2f9b4e7c1a3d58e06b2c","compositionId":"cmp_cc26cb47fd6004aa5fba","projectId":"prj_9cf6ba9cd17fd89cf513","jobId":"job_5d1a8e3f0c6b49a27e5d","revision":0,"status":"queued","progress":0,"errorMessage":null,"createdAt":"2026-09-01T11:20:00.000Z","finishedAt":null,"file":null,"downloadUrl":null,"downloadUrlExpiresAt":null,"fileDeletesAt":null,"fileDeletedAt":null},"paidWith":"plan"}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, NOT_READY, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["NOT_READY","IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"Uses one export of the daily allowance, which resets at 00:00 UTC, and no credits. When the API bonus pays for it, it also uses one bonus credit. Nothing is returned if the export fails or is cancelled.","x-bonus-credits":1,"x-stability":"beta"}},"/exports/{exportId}":{"get":{"operationId":"get_export","summary":"Get an export","description":"Returns an export: its status, its file and, once it is done, a fresh download link.\n\nCall this to follow an export that create_export started, and to download its file. While the export is queued or rendering, add ?wait= with up to 25 seconds to hold the request until it ends, then call again if it is still working. Once the status is done, downloadUrl downloads the MP4 with no API key: the link is short-lived and every read gives a new one, so read the export again right before downloading. Export files are kept for a limited time; see fileDeletesAt. A failed or cancelled export says what happened in errorMessage: export the composition again with create_export and a new Idempotency-Key.","tags":["exports"],"parameters":[{"name":"exportId","in":"path","required":true,"description":"The id of the export, as create_export or list_exports returned it. It starts with rnd_.","schema":{"type":"string","pattern":"^rnd_[0-9a-f]{20}$","description":"The id of the export, as create_export or list_exports returned it. It starts with rnd_."}},{"name":"wait","in":"query","required":false,"description":"Seconds to hold the request while the work is still running, up to 25. Leave it out to answer at once. If many requests of the account are already waiting, it answers at once; wait a few seconds before you read again.","schema":{"type":"integer","minimum":0,"maximum":25,"description":"Seconds to hold the request while the work is still running, up to 25. Leave it out to answer at once. If many requests of the account are already waiting, it answers at once; wait a few seconds before you read again."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"export":{"type":"object","properties":{"id":{"type":"string","description":"The export id. It starts with rnd_."},"compositionId":{"type":"string","description":"The composition this export renders."},"projectId":{"type":"string","description":"The project of the composition."},"jobId":{"type":["string","null"],"description":"The job that renders this export, to read with get_job. It starts with job_; null while the export has no job yet."},"revision":{"type":"integer","description":"The revision of the composition in this export. The render reads the composition when it starts, so a change saved while the export waits in the queue is in the file. Until the export is done this is the revision it was asked at; once it is done it is the revision the file holds."},"status":{"type":"string","enum":["queued","rendering","done","failed","cancelled"],"description":"queued and rendering are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the export is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"For a failed or cancelled export, a short message that says what happened; null otherwise."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"When the export ended, done or not; null while it is still working."},"file":{"anyOf":[{"type":"object","properties":{"mimeType":{"type":"string"},"sizeBytes":{"type":"integer"},"durationSec":{"type":["number","null"]},"width":{"anyOf":[{"type":"integer"},{"type":"null"}]},"height":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["mimeType","sizeBytes","durationSec","width","height"]},{"type":"null"}],"description":"The exported MP4, once the export is done; null before. It stays described after the file is deleted (see fileDeletedAt)."},"downloadUrl":{"type":["string","null"],"description":"A link that downloads the MP4 with no API key, for 15 minutes and for this file only. Only get_export and list_exports give one, once the export is done and while the file is kept; every read gives a new link. create_export always answers null."},"downloadUrlExpiresAt":{"type":["string","null"],"description":"When downloadUrl stops working; null when there is no link."},"fileDeletesAt":{"type":["string","null"],"description":"The first time the MP4 may be deleted to free space: export files are kept for a limited time. null when nothing deletes it, and once it is deleted."},"fileDeletedAt":{"type":["string","null"],"description":"When the MP4 was deleted to free space; export the composition again for a new file. null while the file is kept."}},"required":["id","compositionId","projectId","jobId","revision","status","progress","errorMessage","createdAt","finishedAt","file","downloadUrl","downloadUrlExpiresAt","fileDeletesAt","fileDeletedAt"]}},"required":["export"]},"examples":{"example1":{"summary":"Get a finished export","value":{"export":{"id":"rnd_0f6b3e9d2c7a4158b4a3","compositionId":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","jobId":"job_a3e9d05c7b1f4e2896d4","revision":0,"status":"done","progress":1,"errorMessage":null,"createdAt":"2026-09-01T10:10:00.000Z","finishedAt":"2026-09-01T10:15:00.000Z","file":{"mimeType":"video/mp4","sizeBytes":18874368,"durationSec":30,"width":1080,"height":1920},"downloadUrl":"https://www.gpt-video.com/media/ast_c47d2e8a19b54f06d2e1?exp=1788258600&sig=9b2e61c04d7f3a58e1b6c2d9f0a4e7b3","downloadUrlExpiresAt":"2026-09-01T10:30:00.000Z","fileDeletesAt":"2026-09-15T10:15:00.000Z","fileDeletedAt":null}}},"example2":{"summary":"Wait for an export to finish","value":{"export":{"id":"rnd_0f6b3e9d2c7a4158b4a3","compositionId":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","jobId":"job_a3e9d05c7b1f4e2896d4","revision":0,"status":"done","progress":1,"errorMessage":null,"createdAt":"2026-09-01T10:10:00.000Z","finishedAt":"2026-09-01T10:15:00.000Z","file":{"mimeType":"video/mp4","sizeBytes":18874368,"durationSec":30,"width":1080,"height":1920},"downloadUrl":"https://www.gpt-video.com/media/ast_c47d2e8a19b54f06d2e1?exp=1788258600&sig=9b2e61c04d7f3a58e1b6c2d9f0a4e7b3","downloadUrlExpiresAt":"2026-09-01T10:30:00.000Z","fileDeletesAt":"2026-09-15T10:15:00.000Z","fileDeletedAt":null}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/{projectId}/exports":{"get":{"operationId":"list_exports","summary":"List the exports of a project","description":"Lists the exports of a project, newest first, optionally of one composition only.\n\nCall this to find the exports of a project, for example after accepting several clips, or to recover the export of a request whose answer you lost. Pass compositionId to see the exports of one composition only. The list is newest first and paged with cursor and limit. Every finished export whose file is kept comes with its own fresh downloadUrl, as get_export gives it; export files are kept for a limited time, see fileDeletesAt.","tags":["exports"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project whose exports to list. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project whose exports to list. It starts with prj_."}},{"name":"compositionId","in":"query","required":false,"description":"Only the exports of this composition of the project. It starts with cmp_.","schema":{"type":"string","pattern":"^cmp_[0-9a-f]{20}$"}},{"name":"limit","in":"query","required":false,"description":"How many items to return, from 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"description":"How many items to return, from 1 to 100. Defaults to 20.","default":20}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page. Leave it out to get the first page.","schema":{"type":"string","minLength":1,"maxLength":512}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The export id. It starts with rnd_."},"compositionId":{"type":"string","description":"The composition this export renders."},"projectId":{"type":"string","description":"The project of the composition."},"jobId":{"type":["string","null"],"description":"The job that renders this export, to read with get_job. It starts with job_; null while the export has no job yet."},"revision":{"type":"integer","description":"The revision of the composition in this export. The render reads the composition when it starts, so a change saved while the export waits in the queue is in the file. Until the export is done this is the revision it was asked at; once it is done it is the revision the file holds."},"status":{"type":"string","enum":["queued","rendering","done","failed","cancelled"],"description":"queued and rendering are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the export is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"For a failed or cancelled export, a short message that says what happened; null otherwise."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"When the export ended, done or not; null while it is still working."},"file":{"anyOf":[{"type":"object","properties":{"mimeType":{"type":"string"},"sizeBytes":{"type":"integer"},"durationSec":{"type":["number","null"]},"width":{"anyOf":[{"type":"integer"},{"type":"null"}]},"height":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["mimeType","sizeBytes","durationSec","width","height"]},{"type":"null"}],"description":"The exported MP4, once the export is done; null before. It stays described after the file is deleted (see fileDeletedAt)."},"downloadUrl":{"type":["string","null"],"description":"A link that downloads the MP4 with no API key, for 15 minutes and for this file only. Only get_export and list_exports give one, once the export is done and while the file is kept; every read gives a new link. create_export always answers null."},"downloadUrlExpiresAt":{"type":["string","null"],"description":"When downloadUrl stops working; null when there is no link."},"fileDeletesAt":{"type":["string","null"],"description":"The first time the MP4 may be deleted to free space: export files are kept for a limited time. null when nothing deletes it, and once it is deleted."},"fileDeletedAt":{"type":["string","null"],"description":"When the MP4 was deleted to free space; export the composition again for a new file. null while the file is kept."}},"required":["id","compositionId","projectId","jobId","revision","status","progress","errorMessage","createdAt","finishedAt","file","downloadUrl","downloadUrlExpiresAt","fileDeletesAt","fileDeletedAt"]},"description":"The items of this page."},"hasMore":{"type":"boolean","description":"true when there are more items after this page."},"nextCursor":{"type":["string","null"],"description":"Send it as cursor to get the next page. It is null on the last page."}},"required":["data","hasMore","nextCursor"]},"examples":{"example1":{"summary":"List the exports of a project","value":{"data":[{"id":"rnd_0f6b3e9d2c7a4158b4a3","compositionId":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","jobId":"job_a3e9d05c7b1f4e2896d4","revision":0,"status":"done","progress":1,"errorMessage":null,"createdAt":"2026-09-01T10:10:00.000Z","finishedAt":"2026-09-01T10:15:00.000Z","file":{"mimeType":"video/mp4","sizeBytes":18874368,"durationSec":30,"width":1080,"height":1920},"downloadUrl":"https://www.gpt-video.com/media/ast_c47d2e8a19b54f06d2e1?exp=1788258600&sig=9b2e61c04d7f3a58e1b6c2d9f0a4e7b3","downloadUrlExpiresAt":"2026-09-01T10:30:00.000Z","fileDeletesAt":"2026-09-15T10:15:00.000Z","fileDeletedAt":null}],"hasMore":false,"nextCursor":null}},"example2":{"summary":"List the exports of one composition","value":{"data":[{"id":"rnd_0f6b3e9d2c7a4158b4a3","compositionId":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","jobId":"job_a3e9d05c7b1f4e2896d4","revision":0,"status":"done","progress":1,"errorMessage":null,"createdAt":"2026-09-01T10:10:00.000Z","finishedAt":"2026-09-01T10:15:00.000Z","file":{"mimeType":"video/mp4","sizeBytes":18874368,"durationSec":30,"width":1080,"height":1920},"downloadUrl":"https://www.gpt-video.com/media/ast_c47d2e8a19b54f06d2e1?exp=1788258600&sig=9b2e61c04d7f3a58e1b6c2d9f0a4e7b3","downloadUrlExpiresAt":"2026-09-01T10:30:00.000Z","fileDeletesAt":"2026-09-15T10:15:00.000Z","fileDeletedAt":null}],"hasMore":false,"nextCursor":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/split-screen":{"post":{"operationId":"create_split_screen_project","summary":"Create a split screen project","description":"Creates a split screen project from two videos you uploaded: the main video on top and a background video under it.\n\nCall it after complete_upload, with the ids of two videos. The two videos and the language are chosen here and only here: to use other videos, create another project. The layout, the captions and the start of the background can be changed later with update_split_screen_project. Nothing is built and no credits are used until you call build_split_screen_video. Send an Idempotency-Key: a retry without one creates a second project.","tags":["studio"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mainAssetId":{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$","description":"The main video, shown on top and transcribed for the captions: the asset id that complete_upload returned. It cannot be changed later."},"backgroundAssetId":{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$","description":"The background video, shown under the main video, such as gameplay footage. It cannot be changed later."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style, or null for a video with no captions. get_setting_options lists every style with what it looks like."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it. It cannot be changed later."},"backgroundStartSec":{"type":"number","minimum":0,"description":"Where the background video starts, in seconds, before the end of the background video. Leave it out to let the first build choose a random start, which is then kept."},"vocabulary":{"type":"string","maxLength":311,"description":"Names, brands and jargon the transcription should spell right, separated by commas. At most 311 characters."},"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"A name for the project, shown in the GPT-Video app. Leave it out to get a default name."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language"],"additionalProperties":false}}}},"responses":{"201":{"description":"Created","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Create a split screen project","value":{"project":{"id":"prj_5b8e2d71c4a94f06b3e9","kind":"splitscreen","title":"Product demo over the city","status":"draft","sourceAssetId":"ast_8e21b0d94c6f4a17b358","compositionId":null,"settings":null,"missingSettings":[],"errorMessage":null,"splitScreen":{"mainAssetId":"ast_8e21b0d94c6f4a17b358","backgroundAssetId":"ast_8ac5d8b97546145cdbf6","layout":"60-40","captionStyle":"bold-karaoke","language":"en","backgroundStartSec":null,"vocabulary":null},"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"createdAt":"2026-09-01T11:00:00.000Z","updatedAt":"2026-09-01T11:00:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The build is charged when you call build_split_screen_video.","x-stability":"beta"}},"/projects/{projectId}/split-screen":{"patch":{"operationId":"update_split_screen_project","summary":"Update a split screen project","description":"Changes the name, the layout, the captions, the start of the background or the vocabulary of a split screen project.\n\nOnly the fields you send change. The changes are used by the next build, which is charged; a change saved while a build waits in the queue is read by that build. The two videos and the language cannot be changed: sending them is refused, and to use other videos you create another project.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"The new name of the project."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style, or null for a video with no captions. get_setting_options lists every style with what it looks like."},"backgroundStartSec":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Where the background video starts, in seconds; null lets the next build choose a random start, which is then kept."},"vocabulary":{"anyOf":[{"type":"string","maxLength":311},{"type":"null"}],"description":"Names, brands and jargon the transcription should spell right, separated by commas. At most 311 characters; null removes it."}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Change the layout and the start of the background","value":{"project":{"id":"prj_9cf6ba9cd17fd89cf513","kind":"splitscreen","title":"Founder interview, split","status":"ready","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","compositionId":"cmp_cc26cb47fd6004aa5fba","settings":null,"missingSettings":[],"errorMessage":null,"splitScreen":{"mainAssetId":"ast_3f9a1c7e5b2d4086a1c4","backgroundAssetId":"ast_8ac5d8b97546145cdbf6","layout":"50-50","captionStyle":"bold-karaoke","language":"en","backgroundStartSec":12,"vocabulary":null},"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"createdAt":"2026-08-31T21:40:00.000Z","updatedAt":"2026-09-01T11:05:00.000Z"}}},"example2":{"summary":"Remove the captions","value":{"project":{"id":"prj_9cf6ba9cd17fd89cf513","kind":"splitscreen","title":"Founder interview, split","status":"ready","sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","compositionId":"cmp_cc26cb47fd6004aa5fba","settings":null,"missingSettings":[],"errorMessage":null,"splitScreen":{"mainAssetId":"ast_3f9a1c7e5b2d4086a1c4","backgroundAssetId":"ast_8ac5d8b97546145cdbf6","layout":"60-40","captionStyle":null,"language":"en","backgroundStartSec":null,"vocabulary":null},"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":null,"createdAt":"2026-08-31T21:40:00.000Z","updatedAt":"2026-09-01T11:05:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The next build is charged when you call build_split_screen_video.","x-stability":"beta"}},"/projects/{projectId}/split-screen/build":{"post":{"operationId":"build_split_screen_video","summary":"Build a split screen video","description":"Starts the build of the video of a split screen project, and returns the job to follow.\n\nCall it when the project has its settings; estimate_analysis gives the price first. The answer is 202 with the job of the build: follow it with get_job, and when it is done export the composition named by get_project with create_export. A build makes the video again from the settings, replacing the changes made to the composition in the GPT-Video editor. Retrying with the same Idempotency-Key never pays twice; a new key is a new build, and building again pays again for the minutes of both videos, the background included. If a build of the project is already running, you get that job back and nothing is charged.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","description":"The job id. It starts with job_."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does. analysis finds the clips of an Auto Clip project, or prepares a Vibe Editing project. build makes the video of a split screen, streamer or Reddit story project. export renders a composition to a file. framing follows the face in a clip. import brings in a video from a link. story writes the story of a fake text project. voices makes the voices of a fake text story. tool runs a voiceover, an audio separation or a brainstorm. assistant_turn is one turn of the Editor Assistant."},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the job is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the job failed or stopped, in one sentence; null otherwise."},"projectId":{"type":["string","null"],"description":"The project the job works on, when it has one."},"compositionId":{"type":["string","null"],"description":"The composition the job works on, when it has one."},"exportId":{"type":["string","null"],"description":"The export this job renders, for an export job; null otherwise."},"assetId":{"type":["string","null"],"description":"The video an import job brought in, once the job is done; null for every other job, and when that video no longer exists or cannot be used through the API."},"toolRunId":{"type":["string","null"],"description":"The tool run a tool job carries out, to read with get_tool_run; null for every other job."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn an assistant_turn job carries out, to read with get_assistant_turn; null for every other job."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"startedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","kind","status","progress","errorMessage","projectId","compositionId","exportId","assetId","toolRunId","turnId","createdAt","startedAt","finishedAt"]},"creditsCharged":{"type":"integer","minimum":0,"description":"The credits this request was charged: the price of the work it started, 0 when the same work was already running and its job came back."},"reused":{"type":"boolean","description":"true when the same work was already running on the project and this is its job, charged to nobody again."},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["job","creditsCharged","reused","paidWith"]},"examples":{"example1":{"summary":"Build a split screen video","value":{"job":{"id":"job_3e9c5a17d0b84f26e1a7","kind":"build","status":"queued","progress":0,"errorMessage":null,"projectId":"prj_9cf6ba9cd17fd89cf513","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T11:10:00.000Z","startedAt":null,"finishedAt":null},"creditsCharged":31,"reused":false,"paidWith":"plan"}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED, SOURCE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"One credit per started minute of the main video and of the background video together, charged when the build starts and not returned if it fails. Building again is a new build and is charged again.","x-stability":"beta"}},"/projects/streamer":{"post":{"operationId":"create_streamer_project","summary":"Create a streamer project","description":"Creates a streamer project from a clip you uploaded: a vertical video that follows the speaker, with a headline and captions.\n\nCall it after complete_upload, with the id of the clip. The clip and its language are chosen here and only here: to use another clip, create another project. The headline, the captions, the framing and the vocabulary can be changed later with update_streamer_project. Nothing is built and no credits are used until you call build_streamer_video. Send an Idempotency-Key: a retry without one creates a second project.","tags":["studio"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sourceAssetId":{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$","description":"The clip to make vertical: the asset id that complete_upload returned. It cannot be changed later."},"headline":{"type":"string","maxLength":120,"description":"The line shown over the clip, up to 120 characters; \"\" for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it. It cannot be changed later."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style. get_setting_options lists every style with what it looks like."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":"string","maxLength":311,"description":"Names, brands and jargon the transcription should spell right, separated by commas. At most 311 characters."},"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"A name for the project, shown in the GPT-Video app. Leave it out to get a default name."}},"required":["sourceAssetId","headline","language","captionStyle","reframe"],"additionalProperties":false}}}},"responses":{"201":{"description":"Created","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Create a streamer project","value":{"project":{"id":"prj_0c7f3a95e1d24b68a4f2","kind":"streamer","title":"Streamer clip","status":"draft","sourceAssetId":"ast_8e21b0d94c6f4a17b358","compositionId":null,"settings":null,"missingSettings":[],"errorMessage":null,"splitScreen":null,"streamer":{"sourceAssetId":"ast_8e21b0d94c6f4a17b358","headline":"Watch the editor cut it","language":"en","captionStyle":"word-pop","reframe":"face","vocabulary":null},"redditStory":null,"fakeText":null,"vibeEdit":null,"createdAt":"2026-09-01T11:00:00.000Z","updatedAt":"2026-09-01T11:00:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The build is charged when you call build_streamer_video.","x-stability":"beta"}},"/projects/{projectId}/streamer":{"patch":{"operationId":"update_streamer_project","summary":"Update a streamer project","description":"Changes the name, the headline, the captions, the framing or the vocabulary of a streamer project.\n\nOnly the fields you send change. The changes are used by the next build, which is charged; a change saved while a build waits in the queue is read by that build. The clip and its language cannot be changed: sending them is refused, and to use another clip you create another project.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"The new name of the project."},"headline":{"type":"string","maxLength":120,"description":"The line shown over the clip, up to 120 characters; \"\" removes it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style. get_setting_options lists every style with what it looks like."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"anyOf":[{"type":"string","maxLength":311},{"type":"null"}],"description":"Names, brands and jargon the transcription should spell right, separated by commas. At most 311 characters; null removes it."}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Change the headline and keep the middle of the frame","value":{"project":{"id":"prj_b9eb66e5ba20c4464f36","kind":"streamer","title":"The demo in one minute","status":"ready","sourceAssetId":"ast_8e21b0d94c6f4a17b358","compositionId":"cmp_372b3304ae7cd6327fed","settings":null,"missingSettings":[],"errorMessage":null,"splitScreen":null,"streamer":{"sourceAssetId":"ast_8e21b0d94c6f4a17b358","headline":"One minute, one demo","language":"en","captionStyle":"word-pop","reframe":"center","vocabulary":null},"redditStory":null,"fakeText":null,"vibeEdit":null,"createdAt":"2026-08-31T21:50:00.000Z","updatedAt":"2026-09-01T11:05:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The next build is charged when you call build_streamer_video.","x-stability":"beta"}},"/projects/{projectId}/streamer/build":{"post":{"operationId":"build_streamer_video","summary":"Build a streamer video","description":"Starts the build of the vertical video of a streamer project, and returns the job to follow.\n\nCall it when the project has its settings; estimate_analysis gives the price first. The answer is 202 with the job of the build: follow it with get_job. When reframe is face, the build also starts computing the framing on the speaker's face, and create_export answers NOT_READY until it is done. A build makes the video again from the settings, replacing the changes made to the composition in the GPT-Video editor. Retrying with the same Idempotency-Key never pays twice; a new key is a new build, and it is charged again. If a build of the project is already running, you get that job back and nothing is charged.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","description":"The job id. It starts with job_."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does. analysis finds the clips of an Auto Clip project, or prepares a Vibe Editing project. build makes the video of a split screen, streamer or Reddit story project. export renders a composition to a file. framing follows the face in a clip. import brings in a video from a link. story writes the story of a fake text project. voices makes the voices of a fake text story. tool runs a voiceover, an audio separation or a brainstorm. assistant_turn is one turn of the Editor Assistant."},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the job is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the job failed or stopped, in one sentence; null otherwise."},"projectId":{"type":["string","null"],"description":"The project the job works on, when it has one."},"compositionId":{"type":["string","null"],"description":"The composition the job works on, when it has one."},"exportId":{"type":["string","null"],"description":"The export this job renders, for an export job; null otherwise."},"assetId":{"type":["string","null"],"description":"The video an import job brought in, once the job is done; null for every other job, and when that video no longer exists or cannot be used through the API."},"toolRunId":{"type":["string","null"],"description":"The tool run a tool job carries out, to read with get_tool_run; null for every other job."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn an assistant_turn job carries out, to read with get_assistant_turn; null for every other job."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"startedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","kind","status","progress","errorMessage","projectId","compositionId","exportId","assetId","toolRunId","turnId","createdAt","startedAt","finishedAt"]},"creditsCharged":{"type":"integer","minimum":0,"description":"The credits this request was charged: the price of the work it started, 0 when the same work was already running and its job came back."},"reused":{"type":"boolean","description":"true when the same work was already running on the project and this is its job, charged to nobody again."},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["job","creditsCharged","reused","paidWith"]},"examples":{"example1":{"summary":"Build a streamer video","value":{"job":{"id":"job_7a1d4f0c9e2b56a83d1c","kind":"build","status":"queued","progress":0,"errorMessage":null,"projectId":"prj_b9eb66e5ba20c4464f36","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T11:10:00.000Z","startedAt":null,"finishedAt":null},"creditsCharged":2,"reused":false,"paidWith":"plan"}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED, SOURCE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"One credit per started minute of the clip, charged when the build starts and not returned if it fails. Building again is charged again.","x-stability":"beta"}},"/projects/reddit-story":{"post":{"operationId":"create_reddit_story_project","summary":"Create a Reddit story project","description":"Creates a Reddit story project: a post read by a synthetic voice over a background video, with a title card and captions.\n\nSend the post, who wrote it and where, the voice and the language: list_voices names the voices of each language. The background video is optional and can be changed later. Everything can be changed with update_reddit_story_project. Nothing is built and no credits are used until you call build_reddit_story_video. Send an Idempotency-Key: a retry without one creates a second project.","tags":["studio"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"postTitle":{"type":"string","minLength":1,"maxLength":300,"pattern":"\\S","description":"The title of the post, shown on the title card and read first. From 1 to 300 characters."},"postBody":{"type":"string","minLength":1,"maxLength":8000,"pattern":"\\S","description":"The text of the post, read by the voice. From 1 to 8000 characters."},"author":{"type":"string","minLength":1,"maxLength":40,"description":"The author shown on the title card, such as u/thrown_away. From 1 to 40 characters."},"subreddit":{"type":"string","minLength":1,"maxLength":40,"description":"The community shown on the title card, such as r/stories. From 1 to 40 characters."},"voice":{"type":"string","enum":["en-aria","en-jenny","en-guy","en-christopher","it-elsa","it-isabella","it-diego","it-giuseppe"],"description":"The voice that reads the story, as list_voices names it. It must be a voice of the story's language."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style. get_setting_options lists every style with what it looks like."},"backgroundAssetId":{"anyOf":[{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$"},{"type":"null"}],"description":"The background video, as complete_upload returned it; null for none."},"vocabulary":{"type":"string","maxLength":311,"description":"Names, brands and jargon the transcription should spell right, separated by commas. At most 311 characters."},"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"A name for the project, shown in the GPT-Video app. Leave it out to get a default name."}},"required":["postTitle","postBody","author","subreddit","voice","language","captionStyle","backgroundAssetId"],"additionalProperties":false}}}},"responses":{"201":{"description":"Created","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Create a Reddit story project","value":{"project":{"id":"prj_e94a1c6b07d35f28c1b4","kind":"redditstory","title":"Reddit story","status":"draft","sourceAssetId":null,"compositionId":null,"settings":null,"missingSettings":[],"errorMessage":null,"splitScreen":null,"streamer":null,"redditStory":{"postTitle":"I said no to my boss's weekend trip","postBody":"My boss planned a team trip on my only free weekend of the month. I said no, and now the team thinks I am the problem.","author":"u/weekend_keeper","subreddit":"r/stories","voice":"en-jenny","language":"en","backgroundAssetId":"ast_8ac5d8b97546145cdbf6","captionStyle":"bold-karaoke","vocabulary":null},"fakeText":null,"vibeEdit":null,"createdAt":"2026-09-01T11:00:00.000Z","updatedAt":"2026-09-01T11:00:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The build is charged when you call build_reddit_story_video.","x-stability":"beta"}},"/projects/{projectId}/reddit-story":{"patch":{"operationId":"update_reddit_story_project","summary":"Update a Reddit story project","description":"Changes the post, the voice, the language, the captions or the background video of a Reddit story project.\n\nOnly the fields you send change. A new language needs a voice of that language in the same request, because each voice reads one language. The background video can be changed, or removed with null. The changes are used by the next build, which is charged; a change saved while a build waits in the queue is read by that build.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"The new name of the project."},"postTitle":{"type":"string","minLength":1,"maxLength":300,"pattern":"\\S","description":"The title of the post, shown on the title card and read first. From 1 to 300 characters."},"postBody":{"type":"string","minLength":1,"maxLength":8000,"pattern":"\\S","description":"The text of the post, read by the voice. From 1 to 8000 characters."},"author":{"type":"string","minLength":1,"maxLength":40,"description":"The author shown on the title card, such as u/thrown_away. From 1 to 40 characters."},"subreddit":{"type":"string","minLength":1,"maxLength":40,"description":"The community shown on the title card, such as r/stories. From 1 to 40 characters."},"voice":{"type":"string","enum":["en-aria","en-jenny","en-guy","en-christopher","it-elsa","it-isabella","it-diego","it-giuseppe"],"description":"The voice that reads the story, as list_voices names it. It must be a voice of the story's language."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice. Send the voice of the new language in the same request."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style. get_setting_options lists every style with what it looks like."},"backgroundAssetId":{"anyOf":[{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$"},{"type":"null"}],"description":"The new background video, as complete_upload returned it; null removes the background."},"vocabulary":{"anyOf":[{"type":"string","maxLength":311},{"type":"null"}],"description":"Names, brands and jargon the transcription should spell right, separated by commas. At most 311 characters; null removes it."}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Change the post and the background video","value":{"project":{"id":"prj_b71ffef7c27c5ea1cc87","kind":"redditstory","title":"Leaving my own party","status":"ready","sourceAssetId":null,"compositionId":"cmp_926433093fafcd62c9cb","settings":null,"missingSettings":[],"errorMessage":null,"splitScreen":null,"streamer":null,"redditStory":{"postBody":"I left my own birthday party after an hour and my sister says I ruined it","author":"u/thrown_away_42","voice":"en-aria","language":"en","captionStyle":"bold-karaoke","vocabulary":null,"postTitle":"Was I wrong to leave my own party early?","subreddit":"r/TrueOffMyChest","backgroundAssetId":"ast_2a2215a18805ec31c629"},"fakeText":null,"vibeEdit":null,"createdAt":"2026-08-31T22:00:00.000Z","updatedAt":"2026-09-01T11:05:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The next build is charged when you call build_reddit_story_video.","x-stability":"beta"}},"/projects/{projectId}/reddit-story/build":{"post":{"operationId":"build_reddit_story_video","summary":"Build a Reddit story video","description":"Starts the build of the video of a Reddit story project, with its synthetic voice, and returns the job to follow.\n\nCall it when the post is written; estimate_analysis gives the price first. The build reads the post with a synthetic voice, times the captions on it and puts them over the background. The answer is 202 with the job of the build: follow it with get_job, then export the composition named by get_project with create_export. A build makes the video again from the settings, replacing the changes made to the composition in the GPT-Video editor. Retrying with the same Idempotency-Key never pays twice; a new key is a new build, and it is charged again.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","description":"The job id. It starts with job_."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does. analysis finds the clips of an Auto Clip project, or prepares a Vibe Editing project. build makes the video of a split screen, streamer or Reddit story project. export renders a composition to a file. framing follows the face in a clip. import brings in a video from a link. story writes the story of a fake text project. voices makes the voices of a fake text story. tool runs a voiceover, an audio separation or a brainstorm. assistant_turn is one turn of the Editor Assistant."},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the job is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the job failed or stopped, in one sentence; null otherwise."},"projectId":{"type":["string","null"],"description":"The project the job works on, when it has one."},"compositionId":{"type":["string","null"],"description":"The composition the job works on, when it has one."},"exportId":{"type":["string","null"],"description":"The export this job renders, for an export job; null otherwise."},"assetId":{"type":["string","null"],"description":"The video an import job brought in, once the job is done; null for every other job, and when that video no longer exists or cannot be used through the API."},"toolRunId":{"type":["string","null"],"description":"The tool run a tool job carries out, to read with get_tool_run; null for every other job."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn an assistant_turn job carries out, to read with get_assistant_turn; null for every other job."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"startedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","kind","status","progress","errorMessage","projectId","compositionId","exportId","assetId","toolRunId","turnId","createdAt","startedAt","finishedAt"]},"creditsCharged":{"type":"integer","minimum":0,"description":"The credits this request was charged: the price of the work it started, 0 when the same work was already running and its job came back."},"reused":{"type":"boolean","description":"true when the same work was already running on the project and this is its job, charged to nobody again."},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["job","creditsCharged","reused","paidWith"]},"examples":{"example1":{"summary":"Build a Reddit story video","value":{"job":{"id":"job_c25e8b3f61a04d97b0e5","kind":"build","status":"queued","progress":0,"errorMessage":null,"projectId":"prj_b71ffef7c27c5ea1cc87","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T11:10:00.000Z","startedAt":null,"finishedAt":null},"creditsCharged":1,"reused":false,"paidWith":"plan"}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED, SOURCE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"One credit per build, whatever the length of the story, charged when the build starts and not returned if it fails. Building again is charged again.","x-stability":"beta"}},"/projects/fake-text":{"post":{"operationId":"create_fake_text_project","summary":"Create a fake text project","description":"Creates a fake text project, a chat story shown as a vertical video, with its look, language, voices and background chosen now.\n\nUse it to start a fake text video. Choose the look of the chat, the language of the story, whether the lines get voices and the background video now; you can change them later with update_fake_text_project. The project starts without a story: write one with update_fake_text_story, or let GPT-Video write one with generate_fake_text_story. Then make the voices with create_fake_text_voices and export the video with create_export, using the compositionId of the project.","tags":["studio"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices: en or it. A story GPT-Video writes is written in it."},"voiceover":{"type":"boolean","description":"true to give each line a voice when you call create_fake_text_voices; false for a silent chat."},"backgroundAssetId":{"anyOf":[{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$"},{"type":"null"}],"description":"The video shown behind the chat: the asset id of a video you uploaded or imported. null for no background."},"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"The name of the project. Without it the project is called Fake text story until GPT-Video writes a story for it, which names it."}},"required":["theme","language","voiceover","backgroundAssetId"],"additionalProperties":false}}}},"responses":{"201":{"description":"Created","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Create a fake text project","value":{"project":{"id":"prj_3c0f8e1d5a9b4e2786d1","kind":"faketext","title":"Group chat drama","status":"draft","sourceAssetId":null,"compositionId":null,"settings":null,"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":{"theme":"imessage","language":"en","voiceover":true,"backgroundAssetId":"ast_8ac5d8b97546145cdbf6","storyId":null},"vibeEdit":null,"errorMessage":null,"createdAt":"2026-09-01T11:00:00.000Z","updatedAt":"2026-09-01T11:00:00.000Z"}}},"example2":{"summary":"A silent chat with no background","value":{"project":{"id":"prj_3c0f8e1d5a9b4e2786d1","kind":"faketext","title":"Fake text story","status":"draft","sourceAssetId":null,"compositionId":null,"settings":null,"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":{"theme":"whatsapp","language":"it","voiceover":false,"backgroundAssetId":null,"storyId":null},"vibeEdit":null,"errorMessage":null,"createdAt":"2026-09-01T11:00:00.000Z","updatedAt":"2026-09-01T11:00:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/{projectId}/fake-text":{"patch":{"operationId":"update_fake_text_project","summary":"Update a fake text project","description":"Changes the name, look, language, voices setting or background of a fake text project, leaving every field you do not send as it was.\n\nUse it to change a choice made at creation. Only the fields you send change, and the video of the project is rebuilt with them. The look of the chat is written to the project and to its story. Changing the language keeps the words of the story and gives the default voice of the new language to each side whose voice is of the other language. Send backgroundAssetId null to remove the background.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"The new name of the project."},"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices: en or it."},"voiceover":{"type":"boolean","description":"true to give each line a voice when you call create_fake_text_voices; false for a silent chat."},"backgroundAssetId":{"anyOf":[{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$"},{"type":"null"}],"description":"The video shown behind the chat: the asset id of a video you uploaded or imported. null for no background."}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Show the chat as WhatsApp","value":{"project":{"id":"prj_ba8b07a88bfb14585459","kind":"faketext","title":"The surprise party","status":"ready","sourceAssetId":null,"compositionId":"cmp_47e9069a7ece7041f213","settings":null,"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":{"theme":"whatsapp","language":"en","voiceover":true,"backgroundAssetId":"ast_8ac5d8b97546145cdbf6","storyId":"cnv_a744d5ef6cc005e19285"},"vibeEdit":null,"errorMessage":null,"createdAt":"2026-08-31T22:10:00.000Z","updatedAt":"2026-09-01T11:05:00.000Z"}}},"example2":{"summary":"Remove the background","value":{"project":{"id":"prj_ba8b07a88bfb14585459","kind":"faketext","title":"The surprise party","status":"ready","sourceAssetId":null,"compositionId":"cmp_47e9069a7ece7041f213","settings":null,"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":{"theme":"imessage","language":"en","voiceover":true,"backgroundAssetId":null,"storyId":"cnv_a744d5ef6cc005e19285"},"vibeEdit":null,"errorMessage":null,"createdAt":"2026-08-31T22:10:00.000Z","updatedAt":"2026-09-01T11:05:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/{projectId}/story":{"get":{"operationId":"get_fake_text_story","summary":"Get the story of a fake text project","description":"Returns the story of a fake text project, line by line, with the voice of each side and which lines have their voice.\n\nUse it to read the story before you change it with update_fake_text_story: send back the line ids you read here to keep those lines and their voices. story is null until the project has a story. Each line says whether it has its voice; create_fake_text_voices makes the missing ones.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"story":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"The story id. It starts with cnv_."},"projectId":{"type":"string"},"title":{"type":"string"},"contactName":{"type":"string","description":"The name shown at the top of the chat."},"language":{"type":"string","enum":["en","it"]},"left":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"],"description":"The other person in the chat."},"right":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"],"description":"The person whose phone shows the chat."},"voices":{"type":"object","properties":{"left":{"type":["string","null"]},"right":{"type":["string","null"]}},"required":["left","right"],"description":"The voice of each side, as list_voices names it; null for the default voice of the language, or for a voice that is not available through the API."},"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The line id. Send it back with update_fake_text_story to keep the line and its voice."},"side":{"type":"string","enum":["left","right"]},"text":{"type":"string"},"voiced":{"type":"boolean","description":"true when the line has its voice."},"voiceDurationSec":{"type":["number","null"],"description":"How long the voice of the line lasts, in seconds; null without a voice."}},"required":["id","side","text","voiced","voiceDurationSec"]}},"voicedCount":{"type":"integer","description":"How many lines have their voice."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","title","contactName","language","left","right","voices","messages","voicedCount","createdAt","updatedAt"]},{"type":"null"}],"description":"The story of the project; null until it has one."}},"required":["story"]},"examples":{"example1":{"summary":"Read the story","value":{"story":{"id":"cnv_a744d5ef6cc005e19285","projectId":"prj_ba8b07a88bfb14585459","title":"The surprise party","contactName":"Sam","language":"en","left":{"name":"Sam"},"right":{"name":"Me"},"voices":{"left":"en-guy","right":"en-aria"},"messages":[{"id":"msg_e09afef44e32faf0bcb7","side":"left","text":"Are you free on Saturday night?","voiced":true,"voiceDurationSec":1.9},{"id":"msg_568316dbc0cca81d3b24","side":"right","text":"Maybe, why?","voiced":false,"voiceDurationSec":null},{"id":"msg_556466181cf09d6bf0a2","side":"left","text":"No reason. Wear something nice.","voiced":true,"voiceDurationSec":1.9},{"id":"msg_0d93572450a652e08706","side":"right","text":"Now I am worried.","voiced":false,"voiceDurationSec":null}],"voicedCount":2,"createdAt":"2026-08-31T22:12:00.000Z","updatedAt":"2026-08-31T22:14:00.000Z"}}},"example2":{"summary":"A project with no story yet","value":{"story":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"},"put":{"operationId":"update_fake_text_story","summary":"Write the story of a fake text project","description":"Replaces the story of a fake text project with the one you send, or writes its first story, and rebuilds its video.\n\nSend the whole story as you want it: the title, the two people, the voices and every line in order. Send the line ids you read with get_fake_text_story: a line sent with its id keeps its voice while its text does not change. Lines sent without an id get a new id each time you send the story, and a line with a new id has no voice until create_fake_text_voices makes it. A project without a story gets this one as its first, and nothing is used. The language of the story is the language of the project. The answer is the story as it is saved.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200,"pattern":"\\S","description":"The title of the story, also the title of its video."},"contactName":{"type":"string","minLength":1,"maxLength":60,"pattern":"\\S","description":"The name shown at the top of the chat. Without it the chat shows left.name."},"left":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60,"pattern":"\\S","description":"The name of the other person in the chat."}},"required":["name"],"additionalProperties":false,"description":"The other person in the chat, whose bubbles are on the left."},"right":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60,"pattern":"\\S","description":"The name of the person whose phone shows the chat."}},"required":["name"],"additionalProperties":false,"description":"The person whose phone shows the chat, whose bubbles are on the right."},"voices":{"type":"object","properties":{"left":{"anyOf":[{"type":"string","minLength":1,"maxLength":40},{"type":"null"}],"description":"A voice id as list_voices names it, in the language of the project. null gives this side the default voice of the language; leaving it out keeps the voice this side has."},"right":{"anyOf":[{"type":"string","minLength":1,"maxLength":40},{"type":"null"}],"description":"A voice id as list_voices names it, in the language of the project. null gives this side the default voice of the language; leaving it out keeps the voice this side has."}},"additionalProperties":false,"description":"The voice of each side. A side you leave out keeps its voice."},"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$","description":"The id of a line you read with get_fake_text_story. Send it to keep the line and its voice; leave it out for a new line."},"side":{"type":"string","enum":["left","right"],"description":"Who sends the line: left is the other person, right is the person whose phone shows the chat."},"text":{"type":"string","minLength":1,"maxLength":300,"pattern":"\\S","description":"The words of the line, up to 300 characters."}},"required":["side","text"],"additionalProperties":false},"minItems":1,"maxItems":60,"description":"The lines of the chat in the order they appear, from 1 to 60."}},"required":["title","left","right","messages"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"story":{"type":"object","properties":{"id":{"type":"string","description":"The story id. It starts with cnv_."},"projectId":{"type":"string"},"title":{"type":"string"},"contactName":{"type":"string","description":"The name shown at the top of the chat."},"language":{"type":"string","enum":["en","it"]},"left":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"],"description":"The other person in the chat."},"right":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"],"description":"The person whose phone shows the chat."},"voices":{"type":"object","properties":{"left":{"type":["string","null"]},"right":{"type":["string","null"]}},"required":["left","right"],"description":"The voice of each side, as list_voices names it; null for the default voice of the language, or for a voice that is not available through the API."},"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The line id. Send it back with update_fake_text_story to keep the line and its voice."},"side":{"type":"string","enum":["left","right"]},"text":{"type":"string"},"voiced":{"type":"boolean","description":"true when the line has its voice."},"voiceDurationSec":{"type":["number","null"],"description":"How long the voice of the line lasts, in seconds; null without a voice."}},"required":["id","side","text","voiced","voiceDurationSec"]}},"voicedCount":{"type":"integer","description":"How many lines have their voice."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","projectId","title","contactName","language","left","right","voices","messages","voicedCount","createdAt","updatedAt"]}},"required":["story"]},"examples":{"example1":{"summary":"Change a line and add one","value":{"story":{"id":"cnv_a744d5ef6cc005e19285","projectId":"prj_ba8b07a88bfb14585459","title":"The surprise party","contactName":"Sam","language":"en","left":{"name":"Sam"},"right":{"name":"Me"},"voices":{"left":"en-guy","right":"en-aria"},"messages":[{"id":"msg_e09afef44e32faf0bcb7","side":"left","text":"Are you free on Saturday night?","voiced":true,"voiceDurationSec":1.9},{"id":"msg_568316dbc0cca81d3b24","side":"right","text":"Maybe. Why do you ask?","voiced":false,"voiceDurationSec":null},{"id":"msg_556466181cf09d6bf0a2","side":"left","text":"No reason. Wear something nice.","voiced":true,"voiceDurationSec":1.9},{"id":"msg_9b3e1f7c2a5d4860b1c4","side":"right","text":"Should I be worried?","voiced":false,"voiceDurationSec":null}],"voicedCount":2,"createdAt":"2026-08-31T22:12:00.000Z","updatedAt":"2026-09-01T11:05:00.000Z"}}},"example2":{"summary":"Write the first story of a project","value":{"story":{"id":"cnv_5f1e2d3c4b5a6978a8b9","projectId":"prj_ba8b07a88bfb14585459","title":"The last slice","contactName":"Alex","language":"en","left":{"name":"Alex"},"right":{"name":"Me"},"voices":{"left":null,"right":null},"messages":[{"id":"msg_1a6c4e8f0b2d4975a3c8","side":"left","text":"Who ate my pizza?","voiced":false,"voiceDurationSec":null},{"id":"msg_7e0b5d3a9c1f4268e4d0","side":"right","text":"Not me.","voiced":false,"voiceDurationSec":null}],"voicedCount":0,"createdAt":"2026-09-01T11:05:00.000Z","updatedAt":"2026-09-01T11:05:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/{projectId}/story/generate":{"post":{"operationId":"generate_fake_text_story","summary":"Write a fake text story with GPT-Video","description":"Starts writing a new story for a fake text project from your brief, and returns the job to follow.\n\nUse it to let GPT-Video write the story from a short brief; an empty brief writes a sample story. The answer is 202 with the job: follow it with get_job, then read the story with get_fake_text_story. The new story replaces the story of the project, and the video follows it; the old story is no longer shown. If a story is already being written for the project, you get that job back and nothing is used (reused is true). Make the voices afterwards with create_fake_text_voices.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"brief":{"type":"string","maxLength":4000,"description":"What the story is about, up to 4000 characters. An empty brief writes a sample story."}},"required":["brief"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","description":"The job id. It starts with job_."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does. analysis finds the clips of an Auto Clip project, or prepares a Vibe Editing project. build makes the video of a split screen, streamer or Reddit story project. export renders a composition to a file. framing follows the face in a clip. import brings in a video from a link. story writes the story of a fake text project. voices makes the voices of a fake text story. tool runs a voiceover, an audio separation or a brainstorm. assistant_turn is one turn of the Editor Assistant."},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the job is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the job failed or stopped, in one sentence; null otherwise."},"projectId":{"type":["string","null"],"description":"The project the job works on, when it has one."},"compositionId":{"type":["string","null"],"description":"The composition the job works on, when it has one."},"exportId":{"type":["string","null"],"description":"The export this job renders, for an export job; null otherwise."},"assetId":{"type":["string","null"],"description":"The video an import job brought in, once the job is done; null for every other job, and when that video no longer exists or cannot be used through the API."},"toolRunId":{"type":["string","null"],"description":"The tool run a tool job carries out, to read with get_tool_run; null for every other job."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn an assistant_turn job carries out, to read with get_assistant_turn; null for every other job."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"startedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","kind","status","progress","errorMessage","projectId","compositionId","exportId","assetId","toolRunId","turnId","createdAt","startedAt","finishedAt"]},"reused":{"type":"boolean","description":"true when a story was already running for this project and this is its job, paid by nobody again."},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["job","reused","paidWith"]},"examples":{"example1":{"summary":"Write a story from a brief","value":{"job":{"status":"queued","progress":0,"errorMessage":null,"projectId":"prj_ba8b07a88bfb14585459","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T11:10:00.000Z","startedAt":null,"finishedAt":null,"id":"job_7d2c9a4e1f0b4386c5a2","kind":"story"},"reused":false,"paidWith":"plan"}},"example2":{"summary":"A story that is already being written","value":{"job":{"status":"running","progress":0.4,"errorMessage":null,"projectId":"prj_ba8b07a88bfb14585459","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-08-31T22:10:00.000Z","startedAt":"2026-08-31T22:11:00.000Z","finishedAt":null,"id":"job_a84eefa1e7fd196089dd","kind":"story"},"reused":true,"paidWith":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"Uses one fake text script of the plan's daily allowance, which resets at 00:00 UTC. When the API bonus pays, it also uses one bonus credit. Nothing is returned if the work fails.","x-bonus-credits":1,"x-stability":"beta"}},"/projects/{projectId}/story/voices":{"post":{"operationId":"create_fake_text_voices","summary":"Make the voices of a fake text story","description":"Starts making the voice of every line of the story that does not have it yet, and returns the job to follow.\n\nCall it once the story is as you want it and voiceover is on. Only lines without their voice are voiced: new lines, lines whose words changed, and the lines of a side whose voice changed. The answer is 202 with the job: follow it with get_job, then export the video with create_export. If voices are already being made for the story, you get that job back and nothing is used (reused is true). A story whose lines all have their voice is refused before anything is used.","tags":["studio"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","description":"The job id. It starts with job_."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does. analysis finds the clips of an Auto Clip project, or prepares a Vibe Editing project. build makes the video of a split screen, streamer or Reddit story project. export renders a composition to a file. framing follows the face in a clip. import brings in a video from a link. story writes the story of a fake text project. voices makes the voices of a fake text story. tool runs a voiceover, an audio separation or a brainstorm. assistant_turn is one turn of the Editor Assistant."},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the job is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the job failed or stopped, in one sentence; null otherwise."},"projectId":{"type":["string","null"],"description":"The project the job works on, when it has one."},"compositionId":{"type":["string","null"],"description":"The composition the job works on, when it has one."},"exportId":{"type":["string","null"],"description":"The export this job renders, for an export job; null otherwise."},"assetId":{"type":["string","null"],"description":"The video an import job brought in, once the job is done; null for every other job, and when that video no longer exists or cannot be used through the API."},"toolRunId":{"type":["string","null"],"description":"The tool run a tool job carries out, to read with get_tool_run; null for every other job."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn an assistant_turn job carries out, to read with get_assistant_turn; null for every other job."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"startedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","kind","status","progress","errorMessage","projectId","compositionId","exportId","assetId","toolRunId","turnId","createdAt","startedAt","finishedAt"]},"reused":{"type":"boolean","description":"true when making the voices was already running for this project and this is its job, paid by nobody again."},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["job","reused","paidWith"]},"examples":{"example1":{"summary":"Make the voices of the story","value":{"job":{"status":"queued","progress":0,"errorMessage":null,"projectId":"prj_ba8b07a88bfb14585459","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T11:10:00.000Z","startedAt":null,"finishedAt":null,"id":"job_7d2c9a4e1f0b4386c5a2","kind":"voices"},"reused":false,"paidWith":"plan"}},"example2":{"summary":"Voices that are already being made","value":{"job":{"status":"running","progress":0.5,"errorMessage":null,"projectId":"prj_ba8b07a88bfb14585459","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-08-31T22:12:00.000Z","startedAt":"2026-08-31T22:13:00.000Z","finishedAt":null,"id":"job_8060ba8cd16645d280c1","kind":"voices"},"reused":true,"paidWith":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"Uses one fake text script of the plan's daily allowance, which resets at 00:00 UTC. When the API bonus pays, it also uses one bonus credit. Nothing is returned if the work fails.","x-bonus-credits":1,"x-stability":"beta"}},"/voiceovers":{"post":{"operationId":"create_voiceover","summary":"Create a voiceover","description":"Starts reading a script aloud with a synthetic voice, and returns the tool run that makes the audio file.\n\nCall this to turn a script into an MP3 file read by a synthetic voice. Choose the voice with list_voices: it must speak the language you send. The call answers 202 at once with the run, queued, and a Location to follow; read it with get_tool_run (with ?wait= to hold the request) until it is done, then download the file from its downloadUrl. The file is also an asset of the account, with origin voice. Always send an Idempotency-Key, the same one on every retry: a retry of the same request returns the same run and never uses a second tool run.","tags":["tools"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"script":{"type":"string","minLength":1,"maxLength":5000,"description":"The text to read aloud, up to 5000 characters."},"voice":{"type":"string","enum":["en-aria","en-jenny","en-guy","en-christopher","it-elsa","it-isabella","it-diego","it-giuseppe"],"description":"The voice that reads the script, as list_voices names it, like en-aria. It must speak the language of the script."},"language":{"type":"string","enum":["en","it"],"description":"The language of the script: en for English, it for Italian."},"title":{"type":"string","minLength":1,"maxLength":120,"description":"A name for the run and its file. Leave it out to use the start of the script."}},"required":["script","voice","language"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"toolRun":{"type":"object","properties":{"id":{"type":"string","description":"The tool run id. It starts with run_."},"tool":{"type":"string","enum":["voiceover","audio_separation","brainstorm"]},"status":{"type":"string","enum":["queued","running","done","failed"],"description":"queued and running are still working; done and failed are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the run failed, in one sentence; null otherwise."},"voiceover":{"anyOf":[{"type":"object","properties":{"title":{"type":"string"},"script":{"type":"string"},"voice":{"type":["string","null"],"description":"The voice, as list_voices names it; null for a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"]}},"required":["title","script","voice","language"]},{"type":"null"}],"description":"What a voiceover was asked to read; null for the other tools."},"separation":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video whose sound is separated. null when the file no longer exists or cannot be used through the API."},"keep":{"type":"string","enum":["vocals","instrumental"],"description":"vocals keeps the voices, instrumental keeps everything else."}},"required":["sourceAssetId","keep"]},{"type":"null"}],"description":"What an audio separation works on; null for the other tools."},"brainstorm":{"anyOf":[{"type":"object","properties":{"topic":{"type":"string"},"tone":{"type":"string"},"audience":{"type":"string"},"videoType":{"type":"string","enum":["story","fake_text","split_screen","any"]},"language":{"type":"string","enum":["en","it"]},"count":{"type":"integer"}},"required":["topic","tone","audience","videoType","language","count"]},{"type":"null"}],"description":"What a brainstorm was asked; null for the other tools."},"file":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"},"mimeType":{"type":"string"},"durationSec":{"type":["number","null"]},"sizeBytes":{"type":"integer"},"downloadUrl":{"type":["string","null"],"description":"A link to download the file, on a read of a finished run; null otherwise."},"downloadUrlExpiresAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["assetId","mimeType","durationSec","sizeBytes","downloadUrl","downloadUrlExpiresAt"]},{"type":"null"}],"description":"The audio file a voiceover or a separation made, once the run is done; null otherwise."},"ideas":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"hook":{"type":"string"},"outline":{"type":"string"},"format":{"type":"string"},"whyItWorks":{"type":"string"}},"required":["title","hook","outline","format","whyItWorks"]}},{"type":"null"}],"description":"The ideas of a finished brainstorm; null otherwise."},"jobId":{"type":["string","null"],"description":"The job that carries out the run, to follow with get_job; null once it is gone."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","tool","status","progress","errorMessage","voiceover","separation","brainstorm","file","ideas","jobId","createdAt","finishedAt"]},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["toolRun","paidWith"]},"examples":{"example1":{"summary":"Read a script with an English voice","value":{"toolRun":{"id":"run_5e8a1c3f7d2b4096a1e4","tool":"voiceover","status":"queued","progress":0,"errorMessage":null,"file":null,"ideas":null,"jobId":"job_2c7f9e1a4d6b48035f9e","createdAt":"2026-09-01T11:00:00.000Z","finishedAt":null,"voiceover":{"title":"Launch voiceover","script":"Meet the editor that turns one long video into ten short clips.","voice":"en-aria","language":"en"},"separation":null,"brainstorm":null},"paidWith":"plan"}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"Uses one tool run of the plan's daily allowance, which resets at 00:00 UTC. When the API bonus pays, it also uses one bonus credit. Nothing is returned if the run fails.","x-bonus-credits":1,"x-stability":"beta"}},"/audio-separations":{"post":{"operationId":"separate_audio","summary":"Separate the voices of a video","description":"Starts splitting the sound of a video into its voices or everything else, and returns the tool run that makes the audio file.\n\nCall this to get the voices of a video without the music and noise (keep vocals), or the music and noise without the voices (keep instrumental). The result is an MP3 file. The video must have sound and be at most 60 minutes long, and a video whose file was deleted to free up storage cannot be separated: these are checked before anything is used. The call answers 202 at once with the run, queued, and a Location to follow; read it with get_tool_run (with ?wait= to hold the request) until it is done, then download the file from its downloadUrl. A separation takes a few minutes. Always send an Idempotency-Key, the same one on every retry: a retry of the same request returns the same run and never uses a second tool run.","tags":["tools"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sourceAssetId":{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$","description":"The video whose sound to separate, as complete_upload or list_assets returned it. It starts with ast_."},"keep":{"type":"string","enum":["vocals","instrumental"],"description":"vocals keeps the voices, instrumental keeps everything else."}},"required":["sourceAssetId","keep"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"toolRun":{"type":"object","properties":{"id":{"type":"string","description":"The tool run id. It starts with run_."},"tool":{"type":"string","enum":["voiceover","audio_separation","brainstorm"]},"status":{"type":"string","enum":["queued","running","done","failed"],"description":"queued and running are still working; done and failed are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the run failed, in one sentence; null otherwise."},"voiceover":{"anyOf":[{"type":"object","properties":{"title":{"type":"string"},"script":{"type":"string"},"voice":{"type":["string","null"],"description":"The voice, as list_voices names it; null for a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"]}},"required":["title","script","voice","language"]},{"type":"null"}],"description":"What a voiceover was asked to read; null for the other tools."},"separation":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video whose sound is separated. null when the file no longer exists or cannot be used through the API."},"keep":{"type":"string","enum":["vocals","instrumental"],"description":"vocals keeps the voices, instrumental keeps everything else."}},"required":["sourceAssetId","keep"]},{"type":"null"}],"description":"What an audio separation works on; null for the other tools."},"brainstorm":{"anyOf":[{"type":"object","properties":{"topic":{"type":"string"},"tone":{"type":"string"},"audience":{"type":"string"},"videoType":{"type":"string","enum":["story","fake_text","split_screen","any"]},"language":{"type":"string","enum":["en","it"]},"count":{"type":"integer"}},"required":["topic","tone","audience","videoType","language","count"]},{"type":"null"}],"description":"What a brainstorm was asked; null for the other tools."},"file":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"},"mimeType":{"type":"string"},"durationSec":{"type":["number","null"]},"sizeBytes":{"type":"integer"},"downloadUrl":{"type":["string","null"],"description":"A link to download the file, on a read of a finished run; null otherwise."},"downloadUrlExpiresAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["assetId","mimeType","durationSec","sizeBytes","downloadUrl","downloadUrlExpiresAt"]},{"type":"null"}],"description":"The audio file a voiceover or a separation made, once the run is done; null otherwise."},"ideas":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"hook":{"type":"string"},"outline":{"type":"string"},"format":{"type":"string"},"whyItWorks":{"type":"string"}},"required":["title","hook","outline","format","whyItWorks"]}},{"type":"null"}],"description":"The ideas of a finished brainstorm; null otherwise."},"jobId":{"type":["string","null"],"description":"The job that carries out the run, to follow with get_job; null once it is gone."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","tool","status","progress","errorMessage","voiceover","separation","brainstorm","file","ideas","jobId","createdAt","finishedAt"]},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["toolRun","paidWith"]},"examples":{"example1":{"summary":"Keep the voices of a video","value":{"toolRun":{"id":"run_5e8a1c3f7d2b4096a1e4","tool":"audio_separation","status":"queued","progress":0,"errorMessage":null,"file":null,"ideas":null,"jobId":"job_2c7f9e1a4d6b48035f9e","createdAt":"2026-09-01T11:00:00.000Z","finishedAt":null,"voiceover":null,"separation":{"sourceAssetId":"ast_3f9a1c7e5b2d4086a1c4","keep":"vocals"},"brainstorm":null},"paidWith":"plan"}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"Uses one tool run of the plan's daily allowance, which resets at 00:00 UTC. When the API bonus pays, it also uses one bonus credit. Nothing is returned if the run fails.","x-bonus-credits":1,"x-stability":"beta"}},"/brainstorms":{"post":{"operationId":"brainstorm_ideas","summary":"Brainstorm video ideas","description":"Starts writing ideas for short videos on a topic, and returns the tool run that holds them once it is done.\n\nCall this to get ideas for short videos on a topic: each idea has a title, a hook, an outline, a format and why it works. Say the kind of video with videoType (get_setting_options lists them), the language of the ideas and how many you want. The call answers 202 at once with the run, queued, and a Location to follow; read it with get_tool_run (with ?wait= to hold the request) until it is done, then read the ideas in its ideas field. Always send an Idempotency-Key, the same one on every retry: a retry of the same request returns the same run and never uses a second tool run.","tags":["tools"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","minLength":1,"maxLength":300,"description":"What the videos are about, up to 300 characters."},"tone":{"type":"string","maxLength":60,"description":"The tone of the videos, like funny or serious, up to 60 characters."},"audience":{"type":"string","maxLength":200,"description":"Who the videos are for, up to 200 characters."},"videoType":{"type":"string","enum":["story","fake_text","split_screen","any"],"description":"The kind of video the ideas are for: story, fake_text, split_screen, or any."},"language":{"type":"string","enum":["en","it"],"description":"The language of the ideas: en for English, it for Italian."},"count":{"type":"integer","minimum":3,"maximum":30,"description":"How many ideas to write, from 3 to 30."}},"required":["topic","videoType","language","count"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"toolRun":{"type":"object","properties":{"id":{"type":"string","description":"The tool run id. It starts with run_."},"tool":{"type":"string","enum":["voiceover","audio_separation","brainstorm"]},"status":{"type":"string","enum":["queued","running","done","failed"],"description":"queued and running are still working; done and failed are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the run failed, in one sentence; null otherwise."},"voiceover":{"anyOf":[{"type":"object","properties":{"title":{"type":"string"},"script":{"type":"string"},"voice":{"type":["string","null"],"description":"The voice, as list_voices names it; null for a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"]}},"required":["title","script","voice","language"]},{"type":"null"}],"description":"What a voiceover was asked to read; null for the other tools."},"separation":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video whose sound is separated. null when the file no longer exists or cannot be used through the API."},"keep":{"type":"string","enum":["vocals","instrumental"],"description":"vocals keeps the voices, instrumental keeps everything else."}},"required":["sourceAssetId","keep"]},{"type":"null"}],"description":"What an audio separation works on; null for the other tools."},"brainstorm":{"anyOf":[{"type":"object","properties":{"topic":{"type":"string"},"tone":{"type":"string"},"audience":{"type":"string"},"videoType":{"type":"string","enum":["story","fake_text","split_screen","any"]},"language":{"type":"string","enum":["en","it"]},"count":{"type":"integer"}},"required":["topic","tone","audience","videoType","language","count"]},{"type":"null"}],"description":"What a brainstorm was asked; null for the other tools."},"file":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"},"mimeType":{"type":"string"},"durationSec":{"type":["number","null"]},"sizeBytes":{"type":"integer"},"downloadUrl":{"type":["string","null"],"description":"A link to download the file, on a read of a finished run; null otherwise."},"downloadUrlExpiresAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["assetId","mimeType","durationSec","sizeBytes","downloadUrl","downloadUrlExpiresAt"]},{"type":"null"}],"description":"The audio file a voiceover or a separation made, once the run is done; null otherwise."},"ideas":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"hook":{"type":"string"},"outline":{"type":"string"},"format":{"type":"string"},"whyItWorks":{"type":"string"}},"required":["title","hook","outline","format","whyItWorks"]}},{"type":"null"}],"description":"The ideas of a finished brainstorm; null otherwise."},"jobId":{"type":["string","null"],"description":"The job that carries out the run, to follow with get_job; null once it is gone."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","tool","status","progress","errorMessage","voiceover","separation","brainstorm","file","ideas","jobId","createdAt","finishedAt"]},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["toolRun","paidWith"]},"examples":{"example1":{"summary":"Ideas for story videos","value":{"toolRun":{"id":"run_5e8a1c3f7d2b4096a1e4","tool":"brainstorm","status":"queued","progress":0,"errorMessage":null,"file":null,"ideas":null,"jobId":"job_2c7f9e1a4d6b48035f9e","createdAt":"2026-09-01T11:00:00.000Z","finishedAt":null,"voiceover":null,"separation":null,"brainstorm":{"topic":"Morning routines for busy parents","tone":"","audience":"","videoType":"story","language":"en","count":5}},"paidWith":"plan"}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"Uses one tool run of the plan's daily allowance, which resets at 00:00 UTC. When the API bonus pays, it also uses one bonus credit. Nothing is returned if the run fails.","x-bonus-credits":1,"x-stability":"beta"}},"/tool-runs/{toolRunId}":{"get":{"operationId":"get_tool_run","summary":"Get a tool run","description":"Returns a tool run: its status and, once it is done, its audio file with a fresh download link, or its ideas.\n\nCall this to follow a voiceover, an audio separation or a brainstorm. While the run is queued or running, add ?wait= with up to 25 seconds to hold the request until it ends, then call again if it is still working. Once the status is done, a voiceover or a separation has its file, whose downloadUrl downloads the MP3 with no API key: the link is short-lived and every read gives a new one. A brainstorm has its ideas. A failed run says what happened in errorMessage: start it again with a new Idempotency-Key.","tags":["tools"],"parameters":[{"name":"toolRunId","in":"path","required":true,"description":"The id of the tool run, as create_voiceover, separate_audio, brainstorm_ideas or list_tool_runs returned it. It starts with run_.","schema":{"type":"string","pattern":"^run_[0-9a-f]{20}$","description":"The id of the tool run, as create_voiceover, separate_audio, brainstorm_ideas or list_tool_runs returned it. It starts with run_."}},{"name":"wait","in":"query","required":false,"description":"Seconds to hold the request while the work is still running, up to 25. Leave it out to answer at once. If many requests of the account are already waiting, it answers at once; wait a few seconds before you read again.","schema":{"type":"integer","minimum":0,"maximum":25,"description":"Seconds to hold the request while the work is still running, up to 25. Leave it out to answer at once. If many requests of the account are already waiting, it answers at once; wait a few seconds before you read again."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"toolRun":{"type":"object","properties":{"id":{"type":"string","description":"The tool run id. It starts with run_."},"tool":{"type":"string","enum":["voiceover","audio_separation","brainstorm"]},"status":{"type":"string","enum":["queued","running","done","failed"],"description":"queued and running are still working; done and failed are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the run failed, in one sentence; null otherwise."},"voiceover":{"anyOf":[{"type":"object","properties":{"title":{"type":"string"},"script":{"type":"string"},"voice":{"type":["string","null"],"description":"The voice, as list_voices names it; null for a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"]}},"required":["title","script","voice","language"]},{"type":"null"}],"description":"What a voiceover was asked to read; null for the other tools."},"separation":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video whose sound is separated. null when the file no longer exists or cannot be used through the API."},"keep":{"type":"string","enum":["vocals","instrumental"],"description":"vocals keeps the voices, instrumental keeps everything else."}},"required":["sourceAssetId","keep"]},{"type":"null"}],"description":"What an audio separation works on; null for the other tools."},"brainstorm":{"anyOf":[{"type":"object","properties":{"topic":{"type":"string"},"tone":{"type":"string"},"audience":{"type":"string"},"videoType":{"type":"string","enum":["story","fake_text","split_screen","any"]},"language":{"type":"string","enum":["en","it"]},"count":{"type":"integer"}},"required":["topic","tone","audience","videoType","language","count"]},{"type":"null"}],"description":"What a brainstorm was asked; null for the other tools."},"file":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"},"mimeType":{"type":"string"},"durationSec":{"type":["number","null"]},"sizeBytes":{"type":"integer"},"downloadUrl":{"type":["string","null"],"description":"A link to download the file, on a read of a finished run; null otherwise."},"downloadUrlExpiresAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["assetId","mimeType","durationSec","sizeBytes","downloadUrl","downloadUrlExpiresAt"]},{"type":"null"}],"description":"The audio file a voiceover or a separation made, once the run is done; null otherwise."},"ideas":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"hook":{"type":"string"},"outline":{"type":"string"},"format":{"type":"string"},"whyItWorks":{"type":"string"}},"required":["title","hook","outline","format","whyItWorks"]}},{"type":"null"}],"description":"The ideas of a finished brainstorm; null otherwise."},"jobId":{"type":["string","null"],"description":"The job that carries out the run, to follow with get_job; null once it is gone."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","tool","status","progress","errorMessage","voiceover","separation","brainstorm","file","ideas","jobId","createdAt","finishedAt"]}},"required":["toolRun"]},"examples":{"example1":{"summary":"Get a finished voiceover","value":{"toolRun":{"id":"run_b014441ea91a51965c46","tool":"voiceover","status":"done","progress":1,"errorMessage":null,"voiceover":{"title":"Launch voiceover","script":"Meet the editor that turns one long video into ten short clips.","voice":"en-aria","language":"en"},"separation":null,"brainstorm":null,"file":{"assetId":"ast_e8a35ed674148f27b585","mimeType":"audio/mpeg","durationSec":14,"sizeBytes":224000,"downloadUrl":"https://www.gpt-video.com/media/ast_e8a35ed674148f27b585?exp=1788258600&sig=4c1e9a7f2b5d8e03a6c9f1b4d7e2a5c8","downloadUrlExpiresAt":"2026-09-01T10:30:00.000Z"},"ideas":null,"jobId":"job_bd92cb70ed9c45575464","createdAt":"2026-08-31T21:30:00.000Z","finishedAt":"2026-08-31T21:32:00.000Z"}}},"example2":{"summary":"Wait for a run to finish","value":{"toolRun":{"id":"run_b014441ea91a51965c46","tool":"voiceover","status":"done","progress":1,"errorMessage":null,"voiceover":{"title":"Launch voiceover","script":"Meet the editor that turns one long video into ten short clips.","voice":"en-aria","language":"en"},"separation":null,"brainstorm":null,"file":{"assetId":"ast_e8a35ed674148f27b585","mimeType":"audio/mpeg","durationSec":14,"sizeBytes":224000,"downloadUrl":"https://www.gpt-video.com/media/ast_e8a35ed674148f27b585?exp=1788258600&sig=4c1e9a7f2b5d8e03a6c9f1b4d7e2a5c8","downloadUrlExpiresAt":"2026-09-01T10:30:00.000Z"},"ideas":null,"jobId":"job_bd92cb70ed9c45575464","createdAt":"2026-08-31T21:30:00.000Z","finishedAt":"2026-08-31T21:32:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/tool-runs":{"get":{"operationId":"list_tool_runs","summary":"List the tool runs","description":"Lists the voiceovers, audio separations and brainstorms of the account, newest first.\n\nCall this to find the tool runs of the account, for example to recover the run of a request whose answer you lost. Pass tool to see one kind only. The list is newest first and paged with cursor and limit. A page never carries download links: read a run with get_tool_run to get one.","tags":["tools"],"parameters":[{"name":"tool","in":"query","required":false,"description":"Only the runs of this tool. Leave it out to list every tool.","schema":{"type":"string","enum":["voiceover","audio_separation","brainstorm"]}},{"name":"limit","in":"query","required":false,"description":"How many items to return, from 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"description":"How many items to return, from 1 to 100. Defaults to 20.","default":20}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page. Leave it out to get the first page.","schema":{"type":"string","minLength":1,"maxLength":512}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The tool run id. It starts with run_."},"tool":{"type":"string","enum":["voiceover","audio_separation","brainstorm"]},"status":{"type":"string","enum":["queued","running","done","failed"],"description":"queued and running are still working; done and failed are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the run failed, in one sentence; null otherwise."},"voiceover":{"anyOf":[{"type":"object","properties":{"title":{"type":"string"},"script":{"type":"string"},"voice":{"type":["string","null"],"description":"The voice, as list_voices names it; null for a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"]}},"required":["title","script","voice","language"]},{"type":"null"}],"description":"What a voiceover was asked to read; null for the other tools."},"separation":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video whose sound is separated. null when the file no longer exists or cannot be used through the API."},"keep":{"type":"string","enum":["vocals","instrumental"],"description":"vocals keeps the voices, instrumental keeps everything else."}},"required":["sourceAssetId","keep"]},{"type":"null"}],"description":"What an audio separation works on; null for the other tools."},"brainstorm":{"anyOf":[{"type":"object","properties":{"topic":{"type":"string"},"tone":{"type":"string"},"audience":{"type":"string"},"videoType":{"type":"string","enum":["story","fake_text","split_screen","any"]},"language":{"type":"string","enum":["en","it"]},"count":{"type":"integer"}},"required":["topic","tone","audience","videoType","language","count"]},{"type":"null"}],"description":"What a brainstorm was asked; null for the other tools."},"file":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"},"mimeType":{"type":"string"},"durationSec":{"type":["number","null"]},"sizeBytes":{"type":"integer"},"downloadUrl":{"type":["string","null"],"description":"A link to download the file, on a read of a finished run; null otherwise."},"downloadUrlExpiresAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["assetId","mimeType","durationSec","sizeBytes","downloadUrl","downloadUrlExpiresAt"]},{"type":"null"}],"description":"The audio file a voiceover or a separation made, once the run is done; null otherwise."},"ideas":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"hook":{"type":"string"},"outline":{"type":"string"},"format":{"type":"string"},"whyItWorks":{"type":"string"}},"required":["title","hook","outline","format","whyItWorks"]}},{"type":"null"}],"description":"The ideas of a finished brainstorm; null otherwise."},"jobId":{"type":["string","null"],"description":"The job that carries out the run, to follow with get_job; null once it is gone."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","tool","status","progress","errorMessage","voiceover","separation","brainstorm","file","ideas","jobId","createdAt","finishedAt"]},"description":"The items of this page."},"hasMore":{"type":"boolean","description":"true when there are more items after this page."},"nextCursor":{"type":["string","null"],"description":"Send it as cursor to get the next page. It is null on the last page."}},"required":["data","hasMore","nextCursor"]},"examples":{"example1":{"summary":"List the tool runs","value":{"data":[{"id":"run_b014441ea91a51965c46","tool":"voiceover","status":"done","progress":1,"errorMessage":null,"voiceover":{"title":"Launch voiceover","script":"Meet the editor that turns one long video into ten short clips.","voice":"en-aria","language":"en"},"separation":null,"brainstorm":null,"file":{"assetId":"ast_e8a35ed674148f27b585","mimeType":"audio/mpeg","durationSec":14,"sizeBytes":224000,"downloadUrl":null,"downloadUrlExpiresAt":null},"ideas":null,"jobId":"job_bd92cb70ed9c45575464","createdAt":"2026-08-31T21:30:00.000Z","finishedAt":"2026-08-31T21:32:00.000Z"}],"hasMore":false,"nextCursor":null}},"example2":{"summary":"List the voiceovers only","value":{"data":[{"id":"run_b014441ea91a51965c46","tool":"voiceover","status":"done","progress":1,"errorMessage":null,"voiceover":{"title":"Launch voiceover","script":"Meet the editor that turns one long video into ten short clips.","voice":"en-aria","language":"en"},"separation":null,"brainstorm":null,"file":{"assetId":"ast_e8a35ed674148f27b585","mimeType":"audio/mpeg","durationSec":14,"sizeBytes":224000,"downloadUrl":null,"downloadUrlExpiresAt":null},"ideas":null,"jobId":"job_bd92cb70ed9c45575464","createdAt":"2026-08-31T21:30:00.000Z","finishedAt":"2026-08-31T21:32:00.000Z"}],"hasMore":false,"nextCursor":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/vibe-edit":{"post":{"operationId":"create_vibe_edit_project","summary":"Create a Vibe Editing project","description":"Creates a Vibe Editing project from a video you uploaded: an edit of the whole video that you change with timeline operations.\n\nCall it after complete_upload, with the id of the video to edit. The video is chosen here and only here: to edit another video, create another project. The language, the caption style and the shape are the choices the edit starts with; once it is prepared, change them on the timeline with apply_timeline_operations. Nothing is prepared and no credits are used until you call prepare_timeline. Send an Idempotency-Key: a retry without one creates a second project.","tags":["editing"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sourceAssetId":{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$","description":"The video to edit: the asset id that complete_upload returned. It cannot be changed later."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with. get_setting_options lists every style with what it looks like."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video, 9:16 is vertical, 1:1 square, 16:9 wide."},"vocabulary":{"type":"string","maxLength":311,"description":"Names, brands and jargon the transcription should spell right, separated by commas. At most 311 characters."},"title":{"type":"string","minLength":1,"maxLength":120,"pattern":"\\S","description":"A name for the project, shown in the GPT-Video app. Leave it out to get a default name."}},"required":["sourceAssetId","language","captionStyle","aspect"],"additionalProperties":false}}}},"responses":{"201":{"description":"Created","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","description":"The project id. It starts with prj_."},"kind":{"type":"string","enum":["autoclip","splitscreen","faketext","redditstory","streamer","vibeedit"],"description":"The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too."},"title":{"type":"string","description":"The name of the project."},"status":{"type":"string","enum":["draft","processing","ready","failed"],"description":"draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why."},"sourceAssetId":{"type":["string","null"],"description":"The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API."},"compositionId":{"type":["string","null"],"description":"The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export. null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet."},"settings":{"anyOf":[{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["auto","it","en"]},{"type":"null"}],"description":"The language spoken in the video: en, it, or auto to detect it. null until it is chosen."},"clipCount":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"How many clips the analysis proposes. null until it is chosen."},"minDurationSec":{"type":["number","null"],"description":"The shortest clip the analysis may propose, in seconds. null until it is chosen."},"maxDurationSec":{"type":["number","null"],"description":"The longest clip the analysis may propose, in seconds. null until it is chosen."},"objective":{"anyOf":[{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"]},{"type":"null"}],"description":"What the clips should be good at. get_setting_options lists every objective with what it means. null until it is chosen."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style of the clips. get_setting_options lists every style with what it looks like. null until it is chosen."},"reframe":{"anyOf":[{"type":"string","enum":["face","center"]},{"type":"null"}],"description":"How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen."},"instructions":{"type":["string","null"],"description":"Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none."}},"required":["language","clipCount","minDurationSec","maxDurationSec","objective","captionStyle","reframe","instructions","vocabulary"]},{"type":"null"}],"description":"The settings of an Auto Clip project; null for every other kind."},"missingSettings":{"type":"array","items":{"type":"string","enum":["objective","language","clipCount","minDurationSec","maxDurationSec","captionStyle","reframe"]},"description":"The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip."},"splitScreen":{"anyOf":[{"type":"object","properties":{"mainAssetId":{"type":["string","null"],"description":"The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API."},"backgroundAssetId":{"type":["string","null"],"description":"The background video, shown under the main video. null when the file no longer exists or cannot be used through the API."},"layout":{"type":"string","enum":["50-50","60-40"],"description":"How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more."},"captionStyle":{"anyOf":[{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},{"type":"null"}],"description":"The caption style; null when the video has no captions."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the main video: en, it, or auto to detect it."},"backgroundStartSec":{"type":["number","null"],"description":"Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["mainAssetId","backgroundAssetId","layout","captionStyle","language","backgroundStartSec","vocabulary"]},{"type":"null"}],"description":"The choices of a split screen project; null for every other kind."},"streamer":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The clip the project is made from. null when the file no longer exists or cannot be used through the API."},"headline":{"type":"string","description":"The line shown over the clip; empty for none."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the clip: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"reframe":{"type":"string","enum":["face","center"],"description":"How the video follows the speaker: face follows the face, center keeps the middle of the frame."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["sourceAssetId","headline","language","captionStyle","reframe","vocabulary"]},{"type":"null"}],"description":"The choices of a streamer project; null for every other kind."},"redditStory":{"anyOf":[{"type":"object","properties":{"postTitle":{"type":"string","description":"The title of the post, shown on the title card."},"postBody":{"type":"string","description":"The text of the post, read by the voice."},"author":{"type":"string","description":"The author shown on the title card."},"subreddit":{"type":"string","description":"The community shown on the title card."},"voice":{"type":["string","null"],"description":"The voice that reads the story, as list_voices names it; null when the project uses a voice that is not available through the API."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voice."},"backgroundAssetId":{"type":["string","null"],"description":"The background video. null when the file no longer exists or cannot be used through the API."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."}},"required":["postTitle","postBody","author","subreddit","voice","language","backgroundAssetId","captionStyle","vocabulary"]},{"type":"null"}],"description":"The post, the voice and the choices of a Reddit story project; null for every other kind."},"fakeText":{"anyOf":[{"type":"object","properties":{"theme":{"type":"string","enum":["imessage","whatsapp"],"description":"How the chat looks: imessage or whatsapp."},"language":{"type":"string","enum":["en","it"],"description":"The language of the story and of its voices."},"voiceover":{"type":"boolean","description":"true when create_fake_text_voices makes voices for the lines."},"backgroundAssetId":{"type":["string","null"],"description":"The background video behind the chat. null when the file no longer exists or cannot be used through the API."},"storyId":{"type":["string","null"],"description":"The story of the project, read with get_fake_text_story; null until the project has one."}},"required":["theme","language","voiceover","backgroundAssetId","storyId"]},{"type":"null"}],"description":"The choices of a fake text project; null for every other kind."},"vibeEdit":{"anyOf":[{"type":"object","properties":{"sourceAssetId":{"type":["string","null"],"description":"The video the edit starts from. null when the file no longer exists or cannot be used through the API."},"language":{"type":"string","enum":["auto","it","en"],"description":"The language spoken in the video: en, it, or auto to detect it."},"captionStyle":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The caption style the edit starts with."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The shape the edit starts with: source keeps the shape of the video."},"vocabulary":{"type":["string","null"],"description":"Names, brands and jargon the transcription should spell right, separated by commas; null when there are none."},"prepared":{"type":"boolean","description":"true once prepare_timeline has prepared the edit; an edit is never prepared or charged again."}},"required":["sourceAssetId","language","captionStyle","aspect","vocabulary","prepared"]},{"type":"null"}],"description":"The choices of a Vibe Editing project; null for every other kind."},"errorMessage":{"type":["string","null"],"description":"Why the last analysis failed, in one sentence; null unless the status is failed."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"updatedAt":{"type":"string","description":"An ISO 8601 time in UTC."}},"required":["id","kind","title","status","sourceAssetId","compositionId","settings","missingSettings","splitScreen","streamer","redditStory","fakeText","vibeEdit","errorMessage","createdAt","updatedAt"]}},"required":["project"]},"examples":{"example1":{"summary":"Create a Vibe Editing project","value":{"project":{"id":"prj_6e2b9d14a7c3f0581e2d","kind":"vibeedit","title":"Product demo, edited","status":"draft","sourceAssetId":"ast_8e21b0d94c6f4a17b358","compositionId":null,"settings":null,"missingSettings":[],"splitScreen":null,"streamer":null,"redditStory":null,"fakeText":null,"vibeEdit":{"sourceAssetId":"ast_8e21b0d94c6f4a17b358","language":"en","captionStyle":"word-pop","aspect":"9:16","vocabulary":null,"prepared":false},"errorMessage":null,"createdAt":"2026-09-01T11:00:00.000Z","updatedAt":"2026-09-01T11:00:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. The preparation is charged when you call prepare_timeline.","x-stability":"beta"}},"/projects/{projectId}/timeline/prepare":{"post":{"operationId":"prepare_timeline","summary":"Prepare an edit","description":"Starts the preparation of a Vibe Editing project: the video is transcribed and analyzed once, and the edit is built from it.\n\nCall it once on a new Vibe Editing project; estimate_analysis gives the price first. The answer is 202 with the job of the preparation: follow it with get_job, then read the edit with get_timeline. A prepared edit is never prepared or charged again: calling it again answers CONFLICT. Retrying with the same Idempotency-Key never pays twice, and if the preparation is already running you get its job back and nothing is charged.","tags":["editing"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","description":"The job id. It starts with job_."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does. analysis finds the clips of an Auto Clip project, or prepares a Vibe Editing project. build makes the video of a split screen, streamer or Reddit story project. export renders a composition to a file. framing follows the face in a clip. import brings in a video from a link. story writes the story of a fake text project. voices makes the voices of a fake text story. tool runs a voiceover, an audio separation or a brainstorm. assistant_turn is one turn of the Editor Assistant."},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the job is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the job failed or stopped, in one sentence; null otherwise."},"projectId":{"type":["string","null"],"description":"The project the job works on, when it has one."},"compositionId":{"type":["string","null"],"description":"The composition the job works on, when it has one."},"exportId":{"type":["string","null"],"description":"The export this job renders, for an export job; null otherwise."},"assetId":{"type":["string","null"],"description":"The video an import job brought in, once the job is done; null for every other job, and when that video no longer exists or cannot be used through the API."},"toolRunId":{"type":["string","null"],"description":"The tool run a tool job carries out, to read with get_tool_run; null for every other job."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn an assistant_turn job carries out, to read with get_assistant_turn; null for every other job."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"startedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","kind","status","progress","errorMessage","projectId","compositionId","exportId","assetId","toolRunId","turnId","createdAt","startedAt","finishedAt"]},"creditsCharged":{"type":"integer","minimum":0,"description":"The credits this request was charged: the price of the work it started, 0 when the same work was already running and its job came back."},"reused":{"type":"boolean","description":"true when the same work was already running on the project and this is its job, charged to nobody again."},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["job","creditsCharged","reused","paidWith"]},"examples":{"example1":{"summary":"Prepare an edit","value":{"job":{"id":"job_d41c7e0a95b3f26c8e17","kind":"analysis","status":"queued","progress":0,"errorMessage":null,"projectId":"prj_37573e451e0ff7f863c8","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T11:10:00.000Z","startedAt":null,"finishedAt":null},"creditsCharged":2,"reused":false,"paidWith":"plan"}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED, SOURCE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"One credit per started minute of the source video, charged when the preparation starts and not returned if it fails. A prepared edit is never prepared or charged again.","x-stability":"beta"}},"/projects/{projectId}/timeline":{"get":{"operationId":"get_timeline","summary":"Get an edit","description":"Returns the edit of a prepared Vibe Editing project: its videos, segments, texts, b-roll, captions and revision.\n\nCall it after the preparation is done, and before each change: every change sends the revision you read here as expectedRevision. Times come in two bases, named in each field: sourceStartSec and sourceEndSec are seconds of the source video, outputStartSec and the others are seconds of the video that comes out. A file that the API cannot use keeps its place in the edit with assetId null. To export the edit, send compositionId to create_export.","tags":["editing"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"timeline":{"type":"object","properties":{"id":{"type":"string","description":"The edit id. It starts with tml_."},"projectId":{"type":"string"},"compositionId":{"type":["string","null"],"description":"The composition the edit compiles to, to export with create_export; null until the edit is first compiled."},"revision":{"type":"integer","description":"Grows by one at every change; send it as expectedRevision with the next change."},"durationSec":{"type":"number","description":"How long the video that comes out lasts, in seconds."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"]},"reframe":{"type":"string","enum":["off","face","center"],"description":"How the video follows the speaker: off keeps the frame, face follows the face, center keeps the middle."},"captions":{"type":"object","properties":{"enabled":{"type":"boolean"},"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]}},"required":["enabled","style"]},"music":{"anyOf":[{"type":"object","properties":{"assetId":{"type":["string","null"],"description":"The music file. null when the file no longer exists or cannot be used through the API."},"volume":{"type":"number"}},"required":["assetId","volume"]},{"type":"null"}],"description":"The music under the edit; null without music."},"fadeInSec":{"type":"number","description":"The fade from black at the start, in seconds; 0 for none."},"fadeOutSec":{"type":"number","description":"The fade to black at the end, in seconds; 0 for none."},"clips":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":["string","null"],"description":"The video. null when the file no longer exists or cannot be used through the API."},"title":{"type":"string"},"durationSec":{"type":"number"},"state":{"type":"string","enum":["ready","preparing","failed"],"description":"ready can be cut, preparing is still being prepared, failed could not be prepared and is not prepared again by itself."}},"required":["assetId","title","durationSec","state"]},"description":"The videos the edit uses."},"segments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The segment id. It starts with seg_."},"assetId":{"type":["string","null"],"description":"The video the segment comes from. null when the file no longer exists or cannot be used through the API."},"sourceStartSec":{"type":"number"},"sourceEndSec":{"type":"number"},"outputStartSec":{"type":"number"},"outputEndSec":{"type":"number"},"zoom":{"type":"number"},"muted":{"type":"boolean"},"volume":{"type":"number"}},"required":["id","assetId","sourceStartSec","sourceEndSec","outputStartSec","outputEndSec","zoom","muted","volume"]},"description":"The pieces of video, in the order they play."},"texts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The text id. It starts with ovl_."},"text":{"type":"string"},"preset":{"type":"string","enum":["headline","hook","caption-note"]},"outputStartSec":{"type":"number"},"durationSec":{"type":"number"},"xPercent":{"type":["number","null"]},"yPercent":{"type":["number","null"]}},"required":["id","text","preset","outputStartSec","durationSec","xPercent","yPercent"]}},"broll":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The b-roll id. It starts with brl_."},"assetId":{"type":["string","null"],"description":"The video shown over the edit. null when the file no longer exists or cannot be used through the API."},"outputStartSec":{"type":"number"},"durationSec":{"type":"number"},"fit":{"type":"string","enum":["cover","contain"]}},"required":["id","assetId","outputStartSec","durationSec","fit"]}},"diagnostics":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"description":"What the edit cannot do as it is, in one sentence each; empty when nothing."}},"required":["id","projectId","compositionId","revision","durationSec","aspect","reframe","captions","music","fadeInSec","fadeOutSec","clips","segments","texts","broll","diagnostics"]}},"required":["timeline"]},"examples":{"example1":{"summary":"Get an edit","value":{"timeline":{"id":"tml_bbe061171a8229f8daed","projectId":"prj_b9c1f9c7873dcef51a57","compositionId":"cmp_cfbdd85eaaff301fa997","revision":1,"durationSec":60,"aspect":"9:16","reframe":"off","captions":{"enabled":true,"style":"bold-karaoke"},"music":null,"fadeInSec":0,"fadeOutSec":0,"clips":[{"assetId":"ast_3f9a1c7e5b2d4086a1c4","title":"Interview with a founder","durationSec":1800,"state":"ready"}],"segments":[{"id":"seg_7279fbb508f4a22e65a4","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":120,"sourceEndSec":150,"zoom":1,"muted":false,"volume":1,"outputStartSec":0,"outputEndSec":30},{"id":"seg_a9dcee59c1fb9edb6751","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":300,"sourceEndSec":330,"zoom":1,"muted":false,"volume":1,"outputStartSec":30,"outputEndSec":60}],"texts":[{"id":"ovl_49f5239b9cd73496225d","text":"Paid before the product","preset":"headline","outputStartSec":0,"durationSec":3,"xPercent":null,"yPercent":null}],"broll":[{"id":"brl_f44d18e008ec4009bf10","assetId":"ast_8ac5d8b97546145cdbf6","outputStartSec":12,"durationSec":4,"fit":"cover"}],"diagnostics":[]}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, NOT_READY","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["NOT_READY"]},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/{projectId}/timeline/operations":{"post":{"operationId":"apply_timeline_operations","summary":"Change an edit","description":"Applies a list of operations to an edit in one change: cuts, order, transitions, zoom, sound, captions, texts, b-roll, music and shape.\n\nSend the revision you read with get_timeline and from 1 to 50 operations: they apply in order, as one change and one new revision, or not at all. Segments, texts and b-roll are named by the ids get_timeline shows; times of segments are seconds of the source video, times of texts and b-roll are seconds of the video that comes out. Adding a video is not an operation here, because it costs credits: use add_timeline_clip. The answer is the edit after the change, with warnings that say what was adjusted.","tags":["editing"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedRevision":{"type":"integer","minimum":0,"description":"The revision of the edit you read last, from get_timeline or from the answer of your last change. If the edit changed since then, nothing is written and the answer is CONFLICT."},"operations":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"op":{"type":"string","const":"split_segment"},"segmentId":{"type":"string","pattern":"^seg_[0-9a-f]{20}$","description":"The segment id. It starts with seg_."},"atSourceSec":{"type":"number","exclusiveMinimum":0,"description":"Where to cut, in seconds of the source video."}},"required":["op","segmentId","atSourceSec"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"trim_segment"},"segmentId":{"type":"string","pattern":"^seg_[0-9a-f]{20}$","description":"The segment id. It starts with seg_."},"sourceStartSec":{"type":"number","minimum":0,"description":"The new start, in seconds of the source video."},"sourceEndSec":{"type":"number","exclusiveMinimum":0,"description":"The new end, in seconds of the source video."}},"required":["op","segmentId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove_segments"},"segmentIds":{"type":"array","items":{"type":"string","pattern":"^seg_[0-9a-f]{20}$"},"minItems":1,"maxItems":200,"description":"The segment ids, from 1 to 200."}},"required":["op","segmentIds"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"move_segment"},"segmentId":{"type":"string","pattern":"^seg_[0-9a-f]{20}$","description":"The segment id. It starts with seg_."},"beforeSegmentId":{"anyOf":[{"type":"string","pattern":"^seg_[0-9a-f]{20}$"},{"type":"null"}],"description":"The segment to move it in front of; null moves it to the end."}},"required":["op","segmentId","beforeSegmentId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_transition"},"segmentId":{"type":"string","pattern":"^seg_[0-9a-f]{20}$","description":"The segment id. It starts with seg_."},"kind":{"type":"string","enum":["dip","dissolve"]},"sec":{"type":"number","minimum":0,"maximum":3,"description":"How long the transition into this segment lasts, from 0 to 3 seconds; 0 removes it."}},"required":["op","segmentId","kind","sec"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_video_fade"},"edge":{"type":"string","enum":["start","end"]},"sec":{"type":"number","minimum":0,"maximum":3,"description":"How long the fade lasts, from 0 to 3 seconds; 0 removes it."}},"required":["op","edge","sec"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_zoom"},"segmentIds":{"type":"array","items":{"type":"string","pattern":"^seg_[0-9a-f]{20}$"},"minItems":1,"maxItems":200,"description":"The segment ids, from 1 to 200."},"factor":{"type":"number","minimum":1,"maximum":1.5,"description":"1 removes the zoom; up to 1.5."},"mode":{"type":"string","enum":["static","push"]}},"required":["op","segmentIds","factor","mode"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_segment_audio"},"segmentIds":{"type":"array","items":{"type":"string","pattern":"^seg_[0-9a-f]{20}$"},"minItems":1,"maxItems":200,"description":"The segment ids, from 1 to 200."},"volume":{"type":"number","minimum":0,"maximum":2},"muted":{"type":"boolean"}},"required":["op","segmentIds"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove_silences"},"aggressiveness":{"type":"string","enum":["soft","standard","aggressive"]}},"required":["op","aggressiveness"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove_fillers"}},"required":["op"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_captions"},"enabled":{"type":"boolean"},"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]},"options":{"type":"object","properties":{"fontFamily":{"type":"string","enum":["Montserrat","Anton","System"],"description":"The typeface of the captions."},"fontSize":{"type":"integer","minimum":20,"maximum":200,"description":"The size of the caption text, from 20 to 200."},"yPercent":{"type":"number","minimum":0,"maximum":100,"description":"Where the captions sit, from 0 at the top to 100 at the bottom."},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","description":"The color of the words, as #RRGGBB."},"highlightColor":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","description":"The color of the word being spoken, as #RRGGBB."},"maxWordsPerGroup":{"type":"integer","minimum":1,"maximum":12,"description":"How many words are on screen at once, at most, from 1 to 12."},"maxCharsPerGroup":{"type":"integer","minimum":4,"maximum":80,"description":"How many characters are on screen at once, at most, from 4 to 80."},"uppercase":{"type":"boolean","description":"true shows the captions in capital letters."},"maxGapSec":{"type":"number","minimum":0.1,"maximum":5,"description":"The longest pause, in seconds, inside one group of words on screen, from 0.1 to 5."}},"additionalProperties":false,"description":"The caption options to change. A field you leave out stays as it is."}},"required":["op"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"replace_caption_word"},"from":{"type":"string","minLength":1,"maxLength":200},"to":{"type":"string","minLength":1,"maxLength":200},"occurrence":{"type":"integer","minimum":1,"description":"Which match to replace, from 1; leave it out to replace every match."}},"required":["op","from","to"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"add_text"},"text":{"type":"string","minLength":1,"maxLength":200},"preset":{"type":"string","enum":["headline","hook","caption-note"]},"outputStartSec":{"type":"number","minimum":0,"description":"A time in the video that comes out, in seconds."},"durationSec":{"type":"number","exclusiveMinimum":0,"description":"A length in seconds."},"xPercent":{"type":"number","minimum":0,"maximum":100,"description":"The horizontal position, from 0 to 100."},"yPercent":{"type":"number","minimum":0,"maximum":100,"description":"The vertical position, from 0 to 100."}},"required":["op","text","preset","outputStartSec","durationSec"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"update_text"},"textId":{"type":"string","pattern":"^ovl_[0-9a-f]{20}$","description":"The text id. It starts with ovl_."},"text":{"type":"string","minLength":1,"maxLength":200},"preset":{"type":"string","enum":["headline","hook","caption-note"]},"outputStartSec":{"type":"number","minimum":0,"description":"A time in the video that comes out, in seconds."},"durationSec":{"type":"number","exclusiveMinimum":0,"description":"A length in seconds."},"xPercent":{"anyOf":[{"type":"number","minimum":0,"maximum":100,"description":"The horizontal position, from 0 to 100."},{"type":"null"}],"description":"The horizontal position, from 0 to 100."},"yPercent":{"anyOf":[{"type":"number","minimum":0,"maximum":100,"description":"The vertical position, from 0 to 100."},{"type":"null"}],"description":"The vertical position, from 0 to 100."}},"required":["op","textId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove_text"},"textId":{"type":"string","pattern":"^ovl_[0-9a-f]{20}$","description":"The text id. It starts with ovl_."}},"required":["op","textId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"add_broll"},"assetId":{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$"},"outputStartSec":{"type":"number","minimum":0,"description":"A time in the video that comes out, in seconds."},"durationSec":{"type":"number","exclusiveMinimum":0,"description":"A length in seconds."},"fit":{"type":"string","enum":["cover","contain"]}},"required":["op","assetId","outputStartSec","durationSec","fit"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"update_broll"},"brollId":{"type":"string","pattern":"^brl_[0-9a-f]{20}$","description":"The b-roll id. It starts with brl_."},"outputStartSec":{"type":"number","minimum":0,"description":"A time in the video that comes out, in seconds."},"durationSec":{"type":"number","exclusiveMinimum":0,"description":"A length in seconds."},"fit":{"type":"string","enum":["cover","contain"]}},"required":["op","brollId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove_broll"},"brollId":{"type":"string","pattern":"^brl_[0-9a-f]{20}$","description":"The b-roll id. It starts with brl_."}},"required":["op","brollId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_music"},"assetId":{"anyOf":[{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$"},{"type":"null"}],"description":"The music file; null removes the music."},"volume":{"type":"number","minimum":0,"maximum":0.5}},"required":["op","assetId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_aspect"},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"]}},"required":["op","aspect"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_reframe"},"mode":{"type":"string","enum":["off","face","center"]}},"required":["op","mode"],"additionalProperties":false}]},"minItems":1,"maxItems":50,"description":"The operations, from 1 to 50, applied in this order. The op field says which one each is."}},"required":["expectedRevision","operations"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"timeline":{"type":"object","properties":{"id":{"type":"string","description":"The edit id. It starts with tml_."},"projectId":{"type":"string"},"compositionId":{"type":["string","null"],"description":"The composition the edit compiles to, to export with create_export; null until the edit is first compiled."},"revision":{"type":"integer","description":"Grows by one at every change; send it as expectedRevision with the next change."},"durationSec":{"type":"number","description":"How long the video that comes out lasts, in seconds."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"]},"reframe":{"type":"string","enum":["off","face","center"],"description":"How the video follows the speaker: off keeps the frame, face follows the face, center keeps the middle."},"captions":{"type":"object","properties":{"enabled":{"type":"boolean"},"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]}},"required":["enabled","style"]},"music":{"anyOf":[{"type":"object","properties":{"assetId":{"type":["string","null"],"description":"The music file. null when the file no longer exists or cannot be used through the API."},"volume":{"type":"number"}},"required":["assetId","volume"]},{"type":"null"}],"description":"The music under the edit; null without music."},"fadeInSec":{"type":"number","description":"The fade from black at the start, in seconds; 0 for none."},"fadeOutSec":{"type":"number","description":"The fade to black at the end, in seconds; 0 for none."},"clips":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":["string","null"],"description":"The video. null when the file no longer exists or cannot be used through the API."},"title":{"type":"string"},"durationSec":{"type":"number"},"state":{"type":"string","enum":["ready","preparing","failed"],"description":"ready can be cut, preparing is still being prepared, failed could not be prepared and is not prepared again by itself."}},"required":["assetId","title","durationSec","state"]},"description":"The videos the edit uses."},"segments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The segment id. It starts with seg_."},"assetId":{"type":["string","null"],"description":"The video the segment comes from. null when the file no longer exists or cannot be used through the API."},"sourceStartSec":{"type":"number"},"sourceEndSec":{"type":"number"},"outputStartSec":{"type":"number"},"outputEndSec":{"type":"number"},"zoom":{"type":"number"},"muted":{"type":"boolean"},"volume":{"type":"number"}},"required":["id","assetId","sourceStartSec","sourceEndSec","outputStartSec","outputEndSec","zoom","muted","volume"]},"description":"The pieces of video, in the order they play."},"texts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The text id. It starts with ovl_."},"text":{"type":"string"},"preset":{"type":"string","enum":["headline","hook","caption-note"]},"outputStartSec":{"type":"number"},"durationSec":{"type":"number"},"xPercent":{"type":["number","null"]},"yPercent":{"type":["number","null"]}},"required":["id","text","preset","outputStartSec","durationSec","xPercent","yPercent"]}},"broll":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The b-roll id. It starts with brl_."},"assetId":{"type":["string","null"],"description":"The video shown over the edit. null when the file no longer exists or cannot be used through the API."},"outputStartSec":{"type":"number"},"durationSec":{"type":"number"},"fit":{"type":"string","enum":["cover","contain"]}},"required":["id","assetId","outputStartSec","durationSec","fit"]}},"diagnostics":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"description":"What the edit cannot do as it is, in one sentence each; empty when nothing."}},"required":["id","projectId","compositionId","revision","durationSec","aspect","reframe","captions","music","fadeInSec","fadeOutSec","clips","segments","texts","broll","diagnostics"]},"compositionId":{"type":"string","description":"The composition the edit compiles to, to export with create_export."},"warnings":{"type":"array","items":{"type":"string"},"description":"What the change adjusted or could not do, in one sentence each; empty when nothing."}},"required":["timeline","compositionId","warnings"]},"examples":{"example1":{"summary":"Cut a segment in two and remove another","value":{"timeline":{"id":"tml_bbe061171a8229f8daed","projectId":"prj_b9c1f9c7873dcef51a57","compositionId":"cmp_cfbdd85eaaff301fa997","revision":2,"durationSec":30,"aspect":"9:16","reframe":"off","captions":{"enabled":true,"style":"bold-karaoke"},"music":null,"fadeInSec":0,"fadeOutSec":0,"clips":[{"assetId":"ast_3f9a1c7e5b2d4086a1c4","title":"Interview with a founder","durationSec":1800,"state":"ready"}],"segments":[{"id":"seg_7279fbb508f4a22e65a4","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":120,"sourceEndSec":135,"zoom":1,"muted":false,"volume":1,"outputStartSec":0,"outputEndSec":15},{"id":"seg_5a0e3c8f1d7b42e69c13","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":135,"sourceEndSec":150,"zoom":1,"muted":false,"volume":1,"outputStartSec":15,"outputEndSec":30}],"texts":[{"id":"ovl_49f5239b9cd73496225d","text":"Paid before the product","preset":"headline","outputStartSec":0,"durationSec":3,"xPercent":null,"yPercent":null}],"broll":[{"id":"brl_f44d18e008ec4009bf10","assetId":"ast_8ac5d8b97546145cdbf6","outputStartSec":12,"durationSec":4,"fit":"cover"}],"diagnostics":[]},"compositionId":"cmp_cfbdd85eaaff301fa997","warnings":[]}},"example2":{"summary":"Change the order, the cut between two segments, the zoom and the sound","value":{"timeline":{"id":"tml_bbe061171a8229f8daed","projectId":"prj_b9c1f9c7873dcef51a57","compositionId":"cmp_cfbdd85eaaff301fa997","revision":2,"durationSec":58,"aspect":"9:16","reframe":"off","captions":{"enabled":true,"style":"bold-karaoke"},"music":null,"fadeInSec":0,"fadeOutSec":0,"clips":[{"assetId":"ast_3f9a1c7e5b2d4086a1c4","title":"Interview with a founder","durationSec":1800,"state":"ready"}],"segments":[{"id":"seg_a9dcee59c1fb9edb6751","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":302,"sourceEndSec":330,"zoom":1.2,"muted":false,"volume":1,"outputStartSec":0,"outputEndSec":28},{"id":"seg_7279fbb508f4a22e65a4","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":120,"sourceEndSec":150,"zoom":1,"muted":false,"volume":0.8,"outputStartSec":28,"outputEndSec":58}],"texts":[{"id":"ovl_49f5239b9cd73496225d","text":"Paid before the product","preset":"headline","outputStartSec":0,"durationSec":3,"xPercent":null,"yPercent":null}],"broll":[{"id":"brl_f44d18e008ec4009bf10","assetId":"ast_8ac5d8b97546145cdbf6","outputStartSec":12,"durationSec":4,"fit":"cover"}],"diagnostics":[]},"compositionId":"cmp_cfbdd85eaaff301fa997","warnings":[]}},"example3":{"summary":"Change the texts, the b-roll and the music","value":{"timeline":{"id":"tml_bbe061171a8229f8daed","projectId":"prj_b9c1f9c7873dcef51a57","compositionId":"cmp_cfbdd85eaaff301fa997","revision":2,"durationSec":60,"aspect":"9:16","reframe":"off","captions":{"enabled":true,"style":"bold-karaoke"},"music":{"assetId":"ast_e8a35ed674148f27b585","volume":0.2},"fadeInSec":1,"fadeOutSec":0,"clips":[{"assetId":"ast_3f9a1c7e5b2d4086a1c4","title":"Interview with a founder","durationSec":1800,"state":"ready"}],"segments":[{"id":"seg_7279fbb508f4a22e65a4","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":120,"sourceEndSec":150,"zoom":1,"muted":false,"volume":1,"outputStartSec":0,"outputEndSec":30},{"id":"seg_a9dcee59c1fb9edb6751","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":300,"sourceEndSec":330,"zoom":1,"muted":false,"volume":1,"outputStartSec":30,"outputEndSec":60}],"texts":[{"id":"ovl_49f5239b9cd73496225d","text":"They paid before we built it","preset":"headline","outputStartSec":0,"durationSec":3,"xPercent":null,"yPercent":null},{"id":"ovl_7b2d9e04c1a6f538b0e4","text":"Watch to the end","preset":"caption-note","outputStartSec":50,"durationSec":4,"xPercent":null,"yPercent":null}],"broll":[{"id":"brl_f44d18e008ec4009bf10","assetId":"ast_8ac5d8b97546145cdbf6","outputStartSec":12,"durationSec":3,"fit":"cover"},{"id":"brl_1f9c4a7e2d6b08e35c91","assetId":"ast_8ac5d8b97546145cdbf6","outputStartSec":20,"durationSec":3,"fit":"contain"}],"diagnostics":[]},"compositionId":"cmp_cfbdd85eaaff301fa997","warnings":[]}},"example4":{"summary":"Remove a text and a b-roll, and move a segment to the end","value":{"timeline":{"id":"tml_bbe061171a8229f8daed","projectId":"prj_b9c1f9c7873dcef51a57","compositionId":"cmp_cfbdd85eaaff301fa997","revision":2,"durationSec":60,"aspect":"9:16","reframe":"off","captions":{"enabled":true,"style":"bold-karaoke"},"music":null,"fadeInSec":0,"fadeOutSec":0,"clips":[{"assetId":"ast_3f9a1c7e5b2d4086a1c4","title":"Interview with a founder","durationSec":1800,"state":"ready"}],"segments":[{"id":"seg_a9dcee59c1fb9edb6751","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":300,"sourceEndSec":330,"zoom":1,"muted":false,"volume":1,"outputStartSec":0,"outputEndSec":30},{"id":"seg_7279fbb508f4a22e65a4","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":120,"sourceEndSec":150,"zoom":1,"muted":false,"volume":1,"outputStartSec":30,"outputEndSec":60}],"texts":[],"broll":[],"diagnostics":[]},"compositionId":"cmp_cfbdd85eaaff301fa997","warnings":[]}},"example5":{"summary":"Change the captions, a word and the shape","value":{"timeline":{"id":"tml_bbe061171a8229f8daed","projectId":"prj_b9c1f9c7873dcef51a57","compositionId":"cmp_cfbdd85eaaff301fa997","revision":2,"durationSec":60,"aspect":"1:1","reframe":"center","captions":{"enabled":true,"style":"word-pop"},"music":null,"fadeInSec":0,"fadeOutSec":0,"clips":[{"assetId":"ast_3f9a1c7e5b2d4086a1c4","title":"Interview with a founder","durationSec":1800,"state":"ready"}],"segments":[{"id":"seg_7279fbb508f4a22e65a4","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":120,"sourceEndSec":150,"zoom":1,"muted":false,"volume":1,"outputStartSec":0,"outputEndSec":30},{"id":"seg_a9dcee59c1fb9edb6751","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":300,"sourceEndSec":330,"zoom":1,"muted":false,"volume":1,"outputStartSec":30,"outputEndSec":60}],"texts":[{"id":"ovl_49f5239b9cd73496225d","text":"Paid before the product","preset":"headline","outputStartSec":0,"durationSec":3,"xPercent":null,"yPercent":null}],"broll":[{"id":"brl_f44d18e008ec4009bf10","assetId":"ast_8ac5d8b97546145cdbf6","outputStartSec":12,"durationSec":4,"fit":"cover"}],"diagnostics":[]},"compositionId":"cmp_cfbdd85eaaff301fa997","warnings":[]}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, NOT_READY, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["NOT_READY","IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. Adding a video costs credits, and has its own call: add_timeline_clip.","x-stability":"beta"}},"/projects/{projectId}/timeline/clips":{"post":{"operationId":"add_timeline_clip","summary":"Add a video to an edit","description":"Adds another video you uploaded to a prepared edit, as one segment of its whole length, and charges it once.\n\nSend the revision you read with get_timeline, the video to add and the segment to put it in front of; leave beforeSegmentId out, or send null, to add it at the end. The video is prepared in the background: until its state is ready it plays but cannot be cut by its words. A video the edit already uses, or already paid for, costs nothing. Retrying with the same Idempotency-Key never pays twice; if the first try was not written, its credits were given back and the retry answers CONFLICT, so send the change again with a new key.","tags":["editing"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedRevision":{"type":"integer","minimum":0,"description":"The revision of the edit you read last, from get_timeline or from the answer of your last change. If the edit changed since then, nothing is written and the answer is CONFLICT."},"assetId":{"type":"string","pattern":"^ast_n?[0-9a-f]{20}$","description":"The video to add: the asset id that complete_upload returned."},"beforeSegmentId":{"anyOf":[{"type":"string","pattern":"^seg_[0-9a-f]{20}$"},{"type":"null"}],"description":"The segment to put the video in front of. Leave it out, or send null, to add it at the end."}},"required":["expectedRevision","assetId"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"timeline":{"type":"object","properties":{"id":{"type":"string","description":"The edit id. It starts with tml_."},"projectId":{"type":"string"},"compositionId":{"type":["string","null"],"description":"The composition the edit compiles to, to export with create_export; null until the edit is first compiled."},"revision":{"type":"integer","description":"Grows by one at every change; send it as expectedRevision with the next change."},"durationSec":{"type":"number","description":"How long the video that comes out lasts, in seconds."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"]},"reframe":{"type":"string","enum":["off","face","center"],"description":"How the video follows the speaker: off keeps the frame, face follows the face, center keeps the middle."},"captions":{"type":"object","properties":{"enabled":{"type":"boolean"},"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]}},"required":["enabled","style"]},"music":{"anyOf":[{"type":"object","properties":{"assetId":{"type":["string","null"],"description":"The music file. null when the file no longer exists or cannot be used through the API."},"volume":{"type":"number"}},"required":["assetId","volume"]},{"type":"null"}],"description":"The music under the edit; null without music."},"fadeInSec":{"type":"number","description":"The fade from black at the start, in seconds; 0 for none."},"fadeOutSec":{"type":"number","description":"The fade to black at the end, in seconds; 0 for none."},"clips":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":["string","null"],"description":"The video. null when the file no longer exists or cannot be used through the API."},"title":{"type":"string"},"durationSec":{"type":"number"},"state":{"type":"string","enum":["ready","preparing","failed"],"description":"ready can be cut, preparing is still being prepared, failed could not be prepared and is not prepared again by itself."}},"required":["assetId","title","durationSec","state"]},"description":"The videos the edit uses."},"segments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The segment id. It starts with seg_."},"assetId":{"type":["string","null"],"description":"The video the segment comes from. null when the file no longer exists or cannot be used through the API."},"sourceStartSec":{"type":"number"},"sourceEndSec":{"type":"number"},"outputStartSec":{"type":"number"},"outputEndSec":{"type":"number"},"zoom":{"type":"number"},"muted":{"type":"boolean"},"volume":{"type":"number"}},"required":["id","assetId","sourceStartSec","sourceEndSec","outputStartSec","outputEndSec","zoom","muted","volume"]},"description":"The pieces of video, in the order they play."},"texts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The text id. It starts with ovl_."},"text":{"type":"string"},"preset":{"type":"string","enum":["headline","hook","caption-note"]},"outputStartSec":{"type":"number"},"durationSec":{"type":"number"},"xPercent":{"type":["number","null"]},"yPercent":{"type":["number","null"]}},"required":["id","text","preset","outputStartSec","durationSec","xPercent","yPercent"]}},"broll":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The b-roll id. It starts with brl_."},"assetId":{"type":["string","null"],"description":"The video shown over the edit. null when the file no longer exists or cannot be used through the API."},"outputStartSec":{"type":"number"},"durationSec":{"type":"number"},"fit":{"type":"string","enum":["cover","contain"]}},"required":["id","assetId","outputStartSec","durationSec","fit"]}},"diagnostics":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"description":"What the edit cannot do as it is, in one sentence each; empty when nothing."}},"required":["id","projectId","compositionId","revision","durationSec","aspect","reframe","captions","music","fadeInSec","fadeOutSec","clips","segments","texts","broll","diagnostics"]},"creditsCharged":{"type":"integer","minimum":0,"description":"The credits this request was charged: 0 when the edit already had the video, or had paid for it."},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."},"clip":{"type":"object","properties":{"assetId":{"type":"string","description":"The video that was added."},"state":{"type":"string","enum":["ready","preparing","failed"],"description":"ready can be cut, preparing is still being prepared, failed could not be prepared and is not prepared again by itself."}},"required":["assetId","state"]}},"required":["timeline","creditsCharged","paidWith","clip"]},"examples":{"example1":{"summary":"Add a video at the end of an edit","value":{"timeline":{"id":"tml_bbe061171a8229f8daed","projectId":"prj_b9c1f9c7873dcef51a57","compositionId":"cmp_cfbdd85eaaff301fa997","revision":2,"durationSec":180,"aspect":"9:16","reframe":"off","captions":{"enabled":true,"style":"bold-karaoke"},"music":null,"fadeInSec":0,"fadeOutSec":0,"clips":[{"assetId":"ast_3f9a1c7e5b2d4086a1c4","title":"Interview with a founder","durationSec":1800,"state":"ready"},{"assetId":"ast_8e21b0d94c6f4a17b358","title":"Product demo","durationSec":120,"state":"preparing"}],"segments":[{"id":"seg_7279fbb508f4a22e65a4","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":120,"sourceEndSec":150,"zoom":1,"muted":false,"volume":1,"outputStartSec":0,"outputEndSec":30},{"id":"seg_a9dcee59c1fb9edb6751","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":300,"sourceEndSec":330,"zoom":1,"muted":false,"volume":1,"outputStartSec":30,"outputEndSec":60},{"id":"seg_c3f81a6d0e5b9472d1a8","assetId":"ast_8e21b0d94c6f4a17b358","sourceStartSec":0,"sourceEndSec":120,"outputStartSec":60,"outputEndSec":180,"zoom":1,"muted":false,"volume":1}],"texts":[{"id":"ovl_49f5239b9cd73496225d","text":"Paid before the product","preset":"headline","outputStartSec":0,"durationSec":3,"xPercent":null,"yPercent":null}],"broll":[{"id":"brl_f44d18e008ec4009bf10","assetId":"ast_8ac5d8b97546145cdbf6","outputStartSec":12,"durationSec":4,"fit":"cover"}],"diagnostics":[]},"creditsCharged":2,"paidWith":"plan","clip":{"assetId":"ast_8e21b0d94c6f4a17b358","state":"preparing"}}},"example2":{"summary":"Add a video in front of a segment","value":{"timeline":{"id":"tml_bbe061171a8229f8daed","projectId":"prj_b9c1f9c7873dcef51a57","compositionId":"cmp_cfbdd85eaaff301fa997","revision":2,"durationSec":180,"aspect":"9:16","reframe":"off","captions":{"enabled":true,"style":"bold-karaoke"},"music":null,"fadeInSec":0,"fadeOutSec":0,"clips":[{"assetId":"ast_3f9a1c7e5b2d4086a1c4","title":"Interview with a founder","durationSec":1800,"state":"ready"},{"assetId":"ast_8e21b0d94c6f4a17b358","title":"Product demo","durationSec":120,"state":"preparing"}],"segments":[{"id":"seg_7279fbb508f4a22e65a4","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":120,"sourceEndSec":150,"zoom":1,"muted":false,"volume":1,"outputStartSec":0,"outputEndSec":30},{"id":"seg_c3f81a6d0e5b9472d1a8","assetId":"ast_8e21b0d94c6f4a17b358","sourceStartSec":0,"sourceEndSec":120,"outputStartSec":30,"outputEndSec":150,"zoom":1,"muted":false,"volume":1},{"id":"seg_a9dcee59c1fb9edb6751","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":300,"sourceEndSec":330,"zoom":1,"muted":false,"volume":1,"outputStartSec":150,"outputEndSec":180}],"texts":[{"id":"ovl_49f5239b9cd73496225d","text":"Paid before the product","preset":"headline","outputStartSec":0,"durationSec":3,"xPercent":null,"yPercent":null}],"broll":[{"id":"brl_f44d18e008ec4009bf10","assetId":"ast_8ac5d8b97546145cdbf6","outputStartSec":12,"durationSec":4,"fit":"cover"}],"diagnostics":[]},"creditsCharged":2,"paidWith":"plan","clip":{"assetId":"ast_8e21b0d94c6f4a17b358","state":"preparing"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, NOT_READY, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["NOT_READY","IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-cost":"One credit per started minute of the added video, charged once per video in an edit; adding the same video again costs no credits.","x-stability":"beta"}},"/projects/{projectId}/timeline/revisions":{"get":{"operationId":"list_timeline_revisions","summary":"List the revisions of an edit","description":"Lists the revisions of an edit that can be restored, newest first, with who wrote each one and what it did.\n\nCall it to find a revision to go back to with restore_timeline. Only the recent revisions of an edit are kept, for a limited time: a revision that is not in this list cannot be restored. The list is newest first and paged with cursor and limit.","tags":["editing"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"name":"limit","in":"query","required":false,"description":"How many items to return, from 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"description":"How many items to return, from 1 to 100. Defaults to 20.","default":20}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page. Leave it out to get the first page.","schema":{"type":"string","minLength":1,"maxLength":512}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"revision":{"type":"integer","description":"The revision, to restore with restore_timeline."},"createdAt":{"type":"string","description":"When the revision was written, in UTC (ISO 8601)."},"source":{"type":"string","enum":["app","api","assistant"],"description":"Who wrote it: app is someone in the GPT-Video app, api a call of the public API, assistant the Editor Assistant."},"summary":{"type":"string","description":"What the change did, in short."}},"required":["revision","createdAt","source","summary"]},"description":"The items of this page."},"hasMore":{"type":"boolean","description":"true when there are more items after this page."},"nextCursor":{"type":["string","null"],"description":"Send it as cursor to get the next page. It is null on the last page."}},"required":["data","hasMore","nextCursor"]},"examples":{"example1":{"summary":"List the revisions of an edit","value":{"data":[{"revision":3,"createdAt":"2026-09-01T11:20:00.000Z","source":"api","summary":"Captions on."},{"revision":2,"createdAt":"2026-09-01T11:15:00.000Z","source":"api","summary":"Captions off."}],"hasMore":false,"nextCursor":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, NOT_READY","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["NOT_READY"]},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/projects/{projectId}/timeline/restore":{"post":{"operationId":"restore_timeline","summary":"Restore a revision of an edit","description":"Brings an edit back to a revision listed by list_timeline_revisions, as a new revision.\n\nSend the revision to go back to and the revision you read last as expectedRevision. The edit becomes what it was at that revision, and the change is a new revision, so it can be undone the same way. A restore never costs credits: a revision that would bring back a video that is not paid for is refused, and the video can be added again with add_timeline_clip.","tags":["editing"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project id. It starts with prj_.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The project id. It starts with prj_."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"revision":{"type":"integer","minimum":0,"description":"The revision to go back to, as list_timeline_revisions lists it."},"expectedRevision":{"type":"integer","minimum":0,"description":"The revision of the edit you read last, from get_timeline or from the answer of your last change. If the edit changed since then, nothing is written and the answer is CONFLICT."}},"required":["revision","expectedRevision"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"timeline":{"type":"object","properties":{"id":{"type":"string","description":"The edit id. It starts with tml_."},"projectId":{"type":"string"},"compositionId":{"type":["string","null"],"description":"The composition the edit compiles to, to export with create_export; null until the edit is first compiled."},"revision":{"type":"integer","description":"Grows by one at every change; send it as expectedRevision with the next change."},"durationSec":{"type":"number","description":"How long the video that comes out lasts, in seconds."},"aspect":{"type":"string","enum":["source","9:16","1:1","16:9"]},"reframe":{"type":"string","enum":["off","face","center"],"description":"How the video follows the speaker: off keeps the frame, face follows the face, center keeps the middle."},"captions":{"type":"object","properties":{"enabled":{"type":"boolean"},"style":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"]}},"required":["enabled","style"]},"music":{"anyOf":[{"type":"object","properties":{"assetId":{"type":["string","null"],"description":"The music file. null when the file no longer exists or cannot be used through the API."},"volume":{"type":"number"}},"required":["assetId","volume"]},{"type":"null"}],"description":"The music under the edit; null without music."},"fadeInSec":{"type":"number","description":"The fade from black at the start, in seconds; 0 for none."},"fadeOutSec":{"type":"number","description":"The fade to black at the end, in seconds; 0 for none."},"clips":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":["string","null"],"description":"The video. null when the file no longer exists or cannot be used through the API."},"title":{"type":"string"},"durationSec":{"type":"number"},"state":{"type":"string","enum":["ready","preparing","failed"],"description":"ready can be cut, preparing is still being prepared, failed could not be prepared and is not prepared again by itself."}},"required":["assetId","title","durationSec","state"]},"description":"The videos the edit uses."},"segments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The segment id. It starts with seg_."},"assetId":{"type":["string","null"],"description":"The video the segment comes from. null when the file no longer exists or cannot be used through the API."},"sourceStartSec":{"type":"number"},"sourceEndSec":{"type":"number"},"outputStartSec":{"type":"number"},"outputEndSec":{"type":"number"},"zoom":{"type":"number"},"muted":{"type":"boolean"},"volume":{"type":"number"}},"required":["id","assetId","sourceStartSec","sourceEndSec","outputStartSec","outputEndSec","zoom","muted","volume"]},"description":"The pieces of video, in the order they play."},"texts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The text id. It starts with ovl_."},"text":{"type":"string"},"preset":{"type":"string","enum":["headline","hook","caption-note"]},"outputStartSec":{"type":"number"},"durationSec":{"type":"number"},"xPercent":{"type":["number","null"]},"yPercent":{"type":["number","null"]}},"required":["id","text","preset","outputStartSec","durationSec","xPercent","yPercent"]}},"broll":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The b-roll id. It starts with brl_."},"assetId":{"type":["string","null"],"description":"The video shown over the edit. null when the file no longer exists or cannot be used through the API."},"outputStartSec":{"type":"number"},"durationSec":{"type":"number"},"fit":{"type":"string","enum":["cover","contain"]}},"required":["id","assetId","outputStartSec","durationSec","fit"]}},"diagnostics":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"description":"What the edit cannot do as it is, in one sentence each; empty when nothing."}},"required":["id","projectId","compositionId","revision","durationSec","aspect","reframe","captions","music","fadeInSec","fadeOutSec","clips","segments","texts","broll","diagnostics"]},"compositionId":{"type":"string","description":"The composition the edit compiles to, to export with create_export."}},"required":["timeline","compositionId"]},"examples":{"example1":{"summary":"Restore a revision of an edit","value":{"timeline":{"id":"tml_bbe061171a8229f8daed","projectId":"prj_b9c1f9c7873dcef51a57","compositionId":"cmp_cfbdd85eaaff301fa997","revision":4,"durationSec":60,"aspect":"9:16","reframe":"off","captions":{"enabled":false,"style":"bold-karaoke"},"music":null,"fadeInSec":0,"fadeOutSec":0,"clips":[{"assetId":"ast_3f9a1c7e5b2d4086a1c4","title":"Interview with a founder","durationSec":1800,"state":"ready"}],"segments":[{"id":"seg_7279fbb508f4a22e65a4","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":120,"sourceEndSec":150,"zoom":1,"muted":false,"volume":1,"outputStartSec":0,"outputEndSec":30},{"id":"seg_a9dcee59c1fb9edb6751","assetId":"ast_3f9a1c7e5b2d4086a1c4","sourceStartSec":300,"sourceEndSec":330,"zoom":1,"muted":false,"volume":1,"outputStartSec":30,"outputEndSec":60}],"texts":[{"id":"ovl_49f5239b9cd73496225d","text":"Paid before the product","preset":"headline","outputStartSec":0,"durationSec":3,"xPercent":null,"yPercent":null}],"broll":[{"id":"brl_f44d18e008ec4009bf10","assetId":"ast_8ac5d8b97546145cdbf6","outputStartSec":12,"durationSec":4,"fit":"cover"}],"diagnostics":[]},"compositionId":"cmp_cfbdd85eaaff301fa997"}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, NOT_READY, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["NOT_READY","IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. A restore that would bring back a video that is not paid for is refused.","x-stability":"beta"}},"/projects/{projectId}/assistant/turns":{"post":{"operationId":"create_assistant_turn","summary":"Send a message to the Editor Assistant","description":"Asks the Editor Assistant to change a project in plain words, and returns the turn that does it.\n\nCall this to ask the Editor Assistant to edit a project, for example \"cut the pauses longer than one second\" or \"make the captions bolder\". The call answers 202 at once with the turn, queued, and a Location to follow; read it with get_assistant_turn (with ?wait= to hold the request) until it is done, then read its reply and its actions. The conversation is the same one the project shows in the GPT-Video app, where this message is marked as sent through the API. A turn through the API never spends credits or exports by itself: when the request needs an analysis, a build, a new clip in an edit or an export, the reply names the API call to make, which you send with its own Idempotency-Key. It runs at the Fast level, and it does not save notes. While a turn is running on the project, another turn sent through the API is running in the account, or a message written in the GPT-Video app is waiting for its answer, the call answers NOT_READY: wait for it, then send your message again. When the Editor Assistant is paused, the call answers UNAVAILABLE and uses no turn of the day. An Editor Assistant turn can change the project, so the key needs the clips:write scope as well as spend. Always send an Idempotency-Key, the same one on every retry: a retry of the same request returns the same turn and never uses a second turn of the day.","tags":["assistant"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The id of the project the Editor Assistant works on.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The id of the project the Editor Assistant works on."}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","minLength":1,"maxLength":4000,"description":"What you want done, in plain words, up to 4000 characters."}},"required":["message"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Location":{"$ref":"#/components/headers/Location"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"turn":{"type":"object","properties":{"id":{"type":"string","description":"The turn id. It starts with agm_."},"projectId":{"type":"string"},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"message":{"type":"string","description":"The message the turn answers."},"reply":{"type":["string","null"],"description":"What the Editor Assistant answered; null until the turn ends."},"outcome":{"anyOf":[{"type":"string","enum":["done","partial","blocked","needs_input"]},{"type":"null"}],"description":"How the turn ended: done did what was asked, partial did part of it, blocked could not, needs_input asks a question; null until the turn ends."},"question":{"type":["string","null"],"description":"The question the Editor Assistant asks, when outcome is needs_input; null otherwise."},"options":{"type":"array","items":{"type":"string"},"description":"The answers the Editor Assistant offers to its question; empty when there are none."},"actions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The action id. It starts with tc_."},"tool":{"type":"string","description":"What the action did, as a short name."},"status":{"type":"string","enum":["done","failed","undone"]},"summary":{"type":"string","description":"The action in one sentence."},"undoable":{"type":"boolean","description":"true when undo_assistant_action can undo it."},"creditsReturned":{"type":"integer","description":"The credits given back when the action was undone; 0 otherwise."}},"required":["id","tool","status","summary","undoable","creditsReturned"]},"description":"The changes the turn made, in order."},"jobId":{"type":["string","null"],"description":"The job that runs the turn; null once it is gone."},"errorMessage":{"type":["string","null"],"description":"Why the turn failed or stopped, in one sentence; null otherwise."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","projectId","status","message","reply","outcome","question","options","actions","jobId","errorMessage","createdAt","finishedAt"]},"paidWith":{"anyOf":[{"type":"string","enum":["plan","api_bonus"]},{"type":"null"}],"description":"Who paid for this request: plan is the credits or the daily allowance of the account's plan, api_bonus is the API bonus. null when this request paid nothing, because the same work was already running. A retry with the same Idempotency-Key says who paid the first time."}},"required":["turn","paidWith"]},"examples":{"example1":{"summary":"Ask for a change to an edit","value":{"turn":{"id":"agm_7c2e9a4f1b6d38e05a2c","projectId":"prj_b9c1f9c7873dcef51a57","status":"queued","message":"Cut the pauses longer than one second.","reply":null,"outcome":null,"question":null,"options":[],"actions":[],"jobId":"job_3e8b1d6f9a2c40e75b1d","errorMessage":null,"createdAt":"2026-09-01T11:00:00.000Z","finishedAt":null},"paidWith":"plan"}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER, IDEMPOTENCY_KEY_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"INSUFFICIENT_CREDITS, PLAN_REQUIRED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"NOT_READY, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["NOT_READY","IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED, DAILY_LIMIT_REACHED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"spend","x-scope":"spend","x-scopes":["spend","clips:write"],"x-cost":"Uses one Editor Assistant turn of the plan's daily allowance, which resets at 00:00 UTC; the Creator and Studio plans allow part of their turns through the API. When the API bonus pays, it also uses two bonus credits. Nothing is returned if the turn fails. A turn through the API never spends credits or exports on its own: the actions that would, answer with the API call to use.","x-bonus-credits":2,"x-stability":"beta"},"get":{"operationId":"list_assistant_turns","summary":"List the Editor Assistant turns of a project","description":"Lists the turns of the Editor Assistant on a project, newest first, the ones sent from the app included.\n\nCall this to read the conversation of a project with the Editor Assistant, for example to recover the turn of a request whose answer you lost. A project has one conversation, shared with the GPT-Video app, so the list holds the turns sent from the app as well as the ones sent through the API. The list is newest first and paged with cursor and limit.","tags":["assistant"],"parameters":[{"name":"projectId","in":"path","required":true,"description":"The id of the project the Editor Assistant works on.","schema":{"type":"string","pattern":"^prj_[0-9a-f]{20}$","description":"The id of the project the Editor Assistant works on."}},{"name":"limit","in":"query","required":false,"description":"How many items to return, from 1 to 100. Defaults to 20.","schema":{"type":"integer","minimum":1,"maximum":100,"description":"How many items to return, from 1 to 100. Defaults to 20.","default":20}},{"name":"cursor","in":"query","required":false,"description":"The nextCursor value from the previous page. Leave it out to get the first page.","schema":{"type":"string","minLength":1,"maxLength":512}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The turn id. It starts with agm_."},"projectId":{"type":"string"},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"message":{"type":"string","description":"The message the turn answers."},"reply":{"type":["string","null"],"description":"What the Editor Assistant answered; null until the turn ends."},"outcome":{"anyOf":[{"type":"string","enum":["done","partial","blocked","needs_input"]},{"type":"null"}],"description":"How the turn ended: done did what was asked, partial did part of it, blocked could not, needs_input asks a question; null until the turn ends."},"question":{"type":["string","null"],"description":"The question the Editor Assistant asks, when outcome is needs_input; null otherwise."},"options":{"type":"array","items":{"type":"string"},"description":"The answers the Editor Assistant offers to its question; empty when there are none."},"actions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The action id. It starts with tc_."},"tool":{"type":"string","description":"What the action did, as a short name."},"status":{"type":"string","enum":["done","failed","undone"]},"summary":{"type":"string","description":"The action in one sentence."},"undoable":{"type":"boolean","description":"true when undo_assistant_action can undo it."},"creditsReturned":{"type":"integer","description":"The credits given back when the action was undone; 0 otherwise."}},"required":["id","tool","status","summary","undoable","creditsReturned"]},"description":"The changes the turn made, in order."},"jobId":{"type":["string","null"],"description":"The job that runs the turn; null once it is gone."},"errorMessage":{"type":["string","null"],"description":"Why the turn failed or stopped, in one sentence; null otherwise."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","projectId","status","message","reply","outcome","question","options","actions","jobId","errorMessage","createdAt","finishedAt"]},"description":"The items of this page."},"hasMore":{"type":"boolean","description":"true when there are more items after this page."},"nextCursor":{"type":["string","null"],"description":"Send it as cursor to get the next page. It is null on the last page."}},"required":["data","hasMore","nextCursor"]},"examples":{"example1":{"summary":"List the turns of a project","value":{"data":[{"id":"agm_1e3d5feef4076b4329cf","projectId":"prj_b9c1f9c7873dcef51a57","status":"done","message":"Make the captions bolder.","reply":"I switched the captions to the bold karaoke style.","outcome":"done","question":null,"options":[],"actions":[{"id":"tc_6c98ac1c068fc322b284","tool":"set_captions","status":"done","summary":"Captions: bold karaoke","undoable":true,"creditsReturned":0}],"jobId":"job_0724f7cc56c41f889a0c","errorMessage":null,"createdAt":"2026-08-31T22:31:00.000Z","finishedAt":"2026-08-31T22:32:00.000Z"}],"hasMore":false,"nextCursor":null}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/assistant/turns/{turnId}":{"get":{"operationId":"get_assistant_turn","summary":"Get an Editor Assistant turn","description":"Returns a turn of the Editor Assistant: its status, its reply and the actions it took.\n\nCall this to follow a turn. While it is queued or running, add ?wait= with up to 25 seconds to hold the request until it ends, then call again if it is still working. A finished turn has its reply and its actions in order; an action that can be undone has undoable set to true, for undo_assistant_action. When outcome is needs_input, the Editor Assistant asks a question: answer it with a new create_assistant_turn. A failed or cancelled turn says what happened in errorMessage.","tags":["assistant"],"parameters":[{"name":"turnId","in":"path","required":true,"description":"The id of the turn, as create_assistant_turn or list_assistant_turns returned it. It starts with agm_.","schema":{"type":"string","pattern":"^agm_[0-9a-f]{20}$","description":"The id of the turn, as create_assistant_turn or list_assistant_turns returned it. It starts with agm_."}},{"name":"wait","in":"query","required":false,"description":"Seconds to hold the request while the work is still running, up to 25. Leave it out to answer at once. If many requests of the account are already waiting, it answers at once; wait a few seconds before you read again.","schema":{"type":"integer","minimum":0,"maximum":25,"description":"Seconds to hold the request while the work is still running, up to 25. Leave it out to answer at once. If many requests of the account are already waiting, it answers at once; wait a few seconds before you read again."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"turn":{"type":"object","properties":{"id":{"type":"string","description":"The turn id. It starts with agm_."},"projectId":{"type":"string"},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"message":{"type":"string","description":"The message the turn answers."},"reply":{"type":["string","null"],"description":"What the Editor Assistant answered; null until the turn ends."},"outcome":{"anyOf":[{"type":"string","enum":["done","partial","blocked","needs_input"]},{"type":"null"}],"description":"How the turn ended: done did what was asked, partial did part of it, blocked could not, needs_input asks a question; null until the turn ends."},"question":{"type":["string","null"],"description":"The question the Editor Assistant asks, when outcome is needs_input; null otherwise."},"options":{"type":"array","items":{"type":"string"},"description":"The answers the Editor Assistant offers to its question; empty when there are none."},"actions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The action id. It starts with tc_."},"tool":{"type":"string","description":"What the action did, as a short name."},"status":{"type":"string","enum":["done","failed","undone"]},"summary":{"type":"string","description":"The action in one sentence."},"undoable":{"type":"boolean","description":"true when undo_assistant_action can undo it."},"creditsReturned":{"type":"integer","description":"The credits given back when the action was undone; 0 otherwise."}},"required":["id","tool","status","summary","undoable","creditsReturned"]},"description":"The changes the turn made, in order."},"jobId":{"type":["string","null"],"description":"The job that runs the turn; null once it is gone."},"errorMessage":{"type":["string","null"],"description":"Why the turn failed or stopped, in one sentence; null otherwise."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","projectId","status","message","reply","outcome","question","options","actions","jobId","errorMessage","createdAt","finishedAt"]}},"required":["turn"]},"examples":{"example1":{"summary":"Get a finished turn","value":{"turn":{"id":"agm_1e3d5feef4076b4329cf","projectId":"prj_b9c1f9c7873dcef51a57","status":"done","message":"Make the captions bolder.","reply":"I switched the captions to the bold karaoke style.","outcome":"done","question":null,"options":[],"actions":[{"id":"tc_6c98ac1c068fc322b284","tool":"set_captions","status":"done","summary":"Captions: bold karaoke","undoable":true,"creditsReturned":0}],"jobId":"job_0724f7cc56c41f889a0c","errorMessage":null,"createdAt":"2026-08-31T22:31:00.000Z","finishedAt":"2026-08-31T22:32:00.000Z"}}},"example2":{"summary":"Wait for a turn to finish","value":{"turn":{"id":"agm_1e3d5feef4076b4329cf","projectId":"prj_b9c1f9c7873dcef51a57","status":"done","message":"Make the captions bolder.","reply":"I switched the captions to the bold karaoke style.","outcome":"done","question":null,"options":[],"actions":[{"id":"tc_6c98ac1c068fc322b284","tool":"set_captions","status":"done","summary":"Captions: bold karaoke","undoable":true,"creditsReturned":0}],"jobId":"job_0724f7cc56c41f889a0c","errorMessage":null,"createdAt":"2026-08-31T22:31:00.000Z","finishedAt":"2026-08-31T22:32:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/assistant/turns/{turnId}/actions/{actionId}/undo":{"post":{"operationId":"undo_assistant_action","summary":"Undo an action of the Editor Assistant","description":"Puts the project back as it was before one action of a turn, and returns the turn.\n\nCall this to take back one change the Editor Assistant made, named by the id in the actions of its turn. Only an action with undoable set to true can be undone, and only while nothing changed after it: when the project changed since, the call answers CONFLICT and the way forward is a new change. An action that added a clip to an edit gives its credits back when it is undone, unless the edit was exported after it; creditsReturned says how many. Undoing an action that is already undone answers the turn as it is, with creditsReturned 0.","tags":["assistant"],"parameters":[{"name":"turnId","in":"path","required":true,"description":"The id of the turn, as create_assistant_turn or list_assistant_turns returned it. It starts with agm_.","schema":{"type":"string","pattern":"^agm_[0-9a-f]{20}$","description":"The id of the turn, as create_assistant_turn or list_assistant_turns returned it. It starts with agm_."}},{"name":"actionId","in":"path","required":true,"description":"The id of one action of the turn, from its actions. It starts with tc_.","schema":{"type":"string","pattern":"^tc_[0-9a-f]{20}$","description":"The id of one action of the turn, from its actions. It starts with tc_."}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"turn":{"type":"object","properties":{"id":{"type":"string","description":"The turn id. It starts with agm_."},"projectId":{"type":"string"},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"message":{"type":"string","description":"The message the turn answers."},"reply":{"type":["string","null"],"description":"What the Editor Assistant answered; null until the turn ends."},"outcome":{"anyOf":[{"type":"string","enum":["done","partial","blocked","needs_input"]},{"type":"null"}],"description":"How the turn ended: done did what was asked, partial did part of it, blocked could not, needs_input asks a question; null until the turn ends."},"question":{"type":["string","null"],"description":"The question the Editor Assistant asks, when outcome is needs_input; null otherwise."},"options":{"type":"array","items":{"type":"string"},"description":"The answers the Editor Assistant offers to its question; empty when there are none."},"actions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The action id. It starts with tc_."},"tool":{"type":"string","description":"What the action did, as a short name."},"status":{"type":"string","enum":["done","failed","undone"]},"summary":{"type":"string","description":"The action in one sentence."},"undoable":{"type":"boolean","description":"true when undo_assistant_action can undo it."},"creditsReturned":{"type":"integer","description":"The credits given back when the action was undone; 0 otherwise."}},"required":["id","tool","status","summary","undoable","creditsReturned"]},"description":"The changes the turn made, in order."},"jobId":{"type":["string","null"],"description":"The job that runs the turn; null once it is gone."},"errorMessage":{"type":["string","null"],"description":"Why the turn failed or stopped, in one sentence; null otherwise."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","projectId","status","message","reply","outcome","question","options","actions","jobId","errorMessage","createdAt","finishedAt"]},"creditsReturned":{"type":"integer","minimum":0,"description":"The credits this call gave back; 0 when the action bought nothing or was already undone."}},"required":["turn","creditsReturned"]},"examples":{"example1":{"summary":"Undo an action","value":{"turn":{"id":"agm_1e3d5feef4076b4329cf","projectId":"prj_b9c1f9c7873dcef51a57","status":"done","message":"Make the captions bolder.","reply":"I switched the captions to the bold karaoke style.","outcome":"done","question":null,"options":[],"actions":[{"id":"tc_6c98ac1c068fc322b284","tool":"set_captions","status":"undone","summary":"Captions: bold karaoke","undoable":false,"creditsReturned":0}],"jobId":"job_0724f7cc56c41f889a0c","errorMessage":null,"createdAt":"2026-08-31T22:31:00.000Z","finishedAt":"2026-08-31T22:32:00.000Z"},"creditsReturned":0}},"example2":{"summary":"An action that is already undone","value":{"turn":{"id":"agm_1e3d5feef4076b4329cf","projectId":"prj_b9c1f9c7873dcef51a57","status":"done","message":"Make the captions bolder.","reply":"I switched the captions to the bold karaoke style.","outcome":"done","question":null,"options":[],"actions":[{"id":"tc_6c98ac1c068fc322b284","tool":"set_captions","status":"undone","summary":"Captions: bold karaoke","undoable":false,"creditsReturned":0}],"jobId":"job_0724f7cc56c41f889a0c","errorMessage":null,"createdAt":"2026-08-31T22:31:00.000Z","finishedAt":"2026-08-31T22:32:00.000Z"},"creditsReturned":0}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"CONFLICT, NOT_READY, IDEMPOTENCY_IN_PROGRESS","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["NOT_READY","IDEMPOTENCY_IN_PROGRESS"]},"413":{"description":"PAYLOAD_TOO_LARGE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"write","x-scope":"clips:write","x-cost":"No credits are used. Undoing an action that added a clip gives its credits back.","x-stability":"beta"}},"/jobs/{jobId}":{"get":{"operationId":"get_job","summary":"Get a job","description":"Returns a job that another call started: its kind, status and progress.\n\nCall this to follow the work another call started. analyze_project and the build calls return their job, and so do the import of a video from a link and the story and voice calls of a fake text project; a tool run, an Editor Assistant turn and a composition's framing carry the id of their job. While the job is queued or running, add ?wait= with up to 25 seconds to hold the request until it ends, then call again if it is still working. A job that failed or stopped says what happened in errorMessage. A finished import job gives the new video in assetId. A tool job gives its run in toolRunId, to read with get_tool_run, and an assistant_turn job gives its turn in turnId, to read with get_assistant_turn. An export is easier to follow with get_export, which also gives its download link; an export id (rnd_) is not a job id here.","tags":["jobs"],"parameters":[{"name":"jobId","in":"path","required":true,"description":"The id of the job. The calls that start work return it, and so do analysisJobId of a project, framing.jobId of a composition and the jobId of an export, a tool run or an Editor Assistant turn. It starts with job_.","schema":{"type":"string","pattern":"^job_[0-9a-f]{20}$","description":"The id of the job. The calls that start work return it, and so do analysisJobId of a project, framing.jobId of a composition and the jobId of an export, a tool run or an Editor Assistant turn. It starts with job_."}},{"name":"wait","in":"query","required":false,"description":"Seconds to hold the request while the work is still running, up to 25. Leave it out to answer at once. If many requests of the account are already waiting, it answers at once; wait a few seconds before you read again.","schema":{"type":"integer","minimum":0,"maximum":25,"description":"Seconds to hold the request while the work is still running, up to 25. Leave it out to answer at once. If many requests of the account are already waiting, it answers at once; wait a few seconds before you read again."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","description":"The job id. It starts with job_."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does. analysis finds the clips of an Auto Clip project, or prepares a Vibe Editing project. build makes the video of a split screen, streamer or Reddit story project. export renders a composition to a file. framing follows the face in a clip. import brings in a video from a link. story writes the story of a fake text project. voices makes the voices of a fake text story. tool runs a voiceover, an audio separation or a brainstorm. assistant_turn is one turn of the Editor Assistant."},"status":{"type":"string","enum":["queued","running","done","failed","cancelled"],"description":"queued and running are still working; done, failed and cancelled are final."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the job is, from 0 to 1."},"errorMessage":{"type":["string","null"],"description":"Why the job failed or stopped, in one sentence; null otherwise."},"projectId":{"type":["string","null"],"description":"The project the job works on, when it has one."},"compositionId":{"type":["string","null"],"description":"The composition the job works on, when it has one."},"exportId":{"type":["string","null"],"description":"The export this job renders, for an export job; null otherwise."},"assetId":{"type":["string","null"],"description":"The video an import job brought in, once the job is done; null for every other job, and when that video no longer exists or cannot be used through the API."},"toolRunId":{"type":["string","null"],"description":"The tool run a tool job carries out, to read with get_tool_run; null for every other job."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn an assistant_turn job carries out, to read with get_assistant_turn; null for every other job."},"createdAt":{"type":"string","description":"An ISO 8601 time in UTC."},"startedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."},"finishedAt":{"type":["string","null"],"description":"An ISO 8601 time in UTC."}},"required":["id","kind","status","progress","errorMessage","projectId","compositionId","exportId","assetId","toolRunId","turnId","createdAt","startedAt","finishedAt"]}},"required":["job"]},"examples":{"example1":{"summary":"Get a finished analysis","value":{"job":{"id":"job_6c1e8b4a2f0d4a97e3b5","kind":"analysis","status":"done","progress":1,"errorMessage":null,"projectId":"prj_7c2e9a4f1b3d4e8096a5","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T09:11:00.000Z","startedAt":"2026-09-01T09:12:00.000Z","finishedAt":"2026-09-01T09:40:00.000Z"}}},"example2":{"summary":"Get the job of an export","value":{"job":{"id":"job_a3e9d05c7b1f4e2896d4","kind":"export","status":"done","progress":1,"errorMessage":null,"projectId":"prj_7c2e9a4f1b3d4e8096a5","compositionId":"cmp_4e8c2a6f09d14b73a1e5","exportId":"rnd_0f6b3e9d2c7a4158b4a3","assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T10:10:00.000Z","startedAt":"2026-09-01T10:11:00.000Z","finishedAt":"2026-09-01T10:15:00.000Z"}}},"example3":{"summary":"Wait for a job to finish","value":{"job":{"id":"job_6c1e8b4a2f0d4a97e3b5","kind":"analysis","status":"done","progress":1,"errorMessage":null,"projectId":"prj_7c2e9a4f1b3d4e8096a5","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null,"createdAt":"2026-09-01T09:11:00.000Z","startedAt":"2026-09-01T09:12:00.000Z","finishedAt":"2026-09-01T09:40:00.000Z"}}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"NOT_FOUND","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/reference/setting-options":{"get":{"operationId":"get_setting_options","summary":"Get the setting options","description":"Returns the values the settings of a project or a brainstorm accept, with a name and a description for every choice.\n\nCall this before you create or change a project, or start a brainstorm, to know what its settings take. language, objective, captionStyle and reframe take an id from these lists, and clipCount, minDurationSec and maxDurationSec a number within the ranges given here. layout is the layout of a split screen project, theme the look of a fake text project, aspect the shape of a Vibe Editing project and videoType the kind of video of brainstorm_ideas. The voices are listed by list_voices. The names and descriptions are written to show the choices to a person. New values can be added over time, so read the lists instead of copying them into your code. The answer is the same for every account.","tags":["reference"],"parameters":[],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"languages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["auto","it","en"],"description":"The value to send in the setting."},"name":{"type":"string","description":"A short name to show to a person."}},"required":["id","name"]},"description":"The spoken language of the video, used to transcribe it. auto detects it."},"objectives":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["viral","educational","entertaining","emotional","controversial","howto","business"],"description":"The value to send in the setting."},"name":{"type":"string","description":"A short name to show to a person."},"description":{"type":"string","description":"One sentence that says what the choice does."}},"required":["id","name","description"]},"description":"What kind of moments the analysis looks for."},"captionStyles":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["bold-karaoke","word-pop","boxed","outline"],"description":"The value to send in the setting."},"name":{"type":"string","description":"A short name to show to a person."},"description":{"type":"string","description":"One sentence that says what the choice does."}},"required":["id","name","description"]},"description":"How the captions look on a clip."},"reframeModes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["face","center"],"description":"The value to send in the setting."},"name":{"type":"string","description":"A short name to show to a person."},"description":{"type":"string","description":"One sentence that says what the choice does."}},"required":["id","name","description"]},"description":"How the vertical frame is placed on a video that is wider than it is tall."},"clipCount":{"type":"object","properties":{"min":{"type":"integer","description":"The lowest value accepted."},"max":{"type":"integer","description":"The highest value accepted."}},"required":["min","max"],"description":"How many clips an analysis can be asked for."},"minDurationSec":{"type":"object","properties":{"min":{"type":"integer","description":"The lowest value accepted."},"max":{"type":"integer","description":"The highest value accepted."}},"required":["min","max"],"description":"The values minDurationSec accepts, in seconds."},"maxDurationSec":{"type":"object","properties":{"min":{"type":"integer","description":"The lowest value accepted."},"max":{"type":"integer","description":"The highest value accepted."}},"required":["min","max"],"description":"The values maxDurationSec accepts, in seconds. An analysis refuses a minimum longer than the maximum."},"layouts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["50-50","60-40"],"description":"The value to send in the setting."},"name":{"type":"string","description":"A short name to show to a person."},"description":{"type":"string","description":"One sentence that says what the choice does."}},"required":["id","name","description"]},"description":"How a split screen project shares the screen between its two videos (layout)."},"themes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["imessage","whatsapp"],"description":"The value to send in the setting."},"name":{"type":"string","description":"A short name to show to a person."},"description":{"type":"string","description":"One sentence that says what the choice does."}},"required":["id","name","description"]},"description":"How the chat of a fake text project looks (theme)."},"aspects":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["source","9:16","1:1","16:9"],"description":"The value to send in the setting."},"name":{"type":"string","description":"A short name to show to a person."},"description":{"type":"string","description":"One sentence that says what the choice does."}},"required":["id","name","description"]},"description":"The shape a Vibe Editing project starts with (aspect)."},"videoTypes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["story","fake_text","split_screen","any"],"description":"The value to send in the setting."},"name":{"type":"string","description":"A short name to show to a person."},"description":{"type":"string","description":"One sentence that says what the choice does."}},"required":["id","name","description"]},"description":"The kinds of video brainstorm_ideas writes ideas for (videoType)."}},"required":["languages","objectives","captionStyles","reframeModes","clipCount","minDurationSec","maxDurationSec","layouts","themes","aspects","videoTypes"]},"examples":{"example1":{"summary":"Read the options before setting up a project","value":{"languages":[{"id":"auto","name":"Detect automatically"},{"id":"it","name":"Italian"},{"id":"en","name":"English"}],"objectives":[{"id":"viral","name":"Mixed","description":"Moments with a strong opening and a clear payoff, on any topic."},{"id":"educational","name":"Educational","description":"Lessons, methods and figures that a viewer would keep to watch again."},{"id":"entertaining","name":"Entertaining","description":"Jokes, stories and moments nobody saw coming."},{"id":"emotional","name":"Emotional","description":"Personal stories, moments of doubt and words that move people."},{"id":"controversial","name":"Controversial","description":"Strong opinions and positions that go against what most people think."},{"id":"howto","name":"How-to","description":"Practical steps that show how to do one thing."},{"id":"business","name":"Business","description":"Lessons about running a company, with numbers, decisions and mistakes."}],"captionStyles":[{"id":"bold-karaoke","name":"Bold karaoke","description":"Bold uppercase words, and the word being spoken changes color."},{"id":"word-pop","name":"Word pop","description":"One large word at a time, each with a short entrance animation."},{"id":"boxed","name":"Boxed","description":"The sentence sits in a dark box, and the word being spoken is highlighted."},{"id":"outline","name":"Outline","description":"White words with a black outline, readable on any background."}],"reframeModes":[{"id":"face","name":"Follow the face","description":"The vertical frame follows the face of the speaker, and stays in the middle when no face is found."},{"id":"center","name":"Center","description":"The vertical frame stays in the middle of the video."}],"clipCount":{"min":1,"max":100},"minDurationSec":{"min":5,"max":180},"maxDurationSec":{"min":10,"max":300},"layouts":[{"id":"50-50","name":"Half and half","description":"The main video and the background video each take half of the screen."},{"id":"60-40","name":"Main video larger","description":"The main video takes more of the screen than the background video."}],"themes":[{"id":"imessage","name":"iMessage","description":"The chat looks like a conversation in Apple Messages."},{"id":"whatsapp","name":"WhatsApp","description":"The chat looks like a conversation in WhatsApp."}],"aspects":[{"id":"source","name":"Same as the video","description":"The edit keeps the shape of its source video."},{"id":"9:16","name":"Vertical 9:16","description":"A tall frame that fills a phone screen held upright."},{"id":"1:1","name":"Square 1:1","description":"A square frame, as wide as it is tall."},{"id":"16:9","name":"Horizontal 16:9","description":"A wide frame, the shape of most videos made for a computer screen."}],"videoTypes":[{"id":"story","name":"Story","description":"A story read by a voice over a background video."},{"id":"fake_text","name":"Fake text","description":"A chat conversation shown one message at a time."},{"id":"split_screen","name":"Split screen","description":"A talking video above a background video."},{"id":"any","name":"Any","description":"Ideas for any kind of short video."}]}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}},"/reference/voices":{"get":{"operationId":"list_voices","summary":"List the voices","description":"Lists the synthetic voices of a language that a voiceover can use.\n\nCall this before create_voiceover to choose a voice: send the language of the script, and use the id of one of the voices returned. A voice speaks one language only. The list is short and the same for every account, so it is not paged. New voices can be added over time, so read the list instead of copying it into your code.","tags":["reference"],"parameters":[{"name":"language","in":"query","required":true,"description":"The language of the voices: en for English, it for Italian.","schema":{"type":"string","enum":["en","it"],"description":"The language of the voices: en for English, it for Italian."}}],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"voices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The voice id, like en-aria."},"name":{"type":"string"},"language":{"type":"string","enum":["en","it"]},"gender":{"type":"string","enum":["female","male"]}},"required":["id","name","language","gender"]},"description":"The voices of the language, in a fixed order."}},"required":["voices"]},"examples":{"example1":{"summary":"The English voices","value":{"voices":[{"id":"en-aria","name":"Aria","language":"en","gender":"female"},{"id":"en-jenny","name":"Jenny","language":"en","gender":"female"},{"id":"en-guy","name":"Guy","language":"en","gender":"male"},{"id":"en-christopher","name":"Christopher","language":"en","gender":"male"}]}},"example2":{"summary":"The Italian voices","value":{"voices":[{"id":"it-elsa","name":"Elsa","language":"it","gender":"female"},{"id":"it-isabella","name":"Isabella","language":"it","gender":"female"},{"id":"it-diego","name":"Diego","language":"it","gender":"male"},{"id":"it-giuseppe","name":"Giuseppe","language":"it","gender":"male"}]}}}}}},"400":{"description":"VALIDATION_FAILED, UNKNOWN_PARAMETER","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"UNAUTHORIZED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"SCOPE_MISSING","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"RATE_LIMITED","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["RATE_LIMITED"]},"500":{"description":"INTERNAL","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["INTERNAL"]},"503":{"description":"UNAVAILABLE","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"x-retryable":["UNAVAILABLE"]}},"x-effect":"read","x-scope":"clips:read","x-cost":"No credits are used.","x-stability":"beta"}}},"webhooks":{"job.completed":{"post":{"summary":"Job completed","description":"Sent when a job you can read with get_job finishes with status done. Call get_job to read it.","tags":["webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"},{"$ref":"#/components/parameters/WebhookTimestamp"},{"$ref":"#/components/parameters/WebhookSignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","const":"job.completed","description":"The event type."},"timestamp":{"type":"string","description":"When the event happened, in UTC."},"data":{"type":"object","properties":{"jobId":{"type":"string","description":"The job, to read with get_job."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does, as get_job says it."},"projectId":{"type":["string","null"],"description":"The project the job works on. null when the job has none."},"compositionId":{"type":["string","null"],"description":"The composition the job works on. null when the job has none."},"exportId":{"type":["string","null"],"description":"The export the job renders. null when the job has none."},"assetId":{"type":["string","null"],"description":"The video an import brought in. null when the job has none."},"toolRunId":{"type":["string","null"],"description":"The tool run the job carries out. null when the job has none."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn the job carries out. null when the job has none."}},"required":["jobId","kind","projectId","compositionId","exportId","assetId","toolRunId","turnId"]}},"required":["type","timestamp","data"]},"examples":{"example1":{"summary":"Job completed","value":{"type":"job.completed","timestamp":"2026-09-01T09:40:00.000Z","data":{"jobId":"job_6c1e8b4a2f0d4a97e3b5","kind":"analysis","projectId":"prj_7c2e9a4f1b3d4e8096a5","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null}}}}}}},"responses":{"2XX":{"description":"Any 2xx status tells GPT-Video that the event arrived. After any other answer, or none in time, the event is sent again later with the same webhook-id."}}}},"job.failed":{"post":{"summary":"Job failed","description":"Sent when a job finishes with status failed. A job that is tried again is not failed yet. Call get_job to read why.","tags":["webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"},{"$ref":"#/components/parameters/WebhookTimestamp"},{"$ref":"#/components/parameters/WebhookSignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","const":"job.failed","description":"The event type."},"timestamp":{"type":"string","description":"When the event happened, in UTC."},"data":{"type":"object","properties":{"jobId":{"type":"string","description":"The job, to read with get_job."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does, as get_job says it."},"projectId":{"type":["string","null"],"description":"The project the job works on. null when the job has none."},"compositionId":{"type":["string","null"],"description":"The composition the job works on. null when the job has none."},"exportId":{"type":["string","null"],"description":"The export the job renders. null when the job has none."},"assetId":{"type":["string","null"],"description":"The video an import brought in. null when the job has none."},"toolRunId":{"type":["string","null"],"description":"The tool run the job carries out. null when the job has none."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn the job carries out. null when the job has none."}},"required":["jobId","kind","projectId","compositionId","exportId","assetId","toolRunId","turnId"]}},"required":["type","timestamp","data"]},"examples":{"example1":{"summary":"Job failed","value":{"type":"job.failed","timestamp":"2026-09-01T09:40:00.000Z","data":{"jobId":"job_6c1e8b4a2f0d4a97e3b5","kind":"analysis","projectId":"prj_7c2e9a4f1b3d4e8096a5","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null}}}}}}},"responses":{"2XX":{"description":"Any 2xx status tells GPT-Video that the event arrived. After any other answer, or none in time, the event is sent again later with the same webhook-id."}}}},"job.cancelled":{"post":{"summary":"Job cancelled","description":"Sent when a job is cancelled before it finishes.","tags":["webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"},{"$ref":"#/components/parameters/WebhookTimestamp"},{"$ref":"#/components/parameters/WebhookSignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","const":"job.cancelled","description":"The event type."},"timestamp":{"type":"string","description":"When the event happened, in UTC."},"data":{"type":"object","properties":{"jobId":{"type":"string","description":"The job, to read with get_job."},"kind":{"type":"string","enum":["analysis","build","export","framing","import","story","voices","tool","assistant_turn"],"description":"What the job does, as get_job says it."},"projectId":{"type":["string","null"],"description":"The project the job works on. null when the job has none."},"compositionId":{"type":["string","null"],"description":"The composition the job works on. null when the job has none."},"exportId":{"type":["string","null"],"description":"The export the job renders. null when the job has none."},"assetId":{"type":["string","null"],"description":"The video an import brought in. null when the job has none."},"toolRunId":{"type":["string","null"],"description":"The tool run the job carries out. null when the job has none."},"turnId":{"type":["string","null"],"description":"The Editor Assistant turn the job carries out. null when the job has none."}},"required":["jobId","kind","projectId","compositionId","exportId","assetId","toolRunId","turnId"]}},"required":["type","timestamp","data"]},"examples":{"example1":{"summary":"Job cancelled","value":{"type":"job.cancelled","timestamp":"2026-09-01T09:40:00.000Z","data":{"jobId":"job_6c1e8b4a2f0d4a97e3b5","kind":"analysis","projectId":"prj_7c2e9a4f1b3d4e8096a5","compositionId":null,"exportId":null,"assetId":null,"toolRunId":null,"turnId":null}}}}}}},"responses":{"2XX":{"description":"Any 2xx status tells GPT-Video that the event arrived. After any other answer, or none in time, the event is sent again later with the same webhook-id."}}}},"export.completed":{"post":{"summary":"Export completed","description":"Sent when an export is done. Call get_export to download its file.","tags":["webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"},{"$ref":"#/components/parameters/WebhookTimestamp"},{"$ref":"#/components/parameters/WebhookSignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","const":"export.completed","description":"The event type."},"timestamp":{"type":"string","description":"When the event happened, in UTC."},"data":{"type":"object","properties":{"exportId":{"type":"string","description":"The export, to read with get_export."},"compositionId":{"type":"string","description":"The composition the export renders."},"projectId":{"type":"string","description":"The project of the composition."},"jobId":{"type":["string","null"],"description":"The job that renders the export. null for an export that never started."}},"required":["exportId","compositionId","projectId","jobId"]}},"required":["type","timestamp","data"]},"examples":{"example1":{"summary":"Export completed","value":{"type":"export.completed","timestamp":"2026-09-01T10:15:00.000Z","data":{"exportId":"rnd_0f6b3e9d2c7a4158b4a3","compositionId":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","jobId":"job_a3e9d05c7b1f4e2896d4"}}}}}}},"responses":{"2XX":{"description":"Any 2xx status tells GPT-Video that the event arrived. After any other answer, or none in time, the event is sent again later with the same webhook-id."}}}},"export.failed":{"post":{"summary":"Export failed","description":"Sent when an export fails, including an export that never started. Call get_export to read why.","tags":["webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"},{"$ref":"#/components/parameters/WebhookTimestamp"},{"$ref":"#/components/parameters/WebhookSignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","const":"export.failed","description":"The event type."},"timestamp":{"type":"string","description":"When the event happened, in UTC."},"data":{"type":"object","properties":{"exportId":{"type":"string","description":"The export, to read with get_export."},"compositionId":{"type":"string","description":"The composition the export renders."},"projectId":{"type":"string","description":"The project of the composition."},"jobId":{"type":["string","null"],"description":"The job that renders the export. null for an export that never started."}},"required":["exportId","compositionId","projectId","jobId"]}},"required":["type","timestamp","data"]},"examples":{"example1":{"summary":"Export failed","value":{"type":"export.failed","timestamp":"2026-09-01T10:15:00.000Z","data":{"exportId":"rnd_0f6b3e9d2c7a4158b4a3","compositionId":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","jobId":"job_a3e9d05c7b1f4e2896d4"}}}}}}},"responses":{"2XX":{"description":"Any 2xx status tells GPT-Video that the event arrived. After any other answer, or none in time, the event is sent again later with the same webhook-id."}}}},"export.cancelled":{"post":{"summary":"Export cancelled","description":"Sent when an export is cancelled before it finishes.","tags":["webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"},{"$ref":"#/components/parameters/WebhookTimestamp"},{"$ref":"#/components/parameters/WebhookSignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","const":"export.cancelled","description":"The event type."},"timestamp":{"type":"string","description":"When the event happened, in UTC."},"data":{"type":"object","properties":{"exportId":{"type":"string","description":"The export, to read with get_export."},"compositionId":{"type":"string","description":"The composition the export renders."},"projectId":{"type":"string","description":"The project of the composition."},"jobId":{"type":["string","null"],"description":"The job that renders the export. null for an export that never started."}},"required":["exportId","compositionId","projectId","jobId"]}},"required":["type","timestamp","data"]},"examples":{"example1":{"summary":"Export cancelled","value":{"type":"export.cancelled","timestamp":"2026-09-01T10:15:00.000Z","data":{"exportId":"rnd_0f6b3e9d2c7a4158b4a3","compositionId":"cmp_4e8c2a6f09d14b73a1e5","projectId":"prj_7c2e9a4f1b3d4e8096a5","jobId":"job_a3e9d05c7b1f4e2896d4"}}}}}}},"responses":{"2XX":{"description":"Any 2xx status tells GPT-Video that the event arrived. After any other answer, or none in time, the event is sent again later with the same webhook-id."}}}},"webhook.test":{"post":{"summary":"Test event","description":"Sent when you send a test event from the Developers page. It is never sent again and does not count when a webhook keeps failing.","tags":["webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"},{"$ref":"#/components/parameters/WebhookTimestamp"},{"$ref":"#/components/parameters/WebhookSignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","const":"webhook.test","description":"The event type."},"timestamp":{"type":"string","description":"When the event happened, in UTC."},"data":{"type":"object","properties":{"endpointId":{"type":"string","description":"The webhook the test was sent to."}},"required":["endpointId"]}},"required":["type","timestamp","data"]},"examples":{"example1":{"summary":"Test event","value":{"type":"webhook.test","timestamp":"2026-10-03T12:00:00.000Z","data":{"endpointId":"whk_ea7c528e7e454010d9fc"}}}}}}},"responses":{"2XX":{"description":"Any 2xx status tells GPT-Video that the event arrived. This event is sent once, whatever the answer."}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key. It starts with gvk_, and you create it in the GPT-Video app."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_FAILED","UNKNOWN_PARAMETER","IDEMPOTENCY_KEY_REQUIRED","UNAUTHORIZED","INSUFFICIENT_CREDITS","PLAN_REQUIRED","SCOPE_MISSING","NOT_FOUND","METHOD_NOT_ALLOWED","CONFLICT","NOT_READY","IDEMPOTENCY_IN_PROGRESS","PAYLOAD_TOO_LARGE","IDEMPOTENCY_KEY_REUSED","SOURCE_MISSING","UNSUPPORTED_SOURCE_URL","RATE_LIMITED","DAILY_LIMIT_REACHED","INTERNAL","UPSTREAM_FAILED","UNAVAILABLE"]},"message":{"type":"string","minLength":1},"hint":{"type":"string","minLength":1},"docsUrl":{"type":"string","format":"uri"},"requestId":{"type":"string","minLength":1},"details":{}},"required":["code","message","requestId"]}},"required":["error"],"x-retryable":["NOT_READY","IDEMPOTENCY_IN_PROGRESS","RATE_LIMITED","INTERNAL","UPSTREAM_FAILED","UNAVAILABLE"]}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","description":"A random string such as a UUID. Send the same one on every retry of this request. For 24 hours a successful answer is sent again, marked Idempotent-Replayed, and the request does not run a second time. After an error the same request runs again with the same key. A new key is a new request.","required":false,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[\\x21-\\x7E]+$"}},"IdempotencyKeyRequired":{"name":"Idempotency-Key","in":"header","description":"A random string such as a UUID. This operation spends, so the key is required. Send the same one on every retry of this request. For 24 hours a successful answer is sent again, marked Idempotent-Replayed, and the request does not run a second time. After an error, a 500 included, the same request runs again with the same key and never spends twice. Do not switch to a new key to retry: a new key is a new request and spends again.","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[\\x21-\\x7E]+$"}},"WebhookId":{"name":"webhook-id","in":"header","description":"The id of the event. It is the same on every attempt to send the event, so use it to skip an event you already handled.","required":true,"schema":{"type":"string"}},"WebhookTimestamp":{"name":"webhook-timestamp","in":"header","description":"When this attempt was sent, in seconds since the Unix epoch. A retry carries a new time. It is part of what is signed.","required":true,"schema":{"type":"string"}},"WebhookSignature":{"name":"webhook-signature","in":"header","description":"v1, then a comma, then the base64 HMAC-SHA256 of the webhook-id, the webhook-timestamp and the raw body joined by dots, signed with the secret of the webhook (whsec_...). The key is the part of the secret after whsec_, decoded from base64. While a secret is being rotated it carries two signatures separated by a space, and either one is valid. Any Standard Webhooks library can check it.","required":true,"schema":{"type":"string"}}},"headers":{"X-Request-Id":{"description":"The id of this request. Quote it when you contact support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"How many requests of this kind the key may send in 60 seconds.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"How many of them are left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the current window ends.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before sending the same request again.","schema":{"type":"integer"}},"Location":{"description":"Where the created resource, or the job to follow, can be read.","schema":{"type":"string"}},"Idempotent-Replayed":{"description":"true when this answer repeats the one given to an earlier request with the same Idempotency-Key.","schema":{"type":"string"}}}}}