---
title: "Exchange an API key or refresh token for a Bearer token"
method: POST
path: "/api/auth/token"
tags: ["Auth"]
---

# Exchange an API key or refresh token for a Bearer token

`POST /api/auth/token`

## Request

- Base URL: `https://api.wondercal.com`
- URL: `https://api.wondercal.com/api/auth/token`
- Auth: none required

Authenticates using either an API key or a refresh token and returns a short-lived Bearer token plus a new refresh token. This endpoint is exempt from Bearer authentication and global rate limiting. It has its own IP-based rate limit.

## Request body

- TokenExchangeRequest: Provide either apiKey or refreshToken, not both.
  - `apiKey` string: API key starting with 'wcal_'
  - `refreshToken` string: Refresh token from a previous token exchange

## Response `200`

Token exchange succeeded

- object
  - `data` TokenExchangeResponse
    - `token` string, required: Short-lived Bearer token
    - `refreshToken` string, required: Long-lived refresh token for obtaining new Bearer tokens

## Other responses

- `400`: Missing or invalid request body
- `401`: Missing or invalid API key
- `413`: Request body exceeds 1 MB limit
- `429`: Rate limit exceeded. Retry-After header indicates seconds until the next request is allowed.
- `500`: Internal server error

---

[API](https://skmtc.dev/wondercal/apis/wondercal-api.md) · [All operations](https://skmtc.dev/wondercal/apis/wondercal-api/llms.txt) · [OpenAPI document](https://skmtc.dev/wondercal/apis/wondercal-api/revisions/4889176a380f?raw)
