Authentication
Authenticate your API requests with an API key.
API Keys
All API requests require an API key passed via the X-API-Key header.
bashcurl -X POST https://fingerprintiq.com/v1/identify \ -H "Content-Type: application/json" \ -H "X-API-Key: fiq_live_your_api_key" \ -d '{"signals": {...}}'
Key Types
Your API key. Two formats are supported:
fiq_live_— Live key for production traffic. Counts toward your monthly quota.fiq_test_— Test key for development and staging. Full functionality, excluded from monthly quota.
Use test keys (fiq_test_) in your CI/CD pipeline, staging environments, and local development. This keeps your production quota clean and makes it easy to distinguish production traffic in your dashboard.
Creating API Keys
Sign in to the dashboard
Go to fingerprintiq.com/dashboard and sign in.
Navigate to API Keys
Select API Keys from the left sidebar.
Create a new key
Click Create Key, give it a descriptive name (e.g., "Production Web App"), and select the key type.
Copy the key immediately
The full key value is shown only once at creation. Copy it to your secrets manager before closing the dialog.
API keys are shown only once at creation time. If you lose a key, revoke it and create a new one — there is no way to retrieve the original value.
CLI / AI Agent Authentication (Device Code Flow)
If you're building a CLI, an AI agent integration, or any non-browser tool that needs to provision an API key on the user's behalf, use the device code flow instead of asking the user to copy/paste from the dashboard. It's modeled on OAuth 2.0 device authorization (RFC 8628).
How it works:
- Your tool asks FingerprintIQ for a device code.
- Your tool prints a short verification URL to the user.
- The user opens the URL, signs in, picks a project, and clicks Authorize.
- Your tool polls for the key and receives it exactly once.
The issued key is a standard fiq_live_ key scoped to the project the user selected. It appears in Dashboard → API Keys and can be revoked there at any time.
1. Request a device code
bashcurl -X POST https://fingerprintiq.com/api/cli/device-code \ -H "Content-Type: application/json" \ -d '{"client_name": "my-cli"}'
javascriptconst res = await fetch("https://fingerprintiq.com/api/cli/device-code", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ client_name: "my-cli" }),});const grant = await res.json();
pythonimport requestsgrant = requests.post( "https://fingerprintiq.com/api/cli/device-code", json={"client_name": "my-cli"},).json()
Human-readable name shown to the user on the consent screen (e.g. claude-code, cursor, my-cli). Capped at 64 characters.
Response:
json{ "device_code": "…64-char opaque token…", "user_code": "ABCD-EFGH", "verification_url": "https://fingerprintiq.com/cli/auth?code=ABCD-EFGH", "expires_in": 600, "interval": 3}
Opaque token your tool holds on to. Used to poll for the issued key. Never shown to the user.
Short, human-readable code (8 chars, dashed). Shown to the user so they can confirm it matches what's on the consent screen.
URL your tool should open (or print) for the user.
Seconds until the grant expires. Always 600 (10 minutes).
Minimum seconds between token poll requests.
2. Direct the user to authorize
Print the verification_url and user_code and wait:
textOpen this URL in your browser to authorize: https://fingerprintiq.com/cli/auth?code=ABCD-EFGHVerification code: ABCD-EFGHWaiting for authorization…
On the consent page the user will sign in (if needed), pick which project the key should be scoped to, and confirm that the verification code matches.
3. Poll for the API key
While waiting, poll POST /api/cli/token with the device_code every interval seconds:
bashcurl -X POST https://fingerprintiq.com/api/cli/token \ -H "Content-Type: application/json" \ -d '{"device_code": "…"}'
javascriptasync function pollForKey(deviceCode, interval) { while (true) { const res = await fetch("https://fingerprintiq.com/api/cli/token", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ device_code: deviceCode }), }); const data = await res.json(); if (data.status === "authorized") return data.api_key; if (res.status === 410) throw new Error(`Grant ${data.status}`); await new Promise((r) => setTimeout(r, interval * 1000)); }}
pythonimport time, requestsdef poll_for_key(device_code, interval): while True: r = requests.post( "https://fingerprintiq.com/api/cli/token", json={"device_code": device_code}, ) data = r.json() if data.get("status") == "authorized": return data["api_key"] if r.status_code == 410: raise RuntimeError(f"Grant {data.get('status')}") time.sleep(interval)
Poll responses:
| Status | HTTP | Meaning |
|---|---|---|
{"status":"pending","interval":3} | 200 | User hasn't authorized yet. Keep polling. |
{"status":"authorized","api_key":"fiq_live_…"} | 200 | Success. Plaintext is returned exactly once — save it immediately. |
{"status":"expired"} | 410 | 10-minute window elapsed. Start over from step 1. |
{"status":"consumed"} | 410 | Key was already returned on a prior poll. Start over. |
The plaintext key is returned on a single successful poll and then cleared from the server. If your tool doesn't persist it on that first read, you'll need to start a new grant.
4. Use the key
Store the key somewhere your tool can read it on future runs — typically an environment variable:
bashexport FINGERPRINTIQ_API_KEY='fiq_live_…'
Don't write the key to a shared or world-readable file without warning the user. The safest default is to export it for the current shell session and let the user add it to their ~/.zshrc, ~/.bashrc, or project .env themselves.
The issued key is visible in Dashboard → API Keys under the name your tool supplied (e.g. my-cli (CLI)) and can be revoked there at any time.
Rate Limits
| Plan | Requests/second | Monthly limit |
|---|---|---|
| Free | 10 | 10,000 |
| Builder | 1,000 | 50,000 |
| Growth | 1,000 | 250,000 |
| Scale | 1,000 | 2,000,000 |
When rate limited, the API returns 429 Too Many Requests with a JSON body describing the limit:
json{ "error": "Monthly API call limit exceeded", "usage": 10001, "limit": 10000}
The per-second rate limit applies to burst traffic. If your application generates identification requests in bursts (e.g., page load events), implement exponential backoff on 429 responses.
Security Best Practices
Never expose your API key in client-side JavaScript, public repositories, or build artifacts. Use environment variables on your server and NEXT_PUBLIC_ / Vite import.meta.env.VITE_ prefixes only for public keys used directly in the browser SDK.
- Server-side keys — Use for calling the visits API (
/v1/demo/visits/:id). These keys must never reach the browser. - Client-side keys — The SDK uses your key to call
/v1/identify. This endpoint enforces domain allowlisting, so even if the key is visible in source, it cannot be used from unauthorized domains. - Key rotation — Rotate keys periodically (every 90 days) and immediately if you suspect exposure.