Agent Error Recovery & Idempotency

Every SIMOSphere AI endpoint returns structured JSON errors with a stable type field, machine-readable retry guidance, and idempotency support. This page documents the contract AI agents can rely on.

Error envelope

Every 4xx and 5xx response uses the same shape:

{
  "error": {
    "message": "Human-readable explanation",
    "type": "rate_limit",
    "code": "RATE_LIMIT_EXCEEDED",
    "param": "query",
    "retry_after": 42
  }
}

Error types

typeHTTPRetry?Meaning
validation_error400No (fix input)Request body or params malformed.
auth_error401NoMissing or invalid API key.
permission_error403NoAuthenticated but lacks scope.
not_found404NoResource missing or expired (e.g. async job after 30 min).
idempotency_conflict409No (use a new key)Idempotency-Key already used with a different body.
rate_limit429Yes (after retry_after)Quota exceeded. Wait, then retry.
server_error5xxYes (exponential backoff)Transient upstream failure.
byok_provider_missing402NoBYOK model requested but no provider key configured.

Idempotency-Key

Mutating endpoints accept the Idempotency-Key header. Sending the same key with the same body within 24h returns the original response — safe to retry without creating duplicates.

POST /api/jobs HTTP/1.1
Host: simosphereai.com
Content-Type: application/json
Idempotency-Key: 6f7b1f5c-9c4e-4a3a-9ec2-ef2c5e3a8e80

{"type": "ask", "input": {"query": "What is SIMOSphere AI?"}}

Rate limits & backoff

Every response carries RFC 9598 rate-limit headers:

RateLimit-Limit: 60;w=3600
RateLimit-Remaining: 47
RateLimit-Reset: 1842
RateLimit-Policy: "nlweb-ask";q=60;w=3600
Retry-After: 42

When a 429 is returned, agents must:

  1. Wait the number of seconds in Retry-After (or error.retry_after).
  2. Retry the request with the same Idempotency-Key.
  3. Use exponential backoff for repeated 429s — 1s → 2s → 4s → 8s capped at RateLimit-Reset.

Server errors (5xx)

Apply exponential backoff with jitter. Up to 3 retries for idempotent operations (GET, HEAD, or any mutation with an Idempotency-Key). Give up after 3 retries and surface the error to the user.

404 contract

Every non-existent URL under /api/* returns a JSON 404 — never HTML. Agents can rely on:

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8

{
  "error": {
    "message": "No API endpoint at /api/foo. See https://simosphereai.com/openapi.json",
    "type": "not_found",
    "code": "ENDPOINT_NOT_FOUND",
    "documentation_url": "https://simosphereai.com/openapi.json"
  }
}

SSE reconnect

The POST /api/ask.php endpoint with Prefer: streaming emits SSE events. If the connection drops:

Status page

Real-time health for every public endpoint:

Agent tip. When ambiguous, prefer a fresh Idempotency-Key over retrying the same key — duplicate side-effects are far more recoverable than masked errors.

Example: full retry loop (pseudocode)

idem = uuidv4()
for attempt in range(3):
    resp = POST /api/jobs
        Idempotency-Key: {idem}
        body: {type: "ask", input: {query: q}}
    if resp.status == 200 or resp.status == 202:
        return resp.json
    if resp.status in (429, 502, 503, 504):
        wait = resp.headers.get("Retry-After") or (2 ** attempt + jitter())
        sleep(wait)
        continue
    if resp.status in (400, 401, 403, 404, 409):
        raise FatalError(resp.json.error)
raise GiveUpError(resp.json.error)

SIMO GmbH · Würzburger Str. 152 · 63743 Aschaffenburg · Germany · HRB 15769 Aschaffenburg · Trademark DPMA 30 2024 240 269 · Impressum · Datenschutz