---
title: "Create an API token for scripts, MCP clients, or agents."
method: POST
path: "/api/v1/tokens"
tags: ["Tokens"]
---

# Create an API token for scripts, MCP clients, or agents.

`POST /api/v1/tokens`

## Request

- Base URL: `https://commentary.dev`
- URL: `https://commentary.dev/api/v1/tokens`
- Auth: API key in cookie `commentary_session`

Issuance is atomic. Retry unchanged settings with the same Idempotency-Key after an uncertain outcome. Replay confirms the existing credential without returning its one-time secret; deliberately rotate it in Account Developer access for recovery.

## Headers

- `Idempotency-Key` string

## Request body

- CreateTokenRequest
  - `label` string
  - `scopes` union
    - string
    - ExternalScope[]
  - `target` string: Target string such as account, github:owner/repo, github:owner/repo:pull:123, github:owner/repo:branch:main, or draft:sessionId.
  - `expiresAt` string, date-time, nullable

## Response `200`

Successful response.

- object
  - `ok` unknown, required
  - `id` string, required
  - `grantId` string, required
  - `replayed` boolean
  - `token` string: One-time secret, present only for the original successful issue.
  - `tokenHint` string, required

## Other responses

- `400`: The request was invalid.
- `401`: Authentication is required.
- `403`: The token or session does not have permission for this resource.
- `404`: The resource was not found.
- `409`: The issuance key was reused with different settings or the connected account changed.
- `429`: The request was rate limited.

---

[API](https://skmtc.dev/commentary/apis/commentary-public-api.md) · [All operations](https://skmtc.dev/commentary/apis/commentary-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/commentary/apis/commentary-public-api/revisions/7aaafc198c52?raw)
