Authentication
How API keys work, key lifecycle, and rate limits.
Every Public API endpoint requires a Bearer key in the Authorization header:
Authorization: Bearer ck_live_a1b2c3d4...
Key format
Keys look like:
ck_live_<32 hex characters>
- 128 bits of entropy. Effectively unguessable.
- The 8 hex chars right after
ck_live_are stored plaintext (the "prefix") so Coachbot can look up the key cheaply on every request. - The full key is hashed with SHA-256 for storage. Coachbot compares hashes in constant time.
Key lifecycle
- Create — Settings → API keys → New API key. Give it an operator-friendly name (e.g.
production-site). Coachbot returns the plaintext key exactly once in a one-time-reveal panel. Copy it immediately into your secrets manager. There is no way to recover it later. - Use — pass it as
Authorization: Bearer <key>from your backend. - Monitor — Settings → API keys shows when each key was last used. If a key has been silent for weeks but you expect traffic, the key was probably leaked + rotated by someone else, or your client is misconfigured.
- Revoke — click Revoke on the row. Soft delete (
revoked_atstamp). Subsequent calls with that key get401 invalid_or_revoked.
Best practices
- One key per environment. Production, staging, the partner's website — each gets its own key. Easier to revoke without affecting the others.
- Never embed in client JS. The key would be visible to anyone with browser devtools. Use a server-side proxy.
- Rotate periodically. Generate a new key, deploy with the new key, revoke the old one. Coachbot doesn't enforce a rotation interval — it's your policy.
- Don't share between operators. Each operator on your team should have their own way to read keys from your secrets manager, not paste them in Slack.
Rate limits
Per-key limits, currently:
| Window | Limit | What it stops |
|---|---|---|
| 60 seconds | 5 requests | Runaway scripts, double-submitted forms. |
| 60 minutes | 100 requests | Sustained abuse, accidental loops. |
Exceeding either returns 429 rate_limit_exceeded with a Retry-After header. Both windows are keyed on the api_key_id, not the workspace, so multiple keys for the same workspace each get their own budget.
If you legitimately need higher limits, file an issue — these defaults err on the side of safety.
Errors related to authentication
| Status | error value | Means |
|---|---|---|
| 401 | "Missing Authorization header." | No Authorization header at all. |
| 401 | "Authorization header must use the `Bearer <api key>` scheme." | Header present but not Bearer-formatted. |
| 401 | "API key is invalid or revoked." | Bearer present but the key isn't recognised or has been revoked. |
| 429 | "Rate limit exceeded. Wait a minute before retrying." | Per-minute burst limit. |
| 429 | "Hourly rate limit exceeded." | Per-hour limit. |