1. Docs
  2. API Reference
  3. OAuth2 token exchange

OAuth2 token exchange

POST/oauth/token

OAuth2 token endpoint (POST /oauth/token). Supports three grants, client_credentials described last: authorization_code (requires code, redirect_uri, and code_verifier, validates the confidential client's client_secret and the PKCE S256 challenge, enforces single-use of the code and active Environment membership, then returns access_token, id_token, token_type, expires_in, a rotating refresh_token and the granted scope) and refresh_token (requires refresh_token, client_id, and client_secret; the new pair keeps only the scopes still in the client's scopes, and scope in the response names the ones it kept). A client may use only the grants in its grant_types. Both tokens carry aud, the requesting client_id, on either grant. client_credentials (RFC 6749 §4.4) is for a machine client only: authenticated like any client, it may send audience (RFC 8707: the Environment's m2m_default_audience when omitted, or one in the client's allowed_audiences), and scope (from the client's own). It returns access_token, token_type, expires_in (the Environment's m2m_access_token_ttl_seconds, default 300) and scope, with no refresh or ID token. The token's type is service, sub the client's client_id, gty client_credentials, client_id the client and aud the audience, with the claims of the organization the client is pinned to and permissions from the client's own roles when it carries that scope. A machine client is limited to a number of mints a minute. Errors are returned in the RFC 6749 form { error, error_description }, not Canopy's envelope: 400 with invalid_request, invalid_grant, invalid_scope, invalid_target, unauthorized_client or unsupported_grant_type, 401 with invalid_client when client authentication fails, and 429 with invalid_request and Retry-After when a machine client mints too often.

Request body

application/json

grant_typestring Required
codestring Optional
client_idstring Required
client_secretstring Required
redirect_uristring Optional
code_verifierstring Optional
refresh_tokenstring Optional
audiencestring Optional

`client_credentials` only: the resource the token is for (RFC 8707), the Environment's `m2m_default_audience` or one the client lists in `allowed_audiences`. Omitted, the Environment's default.

scopestring Optional

`client_credentials` only: space-separated scopes, each one the client may request. Omitted, the client's own.

Responses

application/json

  • access_tokenstring*

    Access token (RS256 JWT)

  • id_tokenstring

    OpenID Connect ID token. Issued on the `authorization_code` grant only.

  • token_typestring*
  • expires_innumber*

    Access token lifetime in seconds

  • refresh_tokenstring*

    Refresh token. Rotates on every use: the one presented stops working.

  • scopestring*

    The scopes the tokens were granted, space-separated (RFC 6749 §5.1). On a refresh it can be narrower than the original grant: a scope taken off the client since is not carried into the new pair.

application/json

  • errorstring*
  • error_descriptionstring*

application/json

  • errorstring*
  • error_descriptionstring*

application/json

  • errorstring*
  • error_descriptionstring*

Returned object

Request
curl -X POST "https://auth.canopy-io.com/oauth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "string",
    "code": "string",
    "client_id": "string",
    "client_secret": "string",
    "redirect_uri": "string",
    "code_verifier": "string",
    "refresh_token": "string",
    "audience": "string",
    "scope": "string"
  }'
Response
{
  "access_token": "string",
  "id_token": "string",
  "token_type": "Bearer",
  "expires_in": 0,
  "refresh_token": "string",
  "scope": "openid profile email"
}
Related endpoints Was this page helpful?

Tell us how we can improve this guide.