# Authentication API Reference

OpenAPI source: https://api.are.na/v3/openapi.json

## POST /v3/oauth/token

- Label: Obtain access token
- Docs: https://www.are.na/developers/explore/authentication/post-token
- Markdown: https://www.are.na/developers/explore/authentication/post-token.md
- Requires resource id: no
- Response content type: application/json

Exchange credentials for an access token. This is the OAuth 2.0 token endpoint.

**Supported Grant Types:**

- `authorization_code`: Exchange an authorization code for an access token
- `authorization_code` + PKCE: For public clients without a client secret
- `client_credentials`: Authenticate as your application (server-to-server)

**PKCE Support:** For public clients (mobile apps, SPAs), use PKCE:
1. Generate a random `code_verifier` (43-128 chars, alphanumeric + `-._~`)
2. Create `code_challenge` = Base64URL(SHA256(code_verifier))
3. In the authorization request to `https://www.are.na/oauth/authorize`, include:
   - `code_challenge`: The generated challenge
   - `code_challenge_method`: `S256`
4. When exchanging the code at this endpoint, include `code_verifier`

See [RFC 7636](https://tools.ietf.org/html/rfc7636) for details.

Access tokens do not expire and can be used indefinitely. Register your application
at [are.na/oauth/applications](https://www.are.na/oauth/applications) to obtain client credentials.

Request body schema:
```json
{
  "type": "object",
  "required": [
    "grant_type"
  ],
  "properties": {
    "grant_type": {
      "type": "string",
      "nullable": false,
      "description": "The OAuth 2.0 grant type",
      "enum": [
        "authorization_code",
        "client_credentials"
      ]
    },
    "client_id": {
      "type": "string",
      "nullable": false,
      "description": "Your application's client ID (required for all grant types)"
    },
    "client_secret": {
      "type": "string",
      "nullable": false,
      "description": "Your application's client secret (required for confidential clients, omit for PKCE)"
    },
    "code": {
      "type": "string",
      "nullable": false,
      "description": "Authorization code (required for authorization_code grant)"
    },
    "redirect_uri": {
      "type": "string",
      "nullable": false,
      "description": "Redirect URI used in authorization request (required for authorization_code grant)",
      "format": "uri"
    },
    "code_verifier": {
      "type": "string",
      "nullable": false,
      "description": "PKCE code verifier (required when authorization used code_challenge).\nMust be 43-128 characters from [A-Z], [a-z], [0-9], \"-\", \".\", \"_\", \"~\".\n"
    }
  }
}
```

Response schema:
```json
{
  "type": "object",
  "required": [
    "access_token",
    "token_type",
    "scope",
    "created_at"
  ],
  "properties": {
    "access_token": {
      "type": "string",
      "nullable": false,
      "description": "The access token to use for API requests"
    },
    "token_type": {
      "type": "string",
      "nullable": false,
      "description": "Token type (always \"Bearer\")",
      "enum": [
        "Bearer"
      ]
    },
    "scope": {
      "type": "string",
      "nullable": false,
      "description": "Granted scopes (space-separated)",
      "example": "write"
    },
    "created_at": {
      "type": "integer",
      "nullable": false,
      "description": "Unix timestamp when the token was created"
    }
  }
}
```