Authentication & API keys
Reading data does not require a key. A key gives you higher limits, a daily quota of your own, and usage statistics. Creating a key is free.
#Access tiers
| Tier | Per minute | Per day | Browser use |
|---|---|---|---|
| Anonymous (no key) | 30 | no daily quota | yes |
| Publishable key (sn_pk_) | 120 | 5,000 | yes |
| Secret key (sn_sk_) | 300 | 10,000 | no (refused) |
#Key types
#Secret keys: sn_sk_…
For servers, scripts, notebooks and scheduled jobs. A secret key must never be shipped to a browser or mobile app.
- The API refuses a secret key when the request carries an
Originheader (every browser request does), with403 secret_key_in_browser. This stops a leaked key from being reused from web pages. - Store it in an environment variable or secret manager, never in source code.
#Publishable keys: sn_pk_…
For front-end apps that call the API directly from the browser.
- Registered with up to 5 allowed origins, e.g.
https://dashboard.example.org. Requests from any other origin are refused with403 origin_not_allowed, so copying the key from your page's source is useless elsewhere. - Origins must be
https://host[:port].http://is accepted only forlocalhostand127.0.0.1, for development. Wildcards are not allowed. - Publishable keys are visible to your users by design; their lower limits reflect that.
#Sending a key
Use either header:
curl https://api.sentinara.org/v1/keys/me -H "Authorization: Bearer sn_sk_…"
curl https://api.sentinara.org/v1/keys/me -H "X-API-Key: sn_sk_…"Keys in the URL (?api_key=…) are rejected with 400 api_key_in_query: URLs are stored in logs, browser history and Referer headers.
#Getting a key
Use the form at /keys. You choose the type, give your app a name, your email and (for publishable keys) the allowed origins, and pass a quick human check (Cloudflare Turnstile). The key is shown once; SENTINARA stores only a salted hash and cannot show it again.
Limits on creation:
- At most 3 active keys per email created from the same network.
- At most 5 new keys per network in 24 hours. Rotations count toward this limit. For IPv6, a network is a /48 prefix.
#Managing your key
| Action | Request |
|---|---|
| Inspect type, limits, last use and today's usage | GET /v1/keys/me |
| Rotate: new key with the same settings, old key revoked at once | POST /v1/keys/me/rotate |
| Revoke permanently | DELETE /v1/keys/me |
curl -X POST https://api.sentinara.org/v1/keys/me/rotate -H "Authorization: Bearer $SENTINARA_KEY"#Publishable keys: the management token
A publishable key is visible in your page's source, so holding it is not proof of ownership. When you create one you also receive a management token (sn_mt_…, shown once). Rotating or revoking the key requires it in the X-Management-Token header, sent from a terminal or server (requests with an Origin header are refused with 403 management_token_required). Never put the management token in a web page. It stays the same after a rotation.
curl -X POST https://api.sentinara.org/v1/keys/me/rotate \
-H "Authorization: Bearer sn_pk_…" \
-H "X-Management-Token: $SENTINARA_MANAGEMENT_TOKEN"Revocation takes effect within 60 seconds everywhere.
#If a key leaks
- Rotate it immediately (
POST /v1/keys/me/rotate, plus the management token for a publishable key) and deploy the new key. - If you no longer have the old key, create a new one and email security@sentinara.org with the key prefix (the first 12 characters) so we can revoke the old one.
- Review where it was exposed (repository history, logs, client bundles).
#Key format and secret scanning
Keys match ^sn_(sk|pk)_[A-Za-z0-9]{40}$ (about 238 bits of randomness). The fixed prefixes let secret scanners and code reviewers recognise them. Add the pattern to your scanner; for GitHub, enable push protection and a custom pattern.
#Best practices
- One key per application and environment, so you can rotate without downtime.
- Keep secret keys on the server; proxy requests if your front end needs secret-tier limits.
- Cache responses: the data is updated weekly, and conditional requests (
If-None-Match) are cheap. - Handle
401 key_revokedby alerting a human, not by retrying.