Skip to Content

Errors

Every refusal is JSON with an error field, and refusals arrive in a fixed order: the gateway first, then your account standing, then the request itself, then the work. Two rules hold everywhere:

  • A refusal before generation never costs credits. Only a captured success bills you; failed generation is released in full.
  • 404 never confirms existence. A resource that is not yours answers exactly like one that does not exist.

Gateway refusals

These can happen on any endpoint, before anything else is considered.

StatusBodyWhen it happensWhat to do
404{"error": "Not found"} on every pathThe TrueTone API is disabled on the server itself. No request shape causes this, and you should never see it in normal serviceContact support; nothing on your side causes or fixes it
401{"error": "Invalid API key"}Missing or malformed Authorization header, unknown key, revoked key, expired key, or a key with no recognized Capability Groups. All deliberately identicalCheck the header shape, then mint or rotate the key in the dashboard
403{"error": "This API key does not grant the <name> capability", "requiredCapability": "<id>"}The key was not issued the endpoint’s Capability GroupMint a key that carries the named group
403{"error": "Your TrueTone account role no longer includes the <name> capability", "requiredCapability": "<id>"}The key carries a role-sensitive group but your live account role no longer includes itRe-minting will not help; your role has to change
429{"error": "Rate limit exceeded", "message": "...", "retryAfter": <seconds>} plus X-RateLimit-* and Retry-After headersToo many requests in this key’s window for this endpointWait the full Retry-After, then back off. Costs nothing

Account and budget refusals

The key is valid; the account or the budget said no.

StatusBodyWhen it happensWhat to do
403{"error": "API key has no organization binding"}The key’s organization link is gone, for example after an organization was deletedMint a fresh key from an account with an organization
402 usually; 401, 403, or 500 by policy{"error": "...", "code": "<denial code>", "message": "...", "redirectTo": "...", "requiresSetup": <bool>, "subscriptionStatus": "..."}The account’s subscription standing refuses paid work, for example subscription_inactive. There is no read carve-out; a canceled account reads nothing hereBranch on code; resolve billing in the dashboard
403{"error": "Forbidden", "code": "entitlement_scope_mismatch", "message": "..."}The key’s recorded organization no longer matches the owner’s live organizationMint a fresh key under the current organization
429{"error": "Monthly spending cap reached", "currentSpend": <n>, "spendingCap": <n>, "billingPeriod": "YYYY-MM"}The organization’s monthly cap is exhausted. Checked before reservation; nothing heldRaise the cap or wait for the period to roll
402{"error": "Monthly credit allowance reached", "code": "allocation_exceeded", "actionKey": "...", "requiredCredits": <n>, "allowanceRemaining": <n>}Your per-member allowance is spent while the organization still has creditsAsk your org admin for a larger allocation
402{"error": "Insufficient AI credits", "code": "insufficient_credits", "actionKey": "...", "requiredCredits": <n>, "availableCredits": <n>}The organization is out of creditsTop up or wait for the monthly reset

Request refusals

The request itself was defective. All of these are refused before anything runs or reserves.

StatusBodyWhen it happensWhat to do
400{"error": "Invalid <request> ...", "issues": {"<field>": ["<message>"]}}A field failed validation, or the body was not JSONFix the named fields; issues is keyed per field
400{"error": "invalid_request", "message": "..."}A scheduling request missing or misusing a required field; the message states exactly whichFollow the message
400{"error": "unsupported_creation_type", "requested": "...", "supported": [...]}Asking the generation endpoint for a type it does not make, such as an audiogramUse the endpoint the response points you toward
400{"error": "conflicting_parameters", "message": "..."}Asking a social post to both generate an image and use one from your libraryPass one image instruction, not both
400{"error": "<refusal reason>", "message": "..."}An image URL the asset door refuses: url_not_https, url_resolves_privately, url_unreachable, redirect_not_https, too_many_redirects, not_an_image, image_too_largeThe reason is stable; the message says how to fix it
400{"error": "template_too_complex"}A transform whose protected regions exceed what the rewriter will safely handleSplit the document or lock fewer regions

Resource refusals

StatusBodyWhen it happensWhat to do
404{"error": "not_found"}The id does not exist, is malformed, or belongs to someone else. Indistinguishable on purposeCheck the id against your own listings

State and outcome refusals

The request was well-formed; the work could not be done, or could not be done safely.

StatusBodyWhen it happensWhat to do
409{"error": "voice_not_configured", "message": "..."}Audio was requested but the account has no cloned voice yetRecord a voice sample in the dashboard first
409{"error": "not_schedulable", "message": "..."}The creation cannot go on the calendar as it stands: too soon, missing a title or caption, video not recorded, blog not publishedThe message names the missing precondition
422{"error": "locked_region_not_found", "unmatched": [...]}A locked region you named does not occur in source_textSend regions exactly as they appear in the text
422{"error": "unbalanced_conditional"}Template conditional syntax could not be read safelyBalance the conditional markers before sending
422{"error": "unclosed_lock_sentinel"}A lock marker was opened and never closedClose every lock marker
422{"error": "preservation_failed", "missing": [...], "duplicated": [...], "unknownPlaceholders": [...]}The rewrite damaged a protected span. Your credit is releasedRetry; consider fewer or larger locked regions
422{"error": "placement_failed", "contained": [...], "reordered": [...]}Every protected span survived but one landed somewhere unsafe or out of order. Your credit is releasedRetry
502{"error": "generation_failed"}The model call failed or returned nothing. Your reservation is released; never billedRetry with backoff
502{"error": "distribution_failed", "message": "...", "retryable": <bool>}The social publishing provider refused or could not be reachedIf retryable is true, retry later; if false, the message names what to fix, usually a connection in the dashboard
500{"error": "Internal Server Error"}Something unexpected on our side. Details are logged server-side, never leakedRetry with backoff; report it if it persists
⚠️

One success can still carry a failure: scheduling a post returns 200 even when the publishing provider rejects it, with the stored post carrying status: "failed" and an errorMessage. Always read post.status after scheduling. The walkthrough covers this in Seed to scheduled post.

Last updated on