REST API overview
Base URL, authentication, scopes, error envelopes.
Base URL
https://api.thebreeth.comAll endpoints are prefixed with /v1. The current API version is v1.
Authentication
Every request must carry a Bearer token. Two token types are accepted:
| Token | Format | Use case |
|---|---|---|
| API key | ck_live_… | Agents, scripts, the MCP server |
| Clerk JWT | eyJ… | Dashboard sessions (handled automatically) |
curl https://api.thebreeth.com/v1/episodes \
-H "Authorization: Bearer ck_live_..."Keys are minted in the dashboard at API Keys → New key. Plaintext is shown once. Store it like any other secret.
Scopes
Each API key carries an explicit scope set chosen at mint time:
| Scope | Endpoints |
|---|---|
read (implicit, always granted) | GET /v1/episodes/*, GET /v1/entities/*, POST /v1/search, GET /v1/graph/* |
write | POST /v1/episodes, POST /v1/facts |
admin | POST /v1/retract, POST /v1/tasks, key management |
A request to a route whose scope isn't on your key returns 403 missing_scope.
Multi-team keys
A single key can scope to multiple teams (team_ids: [A, B, C]). To pick the active team at request time, send:
X-Cogram-Team-Id: <team_uuid>If the header isn't sent and the key only scopes one team, that team is used implicitly.
Errors
Every error response is a JSON envelope:
{ "error": "<slug>", "message": "<human-readable>" }Common slugs:
| HTTP | Slug | Meaning |
|---|---|---|
| 400 | invalid_request | Bad payload — missing field, wrong type |
| 401 | unauthenticated | Bearer token missing / invalid / expired |
| 402 | payment_required | Subscription past-due or cancelled. Writes blocked until resolved. |
| 403 | missing_scope | Key doesn't carry the scope required for this route |
| 429 | quota_exceeded | Monthly cap reached. Response body includes kind, limit, current, tier |
| 500 | internal_error | Server fault. Includes a request-id you can quote in support. |
Rate limits
Hard caps apply per (team, billing month). See Tiers & Limits. There are no per-second rate limits — every write is metered against the monthly counter.
Idempotency
POST /v1/episodes is not idempotent. Calling it twice with the same content creates two episodes. Breeth dedupes entities/edges across them in the graph, but the episode count goes up by two. Build your own idempotency key on top if you need it.
Versioning
We add new endpoints additively. We do not remove or rename fields without a major-version bump.