Errors

Public API errors

Every error response is an RFC 9457 Problem Details document (application/problem+json):

  • code is the stable machine string to branch on. type links to this page (https://developers.synthesia.io/docs/errors#<code>) — it's documentation, not an identifier, and its URL may change.
  • detail is human-readable and may change without notice; each code below shows example
    messages ({braces} mark request-specific values).
  • requestId (also the Request-Id header) identifies the request in Synthesia's logs —
    include it when contacting support.
  • New codes may appear over time; a rare unmapped 4xx surfaces as http_<status>, and an
    unexpected 5xx keeps its status with code internal. Handle any response you don't
    recognize by its HTTP status.
Statuscodetitle
400bad_requestBad request
400validation_errorInvalid request
401api_key_expiredAPI key expired
401unauthenticatedUnauthenticated
402feature_not_in_planFeature not in plan
402no_creditNo credit
402payment_requiredPayment required
402quota_exceededQuota exceeded
403forbiddenForbidden
403insufficient_scopeInsufficient scope
404not_foundNot found
404unknown_referenceUnknown reference
405method_not_allowedMethod not allowed
409conflictConflict
413payload_too_largePayload too large
415unsupported_media_typeUnsupported media type
429concurrency_limitConcurrency limit exceeded
429rate_limitedRate limit exceeded
500internalInternal error
503admission_unavailableAdmission temporarily unavailable
503service_unavailableService unavailable
504timeoutUpstream timeout

bad_request

Bad request — status 400 — type

The request could not be parsed as sent — usually a body that is not JSON. Fix the request before retrying; an unchanged retry fails the same way.

Example detail messages:

  • The request body is missing or null. Send a JSON object.
  • The request body is not valid JSON. Send a JSON object.
  • The request body was not sent as JSON. Set the Content-Type header to application/json.

validation_error

Invalid request — status 400 — type

One or more request fields were rejected. Fix the fields detail lists and resend; an unchanged retry fails the same way.

For a rejected request body, detail lists each rejected field as path: message, joined with ; ; other validation denials use the standalone messages below.

Example detail messages:

  • Not a valid {concept} id.
  • One or more fields were rejected.
  • The supplied livekitToken cannot be used to join the room.

api_key_expired

API key expired — status 401 — type

The API key is genuine but past its expiry date. Not retryable with this key — create a new key and use it instead. The WWW-Authenticate: Bearer header carries error="invalid_token".

Example detail messages:

  • Your API key has expired. Create a new key and retry with it.

unauthenticated

Unauthenticated — status 401 — type

The request carried no usable API key. Send your key as Authorization: Bearer <key>. An unknown or revoked key is reported only as invalid; an expired key answers api_key_expired instead. The WWW-Authenticate: Bearer header carries realm alone when no key was sent, error="invalid_request" for an Authorization scheme other than Bearer, and error="invalid_token" for a rejected key.

Example detail messages:

  • Invalid API key.
  • Provide your API key in the Authorization header.
  • Unsupported Authorization scheme. Send your API key as 'Authorization: Bearer '.

feature_not_in_plan

Feature not in plan — status 402 — type

Your workspace's plan does not include a feature this endpoint requires; features names it. Not retryable — upgrade the plan or contact your account manager.

Example detail messages:

  • Your plan does not include interactive avatars — upgrade to use this API.
  • Your plan does not include the '{feature}' feature.

no_credit

No credit — status 402 — type

Your workspace has no credit remaining for the metered feature this request consumes. Not retryable until the balance is positive again — top up or upgrade your plan.

Example detail messages:

  • Your plan has no interactive avatar credits. Top up or upgrade to create interactive avatars.

payment_required

Payment required — status 402 — type

The request was declined for billing reasons, such as exhausted credits. Resolve the billing condition, then retry.

quota_exceeded

Quota exceeded — status 402 — type

A usage quota in your plan is used up. Not retryable until your quota is increased or replenished — upgrade your plan or contact your account manager.

Example detail messages:

  • Your session quota is exhausted.

forbidden

Forbidden — status 403 — type

Your API key is valid but not permitted to do this — the resource may belong to another workspace, or your account may lack the required permission. If you believe you should have access, check with your workspace admin.

insufficient_scope

Insufficient scope — status 403 — type

Your API key does not carry the scope this endpoint requires; detail names it, as does scope in the WWW-Authenticate: Bearer error="insufficient_scope" header. Use or create a key with that scope — retrying with the same key fails the same way.

Example detail messages:

  • Your API key does not have the '{scope}' scope this endpoint requires.

not_found

Not found — status 404 — type

Nothing exists at this URL. Check the path and any resource id in it.

unknown_reference

Unknown reference — status 404 — type

The request referenced a resource that does not exist or is not accessible to your workspace. Fix the referenced id and resend.

Example detail messages:

  • One or more of avatarIds does not exist or is not accessible.
  • The referenced avatar, outfit or person does not exist or is not accessible.

method_not_allowed

Method not allowed — status 405 — type

The URL exists, but not for this HTTP method. The Allow header lists the methods it supports.

conflict

Conflict — status 409 — type

The request conflicts with the resource's current state. Fetch the resource, reconcile, and resend.

payload_too_large

Payload too large — status 413 — type

The request body exceeds the size this endpoint accepts. Reduce the payload and resend.

unsupported_media_type

Unsupported media type — status 415 — type

The request's Content-Type is not one this endpoint accepts. Send the body as application/json unless the endpoint documents otherwise.

concurrency_limit

Concurrency limit exceeded — status 429 — type

Your plan's ceiling on concurrently running sessions is reached. Retryable — end an active session or wait for one to finish, honoring Retry-After when present.

Carries Retry-After when Enact sends a wait interval. When known, detail leads with the caller's plan numbers and keeps the guidance to end or wait for a session.

Example detail messages:

  • Too many sessions are running concurrently for your plan. End an active session or wait for one to end.

rate_limited

Rate limit exceeded — status 429 — type

Too many requests in the current window. Retryable — back off for the Retry-After interval, then resend the same request.

The facade's own denials carry RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset-At and Retry-After headers; a domain's 429 carries at most Retry-After.

Example detail messages:

  • Too many requests. Retry after the interval in the Retry-After header.

internal

Internal error — status 500 — type

Something unexpected failed on Synthesia's side. Usually safe to retry; for a request that creates a resource, check whether the operation went through first. If it persists, contact support and quote the requestId.

Example detail messages:

  • An unexpected error occurred.

admission_unavailable

Admission temporarily unavailable — status 503 — type

A billing or rate decision this request needs could not be obtained, so it was denied rather than admitted unchecked. Transient — retry with backoff, honoring Retry-After when present.

Example detail messages:

  • Admission is temporarily unavailable. Retry shortly.

service_unavailable

Service unavailable — status 503 — type

A service this request needs is temporarily unavailable. Transient — retry with backoff, honoring Retry-After when present and any instruction in detail. If it persists, contact support and quote the requestId.

Example detail messages:

  • Authentication is temporarily unavailable. Retry shortly.
  • Plan features for this request could not be verified. Retry shortly.
  • Temporarily unable to create an interactive avatar. Retry the same request with regenerate off.
  • Temporarily unable to read credits. Retry shortly.
  • Temporarily unable to start a session. If you retry, reuse the same livekitUrl and livekitToken.
  • The session could not be started. Retry shortly.

timeout

Upstream timeout — status 504 — type

The request did not finish within its deadline. The underlying operation may still have gone through — follow the guidance in detail on how to retry or poll safely, otherwise retry with backoff.

Example detail messages:

  • Authentication is temporarily unavailable. Retry shortly.
  • Plan features for this request could not be verified. Retry shortly.
  • The request did not complete within its {deadline}s deadline.
  • The session did not start before the deadline. It may still start. If you retry, reuse the same livekitUrl and livekitToken.
  • Timed out reading credits. Retry shortly.
  • Timed out waiting for the avatar status. Generation may still be running; repeat the same request with regenerate off to poll.
  • Timed out waiting for the session to start. It may still start. If you retry, reuse the same livekitUrl and livekitToken.