---
title: "SSO Token Exchange"
method: POST
path: "/v1/integrations/sso/token"
tags: ["authentication", "marketplace"]
---

# SSO Token Exchange

`POST /v1/integrations/sso/token`

## Request

- Base URL: `https://api.vercel.com`
- URL: `https://api.vercel.com/v1/integrations/sso/token`
- Auth: none required

During the autorization process, Vercel sends the user to the provider [redirectLoginUrl](https://vercel.com/docs/integrations/create-integration/submit-integration#redirect-login-url), that includes the OAuth authorization `code` parameter. The provider then calls the SSO Token Exchange endpoint with the sent code and receives the OIDC token. They log the user in based on this token and redirects the user back to the Vercel account using deep-link parameters included the redirectLoginUrl. Providers should not persist the returned `id_token` in a database since the token will expire. See [**Authentication with SSO**](https://vercel.com/docs/integrations/create-integration/marketplace-api#authentication-with-sso) for more details.

## Request body

- union
  - object
    - `code` string, required: The sensitive code received from Vercel
    - `state` string: The state received from the initialization request
    - `client_id` string, required: The integration client id
    - `client_secret` string, required: The integration client secret
    - `redirect_uri` string: The integration redirect URI
    - `grant_type` 'authorization_code', required: The grant type, when using x-www-form-urlencoded content type
  - object
    - `refresh_token` string, required: The refresh token received from previous token exchange
    - `client_id` string, required: The integration client id
    - `client_secret` string, required: The integration client secret
    - `grant_type` 'refresh_token', required: The grant type, when using x-www-form-urlencoded content type

## Response `200`

- union
  - object
    - `access_token` string, nullable, required
    - `expires_in` number
    - `id_token` string, required
    - `refresh_token` string
    - `token_type` string, nullable, required
  - object
    - `access_token` string, required
    - `expires_in` number, required
    - `id_token` string, required
    - `refresh_token` string, required
    - `token_type` string, required

## Other responses

- `400`: One of the provided values in the request body is invalid.
- `403`
- `500`

## Changes

- **2026-01-22** `c12186034433`: 7 breaking, 7 warning, 2 info
  - request body became required
  - the request's body type changed from `object` to no type
  - added `subschema #1, subschema #2` to the response body `oneOf` list for the response status `200`
  - the response's body type changed from `object` to no type for status `200`
  - …12 more
- **2025-11-28** `45991e5c8b6d`: 1 info
  - added the optional property `expires_in` to the response with the `200` status
- **2025-10-09** `50caddad4ae7`: 2 breaking, 1 info
  - the `access_token` response's property type changed from no type to `string` for status `200`
  - the `token_type` response's property type changed from no type to `string` for status `200`
  - added the non-success response with the status `403`
- **2025-04-22** `661a2f6357c1`: 1 info
  - added the new optional request property `grant_type`
- **2025-03-19** `37b482c58c92`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/vercel/apis/vercel-api/changes/v1/integrations/sso/token/post.md)

---

[API](https://skmtc.dev/vercel/apis/vercel-api.md) - [All operations](https://skmtc.dev/vercel/apis/vercel-api/llms.txt) - [OpenAPI document](https://skmtc.dev/vercel/apis/vercel-api/revisions/60686c0e1f6a?raw)
