{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/developer/auth-and-security/sidebars.yaml","oas-api-reference/index.yaml":"oas-api-reference/index.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition","tabs","tab","openapi-response-sample"]},"type":"markdown"},"seo":{"title":"User access tokens","siteUrl":"https://docs.wise.com","projectTitle":"Wise Platform","description":"Obtaining and using user access tokens in the Wise Platform API OAuth 2.0 flow.","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":["openapi"],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"user-access-tokens","__idx":0},"children":["User access tokens"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["How you obtain a user access token depends on your integration model:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Embedded finance partners"]},": Your end customers each have their own Wise profile and can interact with Wise directly through your application. Because each customer authorises your application individually, you use the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["authorization code"]}," grant to obtain a user access token for each customer. You'll go through this flow once per customer.",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["If you created the user's Wise account, you can use the registration code grant to obtain a user access token for each user."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Correspondent and Enterprise partners"]},": Your integration operates through a single Wise profile. There is no end user to redirect through a browser-based authorization flow, so you use the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["registration code"]}," grant to obtain a user access token. You'll typically go through this flow only once during onboarding, then maintain access by refreshing the token.",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["If you can log in to Wise.com, you can also follow the authorization code grant flow."]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Regardless of how you obtain your initial tokens, you are responsible for maintaining uninterrupted access by refreshing tokens before they expire. See the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/developer/auth-and-security/refresh-tokens"},"children":["Refresh tokens guide"]}," for details."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"before-you-begin","__idx":1},"children":["Before you begin"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before you can obtain user access tokens, you must have:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Your ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["client ID"]}," and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["client secret"]}," (retrieve via Developer Hub)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["redirect URL"]}," (coordinated during partner onboarding with the Wise implementation team and only required for the authorization code flow)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Created a Wise account and user (how this occurs will depend on your integration model and you’ll be guided by your onboarding team)."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"obtain-a-user-access-token","__idx":2},"children":["Obtain a user access token"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Select the flow you wish to view in detail:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Authorization code flow (for Embedded finance partners)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Registration code flow (for Correspondent and Enterprise partners)"]}]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Authorization code flow","disable":false},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Obtaining a user access token via the authorization code flow involves:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Directing the user from your application to the Wise authorisation page."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The user logging in and granting permission."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Wise redirecting the user back to your application with an authorisation code."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Your application exchanging the code for an access token and refresh token."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"redirect-to-authorisation-page","__idx":3},"children":["Redirect to authorisation page"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["From your application, direct the user to the Wise authorisation page. This is where the user will grant your application permission to perform transactions via the Wise API."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Wise authorisation page URL path"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"/oauth/authorize?client_id=<client_id>&redirect_uri=<redirect_uri>&response_type=code&state=<state>\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Query parameters"]},":"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_id"]},": Your application's client ID."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redirect_uri"]},": Your registered redirect URL (must match exactly)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["response_type"]},": Always ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["code"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["state"]},": A random string to prevent CSRF attacks. Must be verified on callback."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The user will see a Wise authorisation page where they can log in to the Wise account (if not already logged in), review the permissions your application is requesting, and approve access."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"receive-authorisation-code","__idx":4},"children":["Receive authorisation code"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After the user approves access, Wise redirects them back to your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redirect_uri"]}," with an authorisation code."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The URL will appear in the browser in a format like this:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"https://your-app.com/callback?code=<authorization_code>&state=<state>\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You’ll exchange the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["authorization_code"]}," value for the token in the next step."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Important!"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Verify that the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["state"]}," value matches what you sent in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["state"]}," parameter when redirecting the user to authorise."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"exchange-auth-code-for-tokens","__idx":5},"children":["Exchange auth code for tokens"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Exchange the auth code returned in the previous step for an access token and refresh token by making a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api-reference/oauth-token/oauthtokencreate"},"children":["create an OAuth token request"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["grant_type"]}," set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["authorization_code"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example request"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X POST https://api.wise.com/oauth/token \\\n  -u '<client_id>:<client_secret>' \\\n  -d 'grant_type=authorization_code' \\\n  -d 'client_id=<client_id>' \\\n  -d 'code=<authorization_code>' \\\n  -d 'redirect_uri=<redirect_uri>'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Required data for this request:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_id"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_secret"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["code"]}," is the same authorization code value returned from the previous step."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redirect_uri"]}," is the redirect URL coordinated with Wise during onboarding."]}]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Registration code flow","disable":false},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Obtaining a user access token via the registration code flow involves making a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api-reference/oauth-token/oauthtokencreate"},"children":["create an OAuth token request"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["grant_type"]}," set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["registration_code"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Example request"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X POST https://api.wise.com/oauth/token \\\n  -u '<client_id>:<client_secret>' \\\n  -d 'grant_type=registration_code' \\\n  -d 'client_id=<client_id>' \\\n  -d 'email=<user_email>' \\\n  -d 'registration_code=<registration_code>'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Required data for this request:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_id"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_secret"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["email"]}," is the user’s email address (in the case of the Correspondent integration model, this is a dummy email provided by Wise)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["registration_code"]}," is the same registration code value generated for the create user account request."]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"example-response","__idx":6},"children":["Example response"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The response is the same for both the authorization and registration code flows. It includes both the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["access_token"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["refresh_token"]},"."]},{"$$mdtype":"Tag","name":"OpenApiResponseSample","attributes":{"descriptionFile":"oas-api-reference/index.yaml","operationId":"oauthTokenCreate","responseSamplesResolved":[{"lang":"json","title":"200 application/json","source":"{\n  \"access_token\": \"01234567-89ab-cdef-0123-456789abcdef\",\n  \"token_type\": \"bearer\",\n  \"refresh_token\": \"01234567-89ab-cdef-0123-456789abcdef\",\n  \"expires_in\": 43199,\n  \"expires_at\": \"2025-04-11T03:43:28.148Z\",\n  \"refresh_token_expires_in\": 628639555,\n  \"refresh_token_expires_at\": \"2045-03-12T13:49:23.552Z\",\n  \"scope\": \"transfers\",\n  \"created_at\": \"2020-01-01T12:33:33.12345Z\"\n}"},{"lang":"json","title":"400 application/json","source":"{\n  \"error\": \"invalid_request\",\n  \"error_description\": \"Missing grant type\"\n}"},{"lang":"json","title":"401 application/json","source":"{\n  \"error\": \"invalid_grant\",\n  \"error_description\": \"Invalid user credentials.\"\n}"},{"lang":"json","title":"429 application/json","source":"{}"}]},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can now use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["access_token"]}," in all profile-level requests and refresh the access token prior to its expiration."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"using-the-token","__idx":7},"children":["Using the token"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Include the access token in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization"]}," header when making requests on behalf of the user."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl -X GET https://api.wise.com/v2/profiles \\\n  -H 'Authorization: Bearer <USER_ACCESS_TOKEN>'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"managing-user-access-tokens","__idx":8},"children":["Managing user access tokens"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["User access tokens expire after ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["12 hours"]},". Understanding how token invalidation works is critical to avoiding unexpected ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401"]}," errors in production."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"access-token-invalidation","__idx":9},"children":["Access token invalidation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Only one access token is valid at a time."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you obtain a new access token (whether via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["refresh_token"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["authorization_code"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["registration_code"]},") the previously active access token is immediately invalidated. Any requests using the old token will fail with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 invalid_token"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This means your application must always store and use the most recently issued access token."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This behaviour is the most common cause of unexpected ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401"]}," errors for partners in production. It typically occurs when:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Multiple backend services independently refresh the token, and one service continues using the old token."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A retry mechanism triggers a second refresh before the first response is processed."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The new token is not propagated to all services that make API calls."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"recovery-paths-by-integration-model","__idx":10},"children":["Recovery paths by integration model"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["How you recover from token invalidation depends on your integration model:"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"embedded-finance-partners","__idx":11},"children":["Embedded finance partners"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the user originally authorised via the OAuth redirect flow:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Attempt to refresh using your stored refresh token."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["If the refresh token is also invalid, redirect the user to re-authorise then use the authorization code to obtain new tokens."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"enterprise-and-correspondent-partners","__idx":12},"children":["Enterprise and Correspondent partners"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["These integration models use a single partner account and typically go through the authorisation flow only once:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Attempt to refresh using your stored refresh token."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use your ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["registration code"]}," to generate a new token pair. The registration code is your primary recovery mechanism — store it securely!"]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Using the authorization code flow"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Unlike Embedded finance partners, you 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."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Otherwise, contact your Wise implementation team or ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://docs.wise.com/guides/developer/support"},"children":["Wise Platform support"]}," for further assistance."]}]},{"$$mdtype":"Tag","name":"hr","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"user-access-token-errors","__idx":13},"children":["User access token errors"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This section covers the most common errors you may encounter when obtaining or using user access tokens."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"errors-when-obtaining-tokens","__idx":14},"children":["Errors when obtaining tokens"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"authorization-code-grant","__idx":15},"children":["Authorization code grant"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"HTTP status"},"children":["HTTP status"]},{"$$mdtype":"Tag","name":"th","attributes":{"width":"25%","data-label":"Error"},"children":["Error "]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Cause"},"children":["Cause"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["invalid_grant"]}," — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Authorization code expired.\""]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The authorisation code has a 10-minute TTL. You must exchange it for tokens within that window."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["invalid_grant"]}," — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Authorization code is not valid.\""]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The code has already been used. Each authorisation code can only be exchanged once."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["invalid_grant"]}," — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Redirect URI mismatch.\""]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["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."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["invalid_client"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_id"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_secret"]}," is incorrect, or the Basic Auth header is malformed."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["invalid_request"]}," — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Missing grant type\""]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["grant_type"]}," parameter is missing from the request body."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"registration-code-grant","__idx":16},"children":["Registration code grant"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"HTTP status"},"children":["HTTP status"]},{"$$mdtype":"Tag","name":"th","attributes":{"width":"25%","data-label":"Error"},"children":["Error "]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Cause"},"children":["Cause"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["invalid_grant"]}," — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Invalid user credentials.\""]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The registration code is invalid, or the user has reclaimed their Wise account (for example, by resetting their password)."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"refresh-token-grant","__idx":17},"children":["Refresh token grant"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"HTTP status"},"children":["HTTP status"]},{"$$mdtype":"Tag","name":"th","attributes":{"width":"25%","data-label":"Error"},"children":["Error "]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Cause"},"children":["Cause"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["invalid_grant"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The refresh token is expired, revoked, or not found. Can also be caused when a profile is moved to a different account."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["invalid_client"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_id"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client_secret"]}," is incorrect. If you recently rotated your client secret, ensure you are using the active secret."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"errors-when-using-tokens","__idx":18},"children":["Errors when using tokens"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"HTTP status"},"children":["HTTP status"]},{"$$mdtype":"Tag","name":"th","attributes":{"width":"25%","data-label":"Error"},"children":["Error "]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Cause"},"children":["Cause"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["invalid_token"]}," — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Invalid token\""]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The access token is expired, was never valid, was revoked, or was ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["replaced by a newer token"]},". Can also be caused by profile ownership change when there is an existing token."]}]}]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Legacy error format"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Some API paths may return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{\"error\": \"unauthorized\"}"]}," instead of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{\"error\": \"invalid_token\"}"]},". Both indicate the same issue — the token is not valid."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This inconsistency is being addressed as part of an ongoing migration."]}]}]},"headings":[{"value":"User access tokens","id":"user-access-tokens","depth":1},{"value":"Before you begin","id":"before-you-begin","depth":2},{"value":"Obtain a user access token","id":"obtain-a-user-access-token","depth":2},{"value":"Redirect to authorisation page","id":"redirect-to-authorisation-page","depth":3},{"value":"Receive authorisation code","id":"receive-authorisation-code","depth":3},{"value":"Exchange auth code for tokens","id":"exchange-auth-code-for-tokens","depth":3},{"value":"Example response","id":"example-response","depth":3},{"value":"Using the token","id":"using-the-token","depth":2},{"value":"Managing user access tokens","id":"managing-user-access-tokens","depth":2},{"value":"Access token invalidation","id":"access-token-invalidation","depth":3},{"value":"Recovery paths by integration model","id":"recovery-paths-by-integration-model","depth":3},{"value":"Embedded finance partners","id":"embedded-finance-partners","depth":4},{"value":"Enterprise and Correspondent partners","id":"enterprise-and-correspondent-partners","depth":4},{"value":"User access token errors","id":"user-access-token-errors","depth":2},{"value":"Errors when obtaining tokens","id":"errors-when-obtaining-tokens","depth":3},{"value":"Authorization code grant","id":"authorization-code-grant","depth":4},{"value":"Registration code grant","id":"registration-code-grant","depth":4},{"value":"Refresh token grant","id":"refresh-token-grant","depth":4},{"value":"Errors when using tokens","id":"errors-when-using-tokens","depth":3}],"frontmatter":{"seo":{"description":"Obtaining and using user access tokens in the Wise Platform API OAuth 2.0 flow.","title":"User access tokens"}},"lastModified":"2026-07-16T12:31:35.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/developer/auth-and-security/user-access-token","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}