---
title: "Rotate key (new secret displayed only once)"
method: POST
path: "/keys/{key_id}/rotate"
tags: ["Keys"]
---

# Rotate key (new secret displayed only once)

`POST /keys/{key_id}/rotate`

## Request

- Base URL: `https://console-api.blockvectra.com/v1`
- URL: `https://console-api.blockvectra.com/v1/keys/{key_id}/rotate`
- Auth: HTTP bearer

Permitted for `active`, unexpired keys only. Creates a new key (inheriting label, limits, `cu_cap`, `expires_at`, and settled `cu_spent`; quota not reset by rotation) and revokes old key; the old key is refused by the gateways normally within about 1 second, and at most 5 seconds if a change notification is lost; `replaced` in response is revoked old key whose `replaced_by_key_id` matches new key `key_id`.

The original key must first be enabled, unrevoked and unexpired, otherwise 409 key_not_active. Rotation does not add to the live-key count but remains subject to the rolling 24-hour creation cap (429 rate_limited, error.reason daily_creations, Retry-After: 3600). It preserves the original limits, expiry and settled spending rather than resetting them.

## Path parameters

- `key_id` string, required

## Response `201`

New key, its secret (displayed only this once), and revoked old key.

- KeyRotateResponse
  - `key` KeyView, required
    - `key_id` string, required
    - `label` string, required: 1–64 characters, without control characters.
    - `status` 'active' | 'disabled' | 'revoked', required
    - `cu_per_sec` integer, required: Actual per-key token bucket refill rate (CU/s), including any paid floor or higher custom limit. Effective aggregate across all chains and Data API for this key.
    - `burst_cu` integer, required: Actual per-key token bucket capacity (CU), including any paid floor or higher custom limit. Effective aggregate across all chains and Data API for this key.
    - `created_at` string, date-time, required: RFC 3339 UTC, second precision, ending in `Z` (`2026-09-26T08:00:00Z`); no fractional seconds, without `+00:00` timezone offsets.
    - `created_by` 'console' | 'operator', required: `console` for self-created by client, `operator` for created by support.
    - `revoked_at` string, date-time, required: RFC 3339 UTC, second precision, ending in `Z` (`2026-09-26T08:00:00Z`); no fractional seconds, without `+00:00` timezone offsets.
    - `replaced_by_key_id` string, nullable, required: New key created from rotation; null if never rotated.
    - `cu_cap` integer, nullable, required: Lifetime CU cap for this key; null if unlimited. Inherited by rotated new key.
    - `cu_spent` integer, required: Settled CU counted toward key cap (settled hourly; excludes unsettled usage in latest period); inherited by rotated new key.
    - `expires_at` string, date-time, required: RFC 3339 UTC, second precision, ending in `Z` (`2026-09-26T08:00:00Z`); no fractional seconds, without `+00:00` timezone offsets.
  - `api_key` string, required: Key secret, displayed only this once.
  - `replaced` KeyView, required
    - `key_id` string, required
    - `label` string, required: 1–64 characters, without control characters.
    - `status` 'active' | 'disabled' | 'revoked', required
    - `cu_per_sec` integer, required: Actual per-key token bucket refill rate (CU/s), including any paid floor or higher custom limit. Effective aggregate across all chains and Data API for this key.
    - `burst_cu` integer, required: Actual per-key token bucket capacity (CU), including any paid floor or higher custom limit. Effective aggregate across all chains and Data API for this key.
    - `created_at` string, date-time, required: RFC 3339 UTC, second precision, ending in `Z` (`2026-09-26T08:00:00Z`); no fractional seconds, without `+00:00` timezone offsets.
    - `created_by` 'console' | 'operator', required: `console` for self-created by client, `operator` for created by support.
    - `revoked_at` string, date-time, required: RFC 3339 UTC, second precision, ending in `Z` (`2026-09-26T08:00:00Z`); no fractional seconds, without `+00:00` timezone offsets.
    - `replaced_by_key_id` string, nullable, required: New key created from rotation; null if never rotated.
    - `cu_cap` integer, nullable, required: Lifetime CU cap for this key; null if unlimited. Inherited by rotated new key.
    - `cu_spent` integer, required: Settled CU counted toward key cap (settled hourly; excludes unsettled usage in latest period); inherited by rotated new key.
    - `expires_at` string, date-time, required: RFC 3339 UTC, second precision, ending in `Z` (`2026-09-26T08:00:00Z`); no fractional seconds, without `+00:00` timezone offsets.

## Other responses

- `401`: Missing or invalid session (without distinguishing cause).
- `404`: Key does not exist or does not belong to this account.
- `409`: Key is not `active`.
- `429`: Rate limit exceeded, or daily key creation limit reached for account (rotations count as new keys, with reason: daily_creations).
- `500`: Internal server error.

---

[API](https://skmtc.dev/blockvectra/apis/blockvectra-console-api.md) · [All operations](https://skmtc.dev/blockvectra/apis/blockvectra-console-api/llms.txt) · [OpenAPI document](https://skmtc.dev/blockvectra/apis/blockvectra-console-api/revisions/28c91298f433?raw)
