---
title: "Create a personal API token; plaintext is returned once"
method: POST
path: "/api/tokens"
tags: ["Tokens"]
---

# Create a personal API token; plaintext is returned once

`POST /api/tokens`

## Request

- Base URL: `https://tre-app.com`
- URL: `https://tre-app.com/api/tokens`
- Auth: HTTP bearer

Requires admin token scope or the web session. Read and write tokens receive 403 FORBIDDEN. Optional workspace (slug), scope (read/write/admin, default admin), and future expiresAt limit the token. Sessions and unlimited parents default to every workspace and no expiry. Omitted audience/expiry inherit finite parent limits; inherited audience still requires current membership. An unknown or outside workspace answers 404 NOT_FOUND (Workspace not found); expiry later than the parent answers 403 FORBIDDEN. Idempotency fingerprints include effective resolved limits: a cached broader token cannot be replayed under narrower limits (422 IDEMPOTENCY_KEY_REUSED).

## Headers

- `Idempotency-Key` string

## Request body

- TokenCreate
  - `name` string, required
  - `workspace` string
  - `scope` 'read' | 'write' | 'admin'
  - `expiresAt` string, date-time

## Response `201`

Success

- TokenCreationResult
  - `id` string, uuid, required
  - `name` string, required
  - `prefix` string, required
  - `kind` 'personal' | 'oauth', required
  - `scope` 'read' | 'write' | 'admin', required
  - `workspaceId` string, uuid, nullable, required
  - `clientId` string, nullable, required
  - `grantId` string, uuid, nullable, required: OAuth grant id when kind is oauth; null for personal tokens.
  - `expiresAt` string, date-time, nullable, required
  - `lastUsedAt` string, date-time, nullable, required
  - `createdAt` string, date-time, required
  - `revokedAt` string, date-time, nullable, required
  - `plaintext` string, required

## Other responses

- `400`: Invalid request
- `401`: Unauthenticated
- `403`: Forbidden: insufficient role or token scope; scope denials name the held scope and the operation
- `404`: Not found
- `409`: Conflict
- `422`: Idempotency-Key reused with a different request body (IDEMPOTENCY_KEY_REUSED)
- `429`: Rate limited
- `500`: Internal server error
- `503`: Temporarily unavailable

---

[API](https://skmtc.dev/tre-app/apis/tre-rest-api.md) · [All operations](https://skmtc.dev/tre-app/apis/tre-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tre-app/apis/tre-rest-api/revisions/26a7187a05fc?raw)
