POST /v1/api-keys/:keyId/rotate
Planned key rotation - replaces the secret and returns the new plaintext exactly once.
/v1/api-keys/{keyId}/rotate- Auth
- Bearer
Planned rotation. Replaces both the prefix and the hashed secret. The old secret is instantly invalid - any consumer using it gets 401 UNAUTHENTICATED on the next request. Rotation also re-activates the key: kill_switch is cleared, revoked_at is nulled, is_active flips back to true.
Use this for calendar-driven rotation (quarterly / annual), post-leak recovery after a kill, or bootstrapping a fresh secret for a rotation drill. For active incident response where you want the key dead immediately and recoverable only by a human, use /kill.
The new plaintext secret is returned exactly once in the response body. Store it immediately - Layers cannot retrieve it again.
keyIdstring (UUID)requiredThe api_keys.id of the key to rotate. Must belong to the same org as the calling key.
Idempotency-Keystring (UUID)requiredStrongly recommended. Replays return the SAME new secret - without this, a network retry silently issues two rotations and leaves you with the wrong secret.
Example
# Quarterly rotation
NEW_KEY=$(curl -s -X POST https://api.layers.com/v1/api-keys/c2037bb9-354d-4662-96b7-97a28ad6b6e1/rotate \
-H "Authorization: Bearer $LAYERS_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" | jq -r .secret)
# Deploy NEW_KEY to your services, then verify:
curl https://api.layers.com/v1/whoami -H "Authorization: Bearer $NEW_KEY"{
"apiKey": {
"id": "c2037bb9-354d-4662-96b7-97a28ad6b6e1",
"organizationId": "org_2481fa5c-a404-44ed-a561-565392499abc",
"name": "production-service",
"prefix": "lp_...",
"killSwitch": false,
"isActive": true,
"rotatedAt": "2026-04-20T18:14:02.187Z",
"revokedAt": null
},
"secret": "lp_...",
"warning": "Store this secret now. It cannot be retrieved again. Rotate the key if it's lost."
}Rotation runbook
- Call
/rotatewith a freshIdempotency-Key. Grabsecretfrom the response body. - Deploy the new secret to every service that uses the old one. Do this BEFORE relying on the new key - the old secret is already dead.
- Verify with
GET /v1/whoamiusing the new secret. A 200 confirms end-to-end. - Audit via
GET /v1/audit-log?eventType=api_key.rotated- the rotation is recorded with the calling key + target key + request id.
Idempotency is load-bearing here. If step 1 times out and you retry without the same Idempotency-Key, you'll mint a second rotation and your first secret becomes stale. Always pass an Idempotency-Key.
Errors
| Status | Code | When |
|---|---|---|
| 404 | NOT_FOUND | Key ID doesn't exist, or belongs to a different org. |
| 409 | IDEMPOTENCY_CONFLICT | Idempotency-Key reused with a different body. |
| 422 | VALIDATION | Missing :keyId. |
See also
- Kill - emergency, one-way; use this when the old secret is compromised.
- Delete - retire a key cleanly without replacing it.
- API keys concept - lifecycle diagram.
- Audit log -
api_key.rotatedevents.