API Keys
Publishable keys for browser code, server keys for everything else. Each key carries explicit scopes that control which endpoints it can call.
Updated 2026-10-10
API keys authenticate every request. Each key belongs to one organization and carries explicit scopes. Keys are created and revoked from the dashboard. They’re shown exactly once on creation, so copy them then.
Publishable and server keys
There are two kinds of key. Pick by where the code runs.
| Kind | Scopes | Can call | Where it lives |
|---|---|---|---|
| Publishable | public |
GET /faqs and GET /search, published content only |
Browser code, mobile apps, anywhere |
| Server | read, write, admin |
Every endpoint its scopes allow, including drafts and unpublished translations | Server environment variables only |
A publishable key can’t read drafts, unpublished translations, product facts, key metadata or settings, and it can’t change anything. Every other endpoint answers 403 forbidden. It still counts toward your rate limit and monthly quota, so revoke and replace it if someone abuses it.
A read key is not safe in a browser: it reads draft questions and private product facts. Never put a server key in client code, a VITE_* or NEXT_PUBLIC_* variable, or a URL.
public can’t be combined with read, write or admin on one key. Create two keys instead. Existing read keys keep working on /faqs and /search.
List
curl https://api.thefaq.app/api/v1/acme/api-keys \
-H "Authorization: Bearer $FAQAPP_API_KEY"
Response:
{
"data": [
{
"id": "key_8X3F",
"name": "production-web",
"scopes": ["read", "write"],
"lastUsedAt": "2026-05-20T09:14:08Z",
"createdAt": "2026-04-12T10:00:00Z",
"fingerprint": "a14b2c…"
}
],
"meta": { "pagination": { "limit": 20, "cursor": null, "hasMore": false } }
}
The full key value is never returned by list. Only the SHA-256 fingerprint (first 6 chars) is shown for identification.
Required scope: read. A publishable key can’t list keys.
Create and revoke
Key creation and revocation happen in the dashboard at Settings → API keys. There’s no public endpoint; key lifecycle is a UI operation so that the full key value can only appear in the browser session of the person who created it.
When you create a key:
- Pick a name (visible later on the list endpoint above)
- Pick Publishable for browser code, or Server (
read,write) for backends - Copy the key value immediately. It’s shown once.
When you revoke a key, every request using it starts returning 401 invalid_api_key instantly. There’s no grace period.
Rotation pattern
- Create a new key with the same scopes in the dashboard
- Roll the new value into your env and redeploy
- Wait until you see traffic on the new key (
lastUsedAtupdates on the list endpoint above) - Revoke the old key in the dashboard
Plan ahead. If step 3 is silent for hours, suspect a deploy issue before revoking.
Error codes
invalid_api_key(401): key value doesn’t match any active keyinsufficient_scope(403): your key’s scopes don’t include the one this endpoint requiresplan_limit_reached(402): your org hit its API-key cap; upgrade or revoke an unused key in the dashboard