Layers
Partner APIConcepts

API keys

Key format, scope taxonomy, rate-limit tiers, and revocation paths.

View as Markdown

An API key authenticates every request you make and decides what that request is allowed to do. One key is scoped to one organization. It carries the rate-limit tier that caps throughput and the allowlist of returnUrl values the OAuth flows will accept. A future scope list will gate individual routes.

Key format

lp_<env>_<key_id>_<secret>
  • env is either live or test. Test keys talk to the same API but their traffic is routed to sandboxed back-ends — no production publishing, no real billing.
  • key_id is a 16-character base32 handle. It's public — safe to log, used for rate-limit attribution, and how we look up the row.
  • secret is a 43-character base64url remainder. Everything after the last underscore.

We store bcrypt(cost=12, secret). The plaintext exists only in your client. If you lose it, you rotate.

The secret is shown exactly once — at the moment of creation. We can't recover it, display it again, or confirm you have the right one. Paste it into your secrets manager before you close the tab.

Sending the key

Primary form: X-Api-Key: <key>. Authorization: Bearer <key> is accepted as a fallback for clients that can't set custom headers. If both are sent, the server prefers X-Api-Key.

GET /v1/whoami HTTP/1.1
Host: api.layers.com
X-Api-Key: lp_live_01HX9Y6K7EJ4T2AB_4QZpN...remainder

The first call any client should make is GET /v1/whoami — it resolves your key to the org it's bound to and lets you fail fast if anything is wrong. Response shape:

{
  "organizationId": "2481fa5c-a404-44ed-a561-565392499abc",
  "workspaceId": "2481fa5c-a404-44ed-a561-565392499abc",
  "organizationName": "Acme Growth",
  "scopes": [],
  "rateLimitTier": "standard",
  "killSwitch": false,
  "apiAccessRevoked": false,
  "apiKeyId": "c2037bb9-354d-4662-96b7-97a28ad6b6e1"
}

Scopes (planned)

Scopes are not yet enforced. Partner keys currently carry org-level access across the whole surface and /v1/whoami returns scopes: []. The table below documents the planned vocabulary so your integration can plan for granular access.

ScopeGates
projects:read / projects:writeProject CRUD.
ingest:writeGitHub / website / App Store ingestion.
content:read / content:write / content:approveContent read, generation, and approval actions.
social:read / social:writeSocial account listing and OAuth flows.
publish:writeSchedule and publish posts.
events:read / events:read+piiSDK event stream. +pii includes unredacted fields.
metrics:readOrganic and ads metrics.
ads:read / ads:writeAds reads today; ads CRUD is planned.
influencers:writeInfluencer create / clone / patch.
leased:writeSubmit and release leased-account requests.
engagement:writePatch engagement layer config.
github:adminRegister and read GitHub App installations.
jobs:read / jobs:cancelRead and cancel jobs.

Rate-limit tiers

Tier is a property of the key, not the endpoint. Buckets are keyed per (key_id, endpoint_class) so a runaway generation loop can't starve your reads. Endpoint classes: read-light, write-light, long-running.

TierTypical provisioning
standardDefault for every partner key.
pilotHigher throughput for early-integration partners — granted by Layers on request.
partnerEnterprise tier for GA partners with SLAs.

Every 429 response carries:

  • Retry-After (seconds)
  • X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
  • X-RateLimit-Endpoint-Class, X-RateLimit-Tier
  • Body with error.details.retryAfterMs and error.details.endpointClass

See common patterns for a back-off snippet and rate limits for the full bucket policy.

Rotation

You can rotate a key without downtime:

Ask Layers to create a second key with the same access.
Deploy the new secret to your callers.
Watch last_used_at on the old key drop to zero.
Revoke the old key.

Both keys are active in parallel during the cutover, so there's no flap.

Revocation

Three levers, each stronger than the last:

  • Revoke the key. revoked_at gets stamped. Every subsequent request fails with 401 UNAUTHENTICATED. This is the normal path.
  • Kill switch on the key. Sets kill_switch = true. Requests fail with 503 KILL_SWITCH — a different signal than revoked, so you can tell an incident from a rotation. Clearable without reissuing.
  • Org-wide kill switch. Flips organizations.api_access_revoked = true. Every key on the org fails. Reserved for incident response.

Revocation and kill-switch flips take effect on the next request — propagation is effectively immediate.

On this page