{"openapi":"3.1.0","info":{"title":"Threadwright API","version":"0.0.0","summary":"AI-character voice, image and video tools as asynchronous jobs.","description":"Authenticate with `Authorization: Bearer smp_...` (create a token in Settings > Access tokens). Submit a job, poll it, then fetch its output assets. The agent guide is at https://app.threadwright.ai/skill."},"servers":[{"url":"https://app.threadwright.ai"}],"tags":[{"name":"meta"},{"name":"auth"},{"name":"account"},{"name":"tokens"},{"name":"wallet"},{"name":"billing"},{"name":"assets"},{"name":"jobs"},{"name":"offerings"},{"name":"characters"},{"name":"projects"},{"name":"clips"},{"name":"ideas"}],"paths":{"/api/v1/health":{"get":{"operationId":"getHealth","tags":["meta"],"summary":"Liveness and API version","security":[],"responses":{"200":{"description":"Up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/client-errors":{"post":{"operationId":"reportClientError","tags":["meta"],"summary":"Report a browser error (web app)","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientErrorRequest"}}}},"responses":{"204":{"description":"Done; no body."},"default":{"$ref":"#/components/responses/Error"}},"x-browser-only":true}},"/auth/email/start":{"post":{"operationId":"startEmailSignIn","tags":["auth"],"summary":"Email a sign-in link (browser sign-up and sign-in)","description":"Always answers 202, whether or not the address has an account.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailStartRequest"}}}},"responses":{"202":{"description":"Accepted."},"default":{"$ref":"#/components/responses/Error"}},"x-browser-only":true}},"/auth/google":{"get":{"operationId":"startGoogleSignIn","tags":["auth"],"summary":"Start Google sign-in (browser redirect)","security":[],"parameters":[{"name":"next","in":"query","required":false,"description":"Same-origin path to land on.","schema":{"type":"string"}},{"name":"terms","in":"query","required":false,"description":"The accepted terms version; required to create a new account.","schema":{"type":"string"}}],"responses":{"302":{"description":"Redirect to Google."},"default":{"$ref":"#/components/responses/Error"}},"x-browser-only":true}},"/auth/sign-out":{"post":{"operationId":"signOut","tags":["auth"],"summary":"End the browser session","security":[{"sessionCookie":[]}],"x-browser-only":true,"responses":{"204":{"description":"Done; no body."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/me":{"get":{"operationId":"getMe","tags":["account"],"summary":"The signed-in account, its plan and the credential's scopes","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"responses":{"200":{"description":"The account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}},"patch":{"operationId":"updateMe","tags":["account"],"summary":"Set the display name (1 to 60 characters, trimmed)","security":[{"sessionCookie":[]}],"x-browser-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMeRequest"}}}},"responses":{"200":{"description":"The saved name.","content":{"application/json":{"schema":{"type":"object","properties":{"display_name":{"type":"string"}},"required":["display_name"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"operationId":"deleteMe","tags":["account"],"summary":"Delete the account: cancels the subscription, revokes all access and deletes content; financial records are kept for the retention period","security":[{"sessionCookie":[]}],"x-browser-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountRequest"}}}},"responses":{"202":{"description":"The account is closed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/me/terms":{"post":{"operationId":"acceptTerms","tags":["account"],"summary":"Accept the current Terms of Service and Privacy Policy","security":[{"sessionCookie":[]}],"x-browser-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptTermsRequest"}}}},"responses":{"200":{"description":"The recorded acceptance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptTermsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/tokens":{"get":{"operationId":"listTokens","tags":["tokens"],"summary":"List live access tokens","security":[{"sessionCookie":[]}],"x-browser-only":true,"responses":{"200":{"description":"Tokens, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}},"post":{"operationId":"createToken","tags":["tokens"],"summary":"Create an access token (the secret is shown once)","security":[{"sessionCookie":[]}],"x-browser-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTokenRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTokenResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/tokens/{id}":{"delete":{"operationId":"revokeToken","tags":["tokens"],"summary":"Revoke an access token","security":[{"sessionCookie":[]}],"x-browser-only":true,"parameters":[{"name":"id","in":"path","required":true,"description":"Token id (`tok_...`).","schema":{"type":"string"}}],"responses":{"204":{"description":"Done; no body."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/billing/checkout":{"post":{"operationId":"createCheckout","tags":["billing"],"summary":"Start a Stripe Checkout session for a tier subscription or a credit bundle","security":[{"sessionCookie":[]}],"x-browser-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}}},"responses":{"200":{"description":"The Checkout URL to redirect the browser to.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/billing/free-cta":{"post":{"operationId":"logFreeCta","tags":["billing"],"summary":"Log a free reel offer view or click","security":[{"sessionCookie":[]}],"x-browser-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreeCtaRequest"}}}},"responses":{"204":{"description":"Done; no body."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/billing/portal":{"post":{"operationId":"createPortalSession","tags":["billing"],"summary":"Open the Stripe Customer Portal for the signed-in account","security":[{"sessionCookie":[]}],"x-browser-only":true,"responses":{"200":{"description":"The portal URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/billing/subscription":{"get":{"operationId":"getSubscription","tags":["billing"],"summary":"The account's current plan and Stripe subscription state","security":[{"sessionCookie":[]}],"x-browser-only":true,"responses":{"200":{"description":"Plan, status, current period and cancellation flag.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/webhooks/stripe":{"post":{"operationId":"stripeWebhook","tags":["billing"],"summary":"Stripe webhook endpoint (signature verified; not for API clients)","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Event accepted or already processed."},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/wallet":{"get":{"operationId":"getWallet","tags":["wallet"],"summary":"Credit balance: available, held by running jobs, by grant kind, and the current period","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["wallet:read"],"responses":{"200":{"description":"The balance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Wallet"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/wallet/history":{"get":{"operationId":"getWalletHistory","tags":["wallet"],"summary":"Settled ledger entries, newest first","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["wallet:read"],"parameters":[{"name":"cursor","in":"query","required":false,"description":"The `next_cursor` of the previous page.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"type","in":"query","required":false,"description":"Only entries of this type.","schema":{"type":"string","enum":["grant","capture","refund","adjust","expire"]}}],"responses":{"200":{"description":"A page of entries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletHistory"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/characters":{"get":{"operationId":"listCharacters","tags":["characters"],"summary":"List your characters, newest first","description":"A token with the `characters` scope can read too.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"cursor","in":"query","required":false,"description":"The `next_cursor` of the previous page.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"q","in":"query","required":false,"description":"Case-insensitive contains-search on the name (at most 100 characters; % and _ match themselves).","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"created_after","in":"query","required":false,"description":"Only items created at or after this ISO 8601 UTC time (inclusive), e.g. `2026-10-01T00:00:00Z`. Combines with the cursor; order stays newest first. A bad value is 400 `invalid_request` naming the field.","schema":{"type":"string","format":"date-time"}},{"name":"created_before","in":"query","required":false,"description":"Only items created before this ISO 8601 UTC time (exclusive).","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"A page of characters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CharacterList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}},"post":{"operationId":"createCharacter","tags":["characters"],"summary":"Create a character (the platform's persona file)","description":"`voice_id` must come from `GET /api/v1/voices`; `look` and `captions` are checked like the `finish.develop` and `finish.captions` inputs; `routing` maps a tool id to a model key of the same kind as the tool's default; every `refs` asset must be a ready image of yours. Make references with the `character.create` tool. Send `wish` (one line) and the free fill-in writes `description` and `niche`, picks a voice and sets the finishing defaults; what you send yourself wins.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["characters"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCharacterRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Character"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"description":"A field does not fit: `invalid_voice`, `invalid_look`, `invalid_captions`, `invalid_routing`, `invalid_refs` or `invalid_wish` (names a real person).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/characters/{id}":{"get":{"operationId":"getCharacter","tags":["characters"],"summary":"One character","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"id","in":"path","required":true,"description":"Character id (`chr_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The character.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Character"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such character (`character_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}},"patch":{"operationId":"updateCharacter","tags":["characters"],"summary":"Change any fields of a character","description":"`null` clears a nullable field; `look`, `routing`, `captions` and `refs` replace the stored value as a whole.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["characters"],"parameters":[{"name":"id","in":"path","required":true,"description":"Character id (`chr_...`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCharacterRequest"}}}},"responses":{"200":{"description":"The character.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Character"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such character (`character_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A field does not fit; as for create.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"operationId":"deleteCharacter","tags":["characters"],"summary":"Delete a character (its images stay in your library)","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["characters"],"parameters":[{"name":"id","in":"path","required":true,"description":"Character id (`chr_...`).","schema":{"type":"string"}}],"responses":{"204":{"description":"Done; no body."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/library/characters":{"get":{"operationId":"listLibraryCharacters","tags":["characters"],"summary":"Browse the character library (ready-made platform characters)","description":"Read-only characters with a full config (name, niche, voice, look, reference images). Filter by `gender`, `age_band` and `niche`; library order, not newest first. Clone one with `POST /api/v1/library/characters/{id}/use`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"gender","in":"query","required":false,"description":"Only this gender.","schema":{"type":"string","enum":["female","male","non_binary"]}},{"name":"age_band","in":"query","required":false,"description":"Only this age band.","schema":{"type":"string","enum":["18_24","25_34","35_44","45_54","55_plus"]}},{"name":"niche","in":"query","required":false,"description":"Case-insensitive contains-search on the niche (the page concept).","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"q","in":"query","required":false,"description":"Case-insensitive contains-search on the name (at most 100 characters; % and _ match themselves).","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"cursor","in":"query","required":false,"description":"The `next_cursor` of the previous page.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"A page of library characters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LibraryCharacterList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/library/characters/{id}":{"get":{"operationId":"getLibraryCharacter","tags":["characters"],"summary":"One library character","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"id","in":"path","required":true,"description":"Library character id (`lib_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The character.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LibraryCharacter"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such library character (`library_character_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/library/characters/{id}/images/{slot}":{"get":{"operationId":"getLibraryCharacterImage","tags":["characters"],"summary":"A library character's image (PNG, JPEG or WebP bytes)","description":"`slot` is `front`, `profile`, `full_body`, `hero` or `location-1` to `location-3`; the character's `images` gives the URLs that exist. Needs a credential.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"id","in":"path","required":true,"description":"Library character id (`lib_...`).","schema":{"type":"string"}},{"name":"slot","in":"path","required":true,"description":"Image slot.","schema":{"type":"string"}}],"responses":{"200":{"description":"The image."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such character or image.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/library/characters/{id}/use":{"post":{"operationId":"useLibraryCharacter","tags":["characters"],"summary":"Use this character: a free clone into your own characters","description":"Creates a normal character of yours with the library character's settings and copies its images into your assets (they count toward your storage). Free; the clone is yours to edit. Using the same one twice makes two characters. No body.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["characters"],"parameters":[{"name":"id","in":"path","required":true,"description":"Library character id (`lib_...`).","schema":{"type":"string"}}],"responses":{"201":{"description":"Created: `character_id` and the new `character`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UseLibraryCharacter"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such library character (`library_character_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The images would not fit your storage (`storage_quota_exceeded`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/library/audio":{"get":{"operationId":"listLibraryAudio","tags":["assets"],"summary":"Browse the audio library (platform ambience beds and music)","description":"Free on every plan. Filter by `kind`, one `tag` and a `q` search over name and tags; library order. Each track has a `preview_url` that streams without a credential. Copy one with `POST /api/v1/library/audio/{id}/use`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read","assets"],"parameters":[{"name":"kind","in":"query","required":false,"description":"Only this kind.","schema":{"type":"string","enum":["ambience","music"]}},{"name":"tag","in":"query","required":false,"description":"Only this tag.","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Case-insensitive contains-search on the name or tag (at most 100 characters; % and _ match themselves).","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"cursor","in":"query","required":false,"description":"The `next_cursor` of the previous page.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"A page of tracks.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LibraryAudioList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/library/audio/{id}/preview":{"get":{"operationId":"previewLibraryAudio","tags":["assets"],"summary":"Stream a library track (MP3, public)","description":"No credential needed; supports `Range`, so a browser `<audio>` element can seek. Each track's `preview_url` is this path.","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"Library track id (`libaud_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The MP3 bytes (206 for a `Range` request)."},"404":{"description":"No such track (`library_audio_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/library/audio/{id}/use":{"post":{"operationId":"useLibraryAudio","tags":["assets"],"summary":"Use this track: a free copy into your own assets","description":"Copies the track into your assets (counts toward storage; a `job` asset without a job). The copy carries `library_audio_id`: it plays and mixes in your projects, but `download=1` on it is 403 `library_audio_no_download` on every plan. Capped per account and day. No body.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["assets"],"parameters":[{"name":"id","in":"path","required":true,"description":"Library track id (`libaud_...`).","schema":{"type":"string"}}],"responses":{"201":{"description":"Created: `asset_id` and the new `asset`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UseLibraryAudio"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such track (`library_audio_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Would not fit your storage (`storage_quota_exceeded`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Daily copy cap reached (`library_audio_daily_limit`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/characters/{id}/voice-suggestion":{"get":{"operationId":"suggestCharacterVoice","tags":["characters"],"summary":"A curated voice that fits this character (free, nothing is saved)","description":"Picked by gender, age and vibe from the description and niche. Apply it with PATCH `voice_id`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"id","in":"path","required":true,"description":"Character id (`chr_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The voice, or null when none is curated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceSuggestion"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such character (`character_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/voices":{"get":{"operationId":"listVoices","tags":["characters"],"summary":"The curated voices a character may use","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"responses":{"200":{"description":"The voices.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/assets":{"get":{"operationId":"listAssets","tags":["assets"],"summary":"List your assets, newest first","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"kind","in":"query","required":false,"description":"Only this kind.","schema":{"type":"string","enum":["image","video","audio","file"]}},{"name":"project","in":"query","required":false,"description":"Only this project (`prj_...`).","schema":{"type":"string"}},{"name":"mime","in":"query","required":false,"description":"Exact media type (`image/png`) or a type prefix ending in a slash (`image/`); case-insensitive.","schema":{"type":"string"}},{"name":"source","in":"query","required":false,"description":"Only uploaded assets, or only assets a job made.","schema":{"type":"string","enum":["upload","job"]}},{"name":"character","in":"query","required":false,"description":"Only assets of this character (`chr_...`): those in its reference sets (`refs`), plus those made by your jobs whose input has `character_id` naming it.","schema":{"type":"string"}},{"name":"created_after","in":"query","required":false,"description":"Only items created at or after this ISO 8601 UTC time (inclusive), e.g. `2026-10-01T00:00:00Z`. Combines with the cursor; order stays newest first. A bad value is 400 `invalid_request` naming the field.","schema":{"type":"string","format":"date-time"}},{"name":"created_before","in":"query","required":false,"description":"Only items created before this ISO 8601 UTC time (exclusive).","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","required":false,"description":"The `next_cursor` of the previous page.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"A page of assets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/assets/uploads":{"post":{"operationId":"createUpload","tags":["assets"],"summary":"Reserve an upload and get presigned PUT URL(s)","description":"Single PUT up to 100 MiB; above that a multipart plan. PUT the bytes with exactly the returned headers, then call complete.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["assets"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUploadRequest"}}}},"responses":{"201":{"description":"The upload plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUploadResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/assets/uploads/{id}/complete":{"post":{"operationId":"completeUpload","tags":["assets"],"summary":"Confirm an upload; the asset becomes ready once its safety check clears","description":"Images and videos are checked automatically against the Acceptable Use Policy (free for you). `moderation` is `checking` while the check runs (the status stays `pending` and the asset cannot be used yet; images usually come back checked, videos take longer: poll getAsset), `clear` when it is ready, or `blocked`: it breaks the policy, can never be used or downloaded, and its file is deleted after a short hold. Audio and other files are ready at once.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["assets"],"parameters":[{"name":"id","in":"path","required":true,"description":"The `asset_id` from createUpload.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteUploadRequest"}}}},"responses":{"200":{"description":"The asset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/assets/{id}":{"get":{"operationId":"getAsset","tags":["assets"],"summary":"Asset metadata and a short-lived signed download URL","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"id","in":"path","required":true,"description":"Asset id (`asset_...`).","schema":{"type":"string"}},{"name":"download","in":"query","required":false,"description":"1: as an attachment.","schema":{"type":"string","enum":["0","1"]}}],"responses":{"200":{"description":"The asset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetDetail"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"operationId":"deleteAsset","tags":["assets"],"summary":"Delete an asset and its stored object","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["assets"],"parameters":[{"name":"id","in":"path","required":true,"description":"Asset id (`asset_...`).","schema":{"type":"string"}}],"responses":{"204":{"description":"Done; no body."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/assets/{id}/content":{"get":{"operationId":"getAssetContent","tags":["assets"],"summary":"Redirect to the asset's bytes (302 to a signed URL)","description":"409 `asset_not_ready` while pending, checking or missing; 403 `asset_blocked` when the safety check blocked it.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"id","in":"path","required":true,"description":"Asset id (`asset_...`).","schema":{"type":"string"}}],"responses":{"302":{"description":"Redirect to a presigned GET."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/jobs":{"get":{"operationId":"listJobs","tags":["jobs"],"summary":"List your jobs, newest first","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["jobs"],"parameters":[{"name":"cursor","in":"query","required":false,"description":"The `next_cursor` of the previous page.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"status","in":"query","required":false,"description":"Only this status.","schema":{"type":"string","enum":["queued","running","waiting","succeeded","failed","cancelled"]}},{"name":"tool","in":"query","required":false,"description":"Only jobs of this tool (offering id, e.g. `image.generate`).","schema":{"type":"string"}},{"name":"project","in":"query","required":false,"description":"Only jobs whose input has this `project_id` (`prj_...`).","schema":{"type":"string"}},{"name":"created_after","in":"query","required":false,"description":"Only items created at or after this ISO 8601 UTC time (inclusive), e.g. `2026-10-01T00:00:00Z`. Combines with the cursor; order stays newest first. A bad value is 400 `invalid_request` naming the field.","schema":{"type":"string","format":"date-time"}},{"name":"created_before","in":"query","required":false,"description":"Only items created before this ISO 8601 UTC time (exclusive).","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"A page of jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}},"post":{"operationId":"submitJob","tags":["jobs"],"summary":"Run a tool: validate, hold the estimate, queue","description":"`offering` is a tool id from `GET /api/v1/offerings`; `input` follows its schema. Send `Idempotency-Key` to make retries safe: the same key and body return the same job (200, `Idempotent-Replayed: true`); the same key with another body is 409.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["jobs"],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"1 to 255 visible ASCII characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitJobRequest"}}}},"responses":{"200":{"description":"Replay of an earlier submission with this key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"202":{"description":"Accepted and queued.","headers":{"Location":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Not enough credits (`insufficient_credits`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"description":"`idempotency_conflict`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/jobs/{id}":{"get":{"operationId":"getJob","tags":["jobs"],"summary":"A job's status, credits and outputs (asset ids)","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["jobs"],"parameters":[{"name":"id","in":"path","required":true,"description":"Job id (`job_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/jobs/{id}/cancel":{"post":{"operationId":"cancelJob","tags":["jobs"],"summary":"Cancel a queued or waiting job; its hold is released","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["jobs"],"parameters":[{"name":"id","in":"path","required":true,"description":"Job id (`job_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"description":"`job_not_cancellable` (running or finished).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/offerings":{"get":{"operationId":"listOfferings","tags":["offerings"],"summary":"Tools on your plan with prices (anonymous: the free plan, every plan's prices)","security":[{},{"bearerAuth":[]},{"sessionCookie":[]}],"responses":{"200":{"description":"The catalogue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferingList"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/offerings/{id}":{"get":{"operationId":"getOffering","tags":["offerings"],"summary":"One tool: input and output JSON Schema, price rule, prices, example request","security":[{},{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Tool id, e.g. `image.generate`.","schema":{"type":"string"}}],"responses":{"200":{"description":"The offering.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferingDetail"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/offerings/{id}/estimate":{"post":{"operationId":"estimateOffering","tags":["offerings"],"summary":"Credits a submit of this input would hold, without submitting","security":[{},{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Tool id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateRequest"}}}},"responses":{"200":{"description":"The estimate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateResponse"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/openapi.json":{"get":{"operationId":"getOpenApi","tags":["meta"],"summary":"This document","security":[],"responses":{"200":{"description":"OpenAPI 3.1.","content":{"application/json":{"schema":{"type":"object"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/skill":{"get":{"operationId":"getSkill","tags":["meta"],"summary":"The agent skill (SKILL.md, Agent Skills format)","security":[],"responses":{"200":{"description":"Markdown with YAML frontmatter.","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/api/v1/projects":{"get":{"operationId":"listProjects","tags":["projects"],"summary":"List your projects, newest first","description":"A token with the `projects` scope can read too. `kind` filters to reel or post.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"cursor","in":"query","required":false,"description":"The `next_cursor` of the previous page.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"kind","in":"query","required":false,"description":"Only this kind.","schema":{"type":"string","enum":["reel","post"]}},{"name":"q","in":"query","required":false,"description":"Case-insensitive contains-search on the title (at most 100 characters; % and _ match themselves).","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"created_after","in":"query","required":false,"description":"Only items created at or after this ISO 8601 UTC time (inclusive), e.g. `2026-10-01T00:00:00Z`. Combines with the cursor; order stays newest first. A bad value is 400 `invalid_request` naming the field.","schema":{"type":"string","format":"date-time"}},{"name":"created_before","in":"query","required":false,"description":"Only items created before this ISO 8601 UTC time (exclusive).","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"A page of projects.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}},"post":{"operationId":"createProject","tags":["projects"],"summary":"Create a reel or photo-post project","description":"The spec is the platform's episode.yaml (`shots`, `edit`) or post.yaml (`aspect`, `variants`, `images`). `title` and shot `id`s may be left out. Units (takes, frames, clips, images, finals) are derived from it; see `GET /api/v1/projects/{id}/units`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"description":"`invalid_spec`, `invalid_look`, `invalid_captions` or `invalid_character`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/free-plan":{"get":{"operationId":"getFreePlan","tags":["projects"],"summary":"The Free plan's one guided reel: its project, redos left and the recipe","description":"Free is one idea and one reel project per email, for life, paid by the platform up to a spend ceiling; every step's first run is free, then a shared pool of redos. Outside it Free answers 403 `paid_plan_required` (also for API tokens).","security":[{"sessionCookie":[]}],"x-scopes":["read","projects"],"x-browser-only":true,"responses":{"200":{"description":"The allowance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreePlan"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}":{"get":{"operationId":"getProject","tags":["projects"],"summary":"One project with its spec and state","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}},"patch":{"operationId":"updateProject","tags":["projects"],"summary":"Replace the title, spec, character or saved post caption of a project","description":"`spec` replaces the stored spec as a whole; units that are no longer in it lose their state. Send `If-Match` with the project's `updated_at` as you read it to refuse a save made on an older version (412); without it the save always applies. `post_caption` `{text, hashtags, edited}` saves the post caption in `state.post_caption`; `null` removes it.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}},{"name":"If-Match","in":"header","required":false,"description":"The project's `updated_at` as you last read it (bare or quoted). The check and the write are one statement.","schema":{"type":"string","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectRequest"}}}},"responses":{"200":{"description":"The project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"`stale_version`: the project changed since that version; nothing was saved. `error.details.project` is the project as it is now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"As for create.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"operationId":"deleteProject","tags":["projects"],"summary":"Delete a project (its assets stay in your library)","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}}],"responses":{"204":{"description":"Done; no body."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/units":{"get":{"operationId":"listProjectUnits","tags":["projects"],"summary":"Every unit with its tool, what it waits on, jobs and candidate outputs","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The units.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUnits"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/units/{unit}/run":{"post":{"operationId":"runProjectUnit","tags":["projects"],"summary":"Run a unit's tool with the character applied","description":"Builds the tool input from the spec, the selected upstream assets and the character, merges `overrides` over it and submits a job exactly as `POST /api/v1/jobs` does. 409 `missing_upstream` when a unit it reads has no selection yet (a frame linking a scene reference waits until the reference is generated and selected); 409 `character_incomplete` when the character lacks references the unit needs. A scene reference unit (`ref1.reference`) planned by `assist.write_reel_script` or `assist.write_post_plan` makes its first image free once per project (`free_run` and `estimate_credits: 0` on the unit); every later run, and every run of a reference you added, is charged. 409 `free_run_taken` when a parallel request just took the free run.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}},{"name":"unit","in":"path","required":true,"description":"Unit id (`shot01.take`, `shot02.seg1.clip`, `d1_morning.final`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1 to 255 visible ASCII characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunUnitRequest"}}}},"responses":{"200":{"description":"Replay of an earlier run with this key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunUnitResponse"}}}},"202":{"description":"Accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunUnitResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Not enough credits (`insufficient_credits`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"`project_not_found` or `unit_not_found`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`missing_upstream`, `character_incomplete`, `free_run_taken` or `idempotency_conflict`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/units/{unit}/edit":{"post":{"operationId":"editProjectUnit","tags":["projects"],"summary":"Edit an image or clip candidate by describing the change in words","description":"Describe the change in words; the image is edited and added as a candidate of the same unit (`edited_from` in the unit names its source). `source_asset_id` is one of the unit's candidates (or its selection); the character's look is kept. An edit always enhances: the edit plus 5 credits (`edit_estimate_credits`), whatever `enhance_prompts` says; the rewritten prompt is never returned. Held and settled like any job; same `Idempotency-Key` as `POST /api/v1/jobs`. Clip units: send `candidate` (the clip's job, default the selected clip) instead; the clip is made again from the same first frame, take and model with your change applied to its movement, priced and held as the unit's run plus the enhancement (`edit_estimate_credits`; on the Free plan it uses a redo, no credits). A change to how the shot looks belongs to its visual: 422 `edit_needs_frame`, nothing charged. A model that takes no directions (`clip_editable: false`): 409 `edit_unsupported_model`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}},{"name":"unit","in":"path","required":true,"description":"Unit id (`shot01.take`, `shot02.seg1.clip`, `d1_morning.final`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1 to 255 visible ASCII characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditUnitRequest"}}}},"responses":{"200":{"description":"Replay of an earlier edit with this key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditUnitResponse"}}}},"202":{"description":"Accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditUnitResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Not enough credits (`insufficient_credits`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"`project_not_found`, `unit_not_found` or `asset_not_found`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`idempotency_conflict`; clips: `edit_unsupported_model`, `nothing_to_edit`, `missing_upstream`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`not_editable`, `not_a_candidate`, `asset_not_ready`, `wrong_asset_kind`; clips: `edit_needs_frame`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Clips: `edit_unavailable` (try again; nothing charged).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/build":{"post":{"operationId":"buildProjectReel","tags":["projects"],"summary":"Build a reel: preview, draft, final cut or covers","description":"Submits `project.reel` for a reel project. The credit hold is sized from the project's `duration_seconds` (`timeline_seconds` overrides it); 422 `invalid_spec` naming `duration_seconds` when the reel has none. Same errors and `Idempotency-Key` as `POST /api/v1/jobs`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1 to 255 visible ASCII characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildReelRequest"}}}},"responses":{"200":{"description":"Replay of an earlier build with this key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildReelResponse"}}}},"202":{"description":"Accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildReelResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Not enough credits (`insufficient_credits`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`wrong_kind` or `idempotency_conflict`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`invalid_spec`: the reel has no duration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/run-all/estimate":{"post":{"operationId":"estimateRunAll","tags":["projects"],"summary":"Price Make everything (or Generate all on one step): the total and your balance","description":"Every unit still to run (a scene reference's free first run at 0; clips at the unit's `clip_seconds`, so each matches its `estimate_credits`, except B-roll without a chosen model, held at the dearer of its route and fallback), upscaling each draft clip and the reel's final cut. No draft render. `unavailable` lists units your plan cannot run. With `{\"mode\": \"step\", \"step\": ...}`: Generate all on that step only (its units that never ran; `waiting` lists those still waiting for an earlier pick; no upscale or cut).","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunAllEstimateRequest"}}}},"responses":{"200":{"description":"The estimate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunAllEstimate"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"`paid_plan_required`: Realism on Free.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`invalid_step` for this project kind.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/run-all":{"post":{"operationId":"runAllProject","tags":["projects"],"summary":"Make everything: run every missing unit, finish the clips, build the final cut","description":"One server run walks the units in order, runs what has no selection, selects the first result of each, upscales draft clips and (reels) builds the final cut with three covers. Existing selections are kept. Send the `estimate_credits` you confirmed; a higher estimate is 409 `estimate_changed`. Each unit holds its own credits. Progress is the project's `run` (`GET /api/v1/projects/{id}`). A reel whose `spec.edit.ambience` was never set (not `null`) first gets the ambience bed the script writer suggested (`sound_suggestion` on the project), a free library copy on every plan, or none when the library has no match; music is added only when the reel's format asks for it. Generate all (`run.mode` `step`): send `{\"mode\": \"step\", \"step\": \"voice\" | \"frames\" | \"realism\" | \"grade\" | \"clips\" | \"images\" | \"variants\"}`; it runs that step's units that never ran and are not running (frames and images include the scene references) and selects the first result of each, leaving units with a run or a pick alone; no other step, no build. Holds, Free plan and stop as for Make everything; Realism is paid plans only.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1 to 255 visible ASCII characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunAllRequest"}}}},"responses":{"200":{"description":"Replay of an earlier start with this key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunAllResponse"}}}},"202":{"description":"Started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunAllResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"The balance is below the estimate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`paid_plan_required`: Realism on Free.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`run_in_progress`, `estimate_changed`, `nothing_to_run` (a step with nothing left; `details.waiting`) or `idempotency_conflict`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`invalid_step`, `free_recipe`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/finish-all/estimate":{"post":{"operationId":"estimateFinishAll","tags":["projects"],"summary":"Price Finish in 1080p: the upscales of the draft clips and a new final cut","description":"For a reel whose final cut used draft clips or carries the Free plan's mark (`final_from_drafts`, `final_marked` on the project): the upscale of every draft pick plus the final assembly, from the live prices. 403 `paid_plan_required` on Free; 409 `nothing_to_finish` or `missing_selection`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The estimate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunAllEstimate"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"`paid_plan_required`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`nothing_to_finish` or `missing_selection`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/finish-all":{"post":{"operationId":"finishAllProject","tags":["projects"],"summary":"Finish in 1080p: upscale every draft clip, then build a new final cut","description":"A run (`run.mode` `finish`) that makes no new parts: it upscales each draft pick (credits held per clip) and builds a new final cut without the Free plan's mark, which becomes the current final and cover; the old cut stays in `state.finals`. Send the `estimate_credits` you confirmed. Progress is the project's `run`; stop it with `run-all/stop`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1 to 255 visible ASCII characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinishAllRequest"}}}},"responses":{"200":{"description":"Replay of an earlier start with this key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunAllResponse"}}}},"202":{"description":"Started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunAllResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"The balance is below the estimate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`paid_plan_required` (Free).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`run_in_progress`, `estimate_changed`, `nothing_to_finish`, `missing_selection` or `idempotency_conflict`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/run-all/stop":{"post":{"operationId":"stopRunAll","tags":["projects"],"summary":"Stop Make everything (Finish in 1080p, Generate all) after the running units","description":"Nothing new is started or charged; `run.status` goes `stopping`, then `stopped`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Stopping.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StopRunAllResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`no_active_run`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/cover":{"post":{"operationId":"chooseProjectCover","tags":["projects"],"summary":"Choose the reel's cover: a final-cut cover or a saved frame","description":"`asset_id` is one of the final cut's covers, or a frame saved from any of the project's cuts (an image of yours that a `project.reel` `covers` job of this project made). Free.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChooseCoverRequest"}}}},"responses":{"200":{"description":"The project with `cover_asset_id` set.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`not_a_cover`: neither a final-cut cover nor a saved frame of this project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/caption":{"post":{"operationId":"writeProjectCaption","tags":["projects"],"summary":"Write a caption and hashtags for the project (free)","description":"Optional `hint` steers it. This call stores nothing; save the text you keep with `PATCH /api/v1/projects/{id}` `post_caption`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteCaptionRequest"}}}},"responses":{"200":{"description":"The caption and hashtags.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteCaption"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such project (`project_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/units/{unit}/analyse":{"post":{"operationId":"analyseProjectUnit","tags":["projects"],"summary":"Suggest the items of a Realism step (`<image>.realism`)","description":"Opening the Realism step equals calling this: Threadwright looks at the image the step before picked (free, once per image) and the unit's `items` fill in (`analysis`: `analysing`, then `ready`; poll `GET .../units`). A repeat, or a call before the step before has a pick, starts nothing and returns the unit as it is. Without it the run looks at the image itself; a project's realism run is priced as plain `image.details` either way. After a failed analysis send `{ \"again\": true }` to ask again (free; at most 3 times per image, `analysis_retries_left` on the unit); your saved items are never replaced.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}},{"name":"unit","in":"path","required":true,"description":"Unit id (`shot01.take`, `shot02.seg1.clip`, `d1_morning.final`).","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyseUnitRequest"}}}},"responses":{"200":{"description":"The unit with its analysis state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyseUnitResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"`project_not_found` or `unit_not_found`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_realism`: the unit is not a Realism step.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/units/{unit}/items":{"put":{"operationId":"setProjectUnitItems","tags":["projects"],"summary":"Save the items of a Realism step (`<image>.realism`)","description":"Items are suggested automatically once `POST .../analyse` (or Make everything) has looked at the image the step before picked (`analysis`: `analysing`, then `ready`). This replaces them with your own (at most 12, each up to 300 characters); a later suggestion never overwrites what you saved. An empty list lets Threadwright choose the items when the step runs. `paste_back` (T160) is your choice to keep the person exactly as is by pasting the original back over the edit: `true` On, `false` Off, `null` Auto (Threadwright chooses, the default); send `items`, `paste_back` or both, and what you leave out stays as saved. The run (`POST .../run`, also with `overrides: {paste_back}`), Generate all and Make everything use the saved items and choice; the scale is always chosen by Threadwright. The unit shows your choice as `paste_back` and each run's result as `paste_back` on its `jobs` entry.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}},{"name":"unit","in":"path","required":true,"description":"Unit id (`shot01.take`, `shot02.seg1.clip`, `d1_morning.final`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetUnitItemsRequest"}}}},"responses":{"200":{"description":"The unit with its items.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetUnitItemsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"`project_not_found` or `unit_not_found`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`not_realism`: the unit is not a Realism step.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/units/{unit}/transcribe":{"post":{"operationId":"transcribeProjectUnit","tags":["projects"],"summary":"Transcribe the voice take you uploaded for a unit","description":"Times every word of the unit's selected take so captions can be burned in for its shot. Selecting an upload already starts this; use it to retry after a failure or when the balance was short (`transcription.state` is `failed` or `needed`). Priced as `voice.transcribe` from the take's length (`transcription.estimate_credits`). A running or finished transcription is returned with `replayed: true`, not repeated.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}},{"name":"unit","in":"path","required":true,"description":"Unit id (`shot01.take`, `shot02.seg1.clip`, `d1_morning.final`).","schema":{"type":"string"}}],"responses":{"200":{"description":"A transcription is already running or done.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscribeUnitResponse"}}}},"202":{"description":"Accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscribeUnitResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Not enough credits (`insufficient_credits`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"`project_not_found` or `unit_not_found`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`missing_selection`: no take is selected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`not_a_take` (the unit is not a voice take) or `not_an_upload` (a generated take already has word timings).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/projects/{id}/units/{unit}/select":{"post":{"operationId":"selectProjectUnit","tags":["projects"],"summary":"Choose which output of a unit is the selected one","description":"The asset must be an output of one of the unit's jobs, or an asset you uploaded (`POST /api/v1/assets/uploads`) of the kind the unit makes: an image for frames, images, references, Realism and Grade, a video for a clip (trimmed to its slot at assembly), audio for a voice take. An upload joins the unit's `candidates` (and `uploaded`) like a generated output, and later steps, the edit and assembly treat it the same. The response's `warnings` say what to know first (a clip shorter than its `slot_seconds` is slowed slightly and held; a talking clip's own sound is not used); a voice take you upload has no word timings, so selecting it starts its transcription (`voice.transcribe`, paid by the minute, shown as the unit's `transcription`; free if that asset was transcribed before), and once it is done captions burn in for its shot like a generated take. If the balance is short the select stands, `warnings` says so and `POST .../transcribe` starts it later. A Realism or Grade unit also lists the pick of the step before it as its first candidate (`from_previous`): selecting that skips the step. A unit nobody selected in follows the step before it.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Project id (`prj_...`).","schema":{"type":"string"}},{"name":"unit","in":"path","required":true,"description":"Unit id (`shot01.take`, `shot02.seg1.clip`, `d1_morning.final`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelectUnitRequest"}}}},"responses":{"200":{"description":"The unit with its selection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelectUnitResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"`project_not_found`, `unit_not_found` or `asset_not_found`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`not_a_candidate`, `wrong_asset_kind`, `asset_not_ready`, `duration_unknown`, `upload_too_short` (under 0.5 s) or `upload_too_long` (over 300 s).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/clips/{id}/finish/estimate":{"post":{"operationId":"estimateClipFinish","tags":["clips"],"summary":"Price both ways to finish a draft clip","description":"Talking and B-roll clips render as drafts at their model's draft resolution. This returns `draft`, its `resolution` and both `options` (`upscale`, `regenerate`) with their credits, a one-line `note` and whether each is `available` (`reason` when not). The body may be empty; `resolution` prices a regenerate at that size.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["jobs","projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"The draft clip (`asset_...`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinishEstimateRequest"}}}},"responses":{"200":{"description":"The options.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinishEstimate"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"`asset_not_found`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`wrong_asset_kind` or `asset_not_ready`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/clips/{id}/finish":{"post":{"operationId":"finishClip","tags":["clips"],"summary":"Finish a draft clip: upscale it or make it again at full resolution","description":"`upscale` keeps this exact take, sharper. `regenerate` makes it again from the same inputs at the model's full resolution (or `resolution`); motion and lip-sync may differ. Submits a job and returns it; poll it like any job. A project clip's draft becomes the unit's pick and reads as the finished clip once the job succeeds (`unit`). Same `Idempotency-Key` as `POST /api/v1/jobs`.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["jobs","projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"The draft clip (`asset_...`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"1 to 255 visible ASCII characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinishClipRequest"}}}},"responses":{"200":{"description":"Replay of an earlier finish with this key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinishClip"}}}},"202":{"description":"Accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinishClip"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Not enough credits (`insufficient_credits`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"`asset_not_found`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`not_a_draft` or `idempotency_conflict`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`finish_unavailable`, `wrong_asset_kind` or `asset_not_ready`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/ideas":{"get":{"operationId":"listIdeas","tags":["ideas"],"summary":"List your idea sessions, newest first","description":"A token with the `projects` scope can read too.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"cursor","in":"query","required":false,"description":"The `next_cursor` of the previous page.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"character","in":"query","required":false,"description":"Only sessions for this character (`chr_...`).","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Case-insensitive contains-search on the title (at most 100 characters; % and _ match themselves).","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"created_after","in":"query","required":false,"description":"Only items created at or after this ISO 8601 UTC time (inclusive), e.g. `2026-10-01T00:00:00Z`. Combines with the cursor; order stays newest first. A bad value is 400 `invalid_request` naming the field.","schema":{"type":"string","format":"date-time"}},{"name":"created_before","in":"query","required":false,"description":"Only items created before this ISO 8601 UTC time (exclusive).","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"A page of idea sessions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdeaList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"default":{"$ref":"#/components/responses/Error"}}},"post":{"operationId":"createIdea","tags":["ideas"],"summary":"Start an idea session","description":"`state` is your own working state (formats, ideas, the developed idea under `developed`): any JSON object up to 64 KB.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIdeaRequest"}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Idea"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"description":"`invalid_character`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/ideas/{id}":{"get":{"operationId":"getIdea","tags":["ideas"],"summary":"One idea session","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["read"],"parameters":[{"name":"id","in":"path","required":true,"description":"Idea id (`idea_...`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The idea session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Idea"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such idea (`idea_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}},"patch":{"operationId":"updateIdea","tags":["ideas"],"summary":"Change the title, step, character or state of an idea session","description":"Each field sent replaces the stored one; `state` as a whole.","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Idea id (`idea_...`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateIdeaRequest"}}}},"responses":{"200":{"description":"The idea session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Idea"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such idea (`idea_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`invalid_character`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}},"delete":{"operationId":"deleteIdea","tags":["ideas"],"summary":"Delete an idea session (a project made from it stays)","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Idea id (`idea_...`).","schema":{"type":"string"}}],"responses":{"204":{"description":"Done; no body."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such idea (`idea_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}},"/api/v1/ideas/{id}/project":{"post":{"operationId":"ideaToProject","tags":["ideas"],"summary":"Turn the developed idea into a reel project","description":"Creates a reel project for the session's character, titled with `state.developed.title` and with `spec.duration_seconds` (body, else `state.duration_seconds`, else `state.suggested_seconds`, else the catalog default) and `spec.idea_id`; the session gets `project_id` and `step: done`. Then write its shots with `assist.write_reel_script` (`project_id`, `format_id`, the developed idea as `description`) and save them with `PATCH /api/v1/projects/{id}`; then price and start everything with `POST /api/v1/projects/{id}/run-all/estimate` and `run-all` (the script is a job, so this route cannot start the run itself).","security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-scopes":["projects"],"parameters":[{"name":"id","in":"path","required":true,"description":"Idea id (`idea_...`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdeaToProjectRequest"}}}},"responses":{"201":{"description":"The new project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"No such idea (`idea_not_found`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`idea_not_developed` (no developed idea in `state.developed`), `already_converted` (the session has a project) or `character_required`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"`invalid_spec`: `duration_seconds` is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"$ref":"#/components/responses/Error"}}}}},"components":{"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","minLength":1},"message":{"type":"string"},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false},"Health":{"type":"object","properties":{"ok":{"type":"boolean"},"version":{"type":"string","minLength":1},"db":{"type":"boolean"}},"required":["ok","version","db"],"additionalProperties":false},"Me":{"type":"object","properties":{"account":{"type":"object","properties":{"id":{"type":"string","minLength":1},"email":{"type":["string","null"]},"display_name":{"type":["string","null"]},"plan":{"type":"string","minLength":1},"role":{"type":"string","enum":["user","owner"]},"status":{"type":"string","enum":["active","suspended","closed"]},"created_at":{"type":"string"},"terms_version":{"type":["string","null"]},"terms_accepted_at":{"type":["string","null"]}},"required":["id","email","display_name","plan","role","status","created_at","terms_version","terms_accepted_at"],"additionalProperties":false},"via":{"type":"string","enum":["session","token"]},"scopes":{"type":"array","items":{"type":"string"}}},"required":["account","via","scopes"],"additionalProperties":false},"EmailStartRequest":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"next":{"type":"string","format":"starts_with","pattern":"^\\/.*"},"turnstile_token":{"type":"string","minLength":1},"terms_version":{"type":"string","minLength":1,"maxLength":32}},"required":["email"]},"TokenList":{"type":"object","properties":{"tokens":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"prefix":{"type":"string","minLength":1},"scopes":{"type":"array","items":{"type":"string","enum":["read","jobs","assets","characters","projects","wallet:read"]}},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"expires_at":{"type":["string","null"]}},"required":["id","name","prefix","scopes","created_at","last_used_at","expires_at"],"additionalProperties":false}}},"required":["tokens"],"additionalProperties":false},"CreateTokenRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64},"scopes":{"minItems":1,"type":"array","items":{"type":"string","enum":["read","jobs","assets","characters","projects","wallet:read"]}},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"}},"required":["name"]},"CreateTokenResponse":{"type":"object","properties":{"token":{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"prefix":{"type":"string","minLength":1},"scopes":{"type":"array","items":{"type":"string","enum":["read","jobs","assets","characters","projects","wallet:read"]}},"created_at":{"type":"string"},"last_used_at":{"type":["string","null"]},"expires_at":{"type":["string","null"]}},"required":["id","name","prefix","scopes","created_at","last_used_at","expires_at"],"additionalProperties":false},"secret":{"type":"string","format":"starts_with","pattern":"^smp_.*"}},"required":["token","secret"],"additionalProperties":false},"UpdateMeRequest":{"type":"object","properties":{"display_name":{"type":"string","minLength":1,"maxLength":60}},"required":["display_name"],"additionalProperties":false},"AcceptTermsRequest":{"type":"object","properties":{"terms_version":{"type":"string","const":"2026-10-29"}},"required":["terms_version"],"additionalProperties":false},"AcceptTermsResponse":{"type":"object","properties":{"terms_version":{"type":"string"},"terms_accepted_at":{"type":"string"}},"required":["terms_version","terms_accepted_at"],"additionalProperties":false},"DeleteAccountRequest":{"type":"object","properties":{"confirm":{"type":"string","minLength":1,"maxLength":320}},"required":["confirm"],"additionalProperties":false},"DeleteAccountResponse":{"type":"object","properties":{"status":{"type":"string","enum":["deleting","deleted"]},"retain_until":{"type":"string"}},"required":["status","retain_until"],"additionalProperties":false},"Wallet":{"type":"object","properties":{"available":{"type":"integer","minimum":0,"maximum":9007199254740991},"held":{"type":"integer","minimum":0,"maximum":9007199254740991},"by_kind":{"type":"object","propertyNames":{"type":"string","enum":["subscription","bundle","promo"]},"additionalProperties":{"type":"integer","minimum":0,"maximum":9007199254740991}},"next_expiry":{"anyOf":[{"type":"object","properties":{"credits":{"type":"integer","minimum":0,"maximum":9007199254740991},"expires_at":{"type":"string"},"kind":{"type":"string","enum":["subscription","bundle","promo"]}},"required":["credits","expires_at","kind"],"additionalProperties":false},{"type":"null"}]},"period":{"type":"object","properties":{"credits_granted":{"type":"integer","minimum":0,"maximum":9007199254740991},"starts_at":{"type":["string","null"]},"ends_at":{"type":["string","null"]}},"required":["credits_granted","starts_at","ends_at"],"additionalProperties":false}},"required":["available","held","by_kind","next_expiry","period"],"additionalProperties":false},"WalletHistory":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"type":{"type":"string","enum":["grant","hold","capture","release","refund","adjust","expire"]},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"job_id":{"type":["string","null"]},"note":{"type":["string","null"]},"created_at":{"type":"string"}},"required":["id","type","credits","job_id","note","created_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]}},"required":["entries","next_cursor"],"additionalProperties":false},"Asset":{"type":"object","properties":{"asset":{"type":"object","properties":{"id":{"type":"string","minLength":1},"kind":{"type":"string","enum":["image","video","audio","file"]},"status":{"type":"string","enum":["pending","ready","missing"]},"moderation":{"type":"string","enum":["checking","clear","blocked"]},"mime":{"type":"string","minLength":1},"bytes":{"type":"integer","minimum":0,"maximum":9007199254740991},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"duration_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"sha256":{"type":["string","null"]},"source":{"type":"string","enum":["upload","job"]},"job_id":{"type":["string","null"]},"project_id":{"type":["string","null"]},"parent_ids":{"type":"array","items":{"type":"string"}},"library_audio_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","kind","status","mime","bytes","width","height","duration_ms","sha256","source","job_id","project_id","parent_ids","created_at","updated_at"],"additionalProperties":false}},"required":["asset"],"additionalProperties":false},"AssetDetail":{"type":"object","properties":{"asset":{"type":"object","properties":{"id":{"type":"string","minLength":1},"kind":{"type":"string","enum":["image","video","audio","file"]},"status":{"type":"string","enum":["pending","ready","missing"]},"moderation":{"type":"string","enum":["checking","clear","blocked"]},"mime":{"type":"string","minLength":1},"bytes":{"type":"integer","minimum":0,"maximum":9007199254740991},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"duration_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"sha256":{"type":["string","null"]},"source":{"type":"string","enum":["upload","job"]},"job_id":{"type":["string","null"]},"project_id":{"type":["string","null"]},"parent_ids":{"type":"array","items":{"type":"string"}},"library_audio_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","kind","status","mime","bytes","width","height","duration_ms","sha256","source","job_id","project_id","parent_ids","created_at","updated_at"],"additionalProperties":false},"download_url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Presigned GET, about 10 minutes; null if not ready."},"download_expires_at":{"type":["string","null"]},"preview":{"description":"Free plan: a watermarked preview, not a download.","type":"boolean"}},"required":["asset","download_url","download_expires_at"],"additionalProperties":false},"AssetList":{"type":"object","properties":{"assets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"kind":{"type":"string","enum":["image","video","audio","file"]},"status":{"type":"string","enum":["pending","ready","missing"]},"moderation":{"type":"string","enum":["checking","clear","blocked"]},"mime":{"type":"string","minLength":1},"bytes":{"type":"integer","minimum":0,"maximum":9007199254740991},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"duration_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"sha256":{"type":["string","null"]},"source":{"type":"string","enum":["upload","job"]},"job_id":{"type":["string","null"]},"project_id":{"type":["string","null"]},"parent_ids":{"type":"array","items":{"type":"string"}},"library_audio_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","kind","status","mime","bytes","width","height","duration_ms","sha256","source","job_id","project_id","parent_ids","created_at","updated_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]}},"required":["assets","next_cursor"],"additionalProperties":false},"CreateUploadRequest":{"type":"object","properties":{"mime":{"type":"string","minLength":1},"bytes":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"filename":{"type":"string","minLength":1,"maxLength":255},"sha256":{"type":"string","pattern":"^[0-9a-f]{64}$"},"project_id":{"description":"Attach the upload to a project (`prj_...`).","type":"string"}},"required":["mime","bytes"]},"CreateUploadResponse":{"type":"object","properties":{"asset_id":{"type":"string"},"upload":{"oneOf":[{"type":"object","properties":{"method":{"type":"string","const":"single"},"url":{"type":"string","format":"uri"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"expires_at":{"type":"string"}},"required":["method","url","headers","expires_at"],"additionalProperties":false},{"type":"object","properties":{"method":{"type":"string","const":"multipart"},"upload_id":{"type":"string","minLength":1},"part_size":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"parts":{"minItems":1,"type":"array","items":{"type":"object","properties":{"part_number":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"url":{"type":"string","format":"uri"},"size":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["part_number","url","size"],"additionalProperties":false}},"expires_at":{"type":"string"}},"required":["method","upload_id","part_size","parts","expires_at"],"additionalProperties":false}]}},"required":["asset_id","upload"],"additionalProperties":false},"CompleteUploadRequest":{"type":"object","properties":{"upload_id":{"type":"string","minLength":1},"parts":{"type":"array","items":{"type":"object","properties":{"part_number":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"etag":{"type":"string","minLength":1}},"required":["part_number","etag"]}}}},"Character":{"type":"object","properties":{"character":{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string"},"description":{"type":"string"},"negative_hints":{"type":"string"},"style_suffix":{"type":"string"},"broll_negative":{"type":"string"},"voice_id":{"type":["string","null"]},"voice":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"voice_settings":{"anyOf":[{"type":"object","properties":{"stability":{"type":"number","minimum":0,"maximum":1},"similarity_boost":{"type":"number","minimum":0,"maximum":1}},"additionalProperties":false},{"type":"null"}]},"look":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"routing":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"captions":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"title_card":{"type":["string","null"]},"audio_name":{"type":["string","null"]},"niche":{"type":["string","null"]},"refs":{"type":"object","properties":{"identity":{"type":"array","items":{"type":"string"}},"detail":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"context":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"hero":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"required":["identity"],"additionalProperties":false},"upload_declaration":{"anyOf":[{"type":"object","properties":{"version":{"type":"string"},"accepted_at":{"type":"string"}},"required":["version","accepted_at"],"additionalProperties":false},{"type":"null"}]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","description","negative_hints","style_suffix","broll_negative","voice_id","voice","voice_settings","look","routing","captions","title_card","audio_name","refs","created_at","updated_at"],"additionalProperties":false}},"required":["character"],"additionalProperties":false},"CharacterList":{"type":"object","properties":{"characters":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string"},"description":{"type":"string"},"negative_hints":{"type":"string"},"style_suffix":{"type":"string"},"broll_negative":{"type":"string"},"voice_id":{"type":["string","null"]},"voice":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"voice_settings":{"anyOf":[{"type":"object","properties":{"stability":{"type":"number","minimum":0,"maximum":1},"similarity_boost":{"type":"number","minimum":0,"maximum":1}},"additionalProperties":false},{"type":"null"}]},"look":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"routing":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"captions":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"title_card":{"type":["string","null"]},"audio_name":{"type":["string","null"]},"niche":{"type":["string","null"]},"refs":{"type":"object","properties":{"identity":{"type":"array","items":{"type":"string"}},"detail":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"context":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"hero":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"required":["identity"],"additionalProperties":false},"upload_declaration":{"anyOf":[{"type":"object","properties":{"version":{"type":"string"},"accepted_at":{"type":"string"}},"required":["version","accepted_at"],"additionalProperties":false},{"type":"null"}]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","description","negative_hints","style_suffix","broll_negative","voice_id","voice","voice_settings","look","routing","captions","title_card","audio_name","refs","created_at","updated_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]}},"required":["characters","next_cursor"],"additionalProperties":false},"CreateCharacterRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"wish":{"description":"The character in one line (\"a 30-year-old surfer who teaches beginners\"). Free: fills in what you leave out. `description` and `niche` are written from it, a voice is picked from `GET /api/v1/voices` by gender, age and vibe, and the finishing fields get defaults. Anything you send yourself wins. Only on create.","type":"string","minLength":3,"maxLength":500},"description":{"type":"string","maxLength":4000,"description":"The character's look in words (`character_description`): prepended to prompts."},"negative_hints":{"type":"string","maxLength":2000,"description":"What to avoid; appended after the prompt."},"style_suffix":{"type":"string","maxLength":1000,"description":"Photographic style appended to every prompt."},"broll_negative":{"type":"string","maxLength":1000,"description":"Negative text for B-roll prompts."},"voice_id":{"anyOf":[{"type":"string","minLength":1,"maxLength":128,"description":"A `voice_id` from `GET /api/v1/voices`."},{"type":"null"}]},"voice_settings":{"anyOf":[{"type":"object","properties":{"stability":{"type":"number","minimum":0,"maximum":1},"similarity_boost":{"type":"number","minimum":0,"maximum":1}},"additionalProperties":false},{"type":"null"}]},"look":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"`finish.develop` look overrides (strength, wb, ev, ...)."},"routing":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"Model key per tool id, for example `{ \"image.edit\": \"nano_banana_edit\" }`."},"captions":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Caption style, as `finish.captions`."},{"type":"null"}]},"title_card":{"anyOf":[{"type":"string","maxLength":120,"description":"Title card template, e.g. `FIELD LOG #{episode_no}`."},{"type":"null"}]},"audio_name":{"anyOf":[{"type":"string","maxLength":200,"description":"Original-audio name template for publishing."},{"type":"null"}]},"niche":{"anyOf":[{"type":"string","maxLength":500,"description":"The page concept you work in, in your own words (what the page is about and for whom); the idea helpers read it."},{"type":"null"}]},"refs":{"type":"object","properties":{"identity":{"minItems":1,"maxItems":6,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"detail":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"context":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"hero":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"required":["identity"],"additionalProperties":false},"upload_declaration":{"type":"object","properties":{"version":{"type":"string","minLength":1,"maxLength":40,"description":"The declaration version accepted (`UPLOAD_DECLARATION_VERSION`)."}},"required":["version"],"additionalProperties":false,"description":"Required (422 `declaration_required`) when `refs` adds an uploaded image, or one made directly from an upload: the person confirms the character is original, not a real person, and theirs to use."}},"required":["name"],"additionalProperties":false},"UpdateCharacterRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"description":{"type":"string","maxLength":4000,"description":"The character's look in words (`character_description`): prepended to prompts."},"negative_hints":{"type":"string","maxLength":2000,"description":"What to avoid; appended after the prompt."},"style_suffix":{"type":"string","maxLength":1000,"description":"Photographic style appended to every prompt."},"broll_negative":{"type":"string","maxLength":1000,"description":"Negative text for B-roll prompts."},"voice_id":{"anyOf":[{"type":"string","minLength":1,"maxLength":128,"description":"A `voice_id` from `GET /api/v1/voices`."},{"type":"null"}]},"voice_settings":{"anyOf":[{"type":"object","properties":{"stability":{"type":"number","minimum":0,"maximum":1},"similarity_boost":{"type":"number","minimum":0,"maximum":1}},"additionalProperties":false},{"type":"null"}]},"look":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"`finish.develop` look overrides (strength, wb, ev, ...)."},"routing":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"Model key per tool id, for example `{ \"image.edit\": \"nano_banana_edit\" }`."},"captions":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Caption style, as `finish.captions`."},{"type":"null"}]},"title_card":{"anyOf":[{"type":"string","maxLength":120,"description":"Title card template, e.g. `FIELD LOG #{episode_no}`."},{"type":"null"}]},"audio_name":{"anyOf":[{"type":"string","maxLength":200,"description":"Original-audio name template for publishing."},{"type":"null"}]},"niche":{"anyOf":[{"type":"string","maxLength":500,"description":"The page concept you work in, in your own words (what the page is about and for whom); the idea helpers read it."},{"type":"null"}]},"refs":{"type":"object","properties":{"identity":{"minItems":1,"maxItems":6,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"detail":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"context":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"hero":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"required":["identity"],"additionalProperties":false},"upload_declaration":{"type":"object","properties":{"version":{"type":"string","minLength":1,"maxLength":40,"description":"The declaration version accepted (`UPLOAD_DECLARATION_VERSION`)."}},"required":["version"],"additionalProperties":false,"description":"Required (422 `declaration_required`) when `refs` adds an uploaded image, or one made directly from an upload: the person confirms the character is original, not a real person, and theirs to use."}},"additionalProperties":false},"VoiceList":{"type":"object","properties":{"voices":{"type":"array","items":{"type":"object","properties":{"voice_id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"description":{"type":"string"},"preview_url":{"type":"string"}},"required":["voice_id","name"],"additionalProperties":false}}},"required":["voices"],"additionalProperties":false},"VoiceSuggestion":{"type":"object","properties":{"voice":{"anyOf":[{"type":"object","properties":{"voice_id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"description":{"type":"string"},"preview_url":{"type":"string"}},"required":["voice_id","name"],"additionalProperties":false},{"type":"null"}]}},"required":["voice"],"additionalProperties":false},"LibraryCharacterList":{"type":"object","properties":{"characters":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string"},"description":{"type":"string"},"negative_hints":{"type":"string"},"style_suffix":{"type":"string"},"broll_negative":{"type":"string"},"niche":{"type":"string"},"gender":{"type":"string","enum":["female","male","non_binary"]},"age_band":{"type":"string","enum":["18_24","25_34","35_44","45_54","55_plus"]},"voice_id":{"type":["string","null"]},"voice":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"preview_url":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"voice_settings":{"anyOf":[{"type":"object","properties":{"stability":{"type":"number","minimum":0,"maximum":1},"similarity_boost":{"type":"number","minimum":0,"maximum":1}},"additionalProperties":false},{"type":"null"}]},"look":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"routing":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"captions":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"title_card":{"type":["string","null"]},"audio_name":{"type":["string","null"]},"images":{"type":"object","properties":{"front":{"type":"string"},"profile":{"type":"string"},"full_body":{"type":"string"},"hero":{"type":"string"},"locations":{"type":"array","items":{"type":"string"}}},"required":["front","profile","full_body","locations"],"additionalProperties":false},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","description","negative_hints","style_suffix","broll_negative","niche","gender","age_band","voice_id","voice","voice_settings","look","routing","captions","title_card","audio_name","images","created_at","updated_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]}},"required":["characters","next_cursor"],"additionalProperties":false},"LibraryCharacter":{"type":"object","properties":{"character":{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string"},"description":{"type":"string"},"negative_hints":{"type":"string"},"style_suffix":{"type":"string"},"broll_negative":{"type":"string"},"niche":{"type":"string"},"gender":{"type":"string","enum":["female","male","non_binary"]},"age_band":{"type":"string","enum":["18_24","25_34","35_44","45_54","55_plus"]},"voice_id":{"type":["string","null"]},"voice":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"preview_url":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"voice_settings":{"anyOf":[{"type":"object","properties":{"stability":{"type":"number","minimum":0,"maximum":1},"similarity_boost":{"type":"number","minimum":0,"maximum":1}},"additionalProperties":false},{"type":"null"}]},"look":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"routing":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"captions":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"title_card":{"type":["string","null"]},"audio_name":{"type":["string","null"]},"images":{"type":"object","properties":{"front":{"type":"string"},"profile":{"type":"string"},"full_body":{"type":"string"},"hero":{"type":"string"},"locations":{"type":"array","items":{"type":"string"}}},"required":["front","profile","full_body","locations"],"additionalProperties":false},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","description","negative_hints","style_suffix","broll_negative","niche","gender","age_band","voice_id","voice","voice_settings","look","routing","captions","title_card","audio_name","images","created_at","updated_at"],"additionalProperties":false}},"required":["character"],"additionalProperties":false},"UseLibraryCharacter":{"type":"object","properties":{"character_id":{"type":"string","minLength":1},"character":{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string"},"description":{"type":"string"},"negative_hints":{"type":"string"},"style_suffix":{"type":"string"},"broll_negative":{"type":"string"},"voice_id":{"type":["string","null"]},"voice":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"voice_settings":{"anyOf":[{"type":"object","properties":{"stability":{"type":"number","minimum":0,"maximum":1},"similarity_boost":{"type":"number","minimum":0,"maximum":1}},"additionalProperties":false},{"type":"null"}]},"look":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"routing":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"captions":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"title_card":{"type":["string","null"]},"audio_name":{"type":["string","null"]},"niche":{"type":["string","null"]},"refs":{"type":"object","properties":{"identity":{"type":"array","items":{"type":"string"}},"detail":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"context":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"hero":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"required":["identity"],"additionalProperties":false},"upload_declaration":{"anyOf":[{"type":"object","properties":{"version":{"type":"string"},"accepted_at":{"type":"string"}},"required":["version","accepted_at"],"additionalProperties":false},{"type":"null"}]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","description","negative_hints","style_suffix","broll_negative","voice_id","voice","voice_settings","look","routing","captions","title_card","audio_name","refs","created_at","updated_at"],"additionalProperties":false}},"required":["character_id","character"],"additionalProperties":false},"LibraryAudioList":{"type":"object","properties":{"audio":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"kind":{"type":"string","enum":["ambience","music"]},"name":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"seconds":{"type":"number"},"loop":{"type":"boolean"},"source":{"type":"string","enum":["generated","licensed"]},"licence":{"type":["string","null"]},"licence_url":{"type":["string","null"]},"loudness_lufs":{"type":["number","null"]},"preview_url":{"type":"string"}},"required":["id","kind","name","tags","seconds","loop","source","licence","licence_url","loudness_lufs","preview_url"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]}},"required":["audio","next_cursor"],"additionalProperties":false},"UseLibraryAudio":{"type":"object","properties":{"asset_id":{"type":"string","minLength":1},"library_id":{"type":"string","minLength":1},"asset":{"type":"object","properties":{"id":{"type":"string","minLength":1},"kind":{"type":"string","enum":["image","video","audio","file"]},"status":{"type":"string","enum":["pending","ready","missing"]},"moderation":{"type":"string","enum":["checking","clear","blocked"]},"mime":{"type":"string","minLength":1},"bytes":{"type":"integer","minimum":0,"maximum":9007199254740991},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"duration_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"sha256":{"type":["string","null"]},"source":{"type":"string","enum":["upload","job"]},"job_id":{"type":["string","null"]},"project_id":{"type":["string","null"]},"parent_ids":{"type":"array","items":{"type":"string"}},"library_audio_id":{"type":"string"},"created_at":{"type":"string"}},"required":["id","kind","status","mime","bytes","width","height","duration_ms","sha256","source","job_id","project_id","parent_ids","created_at"],"additionalProperties":false}},"required":["asset_id","library_id","asset"],"additionalProperties":false},"Project":{"type":"object","properties":{"project":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^prj_[0-9a-f-]{36}$"},"title":{"type":"string"},"status":{"type":"string","enum":["draft","in_progress","completed"]},"cover_asset_id":{"type":["string","null"]},"character_id":{"type":["string","null"]},"state":{"type":"object","properties":{"units":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"jobs":{"type":"array","items":{"type":"string"},"description":"Job ids (`job_...`) run for the unit, oldest first."},"selected":{"description":"The chosen output asset id.","type":["string","null"]}},"required":["jobs","selected"],"additionalProperties":false}},"drafts":{"type":"array","items":{"type":"string"},"description":"Job ids of `project.reel` draft runs."},"finals":{"type":"array","items":{"type":"string"},"description":"Job ids of `project.reel` final or `project.post` runs."},"post_caption":{"description":"The saved post caption and hashtags, when there is one (T141).","type":"object","properties":{"text":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"},"description":"Each with its leading `#`."},"edited_at":{"description":"When the creator last edited it; null while it is as the writer wrote it.","type":["string","null"]}},"required":["text","hashtags","edited_at"],"additionalProperties":false}},"required":["units","drafts","finals"],"additionalProperties":false},"run":{"anyOf":[{"type":"object","properties":{"job_id":{"type":"string","description":"The run's own job (`job_...`); it is free."},"status":{"type":"string","enum":["running","stopping","stopped","succeeded","failed"]},"estimate_credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The total the user confirmed."},"started_at":{"type":"string"},"finished_at":{"type":["string","null"]},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"done":{"type":"integer","minimum":0,"maximum":9007199254740991},"running":{"type":"integer","minimum":0,"maximum":9007199254740991},"failed":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Failed units, and units after them that could not run."}},"required":["step","total","done","running","failed"],"additionalProperties":false}},"failures":{"type":"array","items":{"type":"object","properties":{"unit":{"type":"string","description":"The unit id, or `build` for the final cut."},"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"code":{"type":"string"},"message":{"type":"string"}},"required":["unit","step","code","message"],"additionalProperties":false}},"build_job_id":{"description":"Reels: the final build's job, once started.","type":["string","null"]},"mode":{"description":"`finish`: a Finish in 1080p run (T88); `step`: Generate all on one step (T103); left out for Make everything.","type":"string","enum":["all","finish","step"]},"step":{"description":"A `step` run: the step it covers (T103).","type":"string","enum":["voice","frames","realism","grade","clips","images","variants"]}},"required":["job_id","status","estimate_credits","started_at","finished_at","steps","failures","build_job_id"],"additionalProperties":false},{"type":"null"}]},"sound_suggestion":{"anyOf":[{"type":"object","properties":{"ambience_tags":{"type":"array","items":{"type":"string"}},"music_tags":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"ambience_id":{"type":["string","null"]},"music_id":{"type":["string","null"]},"apply_music":{"type":"boolean"}},"required":["ambience_tags","music_tags","ambience_id","music_id","apply_music"],"additionalProperties":false},{"type":"null"}]},"final_from_drafts":{"type":"boolean"},"final_marked":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"kind":{"type":"string","const":"reel"},"spec":{"type":"object","properties":{"duration_seconds":{"description":"Length of the finished reel in seconds, within `projects.reel.duration_seconds` of the catalog; required when a reel is saved with a spec.","type":"number","exclusiveMinimum":0},"references":{"default":[],"description":"Scene references, made before the frames that link them (`{ reference }` refs); none when no shots share a scene.","maxItems":6,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Reference id, unique in the project (`ref1`)."},"title":{"type":"string","minLength":1,"maxLength":60,"description":"Short name shown to people (`Kitchen`)."},"kind":{"type":"string","enum":["location","outfit","object"],"description":"location: the place, no person; outfit: the character in an outfit; object: a key object."},"prompt":{"description":"References you add: what the image shows, in your words. Absent on the script designer's references.","type":"string","minLength":1,"maxLength":2000}},"required":["id","title","kind"],"additionalProperties":false}},"shots":{"default":[],"maxItems":40,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Shot id, unique in the project (`shot01`)."},"type":{"type":"string","enum":["talking","vo_broll"]},"audio":{"type":"string","minLength":1,"maxLength":2500,"description":"The script text the voice says."},"pause_before":{"default":0,"description":"Silent lead-in (s).","type":"number","minimum":0,"maximum":30},"pause_after":{"default":0,"description":"Silent hold after the take (s).","type":"number","minimum":0,"maximum":30},"first_frame_prompt":{"description":"talking: the frame.","type":"string","minLength":1,"maxLength":4000},"first_frame_refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"motion_prompt":{"description":"talking: how it moves.","type":"string","minLength":1,"maxLength":2500},"clip_seconds":{"description":"Clip length in seconds, from what the routed video model allows; default: the smallest allowed length that covers the clip's share (B-roll: a slot a few hundredths past an allowed length gets that length and the cut slows it slightly; talking: the whole take).","type":"number","exclusiveMinimum":0,"maximum":60},"clip_model":{"description":"The clip's model (`video.talking` or `video.broll` `model`, e.g. `kling_avatar`); default: the tool's default model.","type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"},"segments":{"description":"vo_broll only.","minItems":1,"maxItems":6,"type":"array","items":{"type":"object","properties":{"duration":{"default":1,"description":"Share of the shot's length; shares are normalised, so 1, 1, 2 gives 25/25/50 %.","type":"number","exclusiveMinimum":0,"maximum":100},"first_frame_prompt":{"type":"string","minLength":1,"maxLength":4000},"first_frame_refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"motion_prompt":{"type":"string","minLength":1,"maxLength":2500},"clip_seconds":{"description":"Clip length in seconds, from what the routed video model allows; default: the smallest allowed length that covers the clip's share (B-roll: a slot a few hundredths past an allowed length gets that length and the cut slows it slightly; talking: the whole take).","type":"number","exclusiveMinimum":0,"maximum":60},"clip_model":{"description":"The clip's model (`video.talking` or `video.broll` `model`, e.g. `kling_avatar`); default: the tool's default model.","type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"}},"required":["duration","first_frame_prompt","first_frame_refs","motion_prompt"],"additionalProperties":false}}},"required":["id","type","audio","pause_before","pause_after","first_frame_refs"],"additionalProperties":false}},"enhance_prompts":{"default":true,"description":"Enhance prompt before generation for every frame, image and clip of the project (default true): each run's prompt is rewritten for its model first, at the catalog's enhancement price per run (`POST /api/v1/offerings/{id}/estimate` shows it). The Free plan always enhances, at no credit cost.","type":"boolean"},"idea_id":{"description":"The Idea Studio session (`idea_...`) the reel was made from, when there is one.","type":"string","pattern":"^idea_[0-9a-f-]{36}$"},"edit":{"default":{"episode_no":0},"type":"object","properties":{"episode_no":{"default":0,"description":"Number for the title card.","type":"integer","minimum":0,"maximum":9999},"fps":{"type":"integer","minimum":1,"maximum":60},"tail_seconds":{"type":"number","minimum":0,"maximum":30},"acoustics":{"type":"string","enum":["outdoor","indoor_small","indoor_medium","indoor_large"]},"mic_distance":{"type":"string","enum":["close","medium","far"]},"punch_ins":{"type":"boolean"},"title_card":{"description":"Overrides the character's title card.","type":"string","maxLength":80},"ambience":{"anyOf":[{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."},"level":{"type":"number","minimum":0,"maximum":10}},"required":["asset_id"],"additionalProperties":false},{"type":"null"}]},"music":{"anyOf":[{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."},"stop_at":{"description":"Shot id where the music stops.","type":"string","maxLength":64},"level":{"type":"number","minimum":0,"maximum":10}},"required":["asset_id"],"additionalProperties":false},{"type":"null"}]},"captions":{"description":"Caption style; null burns in none.","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"look":{"description":"`finish.develop` look for clips; default: the character's.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["episode_no"],"additionalProperties":false}},"required":["references","shots","enhance_prompts","edit"],"additionalProperties":false}},"required":["id","title","status","cover_asset_id","character_id","state","created_at","updated_at","kind","spec"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","pattern":"^prj_[0-9a-f-]{36}$"},"title":{"type":"string"},"status":{"type":"string","enum":["draft","in_progress","completed"]},"cover_asset_id":{"type":["string","null"]},"character_id":{"type":["string","null"]},"state":{"type":"object","properties":{"units":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"jobs":{"type":"array","items":{"type":"string"},"description":"Job ids (`job_...`) run for the unit, oldest first."},"selected":{"description":"The chosen output asset id.","type":["string","null"]}},"required":["jobs","selected"],"additionalProperties":false}},"drafts":{"type":"array","items":{"type":"string"},"description":"Job ids of `project.reel` draft runs."},"finals":{"type":"array","items":{"type":"string"},"description":"Job ids of `project.reel` final or `project.post` runs."},"post_caption":{"description":"The saved post caption and hashtags, when there is one (T141).","type":"object","properties":{"text":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"},"description":"Each with its leading `#`."},"edited_at":{"description":"When the creator last edited it; null while it is as the writer wrote it.","type":["string","null"]}},"required":["text","hashtags","edited_at"],"additionalProperties":false}},"required":["units","drafts","finals"],"additionalProperties":false},"run":{"anyOf":[{"type":"object","properties":{"job_id":{"type":"string","description":"The run's own job (`job_...`); it is free."},"status":{"type":"string","enum":["running","stopping","stopped","succeeded","failed"]},"estimate_credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The total the user confirmed."},"started_at":{"type":"string"},"finished_at":{"type":["string","null"]},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"done":{"type":"integer","minimum":0,"maximum":9007199254740991},"running":{"type":"integer","minimum":0,"maximum":9007199254740991},"failed":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Failed units, and units after them that could not run."}},"required":["step","total","done","running","failed"],"additionalProperties":false}},"failures":{"type":"array","items":{"type":"object","properties":{"unit":{"type":"string","description":"The unit id, or `build` for the final cut."},"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"code":{"type":"string"},"message":{"type":"string"}},"required":["unit","step","code","message"],"additionalProperties":false}},"build_job_id":{"description":"Reels: the final build's job, once started.","type":["string","null"]},"mode":{"description":"`finish`: a Finish in 1080p run (T88); `step`: Generate all on one step (T103); left out for Make everything.","type":"string","enum":["all","finish","step"]},"step":{"description":"A `step` run: the step it covers (T103).","type":"string","enum":["voice","frames","realism","grade","clips","images","variants"]}},"required":["job_id","status","estimate_credits","started_at","finished_at","steps","failures","build_job_id"],"additionalProperties":false},{"type":"null"}]},"sound_suggestion":{"anyOf":[{"type":"object","properties":{"ambience_tags":{"type":"array","items":{"type":"string"}},"music_tags":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"ambience_id":{"type":["string","null"]},"music_id":{"type":["string","null"]},"apply_music":{"type":"boolean"}},"required":["ambience_tags","music_tags","ambience_id","music_id","apply_music"],"additionalProperties":false},{"type":"null"}]},"final_from_drafts":{"type":"boolean"},"final_marked":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"kind":{"type":"string","const":"post"},"spec":{"type":"object","properties":{"aspect":{"default":"9:16","type":"string","enum":["9:16","4:5","1:1","16:9","3:4"]},"variants":{"default":2,"description":"Candidates made per image run.","type":"integer","minimum":1,"maximum":4},"references":{"default":[],"description":"Scene references, made before the frames that link them (`{ reference }` refs); none when no shots share a scene.","maxItems":6,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Reference id, unique in the project (`ref1`)."},"title":{"type":"string","minLength":1,"maxLength":60,"description":"Short name shown to people (`Kitchen`)."},"kind":{"type":"string","enum":["location","outfit","object"],"description":"location: the place, no person; outfit: the character in an outfit; object: a key object."},"prompt":{"description":"References you add: what the image shows, in your words. Absent on the script designer's references.","type":"string","minLength":1,"maxLength":2000}},"required":["id","title","kind"],"additionalProperties":false}},"images":{"default":[],"maxItems":20,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Image id, unique in the project; the order of the list is the post order."},"prompt":{"type":"string","minLength":1,"maxLength":4000},"refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"details":{"default":[],"description":"Scene-specific lived-in details: the starting items of the image's Realism step (kept for older posts; the step's items are edited with `PUT .../units/{unit}/items`).","maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":300}},"look":{"description":"`finish.develop` look; default: the character's.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","prompt","refs","details"],"additionalProperties":false}},"enhance_prompts":{"default":true,"description":"Enhance prompt before generation for every frame, image and clip of the project (default true): each run's prompt is rewritten for its model first, at the catalog's enhancement price per run (`POST /api/v1/offerings/{id}/estimate` shows it). The Free plan always enhances, at no credit cost.","type":"boolean"}},"required":["aspect","variants","references","images","enhance_prompts"],"additionalProperties":false}},"required":["id","title","status","cover_asset_id","character_id","state","created_at","updated_at","kind","spec"],"additionalProperties":false}]}},"required":["project"],"additionalProperties":false},"ProjectList":{"type":"object","properties":{"projects":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^prj_[0-9a-f-]{36}$"},"title":{"type":"string"},"status":{"type":"string","enum":["draft","in_progress","completed"]},"cover_asset_id":{"type":["string","null"]},"character_id":{"type":["string","null"]},"state":{"type":"object","properties":{"units":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"jobs":{"type":"array","items":{"type":"string"},"description":"Job ids (`job_...`) run for the unit, oldest first."},"selected":{"description":"The chosen output asset id.","type":["string","null"]}},"required":["jobs","selected"],"additionalProperties":false}},"drafts":{"type":"array","items":{"type":"string"},"description":"Job ids of `project.reel` draft runs."},"finals":{"type":"array","items":{"type":"string"},"description":"Job ids of `project.reel` final or `project.post` runs."},"post_caption":{"description":"The saved post caption and hashtags, when there is one (T141).","type":"object","properties":{"text":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"},"description":"Each with its leading `#`."},"edited_at":{"description":"When the creator last edited it; null while it is as the writer wrote it.","type":["string","null"]}},"required":["text","hashtags","edited_at"],"additionalProperties":false}},"required":["units","drafts","finals"],"additionalProperties":false},"run":{"anyOf":[{"type":"object","properties":{"job_id":{"type":"string","description":"The run's own job (`job_...`); it is free."},"status":{"type":"string","enum":["running","stopping","stopped","succeeded","failed"]},"estimate_credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The total the user confirmed."},"started_at":{"type":"string"},"finished_at":{"type":["string","null"]},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"done":{"type":"integer","minimum":0,"maximum":9007199254740991},"running":{"type":"integer","minimum":0,"maximum":9007199254740991},"failed":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Failed units, and units after them that could not run."}},"required":["step","total","done","running","failed"],"additionalProperties":false}},"failures":{"type":"array","items":{"type":"object","properties":{"unit":{"type":"string","description":"The unit id, or `build` for the final cut."},"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"code":{"type":"string"},"message":{"type":"string"}},"required":["unit","step","code","message"],"additionalProperties":false}},"build_job_id":{"description":"Reels: the final build's job, once started.","type":["string","null"]},"mode":{"description":"`finish`: a Finish in 1080p run (T88); `step`: Generate all on one step (T103); left out for Make everything.","type":"string","enum":["all","finish","step"]},"step":{"description":"A `step` run: the step it covers (T103).","type":"string","enum":["voice","frames","realism","grade","clips","images","variants"]}},"required":["job_id","status","estimate_credits","started_at","finished_at","steps","failures","build_job_id"],"additionalProperties":false},{"type":"null"}]},"sound_suggestion":{"anyOf":[{"type":"object","properties":{"ambience_tags":{"type":"array","items":{"type":"string"}},"music_tags":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"ambience_id":{"type":["string","null"]},"music_id":{"type":["string","null"]},"apply_music":{"type":"boolean"}},"required":["ambience_tags","music_tags","ambience_id","music_id","apply_music"],"additionalProperties":false},{"type":"null"}]},"final_from_drafts":{"type":"boolean"},"final_marked":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"kind":{"type":"string","const":"reel"},"spec":{"type":"object","properties":{"duration_seconds":{"description":"Length of the finished reel in seconds, within `projects.reel.duration_seconds` of the catalog; required when a reel is saved with a spec.","type":"number","exclusiveMinimum":0},"references":{"default":[],"description":"Scene references, made before the frames that link them (`{ reference }` refs); none when no shots share a scene.","maxItems":6,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Reference id, unique in the project (`ref1`)."},"title":{"type":"string","minLength":1,"maxLength":60,"description":"Short name shown to people (`Kitchen`)."},"kind":{"type":"string","enum":["location","outfit","object"],"description":"location: the place, no person; outfit: the character in an outfit; object: a key object."},"prompt":{"description":"References you add: what the image shows, in your words. Absent on the script designer's references.","type":"string","minLength":1,"maxLength":2000}},"required":["id","title","kind"],"additionalProperties":false}},"shots":{"default":[],"maxItems":40,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Shot id, unique in the project (`shot01`)."},"type":{"type":"string","enum":["talking","vo_broll"]},"audio":{"type":"string","minLength":1,"maxLength":2500,"description":"The script text the voice says."},"pause_before":{"default":0,"description":"Silent lead-in (s).","type":"number","minimum":0,"maximum":30},"pause_after":{"default":0,"description":"Silent hold after the take (s).","type":"number","minimum":0,"maximum":30},"first_frame_prompt":{"description":"talking: the frame.","type":"string","minLength":1,"maxLength":4000},"first_frame_refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"motion_prompt":{"description":"talking: how it moves.","type":"string","minLength":1,"maxLength":2500},"clip_seconds":{"description":"Clip length in seconds, from what the routed video model allows; default: the smallest allowed length that covers the clip's share (B-roll: a slot a few hundredths past an allowed length gets that length and the cut slows it slightly; talking: the whole take).","type":"number","exclusiveMinimum":0,"maximum":60},"clip_model":{"description":"The clip's model (`video.talking` or `video.broll` `model`, e.g. `kling_avatar`); default: the tool's default model.","type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"},"segments":{"description":"vo_broll only.","minItems":1,"maxItems":6,"type":"array","items":{"type":"object","properties":{"duration":{"default":1,"description":"Share of the shot's length; shares are normalised, so 1, 1, 2 gives 25/25/50 %.","type":"number","exclusiveMinimum":0,"maximum":100},"first_frame_prompt":{"type":"string","minLength":1,"maxLength":4000},"first_frame_refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"motion_prompt":{"type":"string","minLength":1,"maxLength":2500},"clip_seconds":{"description":"Clip length in seconds, from what the routed video model allows; default: the smallest allowed length that covers the clip's share (B-roll: a slot a few hundredths past an allowed length gets that length and the cut slows it slightly; talking: the whole take).","type":"number","exclusiveMinimum":0,"maximum":60},"clip_model":{"description":"The clip's model (`video.talking` or `video.broll` `model`, e.g. `kling_avatar`); default: the tool's default model.","type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"}},"required":["duration","first_frame_prompt","first_frame_refs","motion_prompt"],"additionalProperties":false}}},"required":["id","type","audio","pause_before","pause_after","first_frame_refs"],"additionalProperties":false}},"enhance_prompts":{"default":true,"description":"Enhance prompt before generation for every frame, image and clip of the project (default true): each run's prompt is rewritten for its model first, at the catalog's enhancement price per run (`POST /api/v1/offerings/{id}/estimate` shows it). The Free plan always enhances, at no credit cost.","type":"boolean"},"idea_id":{"description":"The Idea Studio session (`idea_...`) the reel was made from, when there is one.","type":"string","pattern":"^idea_[0-9a-f-]{36}$"},"edit":{"default":{"episode_no":0},"type":"object","properties":{"episode_no":{"default":0,"description":"Number for the title card.","type":"integer","minimum":0,"maximum":9999},"fps":{"type":"integer","minimum":1,"maximum":60},"tail_seconds":{"type":"number","minimum":0,"maximum":30},"acoustics":{"type":"string","enum":["outdoor","indoor_small","indoor_medium","indoor_large"]},"mic_distance":{"type":"string","enum":["close","medium","far"]},"punch_ins":{"type":"boolean"},"title_card":{"description":"Overrides the character's title card.","type":"string","maxLength":80},"ambience":{"anyOf":[{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."},"level":{"type":"number","minimum":0,"maximum":10}},"required":["asset_id"],"additionalProperties":false},{"type":"null"}]},"music":{"anyOf":[{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."},"stop_at":{"description":"Shot id where the music stops.","type":"string","maxLength":64},"level":{"type":"number","minimum":0,"maximum":10}},"required":["asset_id"],"additionalProperties":false},{"type":"null"}]},"captions":{"description":"Caption style; null burns in none.","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"look":{"description":"`finish.develop` look for clips; default: the character's.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["episode_no"],"additionalProperties":false}},"required":["references","shots","enhance_prompts","edit"],"additionalProperties":false}},"required":["id","title","status","cover_asset_id","character_id","state","created_at","updated_at","kind","spec"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","pattern":"^prj_[0-9a-f-]{36}$"},"title":{"type":"string"},"status":{"type":"string","enum":["draft","in_progress","completed"]},"cover_asset_id":{"type":["string","null"]},"character_id":{"type":["string","null"]},"state":{"type":"object","properties":{"units":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"jobs":{"type":"array","items":{"type":"string"},"description":"Job ids (`job_...`) run for the unit, oldest first."},"selected":{"description":"The chosen output asset id.","type":["string","null"]}},"required":["jobs","selected"],"additionalProperties":false}},"drafts":{"type":"array","items":{"type":"string"},"description":"Job ids of `project.reel` draft runs."},"finals":{"type":"array","items":{"type":"string"},"description":"Job ids of `project.reel` final or `project.post` runs."},"post_caption":{"description":"The saved post caption and hashtags, when there is one (T141).","type":"object","properties":{"text":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"},"description":"Each with its leading `#`."},"edited_at":{"description":"When the creator last edited it; null while it is as the writer wrote it.","type":["string","null"]}},"required":["text","hashtags","edited_at"],"additionalProperties":false}},"required":["units","drafts","finals"],"additionalProperties":false},"run":{"anyOf":[{"type":"object","properties":{"job_id":{"type":"string","description":"The run's own job (`job_...`); it is free."},"status":{"type":"string","enum":["running","stopping","stopped","succeeded","failed"]},"estimate_credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The total the user confirmed."},"started_at":{"type":"string"},"finished_at":{"type":["string","null"]},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"done":{"type":"integer","minimum":0,"maximum":9007199254740991},"running":{"type":"integer","minimum":0,"maximum":9007199254740991},"failed":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Failed units, and units after them that could not run."}},"required":["step","total","done","running","failed"],"additionalProperties":false}},"failures":{"type":"array","items":{"type":"object","properties":{"unit":{"type":"string","description":"The unit id, or `build` for the final cut."},"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"code":{"type":"string"},"message":{"type":"string"}},"required":["unit","step","code","message"],"additionalProperties":false}},"build_job_id":{"description":"Reels: the final build's job, once started.","type":["string","null"]},"mode":{"description":"`finish`: a Finish in 1080p run (T88); `step`: Generate all on one step (T103); left out for Make everything.","type":"string","enum":["all","finish","step"]},"step":{"description":"A `step` run: the step it covers (T103).","type":"string","enum":["voice","frames","realism","grade","clips","images","variants"]}},"required":["job_id","status","estimate_credits","started_at","finished_at","steps","failures","build_job_id"],"additionalProperties":false},{"type":"null"}]},"sound_suggestion":{"anyOf":[{"type":"object","properties":{"ambience_tags":{"type":"array","items":{"type":"string"}},"music_tags":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"ambience_id":{"type":["string","null"]},"music_id":{"type":["string","null"]},"apply_music":{"type":"boolean"}},"required":["ambience_tags","music_tags","ambience_id","music_id","apply_music"],"additionalProperties":false},{"type":"null"}]},"final_from_drafts":{"type":"boolean"},"final_marked":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"kind":{"type":"string","const":"post"},"spec":{"type":"object","properties":{"aspect":{"default":"9:16","type":"string","enum":["9:16","4:5","1:1","16:9","3:4"]},"variants":{"default":2,"description":"Candidates made per image run.","type":"integer","minimum":1,"maximum":4},"references":{"default":[],"description":"Scene references, made before the frames that link them (`{ reference }` refs); none when no shots share a scene.","maxItems":6,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Reference id, unique in the project (`ref1`)."},"title":{"type":"string","minLength":1,"maxLength":60,"description":"Short name shown to people (`Kitchen`)."},"kind":{"type":"string","enum":["location","outfit","object"],"description":"location: the place, no person; outfit: the character in an outfit; object: a key object."},"prompt":{"description":"References you add: what the image shows, in your words. Absent on the script designer's references.","type":"string","minLength":1,"maxLength":2000}},"required":["id","title","kind"],"additionalProperties":false}},"images":{"default":[],"maxItems":20,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Image id, unique in the project; the order of the list is the post order."},"prompt":{"type":"string","minLength":1,"maxLength":4000},"refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"details":{"default":[],"description":"Scene-specific lived-in details: the starting items of the image's Realism step (kept for older posts; the step's items are edited with `PUT .../units/{unit}/items`).","maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":300}},"look":{"description":"`finish.develop` look; default: the character's.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","prompt","refs","details"],"additionalProperties":false}},"enhance_prompts":{"default":true,"description":"Enhance prompt before generation for every frame, image and clip of the project (default true): each run's prompt is rewritten for its model first, at the catalog's enhancement price per run (`POST /api/v1/offerings/{id}/estimate` shows it). The Free plan always enhances, at no credit cost.","type":"boolean"}},"required":["aspect","variants","references","images","enhance_prompts"],"additionalProperties":false}},"required":["id","title","status","cover_asset_id","character_id","state","created_at","updated_at","kind","spec"],"additionalProperties":false}]}},"next_cursor":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]}},"required":["projects","next_cursor"],"additionalProperties":false},"CreateProjectRequest":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"reel"},"title":{"description":"Left out: a short title written from the script (free), else `Untitled reel` or `Untitled post`; a project still carrying that placeholder is retitled when its first script is saved.","type":"string","minLength":1,"maxLength":120},"character_id":{"anyOf":[{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A character (`chr_...`) of yours."},{"type":"null"}]},"spec":{"type":"object","properties":{"duration_seconds":{"description":"Length of the finished reel in seconds, within `projects.reel.duration_seconds` of the catalog; required when a reel is saved with a spec.","type":"number","exclusiveMinimum":0},"references":{"default":[],"description":"Scene references, made before the frames that link them (`{ reference }` refs); none when no shots share a scene.","maxItems":6,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Reference id, unique in the project (`ref1`)."},"title":{"type":"string","minLength":1,"maxLength":60,"description":"Short name shown to people (`Kitchen`)."},"kind":{"type":"string","enum":["location","outfit","object"],"description":"location: the place, no person; outfit: the character in an outfit; object: a key object."},"prompt":{"description":"References you add: what the image shows, in your words. Absent on the script designer's references.","type":"string","minLength":1,"maxLength":2000}},"required":["id","title","kind"],"additionalProperties":false}},"shots":{"default":[],"maxItems":40,"type":"array","items":{"type":"object","properties":{"id":{"description":"Shot id, unique in the project; generated (`shot01`, `shot02`, ...) when missing.","type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$"},"type":{"type":"string","enum":["talking","vo_broll"]},"audio":{"type":"string","minLength":1,"maxLength":2500,"description":"The script text the voice says."},"pause_before":{"default":0,"description":"Silent lead-in (s).","type":"number","minimum":0,"maximum":30},"pause_after":{"default":0,"description":"Silent hold after the take (s).","type":"number","minimum":0,"maximum":30},"first_frame_prompt":{"description":"talking: the frame.","type":"string","minLength":1,"maxLength":4000},"first_frame_refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"motion_prompt":{"description":"talking: how it moves.","type":"string","minLength":1,"maxLength":2500},"clip_seconds":{"description":"Clip length in seconds, from what the routed video model allows; default: the smallest allowed length that covers the clip's share (B-roll: a slot a few hundredths past an allowed length gets that length and the cut slows it slightly; talking: the whole take).","type":"number","exclusiveMinimum":0,"maximum":60},"clip_model":{"description":"The clip's model (`video.talking` or `video.broll` `model`, e.g. `kling_avatar`); default: the tool's default model.","type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"},"segments":{"description":"vo_broll only.","minItems":1,"maxItems":6,"type":"array","items":{"type":"object","properties":{"duration":{"default":1,"description":"Share of the shot's length; shares are normalised, so 1, 1, 2 gives 25/25/50 %.","type":"number","exclusiveMinimum":0,"maximum":100},"first_frame_prompt":{"type":"string","minLength":1,"maxLength":4000},"first_frame_refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"motion_prompt":{"type":"string","minLength":1,"maxLength":2500},"clip_seconds":{"description":"Clip length in seconds, from what the routed video model allows; default: the smallest allowed length that covers the clip's share (B-roll: a slot a few hundredths past an allowed length gets that length and the cut slows it slightly; talking: the whole take).","type":"number","exclusiveMinimum":0,"maximum":60},"clip_model":{"description":"The clip's model (`video.talking` or `video.broll` `model`, e.g. `kling_avatar`); default: the tool's default model.","type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"}},"required":["first_frame_prompt","motion_prompt"],"additionalProperties":false}}},"required":["type","audio"],"additionalProperties":false}},"enhance_prompts":{"default":true,"description":"Enhance prompt before generation for every frame, image and clip of the project (default true): each run's prompt is rewritten for its model first, at the catalog's enhancement price per run (`POST /api/v1/offerings/{id}/estimate` shows it). The Free plan always enhances, at no credit cost.","type":"boolean"},"idea_id":{"description":"The Idea Studio session (`idea_...`) the reel was made from, when there is one.","type":"string","pattern":"^idea_[0-9a-f-]{36}$"},"edit":{"default":{"episode_no":0},"type":"object","properties":{"episode_no":{"default":0,"description":"Number for the title card.","type":"integer","minimum":0,"maximum":9999},"fps":{"type":"integer","minimum":1,"maximum":60},"tail_seconds":{"type":"number","minimum":0,"maximum":30},"acoustics":{"type":"string","enum":["outdoor","indoor_small","indoor_medium","indoor_large"]},"mic_distance":{"type":"string","enum":["close","medium","far"]},"punch_ins":{"type":"boolean"},"title_card":{"description":"Overrides the character's title card.","type":"string","maxLength":80},"ambience":{"anyOf":[{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."},"level":{"type":"number","minimum":0,"maximum":10}},"required":["asset_id"],"additionalProperties":false},{"type":"null"}]},"music":{"anyOf":[{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."},"stop_at":{"description":"Shot id where the music stops.","type":"string","maxLength":64},"level":{"type":"number","minimum":0,"maximum":10}},"required":["asset_id"],"additionalProperties":false},{"type":"null"}]},"captions":{"description":"Caption style; null burns in none.","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"look":{"description":"`finish.develop` look for clips; default: the character's.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"additionalProperties":false}},"additionalProperties":false}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"post"},"title":{"description":"Left out: a short title written from the script (free), else `Untitled reel` or `Untitled post`; a project still carrying that placeholder is retitled when its first script is saved.","type":"string","minLength":1,"maxLength":120},"character_id":{"anyOf":[{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A character (`chr_...`) of yours."},{"type":"null"}]},"spec":{"type":"object","properties":{"aspect":{"default":"9:16","type":"string","enum":["9:16","4:5","1:1","16:9","3:4"]},"variants":{"default":2,"description":"Candidates made per image run.","type":"integer","minimum":1,"maximum":4},"references":{"default":[],"description":"Scene references, made before the frames that link them (`{ reference }` refs); none when no shots share a scene.","maxItems":6,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Reference id, unique in the project (`ref1`)."},"title":{"type":"string","minLength":1,"maxLength":60,"description":"Short name shown to people (`Kitchen`)."},"kind":{"type":"string","enum":["location","outfit","object"],"description":"location: the place, no person; outfit: the character in an outfit; object: a key object."},"prompt":{"description":"References you add: what the image shows, in your words. Absent on the script designer's references.","type":"string","minLength":1,"maxLength":2000}},"required":["id","title","kind"],"additionalProperties":false}},"images":{"default":[],"maxItems":20,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Image id, unique in the project; the order of the list is the post order."},"prompt":{"type":"string","minLength":1,"maxLength":4000},"refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"details":{"default":[],"description":"Scene-specific lived-in details: the starting items of the image's Realism step (kept for older posts; the step's items are edited with `PUT .../units/{unit}/items`).","maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":300}},"look":{"description":"`finish.develop` look; default: the character's.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","prompt"],"additionalProperties":false}},"enhance_prompts":{"default":true,"description":"Enhance prompt before generation for every frame, image and clip of the project (default true): each run's prompt is rewritten for its model first, at the catalog's enhancement price per run (`POST /api/v1/offerings/{id}/estimate` shows it). The Free plan always enhances, at no credit cost.","type":"boolean"}},"additionalProperties":false}},"required":["kind"],"additionalProperties":false}]},"UpdateProjectRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":120},"character_id":{"anyOf":[{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A character (`chr_...`) of yours."},{"type":"null"}]},"spec":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"post_caption":{"description":"Saves the post caption and hashtags with the project (`state.post_caption`); `null` or an empty caption removes it. `edited: true` marks the creator's own edit.","anyOf":[{"type":"object","properties":{"text":{"type":"string","maxLength":2200},"hashtags":{"maxItems":15,"type":"array","items":{"type":"string","maxLength":60}},"edited":{"default":false,"type":"boolean"}},"required":["text","hashtags"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"ProjectUnits":{"type":"object","properties":{"units":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"`ref1.reference`, `shot01.take`, `shot02.seg1.clip`, `d1_morning.grade`..."},"kind":{"type":"string","enum":["reference","take","frame","clip","image","realism","grade"]},"tool":{"type":"string","enum":["image.reference","voice.take","image.generate","image.edit","video.talking","video.broll","image.details","finish.develop"]},"group":{"type":"string","description":"The shot, image or scene reference the unit belongs to."},"depends_on":{"type":"array","items":{"type":"string"},"description":"Units whose selected output this one reads."},"waiting_on":{"type":"array","items":{"type":"string"},"description":"The depends_on units that have no selection yet; run is refused until empty."},"jobs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","waiting","succeeded","failed","cancelled"]},"assets":{"type":"array","items":{"type":"string"},"description":"Output asset ids of the job (candidates)."},"paste_back":{"description":"Realism runs (T160): whether the run pasted the original person back over its edit, whether you chose it or Threadwright did. Absent on other jobs and on runs made before it was recorded.","type":"boolean"}},"required":["id","status","assets"],"additionalProperties":false}},"candidates":{"type":"array","items":{"type":"string"},"description":"Output assets of the unit's succeeded jobs."},"selected":{"type":["string","null"]},"uploaded":{"description":"Candidates that are your own uploads (`asset_...`, also listed in `candidates`): upload a file, then `select` it.","type":"array","items":{"type":"string"}},"slot_seconds":{"description":"Clip units: seconds the cut gives the clip (from the selected voice take); null until the take is selected. A longer clip is trimmed, a shorter one slowed slightly then held.","type":["number","null"]},"notes":{"description":"What to know about the current selection, e.g. an uploaded voice take is being transcribed, or has no word timings so no captions are burned in for it.","type":"array","items":{"type":"string"}},"transcription":{"description":"Take units whose selected take you uploaded: where its transcription stands. Selecting the upload starts it (paid by the minute, free if the asset was transcribed before).","type":"object","properties":{"state":{"type":"string","enum":["needed","running","ready","no_speech","failed"],"description":"`needed` (not started, e.g. the balance was short), `running`, `ready` (word timings stored, captions burn in), `no_speech` (nothing heard) or `failed`."},"job_id":{"description":"The newest `voice.transcribe` job, if any.","type":["string","null"]},"estimate_credits":{"description":"Credits to start or retry it (0 once ready; null when the plan lacks the tool).","type":["number","null"]}},"required":["state","job_id","estimate_credits"],"additionalProperties":false},"clip_seconds":{"description":"Clip units: the chosen length, else the default: B-roll the smallest allowed length covering `slot_seconds` (a slot a few hundredths past an allowed length gets that length; the cut slows it slightly), talking the whole take, or before the take the time its line takes to say (as `run-all/estimate` prices it). Null for other units.","type":["number","null"]},"allowed_seconds":{"anyOf":[{"type":"array","items":{"type":"number"}},{"type":"null"}],"description":"Clip units: the lengths the clip's model allows; null for other units."},"clip_model":{"description":"Clip units: the chosen model (`clip_model` in the spec), else the tool's default; null for other units.","type":["string","null"]},"recommended_model":{"description":"Clip units: the model recommended for the shot as written (its motion prompt and length); `assist.recommend_model` with `project_id` and `unit` weighs it more closely. Null for other units.","type":["string","null"]},"estimate_credits":{"description":"Credits one row run of this unit (`POST .../units/{unit}/run`) holds on the caller's plan, at `clip_seconds` and `clip_model`; null when the plan lacks the tool. `run-all/estimate` prices a clip at the same length; it differs only for B-roll without a chosen `clip_model`, which Make everything runs on the platform's choice and holds at the dearer of the route and its fallback (the row run sends the default model and holds its price, raised only if the fallback runs).","type":["number","null"]},"clip_drafts":{"description":"Clip units: the candidates that are drafts, each with its resolution (`480P`). Finish one with `POST /api/v1/clips/{asset_id}/finish`; the finished clip becomes the pick.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"finishing":{"description":"Clip units: drafts being or already finished, each with its finish job (`job_...`).","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"edit_estimate_credits":{"description":"Image and clip units: credits one edit (`POST .../units/{unit}/edit`) holds on the caller's plan: the edit (an image edit, or the clip's run) plus the enhancement price, since an edit always enhances; null for other units or when the plan lacks editing.","type":["number","null"]},"edited_from":{"description":"Candidates made by an edit, each mapped to the candidate it was edited from.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"clip_editable":{"description":"Clip units: whether a clip can be edited in words (`POST .../units/{unit}/edit`) on this clip's model; false for a model that takes no directions (pick another). An edit costs `edit_estimate_credits`: the clip's run plus the enhancement.","type":"boolean"},"free_run":{"description":"Reference units: the next run is the free first run of a script designer's reference (one image, 0 credits).","type":"boolean"},"from_previous":{"description":"Realism and grade units: the image the step keeps when it is skipped, the earlier step's pick (`asset_...`), also the first candidate. Null before the earlier step has a pick; absent on other units.","type":["string","null"]},"items":{"description":"Realism units: the items of the next run, as saved, else as suggested automatically for the earlier pick. Empty: the step's run chooses them.","type":"array","items":{"type":"string"}},"paste_back":{"description":"Realism units (T160): your choice to keep the person exactly as is by pasting the original back over the edit: `true` (On), `false` (Off), `null` (Auto, Threadwright chooses when the step runs). What a run did is `paste_back` on its `jobs` entry.","type":["boolean","null"]},"analysis_retries_left":{"description":"Realism units: how many more times `POST .../units/{unit}/analyse` with `{ again: true }` may ask for a new analysis of this image (3 at most per image); 0 once they are used up.","type":"integer","minimum":0,"maximum":9007199254740991},"analysis":{"description":"Realism units: the automatic, free look at the earlier pick that suggests the items: `analysing` while it runs, `ready` once its items are in `items`, `failed` when it could not be made; `unavailable` while the earlier step has no pick or none was started (`POST .../units/{unit}/analyse` starts it). Items you saved are never replaced by it.","type":"string","enum":["unavailable","analysing","ready","failed"]}},"required":["id","kind","tool","group","depends_on","waiting_on","jobs","candidates","selected","clip_seconds","allowed_seconds","estimate_credits"],"additionalProperties":false}},"estimate":{"description":"Credits for every unit once, plus a draft and a final cut (reels); null when a part is not in the plan or a reel has no duration.","type":["number","null"]}},"required":["units","estimate"],"additionalProperties":false},"BuildReelRequest":{"type":"object","properties":{"step":{"type":"string","enum":["preview","draft","final","covers"]},"cover_at":{"minItems":1,"maxItems":30,"type":"array","items":{"type":"number","minimum":0,"maximum":36000}},"video_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."},"timeline_seconds":{"type":"number","minimum":1,"maximum":600}},"required":["step"],"additionalProperties":false},"BuildReelResponse":{"type":"object","properties":{"tool":{"type":"string","const":"project.reel"},"job_id":{"type":"string"},"status":{"type":"string"},"replayed":{"type":"boolean"},"draft_clips":{"description":"Final builds: clip units whose pick is still a draft (allowed; finish them for a sharper cut).","type":"array","items":{"type":"string"}}},"required":["tool","job_id","status","replayed"],"additionalProperties":false},"RunAllRequest":{"type":"object","properties":{"estimate_credits":{"description":"The estimate the user confirmed; a higher current estimate is 409 `estimate_changed`.","type":"integer","minimum":0,"maximum":9007199254740991},"mode":{"description":"`step` (T103): Generate all on one step only; default `all` (Make everything).","type":"string","enum":["all","step"]},"step":{"description":"With `mode: step`: the step to generate (reel or post steps).","type":"string","enum":["voice","frames","realism","grade","clips","images","variants"]}},"additionalProperties":false},"RunAllEstimateRequest":{"type":"object","properties":{"mode":{"description":"`step` (T103): Generate all on one step only; default `all` (Make everything).","type":"string","enum":["all","step"]},"step":{"description":"With `mode: step`: the step to generate (reel or post steps).","type":"string","enum":["voice","frames","realism","grade","clips","images","variants"]}},"additionalProperties":false},"FinishAllRequest":{"type":"object","properties":{"estimate_credits":{"description":"The estimate the user confirmed; a higher current estimate is 409 `estimate_changed`.","type":"integer","minimum":0,"maximum":9007199254740991}},"additionalProperties":false},"RunAllEstimate":{"type":"object","properties":{"estimate_credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"balance_credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"enough":{"type":"boolean"},"units":{"type":"array","items":{"type":"object","properties":{"unit":{"type":"string"},"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"What the unit's run holds: the unit's `estimate_credits`, except B-roll without a chosen model, held at the dearer of its route and fallback. Null: the tool is not in your plan."}},"required":["unit","step","credits"],"additionalProperties":false},"description":"The units still to run, with their holds."},"finishing_credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Upscaling every draft clip."},"build_credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The final cut (reels)."},"unavailable":{"type":"array","items":{"type":"string"},"description":"Units whose tool your plan lacks; they will fail."},"step":{"description":"A `step` estimate: the step priced (T103).","type":"string","enum":["voice","frames","realism","grade","clips","images","variants"]},"waiting":{"description":"A `step` estimate: the step's units that never ran but wait for a pick in an earlier step; the run leaves them out.","type":"array","items":{"type":"string"}}},"required":["estimate_credits","balance_credits","enough","units","finishing_credits","build_credits","unavailable"],"additionalProperties":false},"FreePlan":{"type":"object","properties":{"free":{"type":"boolean","description":"The caller is on the Free plan."},"idea_id":{"description":"The free idea, once made (`idea_...`).","type":["string","null"]},"project_id":{"description":"The free reel project, once made (`prj_...`); kept when it is deleted.","type":["string","null"]},"redos_left":{"description":"Re-runs left in the project's shared pool.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"redos_total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"limit_reached":{"description":"The platform spend ceiling is reached: nothing more runs.","type":"boolean"},"recipe":{"type":"object","properties":{"seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"talking_shots":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"broll_segments":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"scene_references":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["seconds","talking_shots","broll_segments","scene_references"],"additionalProperties":false}},"required":["free","recipe"],"additionalProperties":false},"RunAllResponse":{"type":"object","properties":{"job_id":{"type":"string"},"status":{"type":"string"},"replayed":{"type":"boolean"},"run":{"type":"object","properties":{"job_id":{"type":"string","description":"The run's own job (`job_...`); it is free."},"status":{"type":"string","enum":["running","stopping","stopped","succeeded","failed"]},"estimate_credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The total the user confirmed."},"started_at":{"type":"string"},"finished_at":{"type":["string","null"]},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"done":{"type":"integer","minimum":0,"maximum":9007199254740991},"running":{"type":"integer","minimum":0,"maximum":9007199254740991},"failed":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Failed units, and units after them that could not run."}},"required":["step","total","done","running","failed"],"additionalProperties":false}},"failures":{"type":"array","items":{"type":"object","properties":{"unit":{"type":"string","description":"The unit id, or `build` for the final cut."},"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"code":{"type":"string"},"message":{"type":"string"}},"required":["unit","step","code","message"],"additionalProperties":false}},"build_job_id":{"description":"Reels: the final build's job, once started.","type":["string","null"]},"mode":{"description":"`finish`: a Finish in 1080p run (T88); `step`: Generate all on one step (T103); left out for Make everything.","type":"string","enum":["all","finish","step"]},"step":{"description":"A `step` run: the step it covers (T103).","type":"string","enum":["voice","frames","realism","grade","clips","images","variants"]}},"required":["job_id","status","estimate_credits","started_at","finished_at","steps","failures","build_job_id"],"additionalProperties":false}},"required":["job_id","status","replayed","run"],"additionalProperties":false},"StopRunAllResponse":{"type":"object","properties":{"run":{"type":"object","properties":{"job_id":{"type":"string","description":"The run's own job (`job_...`); it is free."},"status":{"type":"string","enum":["running","stopping","stopped","succeeded","failed"]},"estimate_credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The total the user confirmed."},"started_at":{"type":"string"},"finished_at":{"type":["string","null"]},"steps":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"done":{"type":"integer","minimum":0,"maximum":9007199254740991},"running":{"type":"integer","minimum":0,"maximum":9007199254740991},"failed":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Failed units, and units after them that could not run."}},"required":["step","total","done","running","failed"],"additionalProperties":false}},"failures":{"type":"array","items":{"type":"object","properties":{"unit":{"type":"string","description":"The unit id, or `build` for the final cut."},"step":{"type":"string","enum":["references","takes","frames","realism","grade","clips","finishing","build"]},"code":{"type":"string"},"message":{"type":"string"}},"required":["unit","step","code","message"],"additionalProperties":false}},"build_job_id":{"description":"Reels: the final build's job, once started.","type":["string","null"]},"mode":{"description":"`finish`: a Finish in 1080p run (T88); `step`: Generate all on one step (T103); left out for Make everything.","type":"string","enum":["all","finish","step"]},"step":{"description":"A `step` run: the step it covers (T103).","type":"string","enum":["voice","frames","realism","grade","clips","images","variants"]}},"required":["job_id","status","estimate_credits","started_at","finished_at","steps","failures","build_job_id"],"additionalProperties":false}},"required":["run"],"additionalProperties":false},"ChooseCoverRequest":{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},"WriteCaptionRequest":{"type":"object","properties":{"hint":{"type":"string","maxLength":300}},"additionalProperties":false},"WriteCaption":{"type":"object","properties":{"caption":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"},"description":"Each with its leading `#`."}},"required":["caption","hashtags"],"additionalProperties":false},"RunUnitRequest":{"type":"object","properties":{"overrides":{"description":"Fields merged over the tool input the project builds.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"additionalProperties":false},"RunUnitResponse":{"type":"object","properties":{"unit":{"type":"string"},"tool":{"type":"string","enum":["image.reference","voice.take","image.generate","image.edit","video.talking","video.broll","image.details","finish.develop"]},"job_id":{"type":"string"},"status":{"type":"string"},"replayed":{"type":"boolean"}},"required":["unit","tool","job_id","status","replayed"],"additionalProperties":false},"EditUnitRequest":{"type":"object","properties":{"source_asset_id":{"description":"Image units: the candidate of this unit to edit (`asset_...`).","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"candidate":{"description":"Clip units: the clip to change, as the job that made it (`job_...`); default the selected clip, else the latest.","type":"string","pattern":"^(job_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"instruction":{"type":"string","minLength":3,"maxLength":500,"description":"What to change, in your own words, e.g. make her jacket red (an image) or she waves at the end (a clip)."}},"required":["instruction"],"additionalProperties":false},"EditUnitResponse":{"type":"object","properties":{"unit":{"type":"string"},"tool":{"type":"string","enum":["image.revise","video.talking","video.broll"]},"job_id":{"type":"string"},"status":{"type":"string"},"replayed":{"type":"boolean"}},"required":["unit","tool","job_id","status","replayed"],"additionalProperties":false},"AnalyseUnitRequest":{"type":"object","properties":{"again":{"description":"Ask again after a failed (or never started) analysis of this image.","type":"boolean"}},"additionalProperties":false},"AnalyseUnitResponse":{"type":"object","properties":{"unit":{"type":"object","properties":{"id":{"type":"string","description":"`ref1.reference`, `shot01.take`, `shot02.seg1.clip`, `d1_morning.grade`..."},"kind":{"type":"string","enum":["reference","take","frame","clip","image","realism","grade"]},"tool":{"type":"string","enum":["image.reference","voice.take","image.generate","image.edit","video.talking","video.broll","image.details","finish.develop"]},"group":{"type":"string","description":"The shot, image or scene reference the unit belongs to."},"depends_on":{"type":"array","items":{"type":"string"},"description":"Units whose selected output this one reads."},"waiting_on":{"type":"array","items":{"type":"string"},"description":"The depends_on units that have no selection yet; run is refused until empty."},"jobs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","waiting","succeeded","failed","cancelled"]},"assets":{"type":"array","items":{"type":"string"},"description":"Output asset ids of the job (candidates)."},"paste_back":{"description":"Realism runs (T160): whether the run pasted the original person back over its edit, whether you chose it or Threadwright did. Absent on other jobs and on runs made before it was recorded.","type":"boolean"}},"required":["id","status","assets"],"additionalProperties":false}},"candidates":{"type":"array","items":{"type":"string"},"description":"Output assets of the unit's succeeded jobs."},"selected":{"type":["string","null"]},"uploaded":{"description":"Candidates that are your own uploads (`asset_...`, also listed in `candidates`): upload a file, then `select` it.","type":"array","items":{"type":"string"}},"slot_seconds":{"description":"Clip units: seconds the cut gives the clip (from the selected voice take); null until the take is selected. A longer clip is trimmed, a shorter one slowed slightly then held.","type":["number","null"]},"notes":{"description":"What to know about the current selection, e.g. an uploaded voice take is being transcribed, or has no word timings so no captions are burned in for it.","type":"array","items":{"type":"string"}},"transcription":{"description":"Take units whose selected take you uploaded: where its transcription stands. Selecting the upload starts it (paid by the minute, free if the asset was transcribed before).","type":"object","properties":{"state":{"type":"string","enum":["needed","running","ready","no_speech","failed"],"description":"`needed` (not started, e.g. the balance was short), `running`, `ready` (word timings stored, captions burn in), `no_speech` (nothing heard) or `failed`."},"job_id":{"description":"The newest `voice.transcribe` job, if any.","type":["string","null"]},"estimate_credits":{"description":"Credits to start or retry it (0 once ready; null when the plan lacks the tool).","type":["number","null"]}},"required":["state","job_id","estimate_credits"],"additionalProperties":false},"clip_seconds":{"description":"Clip units: the chosen length, else the default: B-roll the smallest allowed length covering `slot_seconds` (a slot a few hundredths past an allowed length gets that length; the cut slows it slightly), talking the whole take, or before the take the time its line takes to say (as `run-all/estimate` prices it). Null for other units.","type":["number","null"]},"allowed_seconds":{"anyOf":[{"type":"array","items":{"type":"number"}},{"type":"null"}],"description":"Clip units: the lengths the clip's model allows; null for other units."},"clip_model":{"description":"Clip units: the chosen model (`clip_model` in the spec), else the tool's default; null for other units.","type":["string","null"]},"recommended_model":{"description":"Clip units: the model recommended for the shot as written (its motion prompt and length); `assist.recommend_model` with `project_id` and `unit` weighs it more closely. Null for other units.","type":["string","null"]},"estimate_credits":{"description":"Credits one row run of this unit (`POST .../units/{unit}/run`) holds on the caller's plan, at `clip_seconds` and `clip_model`; null when the plan lacks the tool. `run-all/estimate` prices a clip at the same length; it differs only for B-roll without a chosen `clip_model`, which Make everything runs on the platform's choice and holds at the dearer of the route and its fallback (the row run sends the default model and holds its price, raised only if the fallback runs).","type":["number","null"]},"clip_drafts":{"description":"Clip units: the candidates that are drafts, each with its resolution (`480P`). Finish one with `POST /api/v1/clips/{asset_id}/finish`; the finished clip becomes the pick.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"finishing":{"description":"Clip units: drafts being or already finished, each with its finish job (`job_...`).","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"edit_estimate_credits":{"description":"Image and clip units: credits one edit (`POST .../units/{unit}/edit`) holds on the caller's plan: the edit (an image edit, or the clip's run) plus the enhancement price, since an edit always enhances; null for other units or when the plan lacks editing.","type":["number","null"]},"edited_from":{"description":"Candidates made by an edit, each mapped to the candidate it was edited from.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"clip_editable":{"description":"Clip units: whether a clip can be edited in words (`POST .../units/{unit}/edit`) on this clip's model; false for a model that takes no directions (pick another). An edit costs `edit_estimate_credits`: the clip's run plus the enhancement.","type":"boolean"},"free_run":{"description":"Reference units: the next run is the free first run of a script designer's reference (one image, 0 credits).","type":"boolean"},"from_previous":{"description":"Realism and grade units: the image the step keeps when it is skipped, the earlier step's pick (`asset_...`), also the first candidate. Null before the earlier step has a pick; absent on other units.","type":["string","null"]},"items":{"description":"Realism units: the items of the next run, as saved, else as suggested automatically for the earlier pick. Empty: the step's run chooses them.","type":"array","items":{"type":"string"}},"paste_back":{"description":"Realism units (T160): your choice to keep the person exactly as is by pasting the original back over the edit: `true` (On), `false` (Off), `null` (Auto, Threadwright chooses when the step runs). What a run did is `paste_back` on its `jobs` entry.","type":["boolean","null"]},"analysis_retries_left":{"description":"Realism units: how many more times `POST .../units/{unit}/analyse` with `{ again: true }` may ask for a new analysis of this image (3 at most per image); 0 once they are used up.","type":"integer","minimum":0,"maximum":9007199254740991},"analysis":{"description":"Realism units: the automatic, free look at the earlier pick that suggests the items: `analysing` while it runs, `ready` once its items are in `items`, `failed` when it could not be made; `unavailable` while the earlier step has no pick or none was started (`POST .../units/{unit}/analyse` starts it). Items you saved are never replaced by it.","type":"string","enum":["unavailable","analysing","ready","failed"]}},"required":["id","kind","tool","group","depends_on","waiting_on","jobs","candidates","selected","clip_seconds","allowed_seconds","estimate_credits"],"additionalProperties":false}},"required":["unit"],"additionalProperties":false},"SetUnitItemsRequest":{"type":"object","properties":{"items":{"description":"Things to add, e.g. `a half-drunk mug by the sink`; [] lets the analyzer choose.","maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":300}},"paste_back":{"description":"Keep the person exactly as is (paste the original back over the edit): `true` On, `false` Off, `null` Auto (Threadwright chooses when the step runs, the default). Stored with the unit; every run of it (Run, Generate all, Make everything) uses it.","type":["boolean","null"]}},"additionalProperties":false},"SetUnitItemsResponse":{"type":"object","properties":{"unit":{"type":"object","properties":{"id":{"type":"string","description":"`ref1.reference`, `shot01.take`, `shot02.seg1.clip`, `d1_morning.grade`..."},"kind":{"type":"string","enum":["reference","take","frame","clip","image","realism","grade"]},"tool":{"type":"string","enum":["image.reference","voice.take","image.generate","image.edit","video.talking","video.broll","image.details","finish.develop"]},"group":{"type":"string","description":"The shot, image or scene reference the unit belongs to."},"depends_on":{"type":"array","items":{"type":"string"},"description":"Units whose selected output this one reads."},"waiting_on":{"type":"array","items":{"type":"string"},"description":"The depends_on units that have no selection yet; run is refused until empty."},"jobs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","waiting","succeeded","failed","cancelled"]},"assets":{"type":"array","items":{"type":"string"},"description":"Output asset ids of the job (candidates)."},"paste_back":{"description":"Realism runs (T160): whether the run pasted the original person back over its edit, whether you chose it or Threadwright did. Absent on other jobs and on runs made before it was recorded.","type":"boolean"}},"required":["id","status","assets"],"additionalProperties":false}},"candidates":{"type":"array","items":{"type":"string"},"description":"Output assets of the unit's succeeded jobs."},"selected":{"type":["string","null"]},"uploaded":{"description":"Candidates that are your own uploads (`asset_...`, also listed in `candidates`): upload a file, then `select` it.","type":"array","items":{"type":"string"}},"slot_seconds":{"description":"Clip units: seconds the cut gives the clip (from the selected voice take); null until the take is selected. A longer clip is trimmed, a shorter one slowed slightly then held.","type":["number","null"]},"notes":{"description":"What to know about the current selection, e.g. an uploaded voice take is being transcribed, or has no word timings so no captions are burned in for it.","type":"array","items":{"type":"string"}},"transcription":{"description":"Take units whose selected take you uploaded: where its transcription stands. Selecting the upload starts it (paid by the minute, free if the asset was transcribed before).","type":"object","properties":{"state":{"type":"string","enum":["needed","running","ready","no_speech","failed"],"description":"`needed` (not started, e.g. the balance was short), `running`, `ready` (word timings stored, captions burn in), `no_speech` (nothing heard) or `failed`."},"job_id":{"description":"The newest `voice.transcribe` job, if any.","type":["string","null"]},"estimate_credits":{"description":"Credits to start or retry it (0 once ready; null when the plan lacks the tool).","type":["number","null"]}},"required":["state","job_id","estimate_credits"],"additionalProperties":false},"clip_seconds":{"description":"Clip units: the chosen length, else the default: B-roll the smallest allowed length covering `slot_seconds` (a slot a few hundredths past an allowed length gets that length; the cut slows it slightly), talking the whole take, or before the take the time its line takes to say (as `run-all/estimate` prices it). Null for other units.","type":["number","null"]},"allowed_seconds":{"anyOf":[{"type":"array","items":{"type":"number"}},{"type":"null"}],"description":"Clip units: the lengths the clip's model allows; null for other units."},"clip_model":{"description":"Clip units: the chosen model (`clip_model` in the spec), else the tool's default; null for other units.","type":["string","null"]},"recommended_model":{"description":"Clip units: the model recommended for the shot as written (its motion prompt and length); `assist.recommend_model` with `project_id` and `unit` weighs it more closely. Null for other units.","type":["string","null"]},"estimate_credits":{"description":"Credits one row run of this unit (`POST .../units/{unit}/run`) holds on the caller's plan, at `clip_seconds` and `clip_model`; null when the plan lacks the tool. `run-all/estimate` prices a clip at the same length; it differs only for B-roll without a chosen `clip_model`, which Make everything runs on the platform's choice and holds at the dearer of the route and its fallback (the row run sends the default model and holds its price, raised only if the fallback runs).","type":["number","null"]},"clip_drafts":{"description":"Clip units: the candidates that are drafts, each with its resolution (`480P`). Finish one with `POST /api/v1/clips/{asset_id}/finish`; the finished clip becomes the pick.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"finishing":{"description":"Clip units: drafts being or already finished, each with its finish job (`job_...`).","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"edit_estimate_credits":{"description":"Image and clip units: credits one edit (`POST .../units/{unit}/edit`) holds on the caller's plan: the edit (an image edit, or the clip's run) plus the enhancement price, since an edit always enhances; null for other units or when the plan lacks editing.","type":["number","null"]},"edited_from":{"description":"Candidates made by an edit, each mapped to the candidate it was edited from.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"clip_editable":{"description":"Clip units: whether a clip can be edited in words (`POST .../units/{unit}/edit`) on this clip's model; false for a model that takes no directions (pick another). An edit costs `edit_estimate_credits`: the clip's run plus the enhancement.","type":"boolean"},"free_run":{"description":"Reference units: the next run is the free first run of a script designer's reference (one image, 0 credits).","type":"boolean"},"from_previous":{"description":"Realism and grade units: the image the step keeps when it is skipped, the earlier step's pick (`asset_...`), also the first candidate. Null before the earlier step has a pick; absent on other units.","type":["string","null"]},"items":{"description":"Realism units: the items of the next run, as saved, else as suggested automatically for the earlier pick. Empty: the step's run chooses them.","type":"array","items":{"type":"string"}},"paste_back":{"description":"Realism units (T160): your choice to keep the person exactly as is by pasting the original back over the edit: `true` (On), `false` (Off), `null` (Auto, Threadwright chooses when the step runs). What a run did is `paste_back` on its `jobs` entry.","type":["boolean","null"]},"analysis_retries_left":{"description":"Realism units: how many more times `POST .../units/{unit}/analyse` with `{ again: true }` may ask for a new analysis of this image (3 at most per image); 0 once they are used up.","type":"integer","minimum":0,"maximum":9007199254740991},"analysis":{"description":"Realism units: the automatic, free look at the earlier pick that suggests the items: `analysing` while it runs, `ready` once its items are in `items`, `failed` when it could not be made; `unavailable` while the earlier step has no pick or none was started (`POST .../units/{unit}/analyse` starts it). Items you saved are never replaced by it.","type":"string","enum":["unavailable","analysing","ready","failed"]}},"required":["id","kind","tool","group","depends_on","waiting_on","jobs","candidates","selected","clip_seconds","allowed_seconds","estimate_credits"],"additionalProperties":false}},"required":["unit"],"additionalProperties":false},"SelectUnitRequest":{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},"SelectUnitResponse":{"type":"object","properties":{"unit":{"type":"object","properties":{"id":{"type":"string","description":"`ref1.reference`, `shot01.take`, `shot02.seg1.clip`, `d1_morning.grade`..."},"kind":{"type":"string","enum":["reference","take","frame","clip","image","realism","grade"]},"tool":{"type":"string","enum":["image.reference","voice.take","image.generate","image.edit","video.talking","video.broll","image.details","finish.develop"]},"group":{"type":"string","description":"The shot, image or scene reference the unit belongs to."},"depends_on":{"type":"array","items":{"type":"string"},"description":"Units whose selected output this one reads."},"waiting_on":{"type":"array","items":{"type":"string"},"description":"The depends_on units that have no selection yet; run is refused until empty."},"jobs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","waiting","succeeded","failed","cancelled"]},"assets":{"type":"array","items":{"type":"string"},"description":"Output asset ids of the job (candidates)."},"paste_back":{"description":"Realism runs (T160): whether the run pasted the original person back over its edit, whether you chose it or Threadwright did. Absent on other jobs and on runs made before it was recorded.","type":"boolean"}},"required":["id","status","assets"],"additionalProperties":false}},"candidates":{"type":"array","items":{"type":"string"},"description":"Output assets of the unit's succeeded jobs."},"selected":{"type":["string","null"]},"uploaded":{"description":"Candidates that are your own uploads (`asset_...`, also listed in `candidates`): upload a file, then `select` it.","type":"array","items":{"type":"string"}},"slot_seconds":{"description":"Clip units: seconds the cut gives the clip (from the selected voice take); null until the take is selected. A longer clip is trimmed, a shorter one slowed slightly then held.","type":["number","null"]},"notes":{"description":"What to know about the current selection, e.g. an uploaded voice take is being transcribed, or has no word timings so no captions are burned in for it.","type":"array","items":{"type":"string"}},"transcription":{"description":"Take units whose selected take you uploaded: where its transcription stands. Selecting the upload starts it (paid by the minute, free if the asset was transcribed before).","type":"object","properties":{"state":{"type":"string","enum":["needed","running","ready","no_speech","failed"],"description":"`needed` (not started, e.g. the balance was short), `running`, `ready` (word timings stored, captions burn in), `no_speech` (nothing heard) or `failed`."},"job_id":{"description":"The newest `voice.transcribe` job, if any.","type":["string","null"]},"estimate_credits":{"description":"Credits to start or retry it (0 once ready; null when the plan lacks the tool).","type":["number","null"]}},"required":["state","job_id","estimate_credits"],"additionalProperties":false},"clip_seconds":{"description":"Clip units: the chosen length, else the default: B-roll the smallest allowed length covering `slot_seconds` (a slot a few hundredths past an allowed length gets that length; the cut slows it slightly), talking the whole take, or before the take the time its line takes to say (as `run-all/estimate` prices it). Null for other units.","type":["number","null"]},"allowed_seconds":{"anyOf":[{"type":"array","items":{"type":"number"}},{"type":"null"}],"description":"Clip units: the lengths the clip's model allows; null for other units."},"clip_model":{"description":"Clip units: the chosen model (`clip_model` in the spec), else the tool's default; null for other units.","type":["string","null"]},"recommended_model":{"description":"Clip units: the model recommended for the shot as written (its motion prompt and length); `assist.recommend_model` with `project_id` and `unit` weighs it more closely. Null for other units.","type":["string","null"]},"estimate_credits":{"description":"Credits one row run of this unit (`POST .../units/{unit}/run`) holds on the caller's plan, at `clip_seconds` and `clip_model`; null when the plan lacks the tool. `run-all/estimate` prices a clip at the same length; it differs only for B-roll without a chosen `clip_model`, which Make everything runs on the platform's choice and holds at the dearer of the route and its fallback (the row run sends the default model and holds its price, raised only if the fallback runs).","type":["number","null"]},"clip_drafts":{"description":"Clip units: the candidates that are drafts, each with its resolution (`480P`). Finish one with `POST /api/v1/clips/{asset_id}/finish`; the finished clip becomes the pick.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"finishing":{"description":"Clip units: drafts being or already finished, each with its finish job (`job_...`).","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"edit_estimate_credits":{"description":"Image and clip units: credits one edit (`POST .../units/{unit}/edit`) holds on the caller's plan: the edit (an image edit, or the clip's run) plus the enhancement price, since an edit always enhances; null for other units or when the plan lacks editing.","type":["number","null"]},"edited_from":{"description":"Candidates made by an edit, each mapped to the candidate it was edited from.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"clip_editable":{"description":"Clip units: whether a clip can be edited in words (`POST .../units/{unit}/edit`) on this clip's model; false for a model that takes no directions (pick another). An edit costs `edit_estimate_credits`: the clip's run plus the enhancement.","type":"boolean"},"free_run":{"description":"Reference units: the next run is the free first run of a script designer's reference (one image, 0 credits).","type":"boolean"},"from_previous":{"description":"Realism and grade units: the image the step keeps when it is skipped, the earlier step's pick (`asset_...`), also the first candidate. Null before the earlier step has a pick; absent on other units.","type":["string","null"]},"items":{"description":"Realism units: the items of the next run, as saved, else as suggested automatically for the earlier pick. Empty: the step's run chooses them.","type":"array","items":{"type":"string"}},"paste_back":{"description":"Realism units (T160): your choice to keep the person exactly as is by pasting the original back over the edit: `true` (On), `false` (Off), `null` (Auto, Threadwright chooses when the step runs). What a run did is `paste_back` on its `jobs` entry.","type":["boolean","null"]},"analysis_retries_left":{"description":"Realism units: how many more times `POST .../units/{unit}/analyse` with `{ again: true }` may ask for a new analysis of this image (3 at most per image); 0 once they are used up.","type":"integer","minimum":0,"maximum":9007199254740991},"analysis":{"description":"Realism units: the automatic, free look at the earlier pick that suggests the items: `analysing` while it runs, `ready` once its items are in `items`, `failed` when it could not be made; `unavailable` while the earlier step has no pick or none was started (`POST .../units/{unit}/analyse` starts it). Items you saved are never replaced by it.","type":"string","enum":["unavailable","analysing","ready","failed"]}},"required":["id","kind","tool","group","depends_on","waiting_on","jobs","candidates","selected","clip_seconds","allowed_seconds","estimate_credits"],"additionalProperties":false},"warnings":{"description":"Things to know about an uploaded asset that was just selected, e.g. a clip shorter than its slot. Empty when there are none.","type":"array","items":{"type":"string"}}},"required":["unit"],"additionalProperties":false},"TranscribeUnitResponse":{"type":"object","properties":{"unit":{"type":"string"},"tool":{"type":"string","const":"voice.transcribe"},"job_id":{"type":"string"},"status":{"type":"string"},"replayed":{"type":"boolean"}},"required":["unit","tool","job_id","status","replayed"],"additionalProperties":false},"FinishEstimateRequest":{"type":"object","properties":{"resolution":{"type":"string","pattern":"^[0-9A-Za-z]{1,10}$","description":"Regenerate only: the resolution to make it at (default the model's full one)."}},"additionalProperties":false},"FinishEstimate":{"type":"object","properties":{"asset_id":{"type":"string"},"draft":{"type":"boolean","description":"Whether the clip is a draft; only drafts can be finished."},"resolution":{"description":"The draft's resolution, e.g. `480P`.","type":["string","null"]},"options":{"type":"array","items":{"type":"object","properties":{"mode":{"type":"string","enum":["upscale","regenerate"]},"available":{"type":"boolean"},"credits":{"description":"Credits the finish holds; null when unavailable.","type":["number","null"]},"resolution":{"description":"The size the finished clip comes out at.","type":["string","null"]},"note":{"type":"string"},"reason":{"description":"Why it is unavailable; null when it is available.","type":["string","null"]}},"required":["mode","available","credits","resolution","note","reason"],"additionalProperties":false}}},"required":["asset_id","draft","resolution","options"],"additionalProperties":false},"FinishClipRequest":{"type":"object","properties":{"mode":{"type":"string","enum":["upscale","regenerate"]},"resolution":{"type":"string","pattern":"^[0-9A-Za-z]{1,10}$","description":"Regenerate only: the resolution to make it at (default the model's full one)."}},"required":["mode"],"additionalProperties":false},"FinishClip":{"type":"object","properties":{"asset_id":{"type":"string"},"mode":{"type":"string","enum":["upscale","regenerate"]},"tool":{"type":"string"},"job_id":{"type":"string"},"status":{"type":"string"},"replayed":{"type":"boolean"},"unit":{"description":"The project clip unit the finished clip becomes the pick of, if any.","type":["string","null"]}},"required":["asset_id","mode","tool","job_id","status","replayed","unit"],"additionalProperties":false},"Idea":{"type":"object","properties":{"idea":{"type":"object","properties":{"id":{"type":"string","pattern":"^idea_[0-9a-f-]{36}$"},"title":{"type":"string"},"character_id":{"type":["string","null"]},"project_id":{"type":["string","null"]},"step":{"type":"string","enum":["format","idea","develop","done"]},"state":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","title","character_id","project_id","step","state","created_at","updated_at"],"additionalProperties":false}},"required":["idea"],"additionalProperties":false},"IdeaList":{"type":"object","properties":{"ideas":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^idea_[0-9a-f-]{36}$"},"title":{"type":"string"},"character_id":{"type":["string","null"]},"project_id":{"type":["string","null"]},"step":{"type":"string","enum":["format","idea","develop","done"]},"state":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","title","character_id","project_id","step","state","created_at","updated_at"],"additionalProperties":false}},"next_cursor":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]}},"required":["ideas","next_cursor"],"additionalProperties":false},"CreateIdeaRequest":{"type":"object","properties":{"title":{"description":"Default `New idea`.","type":"string","minLength":1,"maxLength":120},"character_id":{"anyOf":[{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A character (`chr_...`) of yours."},{"type":"null"}]},"step":{"description":"Default `format`.","type":"string","enum":["format","idea","develop","done"]},"state":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"additionalProperties":false},"UpdateIdeaRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":120},"character_id":{"anyOf":[{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A character (`chr_...`) of yours."},{"type":"null"}]},"step":{"type":"string","enum":["format","idea","develop","done"]},"state":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"additionalProperties":false},"IdeaToProjectRequest":{"type":"object","properties":{"duration_seconds":{"description":"Length of the reel in seconds. Default: `state.duration_seconds`, else `state.suggested_seconds`, else the catalog default.","type":"number","exclusiveMinimum":0}},"additionalProperties":false},"CheckoutRequest":{"type":"object","properties":{"kind":{"type":"string","enum":["tier","bundle"]},"id":{"type":"string","minLength":1,"maxLength":64},"withdrawal_consent":{"type":"boolean"},"return_project_id":{"type":"string","minLength":1,"maxLength":64},"interval":{"type":"string","enum":["month","year"]}},"required":["kind","id"],"additionalProperties":false},"FreeCtaRequest":{"type":"object","properties":{"project_id":{"type":"string","minLength":1,"maxLength":64},"action":{"type":"string","enum":["view","click"]}},"required":["project_id","action"],"additionalProperties":false},"ClientErrorRequest":{"type":"object","properties":{"message":{"type":"string","maxLength":10000},"stack":{"type":"string","maxLength":20000},"url":{"type":"string","minLength":1,"maxLength":2048},"release":{"type":"string","maxLength":64},"kind":{"type":"string","enum":["render","unhandled","rejection"]}},"required":["message","url","kind"]},"CheckoutResponse":{"type":"object","properties":{"url":{"type":"string","minLength":1},"session_id":{"type":"string","minLength":1}},"required":["url","session_id"],"additionalProperties":false},"PortalResponse":{"type":"object","properties":{"url":{"type":"string","minLength":1}},"required":["url"],"additionalProperties":false},"Subscription":{"type":"object","properties":{"plan":{"type":"string"},"subscription":{"anyOf":[{"type":"object","properties":{"tier":{"type":"string"},"status":{"type":"string"},"current_period_start":{"type":"string"},"current_period_end":{"type":"string"},"cancel_at_period_end":{"type":"boolean"},"interval":{"type":"string","enum":["month","year"]}},"required":["tier","status","current_period_start","current_period_end","cancel_at_period_end"],"additionalProperties":false},{"type":"null"}]}},"required":["plan","subscription"],"additionalProperties":false},"Job":{"type":"object","properties":{"id":{"type":"string"},"offering":{"type":"string"},"offering_version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"title":{"type":"string"},"project_id":{"type":["string","null"]},"status":{"type":"string","enum":["queued","running","waiting","succeeded","failed","cancelled"]},"tier":{"type":"string"},"queue":{"type":"string","enum":["paid","free"]},"queue_position":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"estimate_credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"actual_credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"outputs":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"started_at":{"type":["string","null"]},"finished_at":{"type":["string","null"]}},"required":["id","offering","offering_version","title","project_id","status","tier","queue","queue_position","estimate_credits","actual_credits","input","outputs","error","created_at","updated_at","started_at","finished_at"],"additionalProperties":false},"JobList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"offering":{"type":"string"},"offering_version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"title":{"type":"string"},"project_id":{"type":["string","null"]},"status":{"type":"string","enum":["queued","running","waiting","succeeded","failed","cancelled"]},"tier":{"type":"string"},"queue":{"type":"string","enum":["paid","free"]},"queue_position":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"estimate_credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"actual_credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"outputs":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"started_at":{"type":["string","null"]},"finished_at":{"type":["string","null"]}},"required":["id","offering","offering_version","title","project_id","status","tier","queue","queue_position","estimate_credits","actual_credits","input","outputs","error","created_at","updated_at","started_at","finished_at"],"additionalProperties":false}},"next_cursor":{"type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"OfferingList":{"type":"object","properties":{"plan":{"type":"string","description":"The plan the list is filtered and priced for (`free` if anonymous)."},"signed_in":{"type":"boolean","description":"False for anonymous callers, who get `prices` for every plan."},"offerings":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The tool id to send as `offering` in `POST /api/v1/jobs`."},"version":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"category":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"providers":{"type":"array","items":{"type":"string","enum":["fal","elevenlabs","anthropic","higgsfield"]}},"run":{"type":"string","enum":["inline","workflow","container"]},"pricing":{"type":"object","properties":{"mode":{"type":"string","enum":["free","credits"]},"rule":{"type":"string","description":"How the price is made up, in one sentence."}},"required":["mode","rule"],"additionalProperties":false},"price":{"type":"object","properties":{"tier":{"type":"string"},"available":{"type":"boolean"},"examples":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"A request `input` for this offering."},"estimate_credits":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Credits a run of this input holds on the plan; null if it cannot run."}},"required":["title","input","estimate_credits"],"additionalProperties":false}}},"required":["tier","available","examples"],"additionalProperties":false,"description":"The price on the plan the response is for."},"models":{"description":"Clip tools: the models the `model` input takes, default first.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The value to send as `model`."},"title":{"type":"string"},"credits_per_second":{"type":"number","description":"Credits per second of clip, before the per-job minimum, padding and overhead (for comparing models; the estimate is exact)."},"recommended":{"type":"boolean","description":"Whether the platform recommends the model; the others are options."},"motion":{"anyOf":[{"type":"string","enum":["still","moving"]},{"type":"null"}],"description":"Talking models: suited to a character that holds still or one that moves."},"fallback":{"description":"The model a refused clip is made with instead (charged at its price).","type":["string","null"]},"deprecated_on":{"description":"The day the provider retires the model (ISO date), if announced.","type":["string","null"]}},"required":["id","title","credits_per_second","recommended","motion","fallback","deprecated_on"],"additionalProperties":false}},"prices":{"description":"Prices on every plan by tier id (anonymous lists and the detail route).","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"tier":{"type":"string"},"available":{"type":"boolean"},"examples":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"A request `input` for this offering."},"estimate_credits":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Credits a run of this input holds on the plan; null if it cannot run."}},"required":["title","input","estimate_credits"],"additionalProperties":false}}},"required":["tier","available","examples"],"additionalProperties":false}}},"required":["id","version","category","title","summary","providers","run","pricing","price"],"additionalProperties":false}},"next_cursor":{"type":"null"}},"required":["plan","signed_in","offerings","next_cursor"],"additionalProperties":false},"OfferingDetail":{"type":"object","properties":{"id":{"type":"string","description":"The tool id to send as `offering` in `POST /api/v1/jobs`."},"version":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"category":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"providers":{"type":"array","items":{"type":"string","enum":["fal","elevenlabs","anthropic","higgsfield"]}},"run":{"type":"string","enum":["inline","workflow","container"]},"pricing":{"type":"object","properties":{"mode":{"type":"string","enum":["free","credits"]},"rule":{"type":"string","description":"How the price is made up, in one sentence."}},"required":["mode","rule"],"additionalProperties":false},"price":{"type":"object","properties":{"tier":{"type":"string"},"available":{"type":"boolean"},"examples":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"A request `input` for this offering."},"estimate_credits":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Credits a run of this input holds on the plan; null if it cannot run."}},"required":["title","input","estimate_credits"],"additionalProperties":false}}},"required":["tier","available","examples"],"additionalProperties":false,"description":"The price on the plan the response is for."},"models":{"description":"Clip tools: the models the `model` input takes, default first.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The value to send as `model`."},"title":{"type":"string"},"credits_per_second":{"type":"number","description":"Credits per second of clip, before the per-job minimum, padding and overhead (for comparing models; the estimate is exact)."},"recommended":{"type":"boolean","description":"Whether the platform recommends the model; the others are options."},"motion":{"anyOf":[{"type":"string","enum":["still","moving"]},{"type":"null"}],"description":"Talking models: suited to a character that holds still or one that moves."},"fallback":{"description":"The model a refused clip is made with instead (charged at its price).","type":["string","null"]},"deprecated_on":{"description":"The day the provider retires the model (ISO date), if announced.","type":["string","null"]}},"required":["id","title","credits_per_second","recommended","motion","fallback","deprecated_on"],"additionalProperties":false}},"prices":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"tier":{"type":"string"},"available":{"type":"boolean"},"examples":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"A request `input` for this offering."},"estimate_credits":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Credits a run of this input holds on the plan; null if it cannot run."}},"required":["title","input","estimate_credits"],"additionalProperties":false}}},"required":["tier","available","examples"],"additionalProperties":false},"description":"Prices on every plan by tier id."},"input_schema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"JSON Schema of `input` in `POST /api/v1/jobs`."},"output_schema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"JSON Schema of the job's `outputs` once it succeeded."},"example_request":{"type":"object","properties":{"offering":{"type":"string"},"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["offering","input"],"additionalProperties":false,"description":"A complete `POST /api/v1/jobs` body (the first example)."}},"required":["id","version","category","title","summary","providers","run","pricing","price","prices","input_schema","output_schema","example_request"],"additionalProperties":false},"EstimateRequest":{"type":"object","properties":{"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The `input` you would submit."},"tier":{"description":"Price for this plan instead of yours (default: yours, or `free` if anonymous).","type":"string","minLength":1,"maxLength":32}},"required":["input"],"additionalProperties":false},"EstimateResponse":{"type":"object","properties":{"offering":{"type":"string"},"tier":{"type":"string"},"estimate_credits":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Credits `POST /api/v1/jobs` would hold for this input: the hold, not the final charge."},"free_daily":{"description":"Tools free for a number of runs per day only: `limit` (runs per UTC day on the plan), `used` (runs today), `remaining` (free runs left) and `resets_at` (next 00:00 UTC). While `remaining` is above 0 the next run is free; after it, `estimate_credits` is the paid price. Anonymous callers see `used: 0`.","type":"object","properties":{"limit":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"used":{"type":"integer","minimum":0,"maximum":9007199254740991},"remaining":{"type":"integer","minimum":0,"maximum":9007199254740991},"resets_at":{"type":"string"}},"required":["limit","used","remaining","resets_at"],"additionalProperties":false}},"required":["offering","tier","estimate_credits"],"additionalProperties":false},"voice.take.input":{"title":"Voice take: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"text":{"type":"string","minLength":1,"maxLength":2500,"description":"What the voice says (1 to 2500 characters; whitespace is normalised)."},"voice_id":{"type":"string","pattern":"^[A-Za-z0-9]{1,64}$","description":"A `voice_id` from `GET /api/v1/voices`."},"model_id":{"default":"eleven_v4_turbo","description":"Speech model id; leave out for the default.","type":"string","minLength":1,"maxLength":64},"settings":{"description":"Voice settings, 0 to 1.","type":"object","properties":{"stability":{"type":"number","minimum":0,"maximum":1},"similarity_boost":{"type":"number","minimum":0,"maximum":1}},"additionalProperties":false},"stability_sweep":{"description":"One take per stability value, labelled `sNN` (`s80` for 0.8).","minItems":1,"maxItems":8,"type":"array","items":{"type":"number","minimum":0,"maximum":1}},"seed":{"description":"Seed shared by every take.","type":"integer","minimum":0,"maximum":4294967295}},"required":["text","voice_id"],"additionalProperties":false},"voice.take.output":{"title":"Voice take: outputs","type":"object","properties":{"takes":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"audio":{"type":"string","minLength":1,"description":"An asset id (`asset_...`)."},"alignment":{"anyOf":[{"type":"string","minLength":1,"description":"An asset id (`asset_...`)."},{"type":"null"}],"description":"JSON asset: { alignment, normalized_alignment }."},"duration_ms":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"Last character end, rounded up."},"characters_billed":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["label","audio","alignment","duration_ms","characters_billed"],"additionalProperties":false}}},"required":["takes"],"additionalProperties":false},"voice.ambience.input":{"title":"Ambience bed: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"prompt":{"type":"string","minLength":1,"maxLength":1000,"description":"The sound of the place, in words."},"seconds":{"default":12,"description":"Length in seconds (0.5 to 30).","type":"number","minimum":0.5,"maximum":30},"prompt_influence":{"default":0.3,"description":"How closely to follow the prompt.","type":"number","minimum":0,"maximum":1},"loop":{"default":true,"description":"Make the bed loop seamlessly.","type":"boolean"}},"required":["prompt"],"additionalProperties":false},"voice.ambience.output":{"title":"Ambience bed: outputs","type":"object","properties":{"audio":{"type":"string","minLength":1,"description":"An asset id (`asset_...`)."},"seconds":{"type":"number","description":"Seconds requested."}},"required":["audio","seconds"],"additionalProperties":false},"voice.music.input":{"title":"Music bed: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"prompt":{"type":"string","minLength":1,"maxLength":2000,"description":"The mood, genre and instruments."},"seconds":{"type":"number","minimum":3,"maximum":300,"description":"Length in seconds (3 to 300)."},"instrumental":{"default":true,"description":"No vocals.","type":"boolean"}},"required":["prompt","seconds"],"additionalProperties":false},"voice.music.output":{"title":"Music bed: outputs","type":"object","properties":{"audio":{"type":"string","minLength":1,"description":"An asset id (`asset_...`)."},"seconds":{"type":"number","description":"Seconds generated (at most 30 on the sound-effect fallback)."},"source":{"type":"string","enum":["music","sound_effect"],"description":"\"sound_effect\" when music was unavailable."}},"required":["audio","seconds","source"],"additionalProperties":false},"voice.transcribe.input":{"title":"Transcribe speech: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"Your own audio or video asset (an upload or a clip), up to 600 seconds."},"seconds":{"type":"number","minimum":0.1,"maximum":600,"description":"Length of the asset in seconds (its `duration_ms` / 1000, rounded up); the credits held are priced from it, and the job fails before spending anything if the asset is longer."},"language_code":{"description":"Language spoken (ISO 639, `en`); leave out to detect it.","type":"string","pattern":"^[a-z]{2,3}$"}},"required":["asset_id","seconds"],"additionalProperties":false},"voice.transcribe.output":{"title":"Transcribe speech: outputs","type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The asset that was transcribed."},"alignment":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"JSON asset: { alignment, normalized_alignment, ... }."},"text":{"type":"string","description":"The transcript (empty when the asset was transcribed before)."},"language_code":{"description":"Language the model heard.","type":["string","null"]},"word_count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Words found; 0 when the asset has no speech."},"seconds":{"type":"number","minimum":0,"description":"Seconds billed: 0 when the asset was transcribed before."},"reused":{"type":"boolean","description":"True when an earlier transcription was found and nothing ran."}},"required":["asset_id","alignment","text","language_code","word_count","seconds","reused"],"additionalProperties":false},"image.generate.input":{"title":"Generate an image: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"prompt":{"type":"string","minLength":1,"maxLength":4000,"description":"What the image shows."},"aspect_ratio":{"default":"9:16","description":"Shape of the image: 9:16 (reel), 4:5 (feed), 1:1, 16:9 or 3:4.","type":"string","enum":["9:16","4:5","1:1","16:9","3:4"]},"variants":{"default":1,"description":"Separate images to make, 1 to 4.","type":"integer","minimum":1,"maximum":4},"negative_hints":{"description":"Appended to the prompt after a blank line (what to avoid, likeness hints).","type":"string","maxLength":2000},"seed":{"description":"Seed of the first variant; later variants add a fixed stride. Random-ish when absent.","type":"integer","minimum":0,"maximum":2147483647},"enhance":{"description":"Enhance prompt before generation (default true): the prompt is rewritten for the chosen model before it runs, adding 5 credits to the run (charged only when the rewrite was used). The rewritten prompt is never returned. false sends your prompt as written.","type":"boolean"}},"required":["prompt"],"additionalProperties":false},"image.generate.output":{"title":"Generate an image: outputs","type":"object","properties":{"images":{"minItems":1,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"asset_id":{"type":"string"},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"seed":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["label","asset_id","width","height","seed"],"additionalProperties":false}}},"required":["images"],"additionalProperties":false},"image.edit.input":{"title":"Edit with references: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"prompt":{"type":"string","minLength":1,"maxLength":4000,"description":"The scene to make, naming what each reference is."},"reference_asset_ids":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."},"description":"1 to 10 image assets the result must stay faithful to."},"aspect_ratio":{"default":"9:16","description":"Shape of the image: 9:16 (reel), 4:5 (feed), 1:1, 16:9 or 3:4.","type":"string","enum":["9:16","4:5","1:1","16:9","3:4"]},"variants":{"default":1,"description":"Separate images to make, 1 to 4.","type":"integer","minimum":1,"maximum":4},"negative_hints":{"description":"Appended to the prompt after a blank line (what to avoid, likeness hints).","type":"string","maxLength":2000},"seed":{"description":"Seed of the first variant; later variants add a fixed stride. Random-ish when absent.","type":"integer","minimum":0,"maximum":2147483647},"enhance":{"description":"Enhance prompt before generation (default true): the prompt is rewritten for the chosen model before it runs, adding 5 credits to the run (charged only when the rewrite was used). The rewritten prompt is never returned. false sends your prompt as written.","type":"boolean"}},"required":["prompt","reference_asset_ids"],"additionalProperties":false},"image.edit.output":{"title":"Edit with references: outputs","type":"object","properties":{"images":{"minItems":1,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"asset_id":{"type":"string"},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"seed":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["label","asset_id","width","height","seed"],"additionalProperties":false}}},"required":["images"],"additionalProperties":false},"image.details.input":{"title":"Realism pass: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"source_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The image asset to add details to."},"auto":{"description":"Set to `ai` to let Threadwright look at the image and choose the details, the scale and (unless you send `paste_back`) paste_back itself; only the edited images are returned. Leave `scale` out; send `items` to use your own details.","type":"string","enum":["ai"]},"items":{"description":"Scene-specific things to add, for example `a mug on the shelf`. Required unless `auto` is set.","minItems":1,"maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":300}},"scale":{"default":"small","description":"`small` adds clutter; `scene` also adds distant passers-by to an empty place.","type":"string","enum":["small","scene"]},"variants":{"default":1,"description":"Separate edits to make, 1 or 2.","type":"integer","minimum":1,"maximum":2},"paste_back":{"default":false,"description":"Paste the original subject back over each edit, so the person is pixel-identical to the source. Runs `image.mask` on the source (free when it was masked before) and needs that tool on your plan. With `auto`, `true` or `false` is your choice; leave it out to let Threadwright choose.","type":"boolean"},"analysis_job_id":{"description":"Set by a project's Realism step: the image analysis it already made of this source (`job_...`), reused so the run makes and charges no new one. Needs `auto`.","type":"string","pattern":"^job_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"seed":{"description":"Seed of the first variant; later variants add a fixed stride. Random-ish when absent.","type":"integer","minimum":0,"maximum":2147483647}},"required":["source_asset_id"],"additionalProperties":false},"image.details.output":{"title":"Realism pass: outputs","type":"object","properties":{"images":{"minItems":1,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"asset_id":{"type":"string"},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"seed":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["label","asset_id","width","height","seed"],"additionalProperties":false}},"mask_asset_id":{"description":"The subject mask used by paste_back, else null. Null on every `auto` run: see `paste_back`.","type":["string","null"]},"paste_back":{"description":"Whether the run pasted the original subject back over its edits: what you sent, or what `auto` chose. Absent on runs made before it was recorded.","type":"boolean"},"mask_credits":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Credits charged for the image.mask run, if this job ran one (0 when cached)."},"container_run":{"anyOf":[{"type":"object","properties":{"cpu_seconds":{"type":"number","minimum":0},"wall_seconds":{"type":"number","minimum":0}},"required":["cpu_seconds","wall_seconds"],"additionalProperties":false},{"type":"null"}],"description":"Container time spent compositing; null without paste_back."}},"required":["images","mask_asset_id","mask_credits","container_run"],"additionalProperties":false},"image.mask.input":{"title":"Subject mask: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"source_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The image asset to cut the subject out of."}},"required":["source_asset_id"],"additionalProperties":false},"image.mask.output":{"title":"Subject mask: outputs","type":"object","properties":{"mask":{"type":"object","properties":{"asset_id":{"type":"string"},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["asset_id","width","height"],"additionalProperties":false},"cached":{"type":"boolean"}},"required":["mask","cached"],"additionalProperties":false},"image.revise.input":{"title":"Edit with words: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"source_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The image to edit."},"instruction":{"type":"string","minLength":3,"maxLength":500,"description":"The change, in your own words."},"reference_asset_ids":{"description":"Character images; only the face and hair are taken from them.","maxItems":9,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"scene_references":{"description":"Places, outfits or objects in the image that stay exactly as they are.","maxItems":9,"type":"array","items":{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The reference image."},"kind":{"type":"string","enum":["location","outfit","object"],"description":"What it shows: a place, an outfit or an object."},"title":{"type":"string","minLength":1,"maxLength":80,"description":"Its name, for example `Balcony`."}},"required":["asset_id","kind","title"],"additionalProperties":false}},"aspect_ratio":{"description":"Default: the source's shape.","type":"string","enum":["9:16","4:5","1:1","16:9","3:4"]},"seed":{"description":"Seed of the first variant; later variants add a fixed stride. Random-ish when absent.","type":"integer","minimum":0,"maximum":2147483647}},"required":["source_asset_id","instruction"],"additionalProperties":false},"image.revise.output":{"title":"Edit with words: outputs","type":"object","properties":{"images":{"minItems":1,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"asset_id":{"type":"string"},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"seed":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["label","asset_id","width","height","seed"],"additionalProperties":false}},"source_asset_id":{"type":"string"}},"required":["images","source_asset_id"],"additionalProperties":false},"image.reference.input":{"title":"Scene reference: input","type":"object","properties":{"project_id":{"type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A project (`prj_...`) of yours."},"reference_id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"The scene reference of the project (`ref1`)."},"reference_asset_ids":{"description":"Character images for an outfit reference; the face stays the same.","maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"aspect_ratio":{"default":"9:16","description":"Shape of the image: 9:16 (reel), 4:5 (feed), 1:1, 16:9 or 3:4.","type":"string","enum":["9:16","4:5","1:1","16:9","3:4"]},"variants":{"default":1,"description":"Separate images to make, 1 to 4.","type":"integer","minimum":1,"maximum":4},"seed":{"description":"Seed of the first variant; later variants add a fixed stride. Random-ish when absent.","type":"integer","minimum":0,"maximum":2147483647}},"required":["project_id","reference_id"],"additionalProperties":false},"image.reference.output":{"title":"Scene reference: outputs","type":"object","properties":{"images":{"minItems":1,"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"asset_id":{"type":"string"},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"seed":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["label","asset_id","width","height","seed"],"additionalProperties":false}},"reference_id":{"type":"string"}},"required":["images","reference_id"],"additionalProperties":false},"video.talking.input":{"title":"Talking clip: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"model":{"default":"h3_fal","description":"The talking model (`GET /api/v1/offerings/video.talking` lists them with prices): `h3_fal` (default) for every talking shot, still or moving, a final clip at 768P; the others are options (`h3_hf` the same model at 2K; `h3_max` at 480P is a draft to finish later).","type":"string","enum":["h3_fal","h3_max","kling_avatar","omnihuman","ltx","kling_v3_standard","kling_v3_pro","veo31_lite","veo31_fast","veo31","h3_hf","seedance2_hf"]},"frame_asset_id":{"type":"string","pattern":"^asset_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The first frame: an image asset (`image.generate`)."},"audio_asset_id":{"type":"string","pattern":"^asset_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The voice take: an audio asset of up to 15 seconds (`voice.take` or an upload); some models take less. A take under the model's minimum is padded with silence."},"audio_seconds":{"type":"number","minimum":0.1,"maximum":15,"description":"Length of the audio in seconds (the asset's `duration_ms` / 1000, rounded up); the credits held are priced from it, and the job fails before spending anything if the audio is longer."},"tail_seconds":{"default":0,"description":"Silence held after the last word, in seconds; counts toward the billed length.","type":"number","minimum":0,"maximum":15},"resolution":{"description":"Output resolution of a model priced by it, one of its own sizes: `h3_fal` 480P, 768P, 2K (default 768P, final); `h3_max` 480P, 768P, 1080P, 2K (default 480P, a draft to finish later). Left out: the model's default. The plan sets the highest. Other models ignore it.","type":"string","enum":["480P","768P","1080P","2K"]},"prompt":{"description":"How the character moves (or what happens around a still one); say it plainly (`she walks toward the camera`). H3 Max ignores it.","type":"string","maxLength":2000},"enhance":{"description":"Enhance prompt before generation (default true): the prompt is rewritten for the chosen model before it runs, adding 5 credits to the run (charged only when the rewrite was used). The rewritten prompt is never returned. false sends your prompt as written. H3 Max takes no prompt: nothing is rewritten or added.","type":"boolean"}},"required":["frame_asset_id","audio_asset_id","audio_seconds"],"additionalProperties":false},"video.talking.output":{"title":"Talking clip: outputs","type":"object","properties":{"video":{"type":"string","description":"The `video/mp4` asset; its parents are the frame and the audio."},"seconds":{"type":"number","description":"Seconds billed: the model's reported duration, else the (padded) audio."},"model":{"description":"The model the clip was made with.","type":"string"},"width":{"description":"Frame width of a clip billed by its size (Seedance 2.0), when known.","type":["number","null"]},"height":{"description":"Frame height of a clip billed by its size (Seedance 2.0), when known.","type":["number","null"]},"container_run":{"anyOf":[{"type":"object","properties":{"cpu_seconds":{"type":"number","minimum":0},"wall_seconds":{"type":"number","minimum":0}},"required":["cpu_seconds","wall_seconds"],"additionalProperties":false},{"type":"null"}],"description":"Container time spent padding the audio or converting the frame rate; null when none was needed."}},"required":["video","seconds","container_run"],"additionalProperties":false},"video.broll.input":{"title":"B-roll clip: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"model":{"description":"The B-roll model (`GET /api/v1/offerings/video.broll` lists them with prices): `seedance_fast` (falls back to `kling_26` when it refuses the frame), `kling_26`, or the options `h3_hf` and `seedance2_hf`. Sent: the hold is that model's price, raised if the fallback runs. Left out: `seedance_fast`, holding the dearer of `seedance_fast` and `kling_26`.","type":"string","enum":["seedance_fast","kling_26","h3_hf","seedance2_hf"]},"frame_asset_id":{"type":"string","pattern":"^asset_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The first frame: an image asset."},"motion_prompt":{"type":"string","minLength":1,"maxLength":2500,"description":"What moves, and how the camera moves."},"seconds":{"default":5,"description":"Clip length in whole seconds, one the model makes: `seedance_fast` 2 to 10, `kling_26` 5 or 10, `h3_hf` 5 to 15, `seedance2_hf` 4 to 15. A `seedance_fast` clip made on `kling_26` (a refusal or an end frame) is made and billed at the shortest Kling length that covers it.","type":"integer","minimum":1,"maximum":15},"end_frame_asset_id":{"description":"An image asset the clip must arrive at (the end frame). Kling, `h3_hf` and `seedance2_hf` take one: with `seedance_fast` the clip is made on `kling_26`.","type":"string","pattern":"^asset_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"enhance":{"description":"Enhance prompt before generation (default true): the prompt is rewritten for the chosen model before it runs, adding 5 credits to the run (charged only when the rewrite was used). The rewritten prompt is never returned. false sends your prompt as written.","type":"boolean"}},"required":["frame_asset_id","motion_prompt"],"additionalProperties":false},"video.broll.output":{"title":"B-roll clip: outputs","type":"object","properties":{"video":{"type":"string","description":"The `video/mp4` asset (no audio); its parents are the frames."},"seconds":{"type":"number","description":"The billed length in seconds (the fallback's length when the clip was made there)."},"model":{"description":"The model the clip was made with (the fallback when the chosen one refused).","type":"string"},"fallback_from":{"description":"Set when the chosen model refused the frame: the model that refused.","type":"string"},"notice":{"description":"A line for the user when the clip was made on another model, and why.","type":"string"},"width":{"description":"Frame width fal reported, if any.","type":["number","null"]},"height":{"description":"Frame height fal reported, if any.","type":["number","null"]}},"required":["video","seconds"],"additionalProperties":false},"video.lipsync.input":{"title":"Lip-sync a clip: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"video_asset_id":{"type":"string","pattern":"^asset_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The clip to re-sync: a video asset."},"audio_asset_id":{"type":"string","pattern":"^asset_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The voice take: an audio asset."},"audio_seconds":{"type":"number","exclusiveMinimum":0,"maximum":300,"description":"Length of the audio in seconds (the asset's `duration_ms` / 1000, rounded up); the credits held are priced from it, and the job fails before spending anything if the audio is longer."},"model":{"default":"sync_v2","description":"`sync_v2` (default, best quality) or `latentsync` (cheaper).","type":"string","enum":["sync_v2","latentsync"]}},"required":["video_asset_id","audio_asset_id","audio_seconds"],"additionalProperties":false},"video.lipsync.output":{"title":"Lip-sync a clip: outputs","type":"object","properties":{"video":{"type":"string","description":"The `video/mp4` asset; its parents are the clip and the audio."},"seconds":{"type":"number","description":"Seconds billed: the model's reported duration, else the audio."}},"required":["video","seconds"],"additionalProperties":false},"finish.develop.input":{"title":"Color grading: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"source_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The image to grade (PNG, JPEG or WebP)."},"look":{"description":"Overrides of the default grade; leave out for the default look.","type":"object","properties":{"strength":{"description":"Scales every step; 0 leaves the image untouched.","type":"number","minimum":-100,"maximum":100},"wb":{"description":"Share of the measured colour cast removed.","type":"number","minimum":-100,"maximum":100},"wb_max_gain":{"description":"Largest move of any channel.","type":"number","minimum":-100,"maximum":100},"chroma_target":{"description":"Mean OKLab chroma the grade pulls toward.","type":"number","minimum":-100,"maximum":100},"chroma_floor":{"description":"Never cut chroma below this fraction.","type":"number","minimum":-100,"maximum":100},"protect_hues":{"description":"OKLab hue bands [from, to] in degrees that keep more colour (skin).","maxItems":8,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-360,"maximum":360},{"type":"number","minimum":-360,"maximum":360}],"items":false,"minItems":2,"maxItems":2}},"protect":{"description":"Share of the chroma cut that protected pixels get.","type":"number","minimum":-100,"maximum":100},"black_lift":{"description":"OKLab lightness added at black.","type":"number","minimum":-100,"maximum":100},"flatten":{"description":"Midtone contrast reduction.","type":"number","minimum":-100,"maximum":100},"highlight":{"description":"Extra push on the top of the highlights.","type":"number","minimum":-100,"maximum":100},"clarity":{"description":"Share of local contrast removed.","type":"number","minimum":-100,"maximum":100},"ev":{"description":"Exposure offset in stops.","type":"number","minimum":-100,"maximum":100},"saturation":{"description":"Plain chroma multiplier.","type":"number","minimum":-100,"maximum":100}},"additionalProperties":false},"auto":{"description":"Set to `ai` to let Threadwright look at the image and choose the grade itself; only the graded image is returned. Leave `look` out.","type":"string","enum":["ai"]}},"required":["source_asset_id"],"additionalProperties":false},"finish.develop.output":{"title":"Color grading: outputs","type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The graded PNG; its parent is the source."},"source_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"before":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Colour statistics of the source (mean chroma and cast)."},"after":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The same statistics after the grade."},"look":{"description":"The look that was applied, defaults filled in; left out with `auto`.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"container_run":{"type":"object","properties":{"cpu_seconds":{"type":"number","minimum":0},"wall_seconds":{"type":"number","minimum":0}},"required":["cpu_seconds","wall_seconds"],"additionalProperties":false}},"required":["asset_id","source_asset_id","before","after","container_run"],"additionalProperties":false},"finish.text.input":{"title":"Text on image or video: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"source_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The image or video to put text on."},"text":{"type":"string","minLength":1,"maxLength":2000,"description":"The text; line breaks are kept."},"background":{"default":"white","description":"Background of the text block: white or black label, none for bare text, or a #rrggbb colour.","anyOf":[{"type":"string","enum":["white","black","none"]},{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}]},"text_color":{"description":"Text colour (#rrggbb); default black or white, whichever suits the background.","type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"font":{"description":"One of the bundled fonts; default DM Sans.","type":"string","enum":["DM Sans","Inter","Montserrat","Playfair Display","Bebas Neue","Caveat"]},"variants":{"default":1,"description":"2 renders a second option (another placement when position is auto, else another background); both are charged.","anyOf":[{"type":"number","const":1},{"type":"number","const":2}]},"format":{"default":"auto","description":"Safe zone to stay inside; auto picks from the size.","type":"string","enum":["auto","story","reel","feed"]},"position":{"default":"auto","description":"Where the block sits; auto looks for the quietest place.","type":"string","enum":["auto","top","upper","middle","lower","bottom"]},"size":{"description":"Font size in px; default scales with the canvas.","type":"number","minimum":8,"maximum":400},"weight":{"default":600,"description":"Font weight.","type":"integer","minimum":100,"maximum":1000},"start":{"description":"Video only: when the text appears (s).","type":"number","minimum":0,"maximum":36000},"end":{"description":"Video only: when it disappears (s).","type":"number","minimum":0,"maximum":36000},"mask_asset_id":{"description":"A subject mask from image.mask (white = character); makes the placement avoid it.","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"use_mask":{"default":true,"description":"false skips the mask entirely (and the image.mask charge).","type":"boolean"}},"required":["source_asset_id","text"],"additionalProperties":false},"finish.text.output":{"title":"Text on image or video: outputs","type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The image or video with the text baked in (the first variant)."},"source_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"mask_asset_id":{"anyOf":[{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},{"type":"null"}],"description":"The mask used, or null when none was."},"mask_credits":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Credits charged for the image.mask run, if this job ran one."},"placement":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Where the block went: x, y, lines, size, box and the overlap with subject and face."},"variants":{"minItems":1,"maxItems":2,"type":"array","items":{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"position":{"type":"string","enum":["auto","top","upper","middle","lower","bottom"]},"background":{"type":"string"},"placement":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["asset_id","position","background","placement"],"additionalProperties":false},"description":"Every option rendered; the first is asset_id."},"container_run":{"type":"object","properties":{"cpu_seconds":{"type":"number","minimum":0},"wall_seconds":{"type":"number","minimum":0}},"required":["cpu_seconds","wall_seconds"],"additionalProperties":false,"description":"Container time of all variants together."}},"required":["asset_id","source_asset_id","mask_asset_id","mask_credits","placement","variants","container_run"],"additionalProperties":false},"finish.captions.input":{"title":"Caption files: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"shots":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"object","properties":{"alignment_asset_id":{"description":"The take's alignment (application/json). Give this or `asset_id`.","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"asset_id":{"description":"Your own audio or video instead: its words are timed first (`voice.transcribe`; free if it was done before). Needs `seconds`.","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"seconds":{"description":"With `asset_id`: its length in seconds (`duration_ms` / 1000, rounded up); the credits held for transcribing are priced from it.","type":"number","minimum":0.1,"maximum":600},"duration":{"description":"Take length in seconds; default: the end of the last aligned character.","type":"number","minimum":0,"maximum":3600},"pause_before":{"default":0,"description":"Silent lead-in before the take (s).","type":"number","minimum":0,"maximum":600},"pause_after":{"default":0,"description":"Silent hold after the take (s).","type":"number","minimum":0,"maximum":600}},"additionalProperties":false},"description":"One entry per take, in play order; the pauses place each take on the timeline."},"style":{"description":"Caption look; leave out for the default.","type":"object","properties":{"font":{"description":"Font family libass looks up (default Arial).","type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9 _-]{0,63}$"},"size":{"description":"Font size on a 1080 px wide canvas (58).","type":"integer","minimum":8,"maximum":300},"outline":{"description":"Outline width (7).","type":"integer","minimum":0,"maximum":50},"shadow":{"description":"Shadow depth (0).","type":"integer","minimum":0,"maximum":50},"margin_h":{"description":"Side margins (90).","type":"integer","minimum":0,"maximum":1000},"margin_v":{"description":"Distance from the bottom edge (210).","type":"integer","minimum":0,"maximum":1900},"wrap_width":{"description":"Characters per line before wrapping (24).","type":"integer","minimum":4,"maximum":200},"max_chars":{"description":"Characters per caption event (46).","type":"integer","minimum":4,"maximum":400},"max_gap":{"description":"Longest silence inside one event, s (0.9).","type":"number","minimum":0,"maximum":10}},"additionalProperties":false},"width":{"default":1080,"description":"Canvas width the ASS file is made for.","type":"integer","minimum":16,"maximum":4096},"height":{"default":1920,"description":"Canvas height.","type":"integer","minimum":16,"maximum":4096},"language_code":{"description":"Language spoken when a shot is transcribed (ISO 639); leave out to detect it.","type":"string","pattern":"^[a-z]{2,3}$"}},"required":["shots"],"additionalProperties":false},"finish.captions.output":{"title":"Caption files: outputs","type":"object","properties":{"ass_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"captions.ass (styled; burn in with libass)."},"srt_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"captions.srt (plain timings and text)."},"event_count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Caption events in the files."},"transcribed_seconds":{"type":"number","minimum":0,"description":"Seconds of speech transcribed and billed (0 when every alignment existed)."},"container_run":{"type":"object","properties":{"cpu_seconds":{"type":"number","minimum":0},"wall_seconds":{"type":"number","minimum":0}},"required":["cpu_seconds","wall_seconds"],"additionalProperties":false}},"required":["ass_asset_id","srt_asset_id","event_count","transcribed_seconds","container_run"],"additionalProperties":false},"edit.assemble.input":{"title":"Assemble a cut: input","type":"object","properties":{"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"spec":{"type":"object","properties":{"episode_no":{"type":"integer","minimum":0,"maximum":9999,"description":"Number used in the title card and file names."},"shots":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$","description":"Shot id, unique in the spec (units and sfx refer to it)."},"take_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The selected voice take. 48 kHz mono WAV joins cleanly with the silent pauses."},"alignment_asset_id":{"description":"The take's word timings (application/json): a voice take's alignment or the result of `voice.transcribe`. Leave out and the cut plays the recording and burns in no captions for that shot.","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"duration":{"type":"number","minimum":0.01,"maximum":3600,"description":"Take length in seconds."},"pause_before":{"default":0,"description":"Silent lead-in (s).","type":"number","minimum":0,"maximum":600},"pause_after":{"default":0,"description":"Silent hold after the take (s).","type":"number","minimum":0,"maximum":600},"voice_from_clip":{"description":"Play the soundtrack of the talking unit's clip (the unit whose id is the shot id) instead of the take, and fit the shot to it; a clip without sound keeps the take.","type":"boolean"}},"required":["id","take_asset_id","duration"],"additionalProperties":false},"description":"Voice takes in play order."},"units":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$","description":"Unit id, unique among units."},"duration":{"type":"number","minimum":0.01,"maximum":3600,"description":"Seconds on screen."},"label":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,31}$","description":"What the unit is: talking, broll, seg1, seg_cut, lead_in..."},"clip_asset_id":{"description":"The selected video clip.","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"still_asset_id":{"description":"A picture to hold when there is no clip (a placeholder card when neither is given).","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"watermark_box":{"description":"[x, y, w, h] fractions of a watermark to remove (delogo).","type":"array","prefixItems":[{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1}],"items":false,"minItems":4,"maxItems":4},"frame_developed":{"description":"The clip was animated from a developed frame.","type":"boolean"},"look":{"description":"Grade for an undeveloped clip; null, false or \"off\" skips it.","anyOf":[{"type":"object","properties":{"strength":{"description":"Scales every step; 0 leaves the image untouched.","type":"number","minimum":-100,"maximum":100},"wb":{"description":"Share of the measured colour cast removed.","type":"number","minimum":-100,"maximum":100},"wb_max_gain":{"description":"Largest move of any channel.","type":"number","minimum":-100,"maximum":100},"chroma_target":{"description":"Mean OKLab chroma the grade pulls toward.","type":"number","minimum":-100,"maximum":100},"chroma_floor":{"description":"Never cut chroma below this fraction.","type":"number","minimum":-100,"maximum":100},"protect_hues":{"description":"OKLab hue bands [from, to] in degrees that keep more colour (skin).","maxItems":8,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-360,"maximum":360},{"type":"number","minimum":-360,"maximum":360}],"items":false,"minItems":2,"maxItems":2}},"protect":{"description":"Share of the chroma cut that protected pixels get.","type":"number","minimum":-100,"maximum":100},"black_lift":{"description":"OKLab lightness added at black.","type":"number","minimum":-100,"maximum":100},"flatten":{"description":"Midtone contrast reduction.","type":"number","minimum":-100,"maximum":100},"highlight":{"description":"Extra push on the top of the highlights.","type":"number","minimum":-100,"maximum":100},"clarity":{"description":"Share of local contrast removed.","type":"number","minimum":-100,"maximum":100},"ev":{"description":"Exposure offset in stops.","type":"number","minimum":-100,"maximum":100},"saturation":{"description":"Plain chroma multiplier.","type":"number","minimum":-100,"maximum":100}},"additionalProperties":false},{"type":"null"},{"type":"boolean","const":false},{"type":"string","const":"off"}]},"black_before":{"type":"number","minimum":0,"maximum":60},"fade_in":{"type":"number","minimum":0,"maximum":60},"fade_out":{"type":"number","minimum":0,"maximum":60},"zoom_out_from":{"type":"number","minimum":1,"maximum":20},"zoom_seconds":{"type":"number","minimum":0,"maximum":60},"stable":{"description":"No handheld shake over this unit.","type":"boolean"},"shake":{"description":"Share of the shake kept (0 to 1).","type":"number","minimum":0,"maximum":1}},"required":["id","duration","label"],"additionalProperties":false},"description":"Picture units in play order."},"edit":{"type":"object","properties":{"fps":{"description":"Output frame rate (24).","type":"integer","minimum":1,"maximum":60},"tail_seconds":{"description":"Hold after the last word (0.5).","type":"number","minimum":0,"maximum":30},"acoustics":{"description":"Room the voice is placed in (indoor_small).","type":"string","enum":["outdoor","indoor_small","indoor_medium","indoor_large"]},"mic_distance":{"type":"string","enum":["close","medium","far"]},"low_cut_hz":{"type":"number","minimum":1,"maximum":2000},"voice_gain_db":{"type":"number","minimum":-40,"maximum":40},"punch_ins":{"description":"Slight zoom changes between units (true).","type":"boolean"},"title_card":{"anyOf":[{"type":"string","maxLength":80},{"type":"boolean"},{"type":"null"}]},"ambience":{"anyOf":[{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A room or place sound bed (audio)."},"level":{"description":"Bed level (0.7); set so the bed sits near -34 LUFS.","type":"number","minimum":0,"maximum":10}},"required":["asset_id"],"additionalProperties":false},{"type":"null"}]},"music":{"anyOf":[{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A music bed (audio)."},"stop_at":{"description":"Shot or unit id, or seconds, where the music stops; default: plays to the end.","anyOf":[{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$"},{"type":"number","minimum":0,"maximum":3600}]},"level":{"description":"Music level (0.25).","type":"number","minimum":0,"maximum":10},"stop_sfx_asset_id":{"description":"A sound laid over the stop (record scratch).","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"stop_sfx_lead":{"type":"number","minimum":0,"maximum":10},"stop_sfx_level":{"type":"number","minimum":0,"maximum":10}},"required":["asset_id"],"additionalProperties":false},{"type":"null"}]},"sfx":{"maxItems":100,"type":"array","items":{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The sound effect (audio)."},"at":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$","description":"Shot or unit id it plays in."},"offset":{"description":"Seconds into that shot or unit.","type":"number","minimum":-60,"maximum":3600},"level":{"description":"Level (0.8).","type":"number","minimum":0,"maximum":10}},"required":["asset_id","at"],"additionalProperties":false}}},"additionalProperties":false},"captions":{"description":"Caption look; null burns in no captions; leave out for the default look.","anyOf":[{"type":"object","properties":{"font":{"description":"Font family libass looks up (default Arial).","type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9 _-]{0,63}$"},"size":{"description":"Font size on a 1080 px wide canvas (58).","type":"integer","minimum":8,"maximum":300},"outline":{"description":"Outline width (7).","type":"integer","minimum":0,"maximum":50},"shadow":{"description":"Shadow depth (0).","type":"integer","minimum":0,"maximum":50},"margin_h":{"description":"Side margins (90).","type":"integer","minimum":0,"maximum":1000},"margin_v":{"description":"Distance from the bottom edge (210).","type":"integer","minimum":0,"maximum":1900},"wrap_width":{"description":"Characters per line before wrapping (24).","type":"integer","minimum":4,"maximum":200},"max_chars":{"description":"Characters per caption event (46).","type":"integer","minimum":4,"maximum":400},"max_gap":{"description":"Longest silence inside one event, s (0.9).","type":"number","minimum":0,"maximum":10}},"additionalProperties":false},{"type":"null"}]},"title_card":{"description":"Title card text; only {episode_no} may be substituted (\"FIELD LOG #{episode_no}\").","type":"string","maxLength":80},"mic_distance":{"description":"Default mic distance (close).","type":"string","enum":["close","medium","far"]},"low_cut_hz":{"type":"number","minimum":1,"maximum":2000},"voice_gain_db":{"description":"Voice gain (0).","type":"number","minimum":-40,"maximum":40}},"required":["episode_no","shots","units"],"additionalProperties":false},"draft":{"default":true,"description":"true: fast low-bitrate draft with a DRAFT mark; false: the final cut.","type":"boolean"},"cover_at":{"description":"Seconds in the finished cut to take cover frames (and 3:4 grid crops) from.","minItems":1,"maxItems":30,"type":"array","items":{"type":"number","minimum":0,"maximum":36000}}},"required":["spec"],"additionalProperties":false},"edit.assemble.output":{"title":"Assemble a cut: outputs","type":"object","properties":{"video_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The cut (video/mp4); every input asset is a parent."},"duration_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"draft":{"type":"boolean"},"covers":{"type":"array","items":{"type":"object","properties":{"at":{"type":"number","description":"Second of the cut the frame was taken at (to 0.1 s)."},"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The full-size PNG."},"grid_asset_id":{"anyOf":[{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},{"type":"null"}],"description":"The 3:4 profile-grid crop of it."}},"required":["at","asset_id","grid_asset_id"],"additionalProperties":false}},"warnings":{"type":"array","items":{"type":"string"},"description":"Things to check before relying on the cut."},"log":{"type":"array","items":{"type":"string"},"description":"The last lines of the assembly log."},"container_run":{"type":"object","properties":{"cpu_seconds":{"type":"number","minimum":0},"wall_seconds":{"type":"number","minimum":0}},"required":["cpu_seconds","wall_seconds"],"additionalProperties":false}},"required":["video_asset_id","duration_ms","width","height","draft","covers","warnings","log","container_run"],"additionalProperties":false},"edit.audio_preview.input":{"title":"Audio preview: input","type":"object","properties":{"spec":{"type":"object","properties":{"episode_no":{"type":"integer","minimum":0,"maximum":9999,"description":"Number used in the title card and file names."},"shots":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$","description":"Shot id, unique in the spec (units and sfx refer to it)."},"take_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The selected voice take. 48 kHz mono WAV joins cleanly with the silent pauses."},"alignment_asset_id":{"description":"The take's word timings (application/json): a voice take's alignment or the result of `voice.transcribe`. Leave out and the cut plays the recording and burns in no captions for that shot.","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"duration":{"type":"number","minimum":0.01,"maximum":3600,"description":"Take length in seconds."},"pause_before":{"default":0,"description":"Silent lead-in (s).","type":"number","minimum":0,"maximum":600},"pause_after":{"default":0,"description":"Silent hold after the take (s).","type":"number","minimum":0,"maximum":600},"voice_from_clip":{"description":"Play the soundtrack of the talking unit's clip (the unit whose id is the shot id) instead of the take, and fit the shot to it; a clip without sound keeps the take.","type":"boolean"}},"required":["id","take_asset_id","duration"],"additionalProperties":false},"description":"Voice takes in play order."},"units":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$","description":"Unit id, unique among units."},"duration":{"type":"number","minimum":0.01,"maximum":3600,"description":"Seconds on screen."},"label":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,31}$","description":"What the unit is: talking, broll, seg1, seg_cut, lead_in..."},"clip_asset_id":{"description":"The selected video clip.","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"still_asset_id":{"description":"A picture to hold when there is no clip (a placeholder card when neither is given).","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"watermark_box":{"description":"[x, y, w, h] fractions of a watermark to remove (delogo).","type":"array","prefixItems":[{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1}],"items":false,"minItems":4,"maxItems":4},"frame_developed":{"description":"The clip was animated from a developed frame.","type":"boolean"},"look":{"description":"Grade for an undeveloped clip; null, false or \"off\" skips it.","anyOf":[{"type":"object","properties":{"strength":{"description":"Scales every step; 0 leaves the image untouched.","type":"number","minimum":-100,"maximum":100},"wb":{"description":"Share of the measured colour cast removed.","type":"number","minimum":-100,"maximum":100},"wb_max_gain":{"description":"Largest move of any channel.","type":"number","minimum":-100,"maximum":100},"chroma_target":{"description":"Mean OKLab chroma the grade pulls toward.","type":"number","minimum":-100,"maximum":100},"chroma_floor":{"description":"Never cut chroma below this fraction.","type":"number","minimum":-100,"maximum":100},"protect_hues":{"description":"OKLab hue bands [from, to] in degrees that keep more colour (skin).","maxItems":8,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":-360,"maximum":360},{"type":"number","minimum":-360,"maximum":360}],"items":false,"minItems":2,"maxItems":2}},"protect":{"description":"Share of the chroma cut that protected pixels get.","type":"number","minimum":-100,"maximum":100},"black_lift":{"description":"OKLab lightness added at black.","type":"number","minimum":-100,"maximum":100},"flatten":{"description":"Midtone contrast reduction.","type":"number","minimum":-100,"maximum":100},"highlight":{"description":"Extra push on the top of the highlights.","type":"number","minimum":-100,"maximum":100},"clarity":{"description":"Share of local contrast removed.","type":"number","minimum":-100,"maximum":100},"ev":{"description":"Exposure offset in stops.","type":"number","minimum":-100,"maximum":100},"saturation":{"description":"Plain chroma multiplier.","type":"number","minimum":-100,"maximum":100}},"additionalProperties":false},{"type":"null"},{"type":"boolean","const":false},{"type":"string","const":"off"}]},"black_before":{"type":"number","minimum":0,"maximum":60},"fade_in":{"type":"number","minimum":0,"maximum":60},"fade_out":{"type":"number","minimum":0,"maximum":60},"zoom_out_from":{"type":"number","minimum":1,"maximum":20},"zoom_seconds":{"type":"number","minimum":0,"maximum":60},"stable":{"description":"No handheld shake over this unit.","type":"boolean"},"shake":{"description":"Share of the shake kept (0 to 1).","type":"number","minimum":0,"maximum":1}},"required":["id","duration","label"],"additionalProperties":false},"description":"Picture units in play order."},"edit":{"type":"object","properties":{"fps":{"description":"Output frame rate (24).","type":"integer","minimum":1,"maximum":60},"tail_seconds":{"description":"Hold after the last word (0.5).","type":"number","minimum":0,"maximum":30},"acoustics":{"description":"Room the voice is placed in (indoor_small).","type":"string","enum":["outdoor","indoor_small","indoor_medium","indoor_large"]},"mic_distance":{"type":"string","enum":["close","medium","far"]},"low_cut_hz":{"type":"number","minimum":1,"maximum":2000},"voice_gain_db":{"type":"number","minimum":-40,"maximum":40},"punch_ins":{"description":"Slight zoom changes between units (true).","type":"boolean"},"title_card":{"anyOf":[{"type":"string","maxLength":80},{"type":"boolean"},{"type":"null"}]},"ambience":{"anyOf":[{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A room or place sound bed (audio)."},"level":{"description":"Bed level (0.7); set so the bed sits near -34 LUFS.","type":"number","minimum":0,"maximum":10}},"required":["asset_id"],"additionalProperties":false},{"type":"null"}]},"music":{"anyOf":[{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A music bed (audio)."},"stop_at":{"description":"Shot or unit id, or seconds, where the music stops; default: plays to the end.","anyOf":[{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$"},{"type":"number","minimum":0,"maximum":3600}]},"level":{"description":"Music level (0.25).","type":"number","minimum":0,"maximum":10},"stop_sfx_asset_id":{"description":"A sound laid over the stop (record scratch).","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"stop_sfx_lead":{"type":"number","minimum":0,"maximum":10},"stop_sfx_level":{"type":"number","minimum":0,"maximum":10}},"required":["asset_id"],"additionalProperties":false},{"type":"null"}]},"sfx":{"maxItems":100,"type":"array","items":{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The sound effect (audio)."},"at":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$","description":"Shot or unit id it plays in."},"offset":{"description":"Seconds into that shot or unit.","type":"number","minimum":-60,"maximum":3600},"level":{"description":"Level (0.8).","type":"number","minimum":0,"maximum":10}},"required":["asset_id","at"],"additionalProperties":false}}},"additionalProperties":false},"captions":{"description":"Caption look; null burns in no captions; leave out for the default look.","anyOf":[{"type":"object","properties":{"font":{"description":"Font family libass looks up (default Arial).","type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9 _-]{0,63}$"},"size":{"description":"Font size on a 1080 px wide canvas (58).","type":"integer","minimum":8,"maximum":300},"outline":{"description":"Outline width (7).","type":"integer","minimum":0,"maximum":50},"shadow":{"description":"Shadow depth (0).","type":"integer","minimum":0,"maximum":50},"margin_h":{"description":"Side margins (90).","type":"integer","minimum":0,"maximum":1000},"margin_v":{"description":"Distance from the bottom edge (210).","type":"integer","minimum":0,"maximum":1900},"wrap_width":{"description":"Characters per line before wrapping (24).","type":"integer","minimum":4,"maximum":200},"max_chars":{"description":"Characters per caption event (46).","type":"integer","minimum":4,"maximum":400},"max_gap":{"description":"Longest silence inside one event, s (0.9).","type":"number","minimum":0,"maximum":10}},"additionalProperties":false},{"type":"null"}]},"title_card":{"description":"Title card text; only {episode_no} may be substituted (\"FIELD LOG #{episode_no}\").","type":"string","maxLength":80},"mic_distance":{"description":"Default mic distance (close).","type":"string","enum":["close","medium","far"]},"low_cut_hz":{"type":"number","minimum":1,"maximum":2000},"voice_gain_db":{"description":"Voice gain (0).","type":"number","minimum":-40,"maximum":40}},"required":["episode_no","shots","units"],"additionalProperties":false},"project_id":{"description":"Tag the outputs with this project (`prj_...`) of yours.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}},"required":["spec"],"additionalProperties":false},"edit.audio_preview.output":{"title":"Audio preview: outputs","type":"object","properties":{"audio_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The soundtrack (audio/mpeg); the takes and beds are parents."},"duration_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"warnings":{"type":"array","items":{"type":"string"}},"container_run":{"type":"object","properties":{"cpu_seconds":{"type":"number","minimum":0},"wall_seconds":{"type":"number","minimum":0}},"required":["cpu_seconds","wall_seconds"],"additionalProperties":false}},"required":["audio_asset_id","duration_ms","warnings","container_run"],"additionalProperties":false},"project.reel.input":{"title":"Build a reel: input","type":"object","properties":{"project_id":{"type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A project (`prj_...`) of yours."},"step":{"type":"string","enum":["draft","final","preview","covers"],"description":"`preview`: the soundtrack as mp3; `draft`: quick marked cut; `final`: the real cut; `covers`: frame grabs from a finished cut."},"cover_at":{"description":"Seconds of the cut to grab covers (and 3:4 grid crops) from.","minItems":1,"maxItems":30,"type":"array","items":{"type":"number","minimum":0,"maximum":36000}},"video_asset_id":{"description":"covers: the cut to grab from; default: the project's latest final, else draft.","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"timeline_seconds":{"description":"Length of the cut in seconds; required for preview, draft and final. `POST /projects/:id/build` fills it from the project's `duration_seconds`. Only sizes the credit hold of a preview.","type":"number","minimum":1,"maximum":600},"captions":{"description":"draft and final: whether the cut burns in on-video captions. `false` burns none. Leave out (or `true`) and it burns them where the project has a caption look and a take with word timings. `POST /projects/:id/build` sets it from the project. The caption burn-in is held unless this is `false`, and charged only when captions were burned in.","type":"boolean"}},"required":["project_id","step"],"additionalProperties":false},"project.reel.output":{"title":"Build a reel: outputs","type":"object","properties":{"step":{"type":"string","enum":["draft","final","preview","covers"]},"video_asset_id":{"anyOf":[{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},{"type":"null"}],"description":"draft and final: the cut."},"audio_asset_id":{"anyOf":[{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},{"type":"null"}],"description":"preview: the soundtrack."},"duration_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"covers":{"type":"array","items":{"type":"object","properties":{"at":{"type":"number","description":"Second of the cut the frame was taken at (to 0.1 s)."},"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The full-size PNG."},"grid_asset_id":{"anyOf":[{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},{"type":"null"}],"description":"The 3:4 profile-grid crop of it."}},"required":["at","asset_id","grid_asset_id"],"additionalProperties":false}},"warnings":{"type":"array","items":{"type":"string"}},"captions_burned":{"type":"boolean"},"container_run":{"type":"object","properties":{"cpu_seconds":{"type":"number","minimum":0},"wall_seconds":{"type":"number","minimum":0}},"required":["cpu_seconds","wall_seconds"],"additionalProperties":false}},"required":["step","video_asset_id","audio_asset_id","duration_ms","covers","warnings","container_run"],"additionalProperties":false},"project.post.input":{"title":"Finish a photo post: input","type":"object","properties":{"project_id":{"type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A project (`prj_...`) of yours."},"step":{"type":"string","enum":["finals"],"description":"`finals`: develop the selected images and select the results."},"image_ids":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$"},"description":"Ids of the project's images to develop (each needs a selected image)."}},"required":["project_id","step","image_ids"],"additionalProperties":false},"project.post.output":{"title":"Finish a photo post: outputs","type":"object","properties":{"step":{"type":"string","enum":["finals"]},"finals":{"type":"array","items":{"type":"object","properties":{"image_id":{"type":"string","description":"The project image id."},"source_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The developed PNG."}},"required":["image_id","source_asset_id","asset_id"],"additionalProperties":false}},"container_run":{"type":"object","properties":{"cpu_seconds":{"type":"number","minimum":0},"wall_seconds":{"type":"number","minimum":0}},"required":["cpu_seconds","wall_seconds"],"additionalProperties":false}},"required":["step","finals","container_run"],"additionalProperties":false},"character.create.input":{"title":"Create a character: input","type":"object","properties":{"step":{"type":"string","enum":["faces","angles","contexts","finalize"],"description":"`faces`, then `angles` from a picked face, then `contexts`, then `finalize`."},"character_id":{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A character (`chr_...`) of yours; its description and hints are used."},"description":{"description":"The character's look in words. Defaults to the character's description.","type":"string","maxLength":4000},"negative_hints":{"description":"Defaults to the character's.","type":"string","maxLength":2000},"style_suffix":{"description":"Defaults to the character's.","type":"string","maxLength":1000},"n":{"description":"faces: how many candidate faces, 2 to 6 (default 4).","type":"integer","minimum":2,"maximum":6},"face_asset_id":{"description":"angles: the picked (or uploaded) face; not needed when all angles are uploaded.","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"uploaded":{"type":"object","properties":{"front":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."},"profile":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."},"full_body":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"additionalProperties":false,"description":"angles: the angles you already have (your own image asset ids); only the others are generated, and with all three the step is free."},"front_asset_id":{"description":"contexts: the locked front image.","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"per_shot":{"description":"angles and contexts: images per angle or location, 1 or 2 (default 1).","type":"integer","minimum":1,"maximum":2},"locations":{"description":"contexts: 0 to 3 places to show the character in (none is free).","maxItems":3,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,23}$","description":"Short lowercase label (`gym`, `balcony`); names the output images."},"description":{"type":"string","minLength":1,"maxLength":1000,"description":"Where the character is and what they wear and do, in a sentence or two."}},"required":["name","description"],"additionalProperties":false}},"refs":{"description":"finalize: the references to lock; `context` is optional.","type":"object","properties":{"identity":{"minItems":1,"maxItems":6,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"detail":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"context":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"hero":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"required":["identity"],"additionalProperties":false},"niche":{"description":"finalize: the page concept you work in, in your own words; stored on the character (`null` clears it, leaving it out keeps it).","anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"upload_declaration":{"description":"finalize: required when `refs` adds an uploaded image (or one made directly from an upload): the character is original, not a real person, and yours to use.","type":"object","properties":{"version":{"type":"string","minLength":1,"maxLength":40,"description":"The declaration version accepted (`UPLOAD_DECLARATION_VERSION`)."}},"required":["version"],"additionalProperties":false},"seed":{"description":"Seed of the first variant; later variants add a fixed stride. Random-ish when absent.","type":"integer","minimum":0,"maximum":2147483647}},"required":["step"],"additionalProperties":false},"character.create.output":{"title":"Create a character: outputs","type":"object","properties":{"step":{"type":"string","enum":["faces","angles","contexts","finalize"]},"images":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","description":"`face`, `front`, `profile`, `full_body`, or the location name of a context."},"label":{"type":"string"},"asset_id":{"type":"string"},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"seed":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["role","label","asset_id","width","height","seed"],"additionalProperties":false},"description":"The images this step made, to review; empty for finalize."},"character":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string"},"description":{"type":"string"},"negative_hints":{"type":"string"},"style_suffix":{"type":"string"},"broll_negative":{"type":"string"},"voice_id":{"type":["string","null"]},"voice":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"voice_settings":{"anyOf":[{"type":"object","properties":{"stability":{"type":"number","minimum":0,"maximum":1},"similarity_boost":{"type":"number","minimum":0,"maximum":1}},"additionalProperties":false},{"type":"null"}]},"look":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"routing":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"captions":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"title_card":{"type":["string","null"]},"audio_name":{"type":["string","null"]},"niche":{"type":["string","null"]},"refs":{"type":"object","properties":{"identity":{"type":"array","items":{"type":"string"}},"detail":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"context":{"maxItems":10,"type":"array","items":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"hero":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of an image you own."}},"required":["identity"],"additionalProperties":false},"upload_declaration":{"anyOf":[{"type":"object","properties":{"version":{"type":"string"},"accepted_at":{"type":"string"}},"required":["version","accepted_at"],"additionalProperties":false},{"type":"null"}]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","description","negative_hints","style_suffix","broll_negative","voice_id","voice","voice_settings","look","routing","captions","title_card","audio_name","refs","created_at","updated_at"],"additionalProperties":false},{"type":"null"}],"description":"finalize: the character with its refs."}},"required":["step","images","character"],"additionalProperties":false},"assist.improve_prompt.input":{"title":"Improve prompt: input","type":"object","properties":{"target":{"type":"string","enum":["image.generate.prompt","image.edit.prompt","video.talking.prompt","video.broll.motion_prompt","voice.take.text","voice.ambience.prompt","voice.music.prompt","character.create.description","project.shot.first_frame_prompt","project.shot.motion_prompt","project.shot.audio"],"description":"The tool field the text is for, `<tool>.<field>`."},"prompt":{"type":"string","minLength":1,"maxLength":2000,"description":"Your rough text or idea, in your own words."},"character_id":{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A character (`chr_...`) of yours the text is for."},"image_asset_id":{"description":"An image of yours to take into account (image and video targets only).","type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}},"required":["target","prompt"],"additionalProperties":false},"assist.improve_prompt.output":{"title":"Improve prompt: outputs","type":"object","properties":{"prompt":{"type":"string","minLength":1,"maxLength":4000,"description":"The improved text, ready for the target field."},"model":{"description":"Clip motion targets (`video.talking.prompt`, `video.broll.motion_prompt`): the recommended `model` for the improved prompt.","type":"string"}},"required":["prompt"],"additionalProperties":false},"assist.suggest_text.input":{"title":"Suggest text: input","type":"object","properties":{"image_asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The image the text goes on."},"hint":{"description":"A topic, a mood or a draft to improve; leave out for open ideas.","type":"string","minLength":1,"maxLength":500}},"required":["image_asset_id"],"additionalProperties":false},"assist.suggest_text.output":{"title":"Suggest text: outputs","type":"object","properties":{"ideas":{"minItems":3,"maxItems":3,"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"description":"Three short, different texts to put on the image."}},"required":["ideas"],"additionalProperties":false},"assist.write_reel_script.input":{"title":"Write a reel script: input","type":"object","properties":{"project_id":{"description":"A reel project of yours; it gives the character, the length and the ref sets.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"description":{"type":"string","minLength":1,"maxLength":2000,"description":"What the video is about, in your own words."},"duration_seconds":{"description":"Length of the reel (overrides the project's). Without it and without a length on the project, the catalog default is used.","type":"number","minimum":5,"maximum":180},"character_id":{"description":"The character who stars; required without `project_id`.","type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"format_id":{"description":"A format from `assist.suggest_formats`: the hook lands in the first 3 seconds and the script follows the format's order.","type":"string","enum":["knowledge_gap","belief_buster","confession","nobody_talks_about","numbered_lessons","before_after","story_cold_open","pov","this_or_that","stop_doing_this","wait_for_it"]},"script":{"description":"The current script to edit (the project's `spec.shots` and `spec.references`, saved or not). With it, `description` says what should change: only that changes, every other shot comes back as it is, and the output carries the new `duration_seconds`.","type":"object","properties":{"shots":{"minItems":1,"maxItems":40,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Shot id, unique in the project (`shot01`)."},"type":{"type":"string","enum":["talking","vo_broll"]},"audio":{"type":"string","minLength":1,"maxLength":2500,"description":"The script text the voice says."},"pause_before":{"default":0,"description":"Silent lead-in (s).","type":"number","minimum":0,"maximum":30},"pause_after":{"default":0,"description":"Silent hold after the take (s).","type":"number","minimum":0,"maximum":30},"first_frame_prompt":{"description":"talking: the frame.","type":"string","minLength":1,"maxLength":4000},"first_frame_refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"motion_prompt":{"description":"talking: how it moves.","type":"string","minLength":1,"maxLength":2500},"clip_seconds":{"description":"Clip length in seconds, from what the routed video model allows; default: the smallest allowed length that covers the clip's share (B-roll: a slot a few hundredths past an allowed length gets that length and the cut slows it slightly; talking: the whole take).","type":"number","exclusiveMinimum":0,"maximum":60},"clip_model":{"description":"The clip's model (`video.talking` or `video.broll` `model`, e.g. `kling_avatar`); default: the tool's default model.","type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"},"segments":{"description":"vo_broll only.","minItems":1,"maxItems":6,"type":"array","items":{"type":"object","properties":{"duration":{"default":1,"description":"Share of the shot's length; shares are normalised, so 1, 1, 2 gives 25/25/50 %.","type":"number","exclusiveMinimum":0,"maximum":100},"first_frame_prompt":{"type":"string","minLength":1,"maxLength":4000},"first_frame_refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"motion_prompt":{"type":"string","minLength":1,"maxLength":2500},"clip_seconds":{"description":"Clip length in seconds, from what the routed video model allows; default: the smallest allowed length that covers the clip's share (B-roll: a slot a few hundredths past an allowed length gets that length and the cut slows it slightly; talking: the whole take).","type":"number","exclusiveMinimum":0,"maximum":60},"clip_model":{"description":"The clip's model (`video.talking` or `video.broll` `model`, e.g. `kling_avatar`); default: the tool's default model.","type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"}},"required":["first_frame_prompt","motion_prompt"],"additionalProperties":false}}},"required":["id","type","audio"],"additionalProperties":false}},"references":{"default":[],"maxItems":6,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Reference id, unique in the project (`ref1`)."},"title":{"type":"string","minLength":1,"maxLength":60,"description":"Short name shown to people (`Kitchen`)."},"kind":{"type":"string","enum":["location","outfit","object"],"description":"location: the place, no person; outfit: the character in an outfit; object: a key object."}},"required":["id","title","kind"],"additionalProperties":false}}},"required":["shots"],"additionalProperties":false}},"required":["description"],"additionalProperties":false},"assist.write_reel_script.output":{"title":"Write a reel script: outputs","type":"object","properties":{"shots":{"minItems":1,"maxItems":40,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Shot id, unique in the project (`shot01`)."},"type":{"type":"string","enum":["talking","vo_broll"]},"audio":{"type":"string","minLength":1,"maxLength":2500,"description":"The script text the voice says."},"pause_before":{"default":0,"description":"Silent lead-in (s).","type":"number","minimum":0,"maximum":30},"pause_after":{"default":0,"description":"Silent hold after the take (s).","type":"number","minimum":0,"maximum":30},"first_frame_prompt":{"description":"talking: the frame.","type":"string","minLength":1,"maxLength":4000},"first_frame_refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"motion_prompt":{"description":"talking: how it moves.","type":"string","minLength":1,"maxLength":2500},"clip_seconds":{"description":"Clip length in seconds, from what the routed video model allows; default: the smallest allowed length that covers the clip's share (B-roll: a slot a few hundredths past an allowed length gets that length and the cut slows it slightly; talking: the whole take).","type":"number","exclusiveMinimum":0,"maximum":60},"clip_model":{"description":"The clip's model (`video.talking` or `video.broll` `model`, e.g. `kling_avatar`); default: the tool's default model.","type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"},"segments":{"description":"vo_broll only.","minItems":1,"maxItems":6,"type":"array","items":{"type":"object","properties":{"duration":{"default":1,"description":"Share of the shot's length; shares are normalised, so 1, 1, 2 gives 25/25/50 %.","type":"number","exclusiveMinimum":0,"maximum":100},"first_frame_prompt":{"type":"string","minLength":1,"maxLength":4000},"first_frame_refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"motion_prompt":{"type":"string","minLength":1,"maxLength":2500},"clip_seconds":{"description":"Clip length in seconds, from what the routed video model allows; default: the smallest allowed length that covers the clip's share (B-roll: a slot a few hundredths past an allowed length gets that length and the cut slows it slightly; talking: the whole take).","type":"number","exclusiveMinimum":0,"maximum":60},"clip_model":{"description":"The clip's model (`video.talking` or `video.broll` `model`, e.g. `kling_avatar`); default: the tool's default model.","type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"}},"required":["duration","first_frame_prompt","first_frame_refs","motion_prompt"],"additionalProperties":false}}},"required":["id","type","audio","pause_before","pause_after","first_frame_refs"],"additionalProperties":false},"description":"The reel's shots, valid as a reel project's `spec.shots`."},"references":{"default":[],"description":"Scene references the shots link (`{ reference }` refs), for the project's `spec.references`; what each shows stays on the server. Only planned with `project_id`.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Reference id, unique in the project (`ref1`)."},"title":{"type":"string","minLength":1,"maxLength":60,"description":"Short name shown to people (`Kitchen`)."},"kind":{"type":"string","enum":["location","outfit","object"],"description":"location: the place, no person; outfit: the character in an outfit; object: a key object."}},"required":["id","title","kind"],"additionalProperties":false}},"sound":{"description":"Suggested sound as audio library tags; with `project_id` the best library match becomes the project's `sound_suggestion`.","type":"object","properties":{"ambience_tags":{"maxItems":6,"type":"array","items":{"type":"string"}},"music_tags":{"anyOf":[{"maxItems":6,"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["ambience_tags","music_tags"],"additionalProperties":false},"duration_seconds":{"description":"Edits only (`script` in the input): the reel's length after the edit, for the project's `spec.duration_seconds`.","type":"number","exclusiveMinimum":0}},"required":["shots","references"],"additionalProperties":false},"assist.write_post_plan.input":{"title":"Plan a photo post: input","type":"object","properties":{"project_id":{"description":"A photo post project of yours; it gives the character, and the scene references are kept for it.","type":"string","pattern":"^(prj_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"idea":{"type":"string","minLength":1,"maxLength":1000,"description":"What the post is about, in one line or two, in your own words."},"count":{"description":"How many images (1 is a single photo, more is a carousel); default: the plan decides.","type":"integer","minimum":1,"maximum":20},"aspect":{"description":"The post's aspect; default: the plan decides.","type":"string","enum":["9:16","4:5","1:1","16:9","3:4"]},"character_id":{"description":"The character who stars; required without `project_id`.","type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}},"required":["idea"],"additionalProperties":false},"assist.write_post_plan.output":{"title":"Plan a photo post: outputs","type":"object","properties":{"aspect":{"type":"string","enum":["9:16","4:5","1:1","16:9","3:4"],"description":"The post's aspect, for the project's `spec.aspect`."},"images":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Image id, unique in the project; the order of the list is the post order."},"prompt":{"type":"string","minLength":1,"maxLength":4000},"refs":{"default":["identity"],"description":"References for the frame, in order: character ref set names, `{ unit }` (that unit's selected output), `{ asset_id }` (an image of yours) or `{ reference }` (a scene reference of the project); [] makes a plain text-to-image.","maxItems":10,"type":"array","items":{"anyOf":[{"type":"string","enum":["identity","detail","context","hero"]},{"type":"object","properties":{"unit":{"type":"string","minLength":1,"maxLength":80,"description":"A unit id (`shot01.frame`)."}},"required":["unit"],"additionalProperties":false},{"type":"object","properties":{"asset_id":{"type":"string","pattern":"^(asset_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"An asset id (`asset_...`) of yours."}},"required":["asset_id"],"additionalProperties":false},{"type":"object","properties":{"reference":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"A scene reference of the project (`ref1`): its selected image."}},"required":["reference"],"additionalProperties":false}]}},"details":{"default":[],"description":"Scene-specific lived-in details: the starting items of the image's Realism step (kept for older posts; the step's items are edited with `PUT .../units/{unit}/items`).","maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":300}},"look":{"description":"`finish.develop` look; default: the character's.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","prompt","refs","details"],"additionalProperties":false},"description":"The post's images (`id`, `prompt`, `refs`, realism `details`), valid as a post project's `spec.images`."},"references":{"default":[],"description":"Scene references the images link (`{ reference }` refs), for the project's `spec.references`; what each shows stays on the server. Only planned with `project_id`.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,31}$","description":"Reference id, unique in the project (`ref1`)."},"title":{"type":"string","minLength":1,"maxLength":60,"description":"Short name shown to people (`Kitchen`)."},"kind":{"type":"string","enum":["location","outfit","object"],"description":"location: the place, no person; outfit: the character in an outfit; object: a key object."}},"required":["id","title","kind"],"additionalProperties":false}}},"required":["aspect","images","references"],"additionalProperties":false},"assist.suggest_formats.input":{"title":"Suggest video formats: input","type":"object","properties":{"character_id":{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The character (`chr_...`) of yours the page is for."},"niche":{"type":"string","minLength":1,"maxLength":500,"description":"The page concept, in your own words; overrides the character's `niche`."}},"required":["character_id"],"additionalProperties":false},"assist.suggest_formats.output":{"title":"Suggest video formats: outputs","type":"object","properties":{"formats":{"minItems":1,"maxItems":3,"type":"array","items":{"type":"object","properties":{"format_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,59}$","description":"A format id from `assist.suggest_formats` (`knowledge_gap`, `pov`, ...)."},"title":{"type":"string","minLength":1,"maxLength":60},"subtitle":{"type":"string","minLength":1,"maxLength":120,"description":"What a video in this format would be for your niche, in one line."},"reason":{"description":"Why this format suits the niche and the core angle a video in it is built on. Send it on as part of `angle` to `assist.suggest_ideas` and `assist.develop_idea`.","type":"string","minLength":1,"maxLength":300}},"required":["format_id","title","subtitle"],"additionalProperties":false},"description":"1 to 3 formats that suit the niche, the best fit first."}},"required":["formats"],"additionalProperties":false},"assist.shape_idea.input":{"title":"Shape my idea: input","type":"object","properties":{"character_id":{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The character (`chr_...`) of yours who stars."},"idea":{"type":"string","minLength":1,"maxLength":2000,"description":"Your own idea for a video, in your own words: a few words up to a rough script."},"niche":{"type":"string","minLength":1,"maxLength":500,"description":"The page concept, in your own words; overrides the character's `niche`."},"answers":{"description":"Your answers to the `questions` of an earlier run; sent with `previous`.","maxItems":2,"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"maxLength":160},"answer":{"type":"string","minLength":1,"maxLength":300}},"required":["question","answer"],"additionalProperties":false}},"previous":{"description":"The earlier result (`outputs`) to improve with `answers`.","type":"object","properties":{"formats":{"minItems":1,"maxItems":3,"type":"array","items":{"type":"object","properties":{"format_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,59}$","description":"A format id from `assist.suggest_formats` (`knowledge_gap`, `pov`, ...)."},"title":{"type":"string","minLength":1,"maxLength":60},"subtitle":{"type":"string","minLength":1,"maxLength":120,"description":"What a video in this format would be for your niche, in one line."},"reason":{"description":"Why this format suits the niche and the core angle a video in it is built on. Send it on as part of `angle` to `assist.suggest_ideas` and `assist.develop_idea`.","type":"string","minLength":1,"maxLength":300},"takes":{"minItems":2,"maxItems":2,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":80},"hook":{"type":"string","minLength":1,"maxLength":160,"description":"The opening line, said or shown in the first 3 seconds."},"summary":{"type":"string","minLength":1,"maxLength":300},"changes":{"type":"string","minLength":1,"maxLength":130,"description":"What this take keeps from your idea and what it adds or changes."}},"required":["title","hook","summary","changes"]},"description":"Exactly 2 takes: the faithful one first, then a bolder one."}},"required":["format_id","title","subtitle","takes"]},"description":"1 to 3 formats that tell your idea best, the best fit first."},"questions":{"maxItems":2,"type":"array","items":{"type":"string","minLength":1,"maxLength":160},"description":"Up to 2 questions whose answers would make the idea stronger; may be empty."},"note":{"description":"What was left out of your idea and why, when something was.","type":"string","minLength":1,"maxLength":220}},"required":["formats","questions"]}},"required":["character_id","idea"],"additionalProperties":false},"assist.shape_idea.output":{"title":"Shape my idea: outputs","type":"object","properties":{"formats":{"minItems":1,"maxItems":3,"type":"array","items":{"type":"object","properties":{"format_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,59}$","description":"A format id from `assist.suggest_formats` (`knowledge_gap`, `pov`, ...)."},"title":{"type":"string","minLength":1,"maxLength":60},"subtitle":{"type":"string","minLength":1,"maxLength":120,"description":"What a video in this format would be for your niche, in one line."},"reason":{"description":"Why this format suits the niche and the core angle a video in it is built on. Send it on as part of `angle` to `assist.suggest_ideas` and `assist.develop_idea`.","type":"string","minLength":1,"maxLength":300},"takes":{"minItems":2,"maxItems":2,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":80},"hook":{"type":"string","minLength":1,"maxLength":160,"description":"The opening line, said or shown in the first 3 seconds."},"summary":{"type":"string","minLength":1,"maxLength":300},"changes":{"type":"string","minLength":1,"maxLength":130,"description":"What this take keeps from your idea and what it adds or changes."}},"required":["title","hook","summary","changes"],"additionalProperties":false},"description":"Exactly 2 takes: the faithful one first, then a bolder one."}},"required":["format_id","title","subtitle","takes"],"additionalProperties":false},"description":"1 to 3 formats that tell your idea best, the best fit first."},"questions":{"maxItems":2,"type":"array","items":{"type":"string","minLength":1,"maxLength":160},"description":"Up to 2 questions whose answers would make the idea stronger; may be empty."},"note":{"description":"What was left out of your idea and why, when something was.","type":"string","minLength":1,"maxLength":220}},"required":["formats","questions"],"additionalProperties":false},"assist.suggest_ideas.input":{"title":"Suggest video ideas: input","type":"object","properties":{"character_id":{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The character (`chr_...`) of yours who stars."},"format_id":{"type":"string","enum":["knowledge_gap","belief_buster","confession","nobody_talks_about","numbered_lessons","before_after","story_cold_open","pov","this_or_that","stop_doing_this","wait_for_it"],"description":"A format id, as `assist.suggest_formats` returns it."},"niche":{"type":"string","minLength":1,"maxLength":500,"description":"The page concept, in your own words; overrides the character's `niche`."},"avoid":{"description":"Titles of ideas you already have (at most 15); the new ones differ from them.","maxItems":15,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"angle":{"type":"string","minLength":1,"maxLength":450,"description":"Why the format was picked: the format's `subtitle` and `reason` from `assist.suggest_formats`, joined. The ideas build on it."},"seed":{"type":"string","minLength":1,"maxLength":2000,"description":"Your own idea, in your own words, when the ideas are built from it."}},"required":["character_id","format_id"],"additionalProperties":false},"assist.suggest_ideas.output":{"title":"Suggest video ideas: outputs","type":"object","properties":{"ideas":{"minItems":5,"maxItems":5,"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":80},"hook":{"type":"string","minLength":1,"maxLength":160,"description":"The opening line, said or shown in the first 3 seconds."},"summary":{"type":"string","minLength":1,"maxLength":300}},"required":["title","hook","summary"],"additionalProperties":false},"description":"Exactly 5 ideas."}},"required":["ideas"],"additionalProperties":false},"assist.develop_idea.input":{"title":"Develop a video idea: input","type":"object","properties":{"character_id":{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"The character (`chr_...`) of yours who stars."},"format_id":{"type":"string","enum":["knowledge_gap","belief_buster","confession","nobody_talks_about","numbered_lessons","before_after","story_cold_open","pov","this_or_that","stop_doing_this","wait_for_it"],"description":"A format id, as `assist.suggest_formats` returns it."},"idea":{"anyOf":[{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":80},"hook":{"type":"string","minLength":1,"maxLength":160},"summary":{"type":"string","minLength":1,"maxLength":300}},"required":["title","summary"],"additionalProperties":false},{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":2000,"description":"Your own idea, in your own words."}},"required":["text"],"additionalProperties":false}],"description":"A suggested idea (`title`, `hook?`, `summary`) or your own (`text`)."},"duration_seconds":{"description":"Length of the reel in seconds. Send it when you have chosen one: the plan fits it. Left out, the plan picks the length the idea needs (the default unless it needs more) and returns it as `duration_seconds`.","type":"number","minimum":5,"maximum":180},"angle":{"type":"string","minLength":1,"maxLength":450,"description":"Why the format was picked: the format's `subtitle` and `reason` from `assist.suggest_formats`, joined. The ideas build on it."},"seed":{"type":"string","minLength":1,"maxLength":2000,"description":"Your own idea, in your own words, when the ideas are built from it."},"previous":{"description":"The developed idea to revise (`outputs.idea` of an earlier run).","type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":80},"hook":{"type":"string","minLength":1,"maxLength":160},"summary":{"type":"string","minLength":1,"maxLength":300},"scenes":{"minItems":3,"maxItems":8,"type":"array","items":{"type":"object","properties":{"summary":{"type":"string","minLength":1,"maxLength":200},"line":{"description":"The words spoken in the scene, when there are any.","type":"string","minLength":1,"maxLength":200}},"required":["summary"],"additionalProperties":false}}},"required":["title","hook","summary","scenes"],"additionalProperties":false},"feedback":{"description":"What to change in `previous`; everything else is kept.","type":"string","minLength":1,"maxLength":1000}},"required":["character_id","format_id","idea"],"additionalProperties":false},"assist.develop_idea.output":{"title":"Develop a video idea: outputs","type":"object","properties":{"idea":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":80},"hook":{"type":"string","minLength":1,"maxLength":160},"summary":{"type":"string","minLength":1,"maxLength":300},"scenes":{"minItems":3,"maxItems":8,"type":"array","items":{"type":"object","properties":{"summary":{"type":"string","minLength":1,"maxLength":200},"line":{"description":"The words spoken in the scene, when there are any.","type":"string","minLength":1,"maxLength":200}},"required":["summary"],"additionalProperties":false}}},"required":["title","hook","summary","scenes"],"additionalProperties":false},"duration_seconds":{"type":"number","exclusiveMinimum":0}},"required":["idea"],"additionalProperties":false},"assist.recommend_model.input":{"title":"Recommend a model: input","type":"object","properties":{"tool":{"type":"string","enum":["video.talking","video.broll"],"description":"The clip tool the model is for."},"motion_prompt":{"description":"The clip's motion prompt.","type":"string","maxLength":2500},"line":{"description":"Talking: what the character says.","type":"string","maxLength":2500},"seconds":{"description":"The clip's length, if known.","type":"number","exclusiveMinimum":0,"maximum":120},"motion":{"description":"Talking: the character holds `still` or is `moving`.","type":"string","enum":["still","moving"]},"quality":{"description":"How much quality matters.","type":"string","enum":["draft","standard","high"]},"character_id":{"type":"string","pattern":"^(chr_)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$","description":"A character (`chr_...`) of yours the text is for."},"project_id":{"description":"A reel project of yours; its `unit` shot is read.","type":"string","pattern":"^(prj_)?[0-9a-f-]{36}$"},"unit":{"type":"string","pattern":"^[a-z0-9_]{1,64}(\\.seg\\d{1,2})?\\.clip$","description":"With `project_id`: a clip unit (`shot01.clip`)."}},"required":["tool"],"additionalProperties":false},"assist.recommend_model.output":{"title":"Recommend a model: outputs","type":"object","properties":{"model":{"type":"string","minLength":1,"description":"The recommended route id: send it as the clip tool's `model` or a shot's `clip_model`."}},"required":["model"],"additionalProperties":false},"SubmitJobRequest":{"description":"A job submission; `offering` selects the `input` schema.","oneOf":[{"title":"voice.take","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"voice.take"},"input":{"$ref":"#/components/schemas/voice.take.input"}}},{"title":"voice.ambience","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"voice.ambience"},"input":{"$ref":"#/components/schemas/voice.ambience.input"}}},{"title":"voice.music","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"voice.music"},"input":{"$ref":"#/components/schemas/voice.music.input"}}},{"title":"voice.transcribe","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"voice.transcribe"},"input":{"$ref":"#/components/schemas/voice.transcribe.input"}}},{"title":"image.generate","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"image.generate"},"input":{"$ref":"#/components/schemas/image.generate.input"}}},{"title":"image.edit","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"image.edit"},"input":{"$ref":"#/components/schemas/image.edit.input"}}},{"title":"image.details","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"image.details"},"input":{"$ref":"#/components/schemas/image.details.input"}}},{"title":"image.mask","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"image.mask"},"input":{"$ref":"#/components/schemas/image.mask.input"}}},{"title":"image.revise","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"image.revise"},"input":{"$ref":"#/components/schemas/image.revise.input"}}},{"title":"image.reference","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"image.reference"},"input":{"$ref":"#/components/schemas/image.reference.input"}}},{"title":"video.talking","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"video.talking"},"input":{"$ref":"#/components/schemas/video.talking.input"}}},{"title":"video.broll","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"video.broll"},"input":{"$ref":"#/components/schemas/video.broll.input"}}},{"title":"video.lipsync","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"video.lipsync"},"input":{"$ref":"#/components/schemas/video.lipsync.input"}}},{"title":"finish.develop","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"finish.develop"},"input":{"$ref":"#/components/schemas/finish.develop.input"}}},{"title":"finish.text","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"finish.text"},"input":{"$ref":"#/components/schemas/finish.text.input"}}},{"title":"finish.captions","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"finish.captions"},"input":{"$ref":"#/components/schemas/finish.captions.input"}}},{"title":"edit.assemble","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"edit.assemble"},"input":{"$ref":"#/components/schemas/edit.assemble.input"}}},{"title":"edit.audio_preview","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"edit.audio_preview"},"input":{"$ref":"#/components/schemas/edit.audio_preview.input"}}},{"title":"project.reel","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"project.reel"},"input":{"$ref":"#/components/schemas/project.reel.input"}}},{"title":"project.post","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"project.post"},"input":{"$ref":"#/components/schemas/project.post.input"}}},{"title":"character.create","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"character.create"},"input":{"$ref":"#/components/schemas/character.create.input"}}},{"title":"assist.improve_prompt","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"assist.improve_prompt"},"input":{"$ref":"#/components/schemas/assist.improve_prompt.input"}}},{"title":"assist.suggest_text","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"assist.suggest_text"},"input":{"$ref":"#/components/schemas/assist.suggest_text.input"}}},{"title":"assist.write_reel_script","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"assist.write_reel_script"},"input":{"$ref":"#/components/schemas/assist.write_reel_script.input"}}},{"title":"assist.write_post_plan","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"assist.write_post_plan"},"input":{"$ref":"#/components/schemas/assist.write_post_plan.input"}}},{"title":"assist.suggest_formats","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"assist.suggest_formats"},"input":{"$ref":"#/components/schemas/assist.suggest_formats.input"}}},{"title":"assist.shape_idea","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"assist.shape_idea"},"input":{"$ref":"#/components/schemas/assist.shape_idea.input"}}},{"title":"assist.suggest_ideas","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"assist.suggest_ideas"},"input":{"$ref":"#/components/schemas/assist.suggest_ideas.input"}}},{"title":"assist.develop_idea","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"assist.develop_idea"},"input":{"$ref":"#/components/schemas/assist.develop_idea.input"}}},{"title":"assist.recommend_model","type":"object","required":["offering","input"],"additionalProperties":false,"properties":{"offering":{"const":"assist.recommend_model"},"input":{"$ref":"#/components/schemas/assist.recommend_model.input"}}}]}},"responses":{"Error":{"description":"An error: `{ error: { code, message, details? } }`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"No valid credential (`unauthorized`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The credential lacks a scope (`forbidden`), or the route needs a browser session (`session_required`), or CSRF failed (`csrf_failed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"smp_<43 base64url characters>","description":"An access token. Its scopes are listed per operation in `x-scopes`."},"sessionCookie":{"type":"apiKey","in":"cookie","name":"__Host-smp_session","description":"Browser session; unsafe methods also need `X-CSRF-Token`."}}}}