Authentication
Every request to the Lune API must include a bearer token. Keys are scoped per environment and you can have many active at once. Lost a key? Rotate it without downtime.
Bearer tokens
Send your key in the Authorization header on every request:
Authorization: Bearer lune_sk_live_a1b2c3d4...
Keys are never logged in plaintext, even by you, after creation — store them in a secrets manager (AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager, or Cloudflare Worker secret bindings).
Key types
| Prefix | Environment | Use for |
|---|---|---|
lune_sk_test_ | Sandbox | Local dev, CI, integration tests. Free, rate-limited. |
lune_sk_live_ | Production | Real customer traffic. Counts against your contract. |
lune_pk_ | Either | Publishable key for browser-side Engage SDK widgets. |
Scopes
Each key carries one or more scopes that restrict what it can do. Set scopes at key creation; you can't widen them later — create a new key instead.
enrich:read— call the/v1/enrichendpoint.enrich:batch— submit batch enrichment jobs.engage:render— for publishable keys; lets the Engage widgets fetch data.target:write— create or modify audience segments.webhooks:manage— register and update webhook endpoints.
Key rotation
Rotation is two-phase, so you never have downtime:
- Create a new key with the same scopes.
- Roll it out to production (both keys are valid).
- Verify traffic on the new key in the dashboard.
- Revoke the old key.
The dashboard shows last-used timestamps per key so you can confirm the cutover before revoking.
Authentication errors
| Status | Body | Meaning |
|---|---|---|
401 | missing_authorization | No Authorization header. |
401 | invalid_key | Key doesn't exist or was revoked. |
403 | missing_scope | Key is valid but lacks the scope required for this endpoint. |
403 | wrong_environment | You hit a production endpoint with a sandbox key, or vice versa. |
