Authentication
How GigaQR API keys work — secret vs publishable, scopes, origin allowlists, rotation.
Every request to the REST API carries a bearer token in the Authorization header:
Authorization: Bearer sk_live_...Two kinds of keys
| Key type | Prefix | Where it runs | Plan |
|---|---|---|---|
| Secret | sk_live_ | Server-only. Never ship to a browser or mobile client. | Pro and above |
| Publishable | pk_live_ | Browser, via the @gigaqr/embed widget. Restricted to specific origins. | Free and above |
Publishable keys can only hit the widget endpoint /api/v1/widget/qr. Secret keys hit the full REST API. Mixing them up (e.g. a pk_live_ in a server request) is rejected with 401.
Scopes
Secret keys carry scopes that narrow what they can do. Grant the minimum a given integration needs. Common scopes:
qr:read— list and fetch QRs and scan events.qr:write— create, update, and delete QRs.bulk:write— submit bulk jobs.scans:export— export raw scan events.
A request that exceeds the key's scope returns 403 with code: "forbidden".
Origin allowlist (publishable keys)
When you create a publishable key, list the origins your widget will run on (e.g. https://acme.com). Requests from other origins are rejected with 403. Add http://localhost:3000 during local development.
Rotating a key
- Create a new secret key with the same scopes.
- Roll it out in your secret manager (Vercel, Doppler, AWS Secrets Manager).
- Wait 24 hours — the Developer page shows Last used for every key.
- Revoke the old key. The audit log records every revoke.
When a key is compromised
Revoke it immediately in the dashboard. A revoked key fails with 401 on the very next request — there is no propagation delay. Rotate into a fresh key and then review Dashboard → Audit log for anything you didn't initiate.
Error shape
{
"error": "Origin not allowed",
"code": "forbidden"
}Every error response has this shape. code is machine-readable and stable; error is human-readable and may change over time.