---
title: "Replace an active token with a new value."
method: POST
path: "/v1/tokens/{token_id}/rotate"
tags: ["tokens"]
---

# Replace an active token with a new value.

`POST /v1/tokens/{token_id}/rotate`

## Request

- Base URL: `https://api.kody.codes`
- URL: `https://api.kody.codes/v1/tokens/{token_id}/rotate`
- Auth: HTTP bearer

Replace an active token with a new value. The old value stops working immediately; scopes and max_expires_at are unchanged. A token-authenticated caller can only rotate tokens whose scopes it holds and that do not outlive it.

Org permission: `token:delete`.

## Path parameters

- `token_id` string, required: API token id (path param on `/v1/tokens/{token_id}`).

## Request body

- object
  - `id` string: Alias for `token_id` (same value as `tokenList` / `tokenGet` output `id`).

## Response `200`

Success.

- object
  - `id` string, required
  - `name` string, required
  - `org_id` string, required: For org-bound tokens: the fixed org id. For user-owned tokens: the personal org id (placeholder; each request picks an org via `?org=`).
  - `org_binding` 'org' | 'user', required: `org`: fixed to org_id. `user`: person-owned; pass `?org=<slug>` on each request (default personal org). Membership/grants are checked live.
  - `scopes` string[], required
  - `status` 'active' | 'expired' | 'revoked', required
  - `idle_ttl_seconds` integer, required
  - `expires_at` string, required: Sliding expiry. Each successful request pushes it forward.
  - `max_expires_at` string, required: Absolute expiry. The token never outlives it.
  - `created_via` string, required
  - `created_at` string, required
  - `last_used_at` string, nullable, required
  - `rotated_at` string, nullable, required
  - `revoked_at` string, nullable, required
  - `profile_name` string, nullable, required: Named connection profile this token is bound to, or null for unlimited.
  - `token` string, required: The bearer token. Shown once; Kody stores only a hash. Send it as `Authorization: Bearer <token>`.
  - `token_type` 'Bearer', required

## Other responses

- `400`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `401`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `403`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `404`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `409`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `413`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `429`: Too many requests (edge IP/token limit) or an entitlement / plan-cap limit. Wait at least `Retry-After` seconds before retrying.
- `500`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `503`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `default`: Error envelope `{ "error": { "code", "message", "details"? } }`.

---

[API](https://skmtc.dev/kody/apis/kody-api.md) · [All operations](https://skmtc.dev/kody/apis/kody-api/llms.txt) · [OpenAPI document](https://skmtc.dev/kody/apis/kody-api/revisions/705f4f022728?raw)
