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

# Create Access Token

`POST /oauth/token`

## Request

- Base URL: `https://api.withpersona.com/api/v1`
- URL: `https://api.withpersona.com/api/v1/oauth/token`
- Auth: HTTP bearer

Exchange a credential for an access token. Supports two grant types:
- `authorization_code`: Exchange an authorization code for an access token
  (cross-org data sharing).
- `client_credentials`: Exchange a signed JWT assertion (`private_key_jwt`)
  for a short-lived access token (machine-to-machine auth, RFC 7523).

## Headers

- `Key-Inflection` 'camel' | 'kebab' | 'snake'
- `Idempotency-Key` string
- `Persona-Version` '2026-09-29' | '2025-12-08' | '2025-10-27' | '2023-01-05' | '2022-09-01' | '2021-08-18' | '2021-07-05' | '2021-02-21' | '2020-05-18': Server API version. More info on versioning can be found [here](https://docs.withpersona.com/versioning).

## Request body

- union
  - OAuthCreateAccessTokenRequest0: Exchange an authorization code for an access token.
    - `code` string, required: Authorization Code
    - `grant-type` string, required: Must be set to 'authorization_code'
  - OAuthCreateAccessTokenRequest1: Exchange a signed JWT assertion for a short-lived access token. The JWT must be signed with the private key corresponding to the public key registered on the OAuth client. Note: parameter names follow OAuth RFC 6749/7523 conventions (snake_case) rather than the Persona API default (kebab-case).
    - `grant_type` string, required: Must be set to 'client_credentials'
    - `client_assertion_type` string, required: Must be 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
    - `client_assertion` string, required: A signed JWT (RS256 or ES256) with claims: iss, sub (both set to the client_id), aud (the token endpoint URL), jti, iat, and exp (max 5 minutes from now).
    - `scope` string: Optional space-separated list of permissions to request. Must be a subset of the OAuth client's registered permissions. Defaults to all client permissions if omitted.

## Response `201`

This endpoint returns an Access Token.

- OAuthCreateAccessTokenResponse201
  - `access-token` string, required: Access Token that can be used wherever an API Key would be used.
  - `expires-in` integer, required: Number of seconds until the access token expires.
  - `scope` string, required: Space-separated list of granted permissions. Format varies by grant type: for client_credentials, bare permission names (e.g. inquiry.read account.read); for authorization_code, permission:object pairs (e.g. inquiry.read:inq_xxx). Empty string when no permissions are granted.
  - `token-type` 'bearer' | 'Bearer', required

## Other responses

- `400`: The request was unacceptable, often due to invalid parameters.
- `401`: An invalid API key was provided.
- `403`: The given API key doesn’t have permissions to perform the request or a quota has been exceeded.
- `404`: The requested resource doesn’t exist.
- `409`: The request conflicts with another request, often due to attempting to create a duplicate resource.
- `422`: The request modifies the resource in an unacceptable way, often due to an invalid action or parameter.
- `429`: Your organization’s rate limit has been exceeded. We recommend an exponential backoff on requests.

---

[API](https://skmtc.dev/withpersona/apis/withpersona-5.md) - [All operations](https://skmtc.dev/withpersona/apis/withpersona-5/llms.txt) - [OpenAPI document](https://skmtc.dev/withpersona/apis/withpersona-5/revisions/0281de74819e?raw)
