Authentication
The Regulatory Snapshot API uses bearer keys. Every call to /v1/* (except the dashboard-only key-management endpoints) carries a single header:
Authorization: Bearer regsn_live_<32 base62 chars>There is no OAuth flow, no signed-request scheme, no separate client_id / client_secret. One key per integration, rotated when you choose. This page walks through the lifecycle of that key — how to create one, where they’re stored, when to rotate, and what happens when something goes wrong.
Anatomy of a key
A key looks like this:
regsn_live_aBcD1234eFgH5678iJkL9012mNoP3456regsn_live_is a literal prefix that lets you grep for keys in logs and source control.- The next 32 characters are base62 (
A–Z a–z 0–9) — ~190 bits of entropy. - Total length is 43 characters; lengths shorter or longer than this are rejected at the gateway.
[!WARNING] Never put a key in a URL. Always use the
Authorizationheader. Keys in URLs leak into browser history, web-server access logs, and HTTPRefererheaders.
Creating a key
Keys are created from the developer dashboard at api.regsn.app . Sign in with your Clerk account, open API keys, click Create key, give it a recognisable name (e.g. production-backend, analyst-laptop), and confirm.
You can also create keys programmatically over POST /v1/keys — but only from a Clerk-authenticated session, which means in practice this endpoint is only useful from the dashboard SPA itself. The exchange:
POST /v1/keys HTTP/1.1
Host: api.regsn.app
Content-Type: application/json
{ "name": "production-backend" }HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "0b3f…",
"name": "production-backend",
"key": "regsn_live_aBcD1234eFgH5678iJkL9012mNoP3456",
"key_prefix": "regsn_live_aBcD…",
"created_at": "2026-05-14T09:12:33Z",
"last_used_at": null,
"revoked_at": null,
"project_id": null
}[!WARNING] One-time reveal. The
keyfield appears exactly once in this response. The moment the response is gone, the only way to see anything about the key is the maskedkey_prefix. Store it now, before you do anything else. If you lose it, revoke and re-issue.
[!WARNING] Treat raw keys like passwords. Store them in your secret manager (AWS Secrets Manager, GCP Secret Manager, Doppler, 1Password CLI,
direnv-backed.envrc). Never commit them. Never paste them into chat.
Naming rules
- 1–64 characters
- Allowed: letters, digits, spaces, hyphens, underscores, dots, parentheses
Per-user limit
You can have up to 10 active keys per account (revoked keys don’t count). The 11th creation attempt returns 422 key_limit_exceeded. Rotate or revoke first.
Listing keys
curl https://api.regsn.app/v1/keys \
-H "Authorization: Bearer $CLERK_SESSION_TOKEN"{
"data": [
{
"id": "0b3f…",
"name": "production-backend",
"key_prefix": "regsn_live_aBcD…",
"created_at": "2026-05-14T09:12:33Z",
"last_used_at": "2026-05-14T14:08:11Z",
"revoked_at": null,
"project_id": null
}
]
}last_used_at is updated atomically with a 60-second debounce — useful for spotting which keys are still in active rotation. (It’s not a security audit trail; use /v1/usage for that.)
Revoking a key
curl -X POST https://api.regsn.app/v1/keys/$KEY_ID/revoke \
-H "Authorization: Bearer $CLERK_SESSION_TOKEN"Revocation is immediate — the gateway invalidates its cache and any subsequent request using the key gets 401 key_revoked. The operation is idempotent: revoking an already-revoked key returns the original revoked_at timestamp, not an error.
Rotation pattern
You don’t get a “rotate” endpoint. The pattern is:
- Create a new key (
production-backend-2). - Deploy the new key to production.
- Wait until
last_used_aton the old key stops advancing. - Revoke the old key.
That’s it. No downtime, no flag day. Because we don’t enforce a one-key-per-name constraint, you can keep both keys live as long as you want during the cutover.
[!WARNING] Rotate before retiring a deployment, not after. Revoking a key while a host is still using it produces immediate
401 key_revokedfailures and silent in-flight job loss. Always issue and deploy the replacement first, watchlast_used_atgo quiet on the old key, then revoke. The same applies when you sunset an integration: rotate the key in, drain traffic to the new key, only then revoke the old one.
How keys are stored
Two things only:
- A SHA-256 hash of the raw key, used for constant-time lookup. The plaintext never touches our database.
- The masked prefix (
regsn_live_xxxx…), so you can identify keys in the UI.
The gateway maintains a 5-minute in-memory cache of key lookups to keep auth overhead low. The cache is invalidated immediately on revocation, so a revoked key is rejected on the next request.
Per-key rate limits
Each key has its own rate-limit bucket. The limits in Rate limits apply per-key, so additional keys scale your per-key limits linearly. Budget (cents/USD) is per-account, so spinning up additional keys does not raise your aggregate scan or export spend.
Pre-auth failure modes
| Status | Code | What it means | What to do |
|---|---|---|---|
| 401 | authentication_required | No Authorization header on the request | Add Authorization: Bearer regsn_live_… |
| 401 | authentication_invalid | Header malformed, or key not recognised | Check for typos; key may have been rolled |
| 401 | key_revoked | Key matched but revoked_at is set | Create a new key in the dashboard |
Every failure carries an X-Request-Id header (request ID). Include it when you file a bug.
See also
- Quickstart — your first authenticated request, end to end.
- Errors — full problem-details schema and recovery patterns.
- Rate limits — per-key buckets and 429 handling.
- Glossary — bearer key, scope, request ID.