---
title: "Token"
method: POST
path: "/token"
tags: ["oauth"]
---

# Token

`POST /token`

## Request

- Base URL: `https://app.zeno-works.ch` (the document declares no server; this is the origin it was published from)
- URL: `https://app.zeno-works.ch/token`
- Auth: none declared

Exchange an authorization code for an access token.

Form-encoded, per RFC 6749 §4.1.3 — not JSON, which is what every compliant client
sends and what this therefore has to read.

**The token minted here is an ordinary ``ApiKey`` row**, which is what makes the whole
design cheap: no second principal path, no new gate, and the owner can revoke it from
the Account → API keys screen on day one. It is minted through
``oauth.issue_for_grant`` and never through ``api_key.mint`` directly — see that
function for the escalation the shortcut produces.

## Response `200`

Successful Response

- TokenOut: RFC 6749 §5.1.
  - `access_token` string, required
  - `token_type` string
  - `expires_in` integer, required
  - `scope` string, required
  - `refresh_token` string, nullable

---

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