Skip to content

Error Reference

All Identity OS API errors follow a consistent format:

{
  "error": "error_code",
  "message": "Human-readable description"
}

Authentication Errors

Code HTTP Meaning Fix
unauthorized 401 Missing or invalid API key Check Authorization: Bearer idos_sk_xxx header
forbidden 403 Valid key but insufficient permissions Check your tier limits or contact support

Instance Errors

Code HTTP Meaning Fix
not_found 404 Instance ID doesn't exist Verify the instance_id; it may have been deleted
invalid_request 422 Missing required fields or invalid values Check request body matches the API spec
conflict 409 Concurrent modification detected Retry the request — optimistic locking will resolve

Engine Errors

Code HTTP Meaning Fix
not_found 404 Instance not found for processing Create the instance first via POST /v1/instances
invalid_request 422 Invalid mode_target or signal_strength mode_target must be one of the 7 modes; signal_strength must be 0.0–1.0
throttled 429 Too many requests in the current cycle Wait for MIN_CYCLE_INTERVAL to pass, or use caller-controlled timestamp

Rate Limiting Errors

Code HTTP Meaning Fix
rate_limited 429 Per-minute rate limit exceeded Check X-RateLimit-Reset header for when to retry
quota_exceeded 429 Monthly quota exhausted Upgrade your plan or wait for the next billing cycle
service_unavailable 503 Rate limiter backend unavailable (fail-closed mode) Transient — retry after a few seconds

Rate limit headers on every response:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1711324800
X-Monthly-Remaining: 99847

Billing Errors

Code HTTP Meaning Fix
stripe_not_configured 500 Stripe keys not set on the server Server admin: set STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET
webhook_verification_failed 400 Invalid Stripe webhook signature Ensure STRIPE_WEBHOOK_SECRET matches your Stripe dashboard
invalid_plan 422 Requested plan tier doesn't exist Valid tiers: free, indie, pro

Common Patterns

"I keep getting 429 throttled"

If you're sending observations faster than 1/second without caller-controlled timestamps:

# Fix: use explicit timestamps
from datetime import datetime, timezone, timedelta

base = datetime.now(timezone.utc)
for i in range(10):
    result = client.engine.process(
        instance_id=inst.id,
        mode_target=Mode.EXPLORATION,
        signal_strength=0.7,
        timestamp=(base + timedelta(seconds=i*2)).isoformat()
    )

"Instance not found after server restart"

If using the memory backend (default for local dev), all data is lost on restart. For persistent data:

# Use PostgreSQL
docker compose up -d
export IDENTITY_OS_DB_BACKEND=supabase
export IDENTITY_OS_SUPABASE_URL=postgresql+asyncpg://...

"Auth error but I set the API key"

Check the header format — must be exactly:

Authorization: Bearer idos_sk_your_key_here

Not ApiKey, not Token, not Basic. Bearer only.