Skip to content

Errors

Every error is JSON with a message. Some errors also carry a code you can branch on. Some carry details.

StatusMeaningBody
400Validation failed, or a user input error{ message: "Validation Failed", details: { "body.date": { message, value } } }
401No key, an unknown key, or an expired key{ message, code: "UNAUTHENTICATED" } or { message, code: "API_KEY_EXPIRED" }
403A valid key without the scope the route needs{ message, code: "INSUFFICIENT_SCOPE" }
403A resource owned by another organization, on most routes{ message, code: "FORBIDDEN" }
404Not found, or a theme owned by another organization{ message }
409A graphic is locked, a publish conflicts, or a stored graphic asset fails verification{ message, code }; LOCKED also includes holder.userName
429The rate limit is exceeded while enforcement is on{ message }
500Unexpected. Retry once, then contact support{ message }

For a 500, send the traceparent header value you used to support. It lets LIGR find your request.

codeStatusWhenFix
API_KEY_EXPIRED401The key passed its expiry dateCreate a new key in the dashboard
INSUFFICIENT_SCOPE403The key lacks the scope the route needs. The message names the scopeCreate a key with that scope
LOCKED409Someone has the graphic open in the dashboard editor, or a stale lock has not expired. A lock expires after 60 secondsWait, then retry. holder.userName names the editor
CONFLICT409Two publishes racedRead the theme again, then publish again
GRAPHIC_ASSET_MISSING409A graphic or theme publish references an S3 asset that is missingUpload the missing asset, then publish again
GRAPHIC_ASSET_INVALID409An asset cannot be read, or its stored size or SHA-256 differs from the recorded valueReplace the asset with the intended bytes, then publish again
CODE_GRAPHIC_INVALID400An unknown control variable type, or a bundle that names a file you did not upload in the session it names and the graphic does not already holdRead details[]. Each line is one problem. Upload the named file, then record the bundle with the uploadSessionId of that upload
BUNDLE_TOO_LARGE400The bundle is over 10 MiB, or one file is over 5 MiBRead details[]. It lists the files that are too large
THEME_LIMIT_REACHED409Your organization already owns five themesDelete a theme you no longer use, or ask your LIGR contact
THEME_IN_USE409A competition still uses the theme you want to deleteRead details[]. Remove the theme instance from each competition, then delete again
GRAPHIC_TYPE_MISMATCH400The id belongs to a Rive graphic, and the route serves code graphicsUse the Rive graphics routes for a Rive graphic
INVALID_ASSET_PATH400A file name holds .., an empty segment, a control character, or one of ?, #, %Rename the file
RUNTIME_HAS_NO_EDITABLE_SOURCE400A raw .riv upload requested source retentionSend retainSource: false. The runtime revision preserves those bytes
INVALID_SELECTION422The chosen artboard, state machine, or archive entry is unavailableRead current import metadata, then send an exact returned index or entry
SCRIPT_SIGNING_UNSUPPORTED422Source requires script signing, which this converter cannot performExport a signed .riv externally, then upload the runtime
IMPORT_UNAVAILABLE503Source import is disabled or not qualified in this environmentRead the capability response and use an available path

A 400 from schema validation names each bad field.

400 Bad Request
{
"message": "Validation Failed",
"details": {
"body.date": {
"message": "invalid ISO 8601 date",
"value": "12-09-2026"
}
}
}
StatusRetry?
400, 401, 403, 404No. Fix the request
409For LOCKED or CONFLICT, retry after resolving the conflict. For GRAPHIC_ASSET_*, repair the asset first
429Yes, after the RateLimit-Reset seconds. See Rate limits
500Once. Then contact support

Make write requests safe to repeat. Read the entity back before you write it again.