API keys — generation, scopes, rotation
API access is an Enterprise+ feature. Keys are workspace-scoped, scope-restricted, and rate-limited per key. Generation, rotation, and revocation are self-serve at /settings/api-keys.
Generation
- Open
/settings/api-keysand click "New key." - Name the key (free-text label; used in audit logs).
- Select scopes — see below. If you select none, the key is issued with the default read-only set.
- Optionally set an expiry (
expires_at). There is no default expiry — a key with noexpires_atdoes not expire until you revoke it. - The full key is rendered once. Copy it; we do not store the plaintext. If you lose it, rotate.
Keys have the wire format fg_live_<14-char prefix>_<32-char secret>. The fg_live_ namespace is the only one issued — there is no separate sandbox/test prefix. Characters are drawn from an unambiguous lowercase-alphanumeric alphabet (no 0, 1, l, i, o).
Scopes
Scopes are additive — a key gets exactly what you grant.
| Scope | What it unlocks |
|---|---|
briefs:read | Brief read endpoints |
search:read | Search endpoints |
notices:read | Notice read endpoints |
entities:read | Entity / relationship-graph read endpoints |
agencies:read | Agency read endpoints |
forecasts:read | Forecast read endpoints |
opportunities:read | Opportunity read endpoints |
pwin:assess | pWin assessment |
exports:read | Export read endpoints |
v1 is read-plus-assess. There are no write scopes — the list above is the complete, enforced set (V1_SCOPES in lib/auth/api-keys.ts). No v1 endpoint mutates workspace state through an API key.
Keys issued before the v1 taxonomy carry legacy scope strings (read:brief, read:search, read:forecast, read:network) which alias forward to their v1 equivalents, so old keys keep working.
Two wildcard scopes exist and satisfy every scope check: * and api:full. Grant them only when a narrower set genuinely will not work.
Rate limits
Rate limiting is per key, per minute, per route budget — the budget name depends on which endpoint you call (search-class reads admit 60/minute; heavier AI-backed routes admit far less). There is no per-day workspace ceiling and no tier-differentiated per-minute number today.
429 responses include a Retry-After header in seconds; honor it and back off exponentially.
Rotation
Rotate at /settings/api-keys → "Rotate." A new key is issued carrying the old key's scopes and expiry, and the old key is revoked immediately — there is no grace window. Stage the new secret in your secrets manager before you rotate.
Revocation
Revoke at /settings/api-keys → "Revoke." Revocation is immediate — the next request from the revoked key returns 401 with code: "key_revoked". Revocation is logged in the audit trail with the actor, timestamp, and originating IP.
Best practices
- One key per integration. Never share keys across services.
- Store in your secrets manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault). Never commit to source control.
- Set the narrowest scopes the integration needs. A Brief mirror needs
briefs:read, not a wildcard. - Rotate quarterly. The
/settings/api-keyspage flags any key older than 90 days.
See Webhooks for the event-driven counterpart.
Last updated 2026-08-02.