Authentication
API Keys
All external API requests use the X-API-Key header.
Do not send keys in query parameters
Requests containing api_key, X-API-Key, or x-api-key in the query string are rejected with 400 Bad Request.
Key Format
Gateway keys are generated in the format bach_{environment}_{random}.
| Prefix | Environment |
|---|---|
bach_live_ |
Production |
bach_test_ |
Test |
Scopes
The current public endpoint requires kb:read.
| Scope | Status |
|---|---|
kb:read |
Required for POST /api/v1/ext/kb/query |
audit:read |
Required for GET /api/v1/ext/audit/session/{id} — tenant-bound |
assess:read |
Required for GET /api/v1/ext/assess/mastery/{id} and GET /api/v1/ext/assess/improvement/{id} — tenant-bound |
admin:* |
Internal/admin use only |
Additional scopes can exist on keys, but only documented public routes enforce them.
Tenant Scoping
audit:read and assess:read reads of learner-scoped data are bound to the
organization on the API key (api_keys.org_id):
- A key without an organization binding receives
403 TENANT_SCOPE_REQUIREDon these endpoints. There are no global-read keys on the external gateway; platform operations use the internal admin surface instead. - A key with an organization binding can only read learners assigned to
that organization (
learner_profiles.organization_id). Learners not yet assigned to any organization are not visible to any key. - Out-of-tenant sessions and learners are indistinguishable from nonexistent
ones (same
404 SESSION_NOT_FOUND/404 USER_NOT_FOUND/ empty mastery payload), so identifiers cannot be enumerated across organizations. - Case-study audit records are visible only to keys in the same organization as the key that generated them.
Tiers
| Tier | RPM | Burst (10s) | Daily Budget | Monthly Budget |
|---|---|---|---|---|
| Free | 60 | 20 | $5.00 | $25.00 |
| Professional | 300 | 60 | $50.00 | $250.00 |
| Enterprise | 1,000 | 200 | $500.00 | $2,500.00 |
IP Allowlisting
Keys can carry an allowed_cidrs allowlist. When present, requests from IPs outside those CIDRs fail with 403 Forbidden.
Rotation
Admin rotation keeps the old key in rolling status while a replacement key is issued. The overlap window is configurable and defaults to 48 hours in the admin route.
Common Failures
| Status | Meaning |
|---|---|
400 |
Key was supplied in the URL instead of the header |
401 |
Missing, invalid, revoked, or expired API key |
403 |
Missing scope, missing organization binding, or unauthorized client IP |