---
title: "An app redeems its one-time code for what the register gives it, unauthenticated"
method: POST
path: "/v1/auth/token"
tags: ["auth"]
---

# An app redeems its one-time code for what the register gives it, unauthenticated

`POST /v1/auth/token`

## Request

- Base URL: `https://api.sixminute.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.sixminute.ai/v1/auth/token`
- Auth: none declared

`authorization_code`: the `sma_` code with the verifier of its challenge, for the client it was issued to. Every code works once whatever the outcome; a used, expired, unknown or other client's code, or a wrong verifier, is 401. A person in several firms is answered `choose_firm` with an `smp_` handle bound to the client, challenge and device, alive ten minutes, which `organization_selection` redeems with the same verifier and device and one of the firms offered. `workos_code`, the desktop only: WorkOS's code from the browser leg with the window's verifier. The device names its platform, which must be one of the client's (400). The desktop requires `X-Six-Minute-Page: 1` from an allowed Origin and is answered a session, its refresh token in the page's http-only cookie; the phone refuses any request carrying an Origin (403) and is answered its device credential only. A sign-in is provisioned on the server as `POST /v1/me/provision` does. A phone's device id of another person is 409; a desktop's, or a revoked one, leaves the session tied to no device, for the engine's enrolment to register the machine. Rate limited per caller.

## Request body

- union
  - object
    - `grant_type` 'authorization_code', required
    - `client` 'desktop' | 'phone', required
    - `code` string, required
    - `code_verifier` string, required
    - `device` object, required
      - `id` string, required
      - `name` string, required
      - `platform` 'macos' | 'windows' | 'ios' | 'android' | 'web', required
  - object
    - `grant_type` 'organization_selection', required
    - `client` 'desktop' | 'phone', required
    - `pending` string, required
    - `code_verifier` string, required
    - `organization_id` string, required
    - `device` object, required
      - `id` string, required
      - `name` string, required
      - `platform` 'macos' | 'windows' | 'ios' | 'android' | 'web', required
  - object
    - `grant_type` 'workos_code', required
    - `client` 'desktop', required
    - `code` string, required
    - `code_verifier` string, required
    - `device` object, required
      - `id` string, required
      - `name` string, required
      - `platform` 'macos' | 'windows' | 'ios' | 'android' | 'web', required

## Response `200`

The client's grant, or the firms to choose from.

- union
  - object
    - `grant` 'session', required
    - `session` object, required
      - `access_token` string, required
      - `organization_id` string, nullable
      - `user` object, required
        - `id` string, required
        - `email` string, required
        - `first_name` string, nullable
        - `last_name` string, nullable
  - object
    - `grant` 'credential', required
    - `enrolled` object, required
      - `credential` string, required
      - `device` object, required
        - `id` string, required
        - `user_id` string, required
        - `name` string, required
        - `platform` 'macos' | 'windows' | 'ios' | 'android' | 'web', required
        - `created_at` string, date-time, required
        - `last_seen_at` string, date-time, nullable
        - `revoked_at` string, date-time, nullable
      - `account` string
      - `tenant_id` string
  - object
    - `choose_firm` object, required
      - `pending` string, required
      - `firms` object[], required
        - `id` string, required
        - `name` string, required

## Other responses

- `400`: The body, query or path did not validate; `errors` lists the fields.
- `401`: No bearer token, or one that does not verify or has expired.
- `403`: The token verified but may not do this: no organisation, not provisioned, wrong role, or a device problem.
- `409`: The id or the email already belongs to something else.
- `422`: The request is well-formed but cannot be carried out as it stands.
- `429`: Too many requests; `Retry-After` says how long to wait.
- `502`: An upstream this service depends on failed or answered nonsense.
- `503`: A capability this service was not configured with, or a practice system that could not be reached; the `type` says which.

## Changes

- **2026-11-04** `605577eadc10`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/sixminute/apis/sixminute-api/changes/v1/auth/token/post.md)

---

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