---
title: "Create a personal access token (secret returned once)"
method: POST
path: "/api/v0/tokens"
tags: ["Auth"]
---

# Create a personal access token (secret returned once)

`POST /api/v0/tokens`

## Request

- Base URL: `https://app.vibeflow.tools`
- URL: `https://app.vibeflow.tools/api/v0/tokens`
- Auth: HTTP bearer

Plan §4.5: {name, scopes, expiresAt?} returns the plaintext vbf_pat_ secret exactly once, plus the prefix-only row. Session-authenticated for bootstrap, or bearer with tokens:manage.

## Request body

- TokenCreate
  - `name` string, required
  - `scopes` string[], required
  - `expiresAt` string, date-time, nullable

## Response `201`

Create a personal access token (secret returned once) — success

- TokenSecret: Creation response — the secret appears here exactly once (plan §4.5).
  - `token` string, required: Full vbf_pat_ secret — shown once, never stored
  - `id` string, required
  - `name` string, required
  - `prefix` string, required
  - `scopes` string[], required
  - `expiresAt` string, date-time, nullable

## Other responses

- `400`: Malformed request (includes invalid task/comment id form)
- `401`: Missing or invalid principal
- `403`: Lacking scope or membership
- `404`: Unknown id
- `429`: Rate limited — cloud per-token quota exceeded (reads 300/min, writes 60/min, token creation 10/hour); counters are per-replica, so the effective limit is the configured value × replicas. The response carries Retry-After.

---

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