Skip to main content

API keys — generation, scopes, rotation

API access is an Enterprise and Government feature. Keys are workspace-scoped, scope-restricted, and rate-limited per key. Generation, rotation, and revocation are self-serve at /settings/api-keys.

Generation

  1. Open /settings/api-keys and fill in the new-key form.
  2. Name the key (free-text label; recorded in the audit log).
  3. Select scopes — see below. The form requires at least one scope.
  4. Optionally set an expiry. If you leave it empty, the key expires 365 days after issuance — set an explicit expiry (or rotate before it lapses) if you need a different lifetime.
  5. Click Create key. The full key is shown 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.

ScopeWhat it unlocks
briefs:readBrief read endpoints
search:readSearch endpoints
notices:readNotice read endpoints
entities:readEntity / relationship-graph read endpoints
agencies:readAgency read endpoints
forecasts:readForecast read endpoints
opportunities:readOpportunity read endpoints
pwin:assesspWin assessment
exports:readExport 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. There is no per-day workspace ceiling and no tier-differentiated per-minute number today.

GET /api/v1/search, /notices, /opportunities, /forecasts, /entities/{id} and /agencies/{slug} all share ONE budget, named "search" (60 admissions/minute, per key). Calling five of those routes in the same minute draws down the same 60-request allowance, not five independent ones. Two routes have their own, smaller budgets: GET /api/v1/briefs uses the synthesize budget (10/minute per key) and POST /api/v1/pwin uses the query budget (30/minute per key).

Every v1 response — success or error — carries the current state of your budget:

  • X-RateLimit-Limit — the budget ceiling for the route you called (60 for the shared search bucket, 10 for briefs, 30 for pWin).
  • X-RateLimit-Remaining — admissions left in the current window, after this request.
  • X-RateLimit-Reset — Unix epoch seconds when the window rolls over.

A 429 additionally carries Retry-After in seconds; honor it and back off exponentially.

Rotation

Click Rotate on the key's row at /settings/api-keys, which calls the rotate_api_key database function so the issue-new/revoke-old pair commits atomically — a mid-rotation crash cannot leave two live keys or zero. 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

Click Revoke on the key's row at /settings/api-keys. Revocation is immediate — the next request from the revoked key returns 401 with error code unauthenticated, the same response as any unknown key. Revocation is recorded in the workspace audit log.

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 on a regular schedule, for example quarterly. /settings/api-keys shows each key's expiry and its last-24-hour usage per endpoint.

See Webhooks for the event-driven counterpart and The REST API v1 for the endpoints.

Last updated 2026-09-21.


Was this article helpful?
Still need help? If you're signed in, file a ticket with the floating "?" button on any app view. Or email justin@fedgrade.com.
API keys — generation, scopes, rotation · Help