Docs / Shared / Authentication
Authentication
One page, shared by every dataset. Send your key as a bearer token on every request.
The header
Authorization: Bearer sk_live_7f3c… // required, on every request // 401 missing_authorization — nothing we could read arrived in that header // 401 unauthorized — a key arrived and is not recognised // 403 forbidden — key valid, but your plan does not include this dataset // 429 rate_limited — see Retry-After and X-RateLimit-Remaining
A rejected request carries WWW-Authenticate: Bearer, so a standard HTTP client reports it as an authentication failure rather than an opaque 401.
The two 401s are worth telling apart, and the code is how. missing_authorization means nothing readable reached us — no header, or one that is not a bearer token — so the first place to look is the transport: a proxy, an SDK or a redirect that rewrites headers produces a request indistinguishable here from one that never carried a key. unauthorized means a key did arrive and we do not recognise it, so the key is the thing to check. A revoked key answers unauthorized too, and there is no separate code for it: revoking removes the key from the set we authenticate against, so by the time a request is refused a revoked key and one that never existed are the same fact. Your dashboard is what settles it — revoked keys stay listed.
unauthorized also says why, in error.reason: invalid_api_key for a key we never issued, revoked_api_key for one that was revoked or whose account is suspended, which the message names. Keep branching on code, which does not change; read reason to tell a typo from a revocation. A split of the code itself was announced for 2027-01-01 and withdrawn.
Keys
sk_live_ | Production keys. Count against your plan's quota and rate limit. |
sk_test_ | Not issued yet. Test keys will return fixture data and never be billed; today every key is a live one. |
| How many | As many as you need. There is no per-plan limit on keys and nobody approves them — create, name and switch them off from your dashboard, and a new one is live within about 30 seconds. Requests are counted per account rather than per key, so a second key costs you nothing and lets you scope and rotate one server at a time. |
| Storage | We hold a SHA-256 digest of your key, never the key itself. Nobody at softon.dev can read it back to you — if you lose it, issue a new one. |
| Transport | HTTPS only. A request over plain HTTP is rejected, not redirected — a redirect would have already leaked the key. |
| Rotation | Issue the replacement first, deploy it, then revoke the old key from your dashboard. Revoking takes effect within about 30 seconds and cannot be undone — nothing is ever deleted, so a revoked key stays listed and its usage stays attributed to it. |