Skip to content

REST Conventions

This page covers the conventions that apply across all Athena REST endpoints. For authentication details see Authentication. For the full error code catalog see Error Codes.


Request Format

AspectConvention
Content-Type (body)application/json
Content-Type (file upload)multipart/form-data
AuthenticationX-API-Key header
Workspace contextRaw UUIDv7 in the X-Workspace-Id header
IdempotencyIdempotency-Key: <uuid> header (optional, execution endpoints)

Response Format

Success

{
"data": { ... }
}

Error

{
"error": {
"code": "snake_case_string",
"message": "Human-readable description",
"details": { "field": "name", ... },
"timestamp": "2026-05-12T10:30:00Z",
"trace_id": "3f2e1d4c-..."
}
}

code is the stable machine-readable identifier. message can change. details is only present when a specific error includes structured context (e.g. validation field names, rate limit timing).


HTTP Status Codes

StatusMeaning
200 OKSuccess with body
201 CreatedResource created
204 No ContentSuccess, no body (e.g. DELETE)
400 Bad RequestValidation error, malformed request
401 UnauthorizedMissing or invalid credentials
402 Payment RequiredInsufficient credits
403 ForbiddenValid credentials, insufficient permissions
404 Not FoundResource does not exist
409 ConflictDuplicate request or conflicting state
429 Too Many RequestsRate limit exceeded
500 Internal Server ErrorUnexpected server error
502 Bad GatewayUpstream provider error
503 Service UnavailableFeature not configured or provider unavailable

Validation Errors

Validation errors include a details object with field-level messages:

{
"error": {
"code": "validation_error",
"message": "Validation error: message is required",
"details": { "field": "message" },
...
}
}

When multiple fields fail:

{
"error": {
"code": "validation_error",
"message": "Request validation failed",
"details": {
"errors": {
"email": ["Invalid email format"],
"role": ["Must be one of: owner, admin, member, guest"]
}
}
}
}

Pagination

List endpoints use cursor-based pagination:

GET /my/conversations?limit=20&cursor=opaque_cursor
ParameterDefaultMax
limit20100
cursorOpaque string from previous response

Response:

{
"data": [ ... ],
"next_cursor": "opaque_string"
}

next_cursor is null when the last page is reached.


Idempotency

Idempotency keys prevent duplicate execution charges and duplicate resource creation:

POST /agents/{id}/execute
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
ScenarioResult
First request with keyProcessed normally
Second request with same key409 Conflict — original response returned
Key reused after 24 hoursProcessed normally (key expired)
Request after 5xx failureGenerate a new key — old key is consumed

Rate Limits

When a rate limit is exceeded, the response is 429 with:

  • Retry-After: <seconds> — always present
  • X-RateLimit-Limit: <N> — present for request and token limits; omitted for cost limits
{
"error": {
"code": "rate_limit_requests_exceeded",
"message": "Request limit of 100 exceeded. Try again in 58 seconds.",
"details": {
"limit_type": "requests",
"scope_type": "customer",
"limit": 100,
"reset_in_seconds": 58
}
}
}

See Rate Limits for the full scope hierarchy and code descriptions.


Streaming (SSE)

Execution endpoints support Server-Sent Events for streaming LLM output:

POST /agents/{id}/execute/stream
Accept: text/event-stream

Each event is a data: line with a JSON payload:

data: {"type":"text","text":"Hello"}
data: {"type":"final","status":"Completed"}

If the client disconnects before the final event, the execution is marked Failed and any pre-deducted credits are refunded.


HTTPS Only

All API communication must use HTTPS. HTTP requests are redirected.