Docs / 11 of 14
API keys
Create, rotate, and revoke Organization ApiKey credentials. Scopes, secret handling, usage ingestion, and the errors a runtime will see. For workspace admins.
An ApiKey belongs to the Organization, not to a User. Most operators never need one. Create a key if a runtime, self-hosted license, or internal job must call /api without a browser session.
Manage keys at /dashboard/api-keys. Empty state: No keys. Create one if you are calling the API. Most operators never need this.
owner or admin only. member and billing cannot issue keys. Rate limit: 10 creates or rotates per hour per Organization.
What is stored
| You see | We store |
|---|---|
| Name you chose | name |
Display prefix, for example nm_live_7Qf2… | prefix (first 12 characters) |
| Secret, once, at creation | sha256 of the secret only (hashedSecret) |
| Scopes | scopes (default ["usage:write"]) |
| Live vs test | livemode |
| Last use, expiry, revoke time | lastUsedAt, expiresAt, revokedAt |
There is no “show secret again.” If you lost it, rotate or create a new key.
Format: nm_{live|test}_{32 chars base62}.
Create
/dashboard/api-keys→ create.- Name the key after the runtime that will hold it (for example
billtray-prod), not after a person. - Set
scopesif you need more than usage write. - Optional
expiresAt. - Copy the secret immediately.
Confirmation: Key created. Copy it now; we will not show it again.
The JSON create response is the only payload that ever contains secret. List endpoints return metadata only.
Send the key as a bearer credential on API-key routes. Do not put it in a query string, a repo, or a frontend bundle. API-key routes must not also present a session cookie.
Scopes
| Scope | Use |
|---|---|
usage:write | POST /api/usage/events — default. |
entitlements:read | GET /api/entitlements, GET /api/entitlements/[productSlug], POST /api/entitlements/check (batch, max 50 slugs). |
A key does not impersonate a User and does not grant owner. It cannot invite members, change plans, or issue other keys.
orgId is taken from the key. Clients cannot pass a different Organization.
Rotate and revoke
Rotate (POST .../api-keys/[id]/rotate): issues a new secret. The old key remains valid for graceMinutes (default 60), then expires. Use this when you can update the runtime within an hour.
Revoke (DELETE): immediate. Confirmation: Key revoked. Calls using it will fail.
Removing a Membership does not revoke keys. If a departing admin copied a secret, revoke that key.
Issuance, rotation, and revocation write AuditLog rows.
Usage ingestion
POST /api/usage/events with scope usage:write. Batch max 500 events. Each event: productSlug, metric, optional quantity, optional occurredAt, required idempotencyKey.
Checks:
- Live Entitlement for that
productSlug, or403 entitlement_required. read_onlyEntitlement →403 entitlement_read_only.metricmust equalProduct.usageMetric, or422 unknown_metric.occurredAtwithin [-7 days, +5 minutes], or422 timestamp_out_of_range.- Duplicate
(orgId, idempotencyKey)→ counted asdeduped, HTTP 202.
Over unitCap, events are still recorded. The response may include warnings: ["unit_cap_exceeded"].
Rate limit: 600 requests per minute per key. Entitlement checks: 1,200 per minute per key. Exceeding returns 429 with Retry-After.
Test vs live
nm_test_… keys are for non-production runtimes. Do not point a production connected worker at test keys. Do not put live keys in a laptop .env that is copied around.
