Skip to main content

Errors

The SpAItial Developer API uses conventional HTTP status codes and returns a stable JSON envelope on every error.

Error shape​

All errors emitted by the API share the same shape:

{
"error": {
"code": "INVALID_INPUT",
"message": "Human-readable description of what went wrong.",
"request_id": "optional trace id",
"details": { "optional": "structured context" }
}
}

Always branch on error.code, not on the human-readable message. The code field is stable.

HTTP status codes​

StatusMeaningTypical error.code
400Malformed request — bad JSON, missing required field, wrong content type.INVALID_INPUT
401Missing, malformed, or revoked API key.UNAUTHORIZED
402Account does not have enough generation credits. details has required_credits and available_credits.INSUFFICIENT_CREDITS
403Authenticated but the key lacks the required scope, or moderation blocked the input.FORBIDDEN, MODERATION_REJECTED
404Resource does not exist (e.g. unknown request_id, file_id, or panorama_id).REQUEST_NOT_FOUND, FILE_NOT_FOUND, PANORAMA_NOT_FOUND
409Idempotency key was reused with a different payload, the requested world/artifact is not ready yet, or a resource is still processing and can't be deleted.IDEMPOTENCY_KEY_REUSED, RESOURCE_NOT_READY, RESOURCE_NOT_DELETABLE
410Short-lived resource has expired.PANORAMA_EXPIRED
422Payload parsed but semantically invalid (validation rule violated).VALIDATION_FAILED
429Rate limit exceeded, or too many of your worlds are already generating — see Rate Limits.RATE_LIMIT_EXCEEDED, WORLD_USER_LIMIT
503World generation intake is paused or temporarily unavailable. Retry later.WORLD_INTAKE_PAUSED, WORLD_INTAKE_UNAVAILABLE
5xxUnexpected server error. Safe to retry with backoff.INTERNAL_ERROR, EDIT_FAILED

Retry strategy​

  • 4xx responses are not retryable by themselves — fix the request first. The exceptions are 409 RESOURCE_NOT_READY (poll again later), 409 RESOURCE_NOT_DELETABLE (cancel the request, or wait for it to finish, then delete again), 409 IDEMPOTENCY_KEY_REUSED (resolve the collision and pick a new key), 429 RATE_LIMIT_EXCEEDED (wait until the window resets — the response includes Retry-After), and 429 WORLD_USER_LIMIT (wait for one of your in-flight worlds to finish).
  • 5xx responses are retryable. Use exponential backoff with jitter, capped at a reasonable ceiling (for example 30s). Pair retries with an Idempotency-Key on mutating endpoints so retries do not produce duplicates.

Panorama edit errors​

Panorama editing adds a few resource-specific codes:

CodeHTTPMeaning
PANORAMA_NOT_FOUND404The pano_... does not exist or is not owned by the caller.
PANORAMA_EXPIRED410The edited panorama has passed its 24-hour TTL.
EDIT_FAILED503The upstream panorama edit failed after the request was accepted. Retry with a fresh or idempotent request.

Validation errors​

400 INVALID_INPUT responses for a malformed body, path parameter, or query parameter name the failing fields in message and list every issue in details.issues. Use it to surface actionable feedback to your users without re-implementing the schema check.

{
"error": {
"code": "INVALID_INPUT",
"message": "Validation failed: webhook.url: Invalid URL",
"details": {
"issues": [{ "path": "webhook.url", "message": "Invalid URL" }]
}
}
}