Authentication
iGregulator uses Bearer tokens: a single opaque API key sent in the
Authorization header. No OAuth, no JWTs, no per-request signatures.
Every authenticated endpoint on api.igregulator.io uses the same
scheme.
1. Overview
Section titled “1. Overview”| Public | Authenticated | |
|---|---|---|
| Needs a key | — | ✓ |
| Rate limit | 10 req / IP / hour | per-plan quota (Starter 10k/mo, Pro 100k/mo, Business fair-use) |
| Example endpoints | /v1/check, /v1/jurisdictions, /v1/operators/search | /v1/operators/:slug, /v1/licenses/:id, /v1/jurisdictions/:code |
| Who it’s for | quick lookup, demo, embed in a landing page | production integrations, bulk jobs, compliance sweeps |
See /pricing for the full plan comparison. Signup is open and free for founding members (full Starter plan); create an account at app.igregulator.io/signup. Paid self-serve billing lands with Phase 2.
2. Generating keys
Section titled “2. Generating keys”- Sign in at app.igregulator.io.
- Go to API keys in the nav.
- Click + generate new key. Give it a descriptive label (“Production server”, “Local dev”, “Staging job”).
- The raw key is displayed once — copy it now. We store a SHA-256 hash only and cannot recover the plaintext. Lose it → rotate.
Key format: igk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (36 chars total).
The igk_ prefix enables GitHub secret-scanning detection, so if you
accidentally commit a key it gets flagged before a bot finds it.
3. Using keys
Section titled “3. Using keys”curl -H "Authorization: Bearer igk_yourkeyhere" \ https://api.igregulator.io/v1/operators/paddy-power-holdings-limitedconst res = await fetch( 'https://api.igregulator.io/v1/operators/paddy-power-holdings-limited', { headers: { Authorization: `Bearer ${process.env.IGREGULATOR_API_KEY}` } },);if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);const operator = await res.json();import os, requests
r = requests.get( 'https://api.igregulator.io/v1/operators/paddy-power-holdings-limited', headers={'Authorization': f'Bearer {os.environ["IGREGULATOR_API_KEY"]}'}, timeout=10,)r.raise_for_status()operator = r.json()Public endpoints work without a key too, but attaching one skips the 10/hour IP cap and uses your plan quota instead — useful when serving dashboards that can burst past the public ceiling.
4. Key rotation
Section titled “4. Key rotation”Rotation is overlap-based — create the new key, deploy it, then revoke the old one. No grace period is needed at our end; old keys stay valid until you explicitly revoke them.
- Generate a new key. Label with the rotation reason.
- Deploy the new key to every consumer (CI variables, running services,
teammates’
.envfiles). - Verify traffic shifted — check the Last used column on the API keys page; the old key should show no recent usage.
- Click Revoke on the old key in the dashboard. Confirmation is
required. Revocation is immediate — the next request carrying the
old key returns
401 auth_revoked.
5. Security
Section titled “5. Security”- Never commit keys to version control. We don’t scan public repos
for you; a leaked key is your risk. GitHub’s secret-scanning may flag
igk_strings, but don’t rely on it as a safety net. - Use environment variables.
process.env.IGREGULATOR_API_KEYin Node,os.environ['IGREGULATOR_API_KEY']in Python, Docker secrets in containerised deploys. - One key per client. Separate keys per environment (prod / staging / dev / CI) make revocation surgical — you kill the leaked instance without affecting every consumer.
- Keys are stored hashed. SHA-256, never plaintext. If the DB is ever read out, the keys themselves don’t leak — only their prefixes (displayed in the UI anyway).
- HTTPS only. The API doesn’t listen on port 80; HTTP would leak the key in plain text.
- Report compromises to [email protected]. We’ll help triage and can check for anomalous usage patterns on our side.
6. Rate limits and quotas
Section titled “6. Rate limits and quotas”Two independent ceilings enforced on every authenticated request:
- Per-second rate limit — sustains your plan’s burst ceiling
(Starter 5/s, Pro 20/s, Business 100/s, Enterprise unlimited).
Breach →
429 rate_limited. - Monthly request quota — plan quota per calendar month, UTC
reset at the first of the month. Breach →
429 quota_exceeded.
Every authenticated response carries headers you can read to stay ahead of either ceiling:
| Header | Meaning |
|---|---|
X-Monthly-Quota-Limit | Your plan’s monthly ceiling, or unlimited |
X-Monthly-Quota-Used | Count so far this month (omitted when unlimited) |
X-Monthly-Quota-Remaining | Quota minus used (omitted when unlimited) |
X-Monthly-Quota-Reset | ISO-8601 timestamp when the counter rolls over |
X-Monthly-Quota-Warning | Present when usage ≥ 80%: 80% of monthly limit used |
X-RateLimit-Limit | Per-second ceiling for the current plan |
X-RateLimit-Policy | Human-readable: tier=starter;limit=5;window=second |
RateLimit-Policy | IETF draft format: "default";q=5;w=1 |
See the rate limits guide for parser examples and the full tier table.
7. Errors
Section titled “7. Errors”Authenticated endpoints return structured JSON on every non-2xx. Branch
on code for behaviour, details.reason for refinement, and use
details.suggestion verbatim in user-facing messaging when present.
| Status | code | When |
|---|---|---|
| 401 | auth_required | No Authorization header. |
| 401 | auth_invalid | Header malformed or key not recognised. |
| 401 | auth_revoked | Key was revoked via the dashboard. |
| 402 | payment_required | Your plan is null or canceled. |
| 429 | rate_limited | Per-second ceiling breached. Sleep, retry once. |
| 429 | quota_exceeded | Monthly quota exhausted. Wait for reset_at or upgrade. |
Full code reference lives in the error handling guide.
Example body (401):
{ "error": "API key has been revoked", "code": "auth_revoked", "details": { "reason": "api_key_revoked", "suggestion": "Generate a new API key at https://app.igregulator.io/api-keys. Revoked keys cannot be restored." }}