Aira

Gateway API

API reference for the Aira Gateway -- transparent LLM proxy endpoints, request and response headers, error formats.

Endpoints

The gateway is mounted at /gateway (no /api/v1 prefix) so the paths match what provider SDKs expect.

MethodPathWire FormatUpstream Default
POST/gateway/openai/v1/chat/completionsOpenAI-compatiblehttps://api.openai.com
POST/gateway/anthropic/v1/messagesAnthropic nativehttps://api.anthropic.com

Both endpoints accept the same request body that the upstream provider expects. The body is forwarded verbatim.

Feature Flag

The gateway requires ENABLE_GATEWAY=true in the backend configuration. This is enabled by default. When disabled, all /gateway/* routes return 404.

Request Headers

OpenAI-compatible endpoint

HeaderRequiredDescription
AuthorizationYesBearer sk-... -- your LLM provider API key, forwarded to upstream
X-Aira-Api-KeyYesaira_live_... -- your Aira API key, consumed by Aira
Content-TypeYesapplication/json
X-Aira-Upstream-UrlNoOverride the upstream base URL (e.g. https://api.deepseek.com)
OpenAI-OrganizationNoForwarded to upstream if present
OpenAI-ProjectNoForwarded to upstream if present

Anthropic endpoint

HeaderRequiredDescription
x-api-keyYessk-ant-... -- your Anthropic API key, forwarded to upstream
X-Aira-Api-KeyYesaira_live_... -- your Aira API key, consumed by Aira
Content-TypeYesapplication/json
anthropic-versionNoForwarded to upstream. Defaults to 2023-06-01 if omitted
anthropic-betaNoForwarded to upstream if present
X-Aira-Upstream-UrlNoOverride the upstream base URL

Response Headers

HeaderDescription
X-Aira-Action-UuidUUID of the Aira action created for this call. Present on all responses (success, error, and streaming).

For streaming responses, these additional headers are set:

HeaderValue
Cache-Controlno-cache
Connectionkeep-alive
X-Accel-Bufferingno

Success Response

On success, the gateway returns the upstream provider's response verbatim with the original status code (typically 200). The X-Aira-Action-Uuid header is added.

Error Responses

403 -- Policy Denied

Returned when an Aira policy blocks the request. The body uses the provider's native error format.

OpenAI format:

{
  "error": {
    "message": "Request denied by Aira policy",
    "type": "aira_policy_denied",
    "code": "policy_denied"
  }
}

Anthropic format:

{
  "type": "error",
  "error": {
    "type": "aira_policy_denied",
    "message": "Request denied by Aira policy"
  }
}

429 -- Pending Approval

Returned when the action requires human approval. Includes a Retry-After: 30 header.

OpenAI format:

{
  "error": {
    "message": "Request held for human approval. Check the Aira dashboard.",
    "type": "aira_pending_approval",
    "code": "pending_approval",
    "aira_action_uuid": "550e8400-e29b-41d4-a716-446655440000"
  }
}

Anthropic format:

{
  "type": "error",
  "error": {
    "type": "aira_pending_approval",
    "message": "Request held for human approval. Check the Aira dashboard."
  }
}

404 -- Gateway Disabled

Returned when ENABLE_GATEWAY is false.

{
  "detail": "Gateway is not enabled",
  "code": "NOT_FOUND"
}

500 -- Internal Gateway Error

Returned on unexpected failures. The upstream was not contacted.

OpenAI format:

{
  "error": {
    "message": "Internal gateway error",
    "type": "aira_internal_error",
    "code": "internal_error"
  }
}

Anthropic format:

{
  "type": "error",
  "error": {
    "type": "aira_internal_error",
    "message": "Internal gateway error"
  }
}

Upstream Errors

If the upstream provider returns an error (e.g. 401 invalid API key, 429 rate limit), the gateway forwards the upstream response and status code verbatim. The X-Aira-Action-Uuid header is still present, and the action is notarized with outcome failed.

Timeouts

The gateway uses a 2-minute read timeout (GATEWAY_TIMEOUT_MS=120000) to accommodate slow LLM responses. The connect timeout is 5 seconds.

Notarization Details

Each gateway call creates an action with action_type: gateway_llm_call. The action details include:

{
  "model": "gpt-4o",
  "prompt_hash": "sha256:abc123...",
  "upstream_url": "https://api.openai.com/v1/chat/completions",
  "wire_format": "openai",
  "stream": false,
  "message_length": 42,
  "scan_hits": 0,
  "scan_worst": null
}

After the response completes, the action is notarized with:

{
  "response_hash": "sha256:def456...",
  "upstream_status": 200,
  "latency_ms": 1234,
  "response_bytes": 5678
}

The prompt content itself is never stored -- only a SHA-256 hash.

On this page