Authentication Flow

Every /v1 request (except health) passes through a fixed middleware pipeline: API-key authentication, request logging, then rate limiting.

The Bearer key

Send your key in the Authorization header on every request:

bash
Authorization: Bearer carrier_sk_live_xxxxxxxxxxxx

The API accepts secret keys (carrier_sk_…) and publishable keys (carrier_pk_…). Protected endpoints (chat, sessions, files, search, usage) require a secret key — see Authentication.

The request pipeline

text
Request  →  GET /v1/health ─────────────────────────► (public, no key)

Request  →  /v1/* (everything else)
              │
              ▼
        authenticateApiKey   validate Bearer key → attach scope, or 401
              │
              ▼
        requestLogger        record the request, stamp X-Request-Id
              │
              ▼
        rateLimiter          enforce the key's daily limit, or 429
              │
              ▼
        route handler        chat / sessions / files / …

1. Authentication

authenticateApiKey parses the Bearer token, validates the key, and attaches the resolved scope to the request:

FieldTypeDescription
req.apiKeyobjectid, name, type, workspaceId, projectId, userId
req.workspaceobjectThe key's workspace record
req.projectobjectThe key's project record

It also updates the key's last-used timestamp. A missing, malformed, or invalid key never reaches your route — it is rejected with 401.

2. Request logging

requestLogger writes one row per request to developer_request_logs — capturing tokens, estimated cost, model, Carrier mode, and session id — and stamps an X-Request-Id response header. Writes are best-effort, so a logging hiccup never blocks your request. These rows power the dashboard Logs and Usage views.

3. Rate limiting

rateLimiter enforces a per-key daily limit based on the key's tier. It counts the day's logged requests and sets standard headers:

FieldTypeDescription
X-RateLimit-LimitheaderRequests allowed per day for the key's tier (or "unlimited")
X-RateLimit-RemainingheaderRequests left in the current window
X-RateLimit-ResetheaderUnix time when the window resets (next UTC midnight)

Exceeding the limit returns 429 TOO_MANY_REQUESTS with the reset time in the message. The limiter is fail-open: if it errors internally, the request is allowed through rather than blocked.

Errors this flow can return

CodeHTTPWhen it occurs
MISSING_API_KEY401No Authorization header, or an empty token.
INVALID_AUTH_HEADER401Header is not in the form 'Bearer <api-key>'.
INVALID_API_KEY401Key not found, revoked, disabled, or the wrong type for the endpoint.
TOO_MANY_REQUESTS429The key's daily rate limit has been reached.
Keep secret keys server-side. If one leaks, revoke it from the API keys page — revocation is instant, and the next request with that key returns 401.
Every response envelope is { success, data?, error? }. Base URL: https://api.carrieros.ai/v1. Full list in Error Codes and Rate Limits.