---
title: "Create an API token, returning its secret exactly once"
method: POST
path: "/v1/tokens"
tags: ["admin"]
---

# Create an API token, returning its secret exactly once

`POST /v1/tokens`

## Request

- Base URL: `https://api.indraft.io`
- URL: `https://api.indraft.io/v1/tokens`
- Auth: HTTP bearer

The secret is in this response and nowhere else. Naming a scope is a request rather than a grant: a token holds the intersection of its scopes and the live role of the member who created it, read at request time, so demoting that person weakens every token they made in the same moment.

## Request body

- object
  - `label` string, required
  - `scopes` string[], required

## Response `201`

Success

- object
  - `id` string, required
  - `prefix` string, required
  - `token` string, required

## Other responses

- `401`: No credential, or one that has been revoked.
- `402`: A product quota is spent, or the subscription is not active.
- `403`: Authenticated, and this capability is not held.
- `409`: A conflict the caller can resolve: a stale expectedVersion, an idempotency key reused for different input, an ambiguous or duplicate identity, or a merge that no longer applies.
- `413`: The body, or a single record inside it, exceeds its bound.
- `422`: The request does not satisfy the schema on this page.
- `429`: Infrastructure protection tripped. This is not a product quota.
- `500`: A defect on our side. The hint says so, and carries an incident id.
- `507`: The workspace is at its storage ceiling.

---

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