Authentication
Every request carries your API key in the X-API-Keyheader. Keys don't expire; they work until you revoke them.
curl "https://api.factql.ai/whoami" -H "X-API-Key: $FACTQL_API_KEY"
Your keys
- Keys start with
fl_live_orfl_test_. The prefix is a label only; both reach the same data and count towards the same usage. - The full key is shown once. FactQL stores only a hash, so a lost key can't be recovered: revoke it and create a new one under API keys in the app.
- The key from signup is bound to one tenant and one workspace. On any other tenant it gets
403.
Full-access and ask-only keys
Choose the access when you create a key under API keys in the app, or send "scope": "query" when creating one through POST /accounts/api-keys. The new key comes back once, in api_key (the same field signup uses); raw_key carries the same value for older integrations. A key created with a workspace-bound key is bound to the same workspace.
Access limits what a key can do; the workspace it belongs to limits which data it reaches. Create a browser key on the API keys page of the workspace your app uses, so it can't reach your other workspaces. An ask-only key still spends your account's usage, and anyone who copies it can send any X-End-User-Id. Keep full-access keys on your server, and revoke an ask-only key if it is misused. GET /whoami reports a key's scope.
Calling FactQL from a browser
Browsers only let a page call another site's API when that API allows the page's origin (CORS). Calls from your server aren't affected, so the simplest setup is to proxy questions through your own backend with a full-access key. To call FactQL straight from your web app, list the app's websites on its ask-only key.
- Create an ask-only key with Allowed websites under API keys in the app, or send them when creating the key:
curl -X POST "https://api.factql.ai/accounts/api-keys" \ -H "X-API-Key: $FACTQL_API_KEY" -H "Content-Type: application/json" \ -d '{"name": "Web app", "scope": "query", "allowed_origins": ["https://app.example.com", "http://localhost:3000"]}'
- Use that key from those websites, with
X-End-User-Idon every call. Change the list any time withPATCH /accounts/api-keys/{key_id}and{"allowed_origins": [...]}; an empty list removes the restriction. Changes can take up to a minute to reach every server.
https://app.example.com, https://app.example.com:8443. No paths or wildcards.http://localhost and http://127.0.0.1 for development.A browser call with that key from any other website gets 403, so another site can't reuse your key from a browser. Allowing a website never replaces the key: anyone who copies an ask-only key can still call the API from a script, which is why it can only ask questions. Calls from FactQL's own sites, such as the Try it panels here, are always accepted.
Check a key
GET /whoami returns what a key is and where it points, so you never have to copy IDs out of the app.
curl "https://api.factql.ai/whoami" -H "X-API-Key: $FACTQL_API_KEY"
prefix, name and environment. Never the key itself.type and plan.Invalid or revoked API key).One key, many people
A key belongs to your account, not to a person. When your app serves many people, send X-End-User-Id with a stable id for the person asking, so each gets their own conversations. See Serving many users.
Sample data
The Try it panels can use a public, read-only key for a demo shop with customers, products and orders. It comes from GET /sample, which needs no key. The sample key:
- can ask questions (
POST /query,/ask,/ask/stream) and check schema status. Anything else gets403. - needs
X-End-User-Idon tenant routes. Try it sets a random id for your browser. - is limited per IP address: 5 requests a minute and 30 questions an hour, then
429withRetry-After.