---
title: "Exchange an authorization code, device code, or refresh token"
method: POST
path: "/api/oauth/token"
tags: ["OAuth 2.0 / OpenID Connect"]
---

# Exchange an authorization code, device code, or refresh token

`POST /api/oauth/token`

Use HTTP Basic client authentication when possible. client_secret_post remains supported for compatibility. Public device clients send client_id without a secret. Repeated parameters and multiple client authentication methods are rejected.

## Response `200`

OAuth tokens.

- OAuthTokenResponse
  - `access_token` string, required
  - `token_type` 'Bearer', required
  - `expires_in` integer, required
  - `refresh_token` string
  - `id_token` string
  - `scope` string

## Other responses

- `400` — Validation error or precondition failure.
- `401` — Missing or invalid credential.
- `403` — Credential lacks the required scope (Agent Key) or insufficient OAuth scope.
- `404` — Resource does not exist or is invisible to the caller. The two are intentionally indistinguishable.
- `409` — Conflicting state (e.g. legal-entity name already taken).
- `429` — Rate limit exceeded. No `Retry-After` header is currently emitted; back off exponentially.
- `500` — Server error.

---

[API](https://skmtc.dev/eprospera/apis/e-pro-spera-api.md) · [All operations](https://skmtc.dev/eprospera/apis/e-pro-spera-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/eprospera/e-pro-spera-api/revisions/9ecdd3ca5a8c/schema)
