| avatar_unavailable | 400 | A presenter circle was asked for on a deployment where the presenter is switched off. | Make the video without one. While the presenter is off, avatarId is not declared on the public schemas at all, so a public caller meets validation_failed first. |
|---|
| avatar_unknown | 400 | The avatarId named is not in the catalogue. | Read GET /catalog/render-options and send an id from avatars. |
|---|
| background_unknown | 400 | The background named is not in the catalogue. | Read GET /catalog/render-options and send an id from backgrounds, or omit the field for the default. |
|---|
| caption_style_unknown | 400 | The captionStyle named is not in the catalogue. | Read GET /catalog/render-options and send an id from captionStyles. |
|---|
| capture_incompatible | 400 | A phone view capture was paired with a landscape orientation. Phone view only makes a portrait video. | Pick a portrait orientation, or switch the capture to a computer window. |
|---|
| capture_unknown | 400 | The capture named is not in the catalogue. | Read GET /catalog/render-options and send an id from captures. |
|---|
| hint_required | 400 | The hint is missing, or it is empty once trimmed. The schema requires 3 to 1000 characters and the service refuses a blank one before a browser is started. | Say what to show in a sentence, for example "show the invoice creation flow". Nothing checks that a hint is specific, so a thin one is accepted and produces a poor video; storyboards.improveHint rewrites one before you spend anything. |
|---|
| hint_too_long | 400 | The hint is longer than 1000 characters. | Shorten it. storyboards.improveHint rewrites a long brief into the form that plans most reliably, within the same bound. |
|---|
| idempotency_key_required | 400 | A mutating operation arrived over HTTP with no Idempotency-Key header. It is refused before the body is parsed, so a caller missing both learns about both at once. | Add an Idempotency-Key header of up to 128 characters, unique to this request. Over MCP the same value goes in the idempotencyKey tool argument. |
|---|
| idempotency_key_unscoped | 400 | An idempotency key arrived on a request with no account to scope it to. | Call with an API key or a signed in session. An unscoped key would deduplicate nothing. |
|---|
| language_unknown | 400 | The language named is not in the catalogue. | Read GET /catalog/render-options and send a code from languages. |
|---|
| length_below_minimum | 400 | The length asked for is shorter than a walkthrough can be. The floor is 30 seconds. | Ask for at least 30 seconds, or omit targetSeconds for Auto, which sizes itself. |
|---|
| login_origins_invalid | 400 | The list of additional sign-in addresses sent with the demo credentials is not valid: more than five entries, an entry that is not https, or an address this API will not fetch. | Send only the https origins the sign-in flow really passes through, each a public address, and retry. |
|---|
| login_url_invalid | 400 | The login page address is not one this API will fetch: a private address, a name that does not resolve, or an address that is not https. The sign-in page must be https because the demo account's password is typed there. | Send a public https address for the page the demo account signs in on. |
|---|
| login_url_required | 400 | A credentials block was sent without loginUrl. Without it the run can only infer where the app is, and a wrong inference produces a video of the wrong thing. | Add credentials.loginUrl, the address of the page those credentials sign in on. The credentials block itself stays optional. |
|---|
| options_invalid | 400 | The render options do not resolve together, for a reason the per field codes do not cover. | Re-read GET /catalog/render-options and send a combination it offers. renders.quote prices options without creating anything. |
|---|
| orientation_unknown | 400 | The orientation named is not in the catalogue. | Read GET /catalog/render-options and send an id from orientations. |
|---|
| site_not_allowed | 400 | The website is a major public platform (a social network, search engine, marketplace or big portal) or a site about a sensitive topic (adult content, gambling, drugs, weapons, hate or violence). details.reason says which: public_platform or sensitive_topic. A sign-in address on a sensitive-topic site is refused too, and so is a sign-in that lands on a refused site. | Use your own product's website. No time was used. If you think your site was refused by mistake, write to support@gogoscreen.com or open a ticket with "Talk to a person": support can allow a site by name. |
|---|
| template_unknown | 400 | The templateId named is neither a system template nor one of this account's saved templates. | Read GET /catalog/render-options and send an id it lists, or a saved template id from GET /templates. |
|---|
| url_invalid | 400 | The address is not one this API will fetch, for a reason the more specific codes do not cover. | Send an absolute public http or https URL. |
|---|
| url_malformed | 400 | The address could not be parsed as a URL. | Send an absolute URL including the scheme. |
|---|
| url_private | 400 | The address resolves to a private, loopback, link local, carrier grade NAT or IPv4 mapped IPv6 address. This API will not fetch inside a network. | Point at a publicly reachable address. There is no way to opt out of this guard. |
|---|
| validation_failed | 400 | The merged path, query and body did not match the operation's schema. The schemas are strict, so an unknown field is a failure rather than something ignored, and a string carrying half of a character is refused before it can be stored. | Read details.issues. Each entry carries a path, a message and a machine readable code. Fix every named field and send the request again; the same body always fails the same way. |
|---|
| voice_language | 400 | The voice chosen does not speak the language chosen. | Read GET /catalog/voices and pick a voice listed for that language, or change the language. |
|---|
| voice_unknown | 400 | The voiceId named is not in the catalogue. | Read GET /catalog/voices and send an id it lists. |
|---|
| unauthorized | 401 | No credential was presented, or the key is unknown, revoked or expired, or an X-API-Key header carried something that is not an API key. details.reason says which. | Send Authorization: Bearer gsk_live_…. A revoked or expired key never starts working again, so issue a new one in the developer console. Put a dashboard session token in Authorization, never in X-API-Key. |
|---|
| insufficient_seconds | 402 | The account's seconds wallet does not hold enough time for the video that was asked for. It is the only refusal on this surface that is a 402. | details.needed and details.available are the two numbers. Buy more time, or ask for a shorter video. Retrying without changing either fails the same way. |
|---|
| forbidden_scope | 403 | The credential does not carry every scope the operation declares, or it is the wrong kind of credential for it. keys.* and assistant.* are user only and can never be called by a key. | details.requiredScopes and details.missingScopes name what is missing. A key's scopes cannot be changed after it is issued, so create a new key with them. When details.allowedActors is present, no key can call this operation at all. |
|---|
| not_found | 404 | No resource of that id belongs to this account. A resource that belongs to somebody else answers 404 as well, never 403. | Check the id. Do not treat this as a permissions problem. |
|---|
| conflict | 409 | The request conflicts with the state the resource is in, and no more specific code applies. | Re-read the resource and decide from its current state. Retrying the same request unchanged will not help. |
|---|
| idempotency_conflict | 409 | That idempotency key has already been used on this operation with a different request body. | Use a fresh key for a different request. A key stands for one intent, not for one attempt. |
|---|
| idempotency_in_progress | 409 | The first request under that key is still being worked. Two concurrent identical requests both reach the store and one of them is told this. | Wait the Retry-After seconds, which is 2, and send exactly the same request again with the same key. Do not change the body and do not mint a new key. |
|---|
| storyboard_in_flight | 409 | A plan is already being made on this account. One at a time. | Poll the running storyboard until state is terminal, or cancel it, then plan again. |
|---|
| payload_too_large | 413 | The request body is over the transport's limit: 256 kb over HTTP, 1 mb over MCP. | Send less. details.limit carries the limit. Version 1 has no upload operations, so a body this size is usually a mistake. |
|---|
| unsupported_media_type | 415 | The request carried a body whose Content-Type is not application/json, whose charset is not utf-8, or whose Content-Encoding this API does not decode. A body nobody can read would otherwise be silently discarded. | Send Content-Type: application/json and utf-8 bytes. details names the charset, encoding or content type that was objected to. |
|---|
| anon_lifetime_cap | 429 | An anonymous free tier session has planned as many walkthroughs as it may. It cannot be reached from the public API, which never mints an anonymous session. | Call with an API key. The free tier is a dashboard funnel, not part of this surface. |
|---|
| origin_daily_cap | 429 | That website has been planned as many times today as it may be, across all accounts. | Try again tomorrow, or plan a different site. |
|---|
| rate_limited | 429 | The credential's per minute budget, the account's per minute ceiling, or a daily cap was exceeded. details.scope is minute, day or account, or global when the product's own daily cap on voice previews is spent. | Wait the Retry-After seconds and retry. details.limit and details.resetAt say what was hit and when it reopens. The RateLimit-* headers on every answer let a client pace itself before it gets here. |
|---|
| internal_error | 500 | An unhandled failure inside this API. The original message is logged and never answered. | Retry once, then quote requestId to support. A 5xx deletes the idempotency claim rather than storing it, so retrying under the same key is safe. |
|---|
| abuse_check_unavailable | 503 | The abuse check that runs before planning starts could not be reached, so the request was refused rather than run without it. | Back off and try again in a minute. Nothing was created and nothing was charged. |
|---|
| budget_exhausted | 503 | Today's planning capacity is used up, so no new plan is started today. | Try again tomorrow. Nothing was created and nothing was charged. |
|---|
| queue_unavailable | 503 | The work could not be started because a service it needs was briefly unavailable. | Back off and retry. Nothing was created and nothing was charged. |
|---|
| vault_unavailable | 503 | The demo credentials could not be stored securely, so the run was refused rather than started without them. | Back off and retry. Nothing was created and nothing was charged. |
|---|