API keys cannot be edited in place — to change a label, scopes, or expiration, you create a new key and revoke the old one. The same flow handles leaked keys, staff offboarding, and routine rotation.

## When to rotate

Rotate immediately if a key has been committed to a public repository, leaked through logs, or shared with someone who has left your team. Rotate on a schedule for keys that sit in CI runners or third-party integrations. Keys live until you revoke them or until their `expiresAt` fires.

## Issue a new key

Open **Developers → API keys** and click **New API key**. Give the replacement a label that identifies the rotation. Pick the same scopes the old key had — see [Create an API key](/developers/api-keys) for the full list. The new key is shown once on a single-reveal panel.

Copy the new key into your secrets manager alongside the old one. Keep both for the cutover.

## Cut over your callers

Deploy your secrets-manager update so every caller picks up the new key. The new and old keys can coexist for as long as you need — there is no platform-level rotation window for API keys (unlike webhook secrets, which have a fixed seven-day dual-verify window).

Watch your call volume in **Developers → API keys** to confirm the cutover landed. The list shows the last-used timestamp for every key.

## Revoke the old key

Once the new key's last-used timestamp is current and the old key's is stale, revoke the old key from **Developers → API keys → … → Revoke**. Revocation is immediate; subsequent calls with the revoked key return `invalid_api_key` (HTTP 401).

## Audit the rotation

Every key creation and revocation emits an audit-log entry tagged with the operator. The audit log is visible to organization owners and admins under **Activity** in the sidebar.

## Troubleshooting

If callers start returning `invalid_api_key` after a rotation, the usual causes are: the secrets-manager update has not propagated, the key was revoked early, or the caller is using the wrong region's key (see [Modes and regions](/developers/modes-and-regions)). The `request_id` on the error envelope points to the exact failure in your logs.