Structured application errors use the following envelope. Not every error
currently has this shape (source reviewed 2026-09-10): SlowAPI may return a
string-valued error, FastAPI request validation may return a detail array,
and proxies can return non-JSON responses. Check the HTTP status, content type
and value types before accessing nested fields:
{
"error": {
"code": "INVALID_API_KEY",
"message": "Human-readable error description",
"type": "authentication_error",
"param": "optional_parameter_name",
"request_id": "req_abc123",
"retryable": false
}
}
Field
Description
code
Machine-readable error code (case may vary — see notes below)
message
Human-readable error description
type
Error classification (see below)
param
Optional: parameter name that caused the error
request_id
Correlation ID — also in X-Request-Id response header
retryable
Whether the operation is safe to retry (true, false, or null if not applicable)
Envelope Variations
Most errors return the canonical {"error": {...}} envelope. Some errors
(particularly validation and routing errors from the framework layer) may be
wrapped in a detail field:
{
"detail": {
"error": {
"code": "UNSUPPORTED_PARAMETER",
"type": "invalid_request_error",
"param": "tools",
"retryable": null
}
}
}
Client handling: Check for error at both the top level and under detail.
Always parse defensively — retryable may be null for errors where retry
semantics are not applicable.
Request ID
Every response includes an X-Request-Id header. If you send an X-Request-Id header in your request, it is echoed back. Otherwise, a new ID is generated. Include this ID when reporting issues.
Error Types
Type
Description
authentication_error
API key missing, invalid, or revoked
authorization_error
Access denied to a resource
account_error
Connected account issue
not_found_error
Resource not found
conversation_error
Conversation continuity issue
validation_error
Invalid request parameters
invalid_request_error
Request rejected (OpenAI-compatible type, used for unsupported parameters)
routing_error
Request routing failure (e.g., conversation not found)
rate_limit_error
Rate limit exceeded
timeout_error
Request or upstream timeout
upstream_error
Provider returned an error
feature_unavailable_error
Feature unavailable (e.g., image generation)
api_error
Generic API error
Error Code Case
Error codes are documented in UPPER_SNAKE_CASE for readability. Some API
responses may return codes in lowercase_snake_case (e.g., conversation_not_found
instead of CONVERSATION_NOT_FOUND). Always compare error codes
case-insensitively when implementing error handling logic.
Authentication Errors
Status
Code
Cause
Action
401
INVALID_API_KEY
Missing or invalid API key
Check your API key
401
MISSING_API_KEY
No Authorization header
Add Authorization: Bearer gmk_live_...
401
EXPIRED_API_KEY
Key has expired
Create a new key
401
REVOKED_API_KEY
Key has been revoked
Create a new key
401
USER_NOT_ACTIVE
Linked user account disabled
Contact your admin
Validation Errors
Status
Code
Type
Cause
Action
400
UNSUPPORTED_PARAMETER
invalid_request_error
Parameter not supported (e.g., tools, n>1)
Remove the parameter
422
VALIDATION_ERROR
validation_error
Request body validation failed
Fix the request body
Permission Errors
Status
Code
Cause
Action
403
TENANT_ACCESS_DENIED
Not permitted for this workspace
Check workspace membership
403
CONVERSATION_ACCESS_DENIED
API key doesn’t own conversation
Use the correct API key
403
ASSET_ACCESS_DENIED
No access to this asset
Check conversation ownership
403
MISSING_SCOPE
API key lacks a required scope (e.g. actions:read, actions:run)
Ask your workspace admin to grant the scope on the key
Routing Errors
Returned by the project-routing layer (type: routing_error) when routing
headers or bindings cannot resolve an eligible destination:
Status
Code
Cause
Action
404
upstream_project_not_found
X-GhostMind-Upstream-Project slug not found or not active
Check GET /v1/projects for valid slugs
403
upstream_project_out_of_scope
Key not allowed to select that upstream project
Add a routing binding or use an allowed project
404
project_not_found
X-GhostMind-Project internal slug not found
Verify the internal project slug
422
wrong_project_header
An upstream project slug was passed in X-GhostMind-Project
Use X-GhostMind-Upstream-Project instead
403
project_out_of_scope
Key is bound to a different internal project
Use the key’s bound project or a key without project binding
404
route_profile_not_found
X-GhostMind-Route-Profile slug not found
Check the profile slug
422
upstream_project_not_configured
No eligible project and routing policy does not allow general space
Create a project or relax the tenant routing policy
Account Errors
Status
Code
Cause
Action
403
ACCOUNT_NOT_CONNECTED
No active ChatGPT account
Connect an account in the dashboard
403
UPSTREAM_ACCOUNT_NOT_AUTHORIZED
Upstream account tier cannot attach files to projects
Use conversation attachments instead; check capabilities.project_files
409
ACCOUNT_NOT_ACTIVE
Account is not active
Check connection status
503
NO_HEALTHY_SESSION
No healthy upstream session
Check connection status
503
ACCOUNT_REAUTH_REQUIRED
Session needs reconnection
Reconnect in dashboard
503
IMAGE_GENERATION_UNAVAILABLE
Image generation failed (plan/quota)
Do not retry blindly; check account plan
Conversation Errors
Status
Code
Cause
Action
404
CONVERSATION_NOT_FOUND
Conversation doesn’t exist
Verify the ID
403
CONVERSATION_ACCESS_DENIED
Not your conversation
Use the correct API key
410
CONVERSATION_DELETED_UPSTREAM
Deleted in ChatGPT
Start a new conversation
403
CONVERSATION_ACCESS_LOST
Access lost
Renew the account session
419
CONVERSATION_SESSION_EXPIRED
Session expired
Renew the session
409
CONVERSATION_CONTINUITY_LOST
Parent chain broken
Start a new conversation
409
CONVERSATION_PROJECT_UNAVAILABLE
Project no longer available
Use a different project
503
CONVERSATION_UPSTREAM_UNAVAILABLE
Account temporarily down
Retry later
Project Errors
Status
Code
Cause
Action
404
PROJECT_NOT_FOUND
Project doesn’t exist
Verify the ID
422
INVALID_MEMORY_POLICY
Invalid memory_policy value
Use: provider_default, account_connected, or project_only
409
PROJECT_ALREADY_EXISTS
Project with same ID exists
Use a different name
502
PROJECT_CREATE_FAILED
Upstream creation failed
Check account status
502
PROJECT_UPDATE_FAILED
Upstream update failed
Check account status
File / Asset Errors
Status
Code
Cause
Action
413
FILE_TOO_LARGE
File exceeds 10MB
Use a smaller file
400
UNSUPPORTED_FILE_TYPE
MIME type not supported
Check supported formats
502
UPLOAD_FAILED
Upload to provider failed
Retry
404
ASSET_NOT_FOUND
Asset doesn’t exist
Verify the ID
409
ASSET_NOT_READY
Asset still processing
Poll until ready
Audio Errors
Status
Code
Cause
Action
503
TRANSCRIPTION_FAILED
Transcription failed
Check audio format
504
TRANSCRIPTION_TIMEOUT
Transcription timed out
Use shorter audio
404
AUDIO_JOB_NOT_FOUND
Job doesn’t exist
Verify the job ID
429
AUDIO_QUOTA_EXCEEDED
Audio quota exceeded
Wait for reset
Provider Errors
Status
Code
Cause
Action
429
PROVIDER_RATE_LIMITED
Provider rate limited
Slow down request rate
503
PROVIDER_UNAVAILABLE
Provider unavailable
Retry later
504
PROVIDER_TIMEOUT
Provider timed out
Retry
400
INVALID_REQUEST
Upstream rejected the request
Fix the request parameters
403
ACCOUNT_REAUTH_REQUIRED
ChatGPT session expired
Reconnect the account in the User App
Streaming Errors
During streaming, provider/session errors are emitted as structured
response.failed lifecycle events — not as assistant content text.
Critical: Never interpret error text as assistant content. Stop reading
the stream on response.failed and check error.retryable.
Retryable Errors
retryable: true indicates a potentially transient failure, not a guarantee
that replaying a write is safe. After a timeout or broken stream, reconcile
job/run state and possible external effects before retrying. Use bounded backoff
and the operation’s idempotency contract where supported. Transient codes include:
PROVIDER_RATE_LIMITED
PROVIDER_UNAVAILABLE
PROVIDER_TIMEOUT
CONVERSATION_UPSTREAM_UNAVAILABLE
TIMEOUT
Not retryable — do not retry without addressing the root cause:
NO_HEALTHY_SESSION — no eligible session was selected. This alone does not
prove permanent session death: inspect connection, pool and cooldown state.
Reconnect when authentication expiry is confirmed, not for every routing failure.
ACCOUNT_REAUTH_REQUIRED — the session expired; reconnect in the User App
IMAGE_GENERATION_UNAVAILABLE — the account/plan cannot generate images for
this request; retrying re-triggers the same fallback and burns quota