---
title: "Exchange a code, rotate a refresh token, or redeem a device code"
method: POST
path: "/api/oauth/token"
tags: ["auth"]
---

# Exchange a code, rotate a refresh token, or redeem a device code

`POST /api/oauth/token`

## Request

- Base URL: `https://www.immersivecommons.com`
- URL: `https://www.immersivecommons.com/api/oauth/token`
- Auth: none required

Anonymous public-client token endpoint (no client secret). grant_type authorization_code (PKCE S256 code_verifier required; code is one-use, 60 s, bound to client_id + redirect_uri), refresh_token (rotates on every use; reusing a spent one revokes the whole connection; scopes re-intersected with the member's live tier), or urn:ietf:params:oauth:grant-type:device_code (RFC 8628 §3.5 shape over /api/agent/signup/poll). The access_token is an ordinary agt_ token valid 1 h. 404 unless the deployment sets OAUTH_CODE_FLOW_ENABLED=true.

## Response `200`

Tokens issued.

- OAuthTokenResponse
  - `access_token` string, required: agt_... bearer for /api/mcp and the REST API.
  - `token_type` 'Bearer', required
  - `expires_in` integer: Seconds; 3600 for code-grant tokens.
  - `refresh_token` string: icr_...; rotates on every use.
  - `scope` string: Space-delimited granted scopes.

## Other responses

- `400`: RFC 6749 §5.2 error: invalid_request, invalid_grant, invalid_scope, invalid_target, unsupported_grant_type, authorization_pending, expired_token, access_denied.
- `401`: invalid_client (unknown client_id, or a client secret was presented).
- `503`: Membership could not be confirmed; retry (the refresh token was not spent).

---

[API](https://skmtc.dev/immersivecommons/apis/immersive-commons-agent-rest-api.md) · [All operations](https://skmtc.dev/immersivecommons/apis/immersive-commons-agent-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/immersivecommons/apis/immersive-commons-agent-rest-api/revisions/be67c1f67c27?raw)
