---
title: "Rotate API key"
method: POST
path: "/api_keys/{id}/rotate"
tags: ["API keys"]
---

# Rotate API key

`POST /api_keys/{id}/rotate`

## Request

- Base URL: `https://arena-predictions.com/api/v1`
- URL: `https://arena-predictions.com/api/v1/api_keys/{id}/rotate`
- Auth: one of:
  - API key in cookie `sb-access-token`
  - HTTP bearer

Replace a key: a new key with the same label and scopes (its token shown once in this response), and the old key kept working for graceSeconds (0 to 86400; 0 revokes it at once). One transaction. A rotating key does not count toward the 10-key cap; a rotation counts toward the 20 keys a day.

## Path parameters

- `id` string, uuid, required

## Request body

- KeyRotateRequest
  - `graceSeconds` integer: How long the old key keeps working. 0 revokes it at once.
  - `expiresInDays` integer: The new key's life. Omitted: the same life as the old key (at most 365 days), or none when the old key had none.

## Response `201`

Rotated.

- KeyRotateResponse
  - `key` KeyView, required
    - `id` string, uuid, required
    - `label` string, required
    - `tokenPrefix` string, required: First 16 characters of the token, for matching a row to a key. Never the token.
    - `scopes` string[], required
    - `status` 'active' | 'rotating' | 'revoked' | 'expired', required: rotating: replaced by a rotation and still inside its grace period (it works until expiresAt).
    - `createdAt` string, date-time, required
    - `lastUsedAt` string, date-time, nullable, required: Updated at most once an hour.
    - `expiresAt` string, date-time, nullable, required
    - `revokedAt` string, date-time, nullable, required
    - `createdVia` 'web' | 'cli', required: web: Settings. cli: arena keys.
    - `rotatedFrom` string, uuid, nullable, required: The key this one replaced by rotation.
    - `rotatedAt` string, date-time, nullable, required: When this key was rotated.
    - `requestsThisMonth` integer, required: Keyed requests counted against this key this month (UTC).
  - `token` string, required: The new plaintext key. Shown once; only its hash is stored.
  - `warning` string, required
  - `replaced` KeyView, required
    - `id` string, uuid, required
    - `label` string, required
    - `tokenPrefix` string, required: First 16 characters of the token, for matching a row to a key. Never the token.
    - `scopes` string[], required
    - `status` 'active' | 'rotating' | 'revoked' | 'expired', required: rotating: replaced by a rotation and still inside its grace period (it works until expiresAt).
    - `createdAt` string, date-time, required
    - `lastUsedAt` string, date-time, nullable, required: Updated at most once an hour.
    - `expiresAt` string, date-time, nullable, required
    - `revokedAt` string, date-time, nullable, required
    - `createdVia` 'web' | 'cli', required: web: Settings. cli: arena keys.
    - `rotatedFrom` string, uuid, nullable, required: The key this one replaced by rotation.
    - `rotatedAt` string, date-time, nullable, required: When this key was rotated.
    - `requestsThisMonth` integer, required: Keyed requests counted against this key this month (UTC).

## Other responses

- `400`: invalid_request: not same-origin (cookie session), not JSON, the id is not a uuid, graceSeconds is out of 0..86400, or expiresInDays is out of 1..365.
- `401`: unauthorized (not signed in) or session_required (an API key was presented).
- `403`: guest_account, or scope_not_available (the key carries trade:write while trading with keys is switched off).
- `404`: key_not_found: not an active key of this account (revoked, expired, already rotated, or not yours).
- `429`: key_creation_limited: 20 keys made in the last 24 hours.
- `500`: Could not rotate the key.

---

[API](https://skmtc.dev/arena-predictions/apis/arena-api.md) · [All operations](https://skmtc.dev/arena-predictions/apis/arena-api/llms.txt) · [OpenAPI document](https://skmtc.dev/arena-predictions/apis/arena-api/revisions/9d89d166dae6?raw)
