A user access token lets your application make requests to the Wise API on behalf of a specific Wise user. Wise issues a user access token once the user authorises the partner application to perform transactions on their behalf.
Wise offers 2 ways to obtain a user access token:
- Registration code grant flow: For partners creating users and authorizing application access via API.
- If you can log in to Wise.com, you can also follow the authorization code grant flow.
- Authorization code grant flow: For partners authorizing application access via Wise.com's authorization page.
- If you created the user's Wise account, you can use the registration code grant to obtain a user access token for each user.
Correspondent and Enterprise partners go through this process only once during onboarding, then maintain access by refreshing the token.
Both flows return a user access token and a refresh token. Once you have a valid access token, using it in requests is the same regardless of which grant type you used to obtain it.
Embedded solutions partners no longer use user access tokens to make requests, as this model has changed to no longer rely on user objects. Partners on this integration model should instead use client credentials tokens for all authenticated requests.
If you are uncertain which token to use for your integration, contact your integration team to confirm.
Before you can obtain user access tokens, you must have:
- Your client ID and client secret (retrieve via Developer Hub).
- A redirect URL (coordinated during partner onboarding with the Wise implementation team and only required for the authorization code flow).
- Created a Wise account and user (how this occurs will depend on your integration model and you’ll be guided by your onboarding team).
Select the flow you wish to view in detail:
Obtaining a user access token via the registration code flow involves making a create OAuth token request with grant_type set to registration_code.
Example request:
curl -X POST https://api.wise.com/oauth/token \
-u '<client_id>:<client_secret>' \
-d 'grant_type=registration_code' \
-d 'client_id=<client_id>' \
-d 'email=<user_email>' \
-d 'registration_code=<registration_code>'Required data for this request:
client_idandclient_secretemailis the user’s email address (in the case of the Correspondent integration model, this is a dummy email provided by Wise).registration_codeis the same registration code value generated for the create user account request.
The response is the same for both the authorization and registration code flows. It includes both the access_token and refresh_token.
{ "access_token": "01234567-89ab-cdef-0123-456789abcdef", "token_type": "bearer", "refresh_token": "01234567-89ab-cdef-0123-456789abcdef", "expires_in": 43199, "expires_at": "2025-04-11T03:43:28.148Z", "refresh_token_expires_in": 628639555, "refresh_token_expires_at": "2045-03-12T13:49:23.552Z", "scope": "transfers", "created_at": "2020-01-01T12:33:33.12345Z" }
You can now use the access_token in all profile-level requests and refresh the access token prior to its expiration.
Include the access token in the Authorization header when making requests on behalf of the user.
- Production Environmenthttps://api.wise.com/2026Q3/profiles
- Sandbox Environmenthttps://api.wise-sandbox.com/2026Q3/profiles
- UserToken
- PersonalToken
curl -i -X GET \
https://api.wise.com/2026Q3/profiles \
-H 'Authorization: Bearer <YOUR_JWT_HERE>' \
-H 'X-External-Correlation-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479'User access tokens expire after 12 hours. Understanding how token invalidation works is critical to avoiding unexpected 401 errors in production.
Only one access token is valid at a time.
When you obtain a new access token (whether via refresh_token, authorization_code, or registration_code) the previously active access token is immediately invalidated. Any requests using the old token will fail with 401 invalid_token.
This means your application must always store and use the most recently issued access token.
This behaviour is the most common cause of unexpected 401 errors for partners in production. It typically occurs when:
- Multiple backend services independently refresh the token, and one service continues using the old token.
- A retry mechanism triggers a second refresh before the first response is processed.
- The new token is not propagated to all services that make API calls.
If the user originally authorised via the OAuth redirect flow:
- Attempt to refresh using your stored refresh token.
- If the refresh token is also invalid, redirect the user to re-authorise then use the authorization code to obtain new tokens.
This flow is typically used by integrations using a single partner account and as such go through the flow only once:
- Attempt to refresh using your stored refresh token.
- Use your registration code to generate a new token pair. The registration code is your primary recovery mechanism — store it securely!
Correspondent and Enterprise partners cannot redirect a user to re-authorise. However, if both your refresh token and registration code are invalid, but you can log in to Wise.com, you may generate an access token via the authorization code flow.
Otherwise, contact your Wise implementation team or Wise Platform support for further assistance.
This section covers the most common errors you may encounter when obtaining or using user access tokens.
| HTTP status | Error | Cause |
|---|---|---|
400 | invalid_grant — "Authorization code expired." | The authorisation code has a 10-minute TTL. You must exchange it for tokens within that window. |
400 | invalid_grant — "Authorization code is not valid." | The code has already been used. Each authorisation code can only be exchanged once. |
400 | invalid_grant — "Redirect URI mismatch." | The redirect_uri in your token request does not match the one used when redirecting the user to authorise. These must be identical, including query parameters. |
401 | invalid_client | Your client_id or client_secret is incorrect, or the Basic Auth header is malformed. |
400 | invalid_request — "Missing grant type" | The grant_type parameter is missing from the request body. |
| HTTP status | Error | Cause |
|---|---|---|
401 | invalid_grant — "Invalid user credentials." | The registration code is invalid, or the user has reclaimed their Wise account (for example, by resetting their password). |
| HTTP status | Error | Cause |
|---|---|---|
400 | invalid_grant | The refresh token is expired, revoked, or not found. Can also be caused when a profile is moved to a different account. |
401 | invalid_client | Your client_id or client_secret is incorrect. If you recently rotated your client secret, ensure you are using the active secret. |
| HTTP status | Error | Cause |
|---|---|---|
401 | invalid_token — "Invalid token" | The access token is expired, was never valid, was revoked, or was replaced by a newer token. Can also be caused by profile ownership change when there is an existing token. |
Some API paths may return {"error": "unauthorized"} instead of {"error": "invalid_token"}. Both indicate the same issue — the token is not valid.
This inconsistency is being addressed as part of an ongoing migration.