Introduction
About
Authentication and integration onboarding are the starting points of Wolt’s integration flow.
The integration onboarding process is a one-time activation experience for venues, whereas the authentication flow must be designed for recurring use.
Wolt offers three integration onboarding products based on OAuth framework to accommodate for the most popular user journeys on the 3P side:
Self-service integration onboarding – helps venues to self-activate the integration on Wolt through the user-interface. Usually, fits POS and middleware providers that already offer self-service experiences to their users;
Wolt-led integration onboarding – helps to activate one or multiple venues at once by reaching out to Wolt; Usually, fits both directly integrated merchants and POS/Middleware providers.
Brand-level authentication onboarding – designed for mono-brand enterprise-sized merchants. With a single set access credentials, it manages the integration with Wolt through a single access token.
Check-list
You selected the OAuth flow your system is going to use WIO and/or SSIO or Brand.
You've chosen an OAuth client library (you can find a list of recommended libraries here and here) for your implementation or have implemented the OAuth framework yourself.
You registered your new integration partner with Wolt and provided required inputs
You received client id and client secret back from Wolt
You could access the integration self-service cabinet here
Tip: Initial configurations for OAuth methods slightly differ, so make sure you request the support of the onboarding method when registering your integration partner on Wolt.
OAuth 2.0 flow
For venues integrated through self-service integration onboarding or Wolt-led integration onboarding, the OAuth 2.0 authorization code flow is used to enable merchants (resource owners) to grant integration partners controlled access to their Wolt venues (resources).
As the result of authentication, Integration partners can then retrieve access and refresh tokens:
Access tokens to call Wolt APIs.
Refresh tokens to get new access and refresh tokens.
The whole OAuth flow could virtually be split into three key operations the implementation must support beyond the API calls itself:
1. Authorization grant – first time authentication, where the auth code received;
2. Token exchange – the first time call to exchange the auth code for the first pair of access and refresh tokens (always distributed in pair)
3. Token refresh – recurring operation to keep access token valid.
Access token
The access token is a short-lived credential used to authenticate API requests. It grants access to the Wolt APIs for the specific venue or resource to which it was issued. The access token must be included in the Authorization header as a Bearer token when making calls to Wolt API. Typically, the authorization code is only used for the initial exchange, and thereafter you should rely exclusively on the refresh token.
Access tokens are valid for one hour. Expired token can no longer be used to make API requests.
Refresh token
The refresh token is a long-lived credential used to obtain a new access token when the current access token expires.
Refresh tokens are valid for 30 days. However, the refresh token is single-use. Each request to exchange the refresh token for a new access token also returns a new refresh token. The returned refresh token must be cached and used in the next request to exchange refresh token for a new access token.
Examples
Authorization grant
Authorization grant operation flow differs per Integration onboarding method and therefore covered in dedicated sub-articles. Please, read one according to the Integration onboarding method you selected.
First tokens exchange
When you get a authorization code from self-service integration onboarding or Wolt-led integration onboarding you need to exchange it for access and refresh tokens.
The authorization code is single-use and valid for 1 hour. After that period, it expires and can no longer be used to obtain tokens. If the code expires, you will need to initiate active integration is reset to receive a new authorization code prior to retrying this step.
[TODO: Insert PIC]
1. Integration partner sends authorization code to Wolt auth service Your system sends the authorization code obtained through self-service integration onboarding or Wolt-led integration onboarding, your client ID and client secret to Wolt’s auth service.
2. Wolt auth service returns access and refresh tokens Wolt’s auth service returns an access token and a refresh token. The authorization code is invalidated and can no longer be used.
3. Integration partner stores the tokens Your system must store the refresh token returned in the response for later use. The refresh token is used to exchange it for new tokens when the current access token expires. You should avoid requesting new access token each time, and instead use the same access token as long as it's valid.
Request URLs
| Environment | Base URL | 
|---|---|
| Development | https://integrations-authentication-service.development.dev.woltapi.com/oauth2/token | 
| Production | https://integrations-authentication-service.wolt.com/oauth2/token | 
Example request
curl -X POST https://integrations-authentication-service.development.dev.woltapi.com/oauth2/token \-H "Content-Type: application/x-www-form-urlencoded" \-u "{{client_id}}:{{client_secret}}" \-d "grant_type=authorization_code" \-d "redirect_uri={{redirect_uri}}" \-d "code={{code}}"
Request headers
| Header name | Description | 
|---|---|
| Authorization | Authorization header using basic auth. Must be Base64 encoding of client_id and client_secret joined by a single colon :.Example: client_id:client_secret -> Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQK | 
| Content-Type | Must be Content-Type: application/x-www-form-urlencoded. | 
All fields are required
Request fields
| Field name | Description | 
|---|---|
| code | The authorization code you want to exchange.Example: ory_ac_7DeVLbm9aw1PH44LU_99B2jF_TidS_k1QHmPNozqpqk | 
| grant_type | Must be set to authorization_code. | 
| redirect_uri | The redirect URL that was used to generate the authorization code. The value depends on the integration onboarding method you used:- When using self-service integration onboarding, this is the URL that you provided in the redirect_uri query parameter of the URL to start the integration onboarding. - When using Wolt-led integration onboarding, this is the URL that was included in payload that was sent to your authorization code endpoint. Example: https://www.partner-site.com/callback | 
All fields are required
Example response
{"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImVmMmY2MGE5LTI0NzItNDZjMC1iYWQyLTQ2NzNiZTMwYTFjMCIsInR5cCI6IkpXVCJ9.eyJhdWQiOltdLCJjbGllbnRfaWQiOiIxNGM5ZDFhMy04N2UzLTQ4NGMtODg5MS01MGJlMTJkNGU5ZDkiLCJleHAiOjE3MTAzNDQ4ODIsImV4dCI6e30sImlhdCI6MTcxMDM0MTI4MiwiaXNzIjoiaHR0cHM6Ly9pbnRlZ3JhdGlvbnMtYXV0aGVudGljYXRpb24tc2VydmljZS5kZXZlbG9wbWVudC5kZXYud29sdGFwaS5jb20vIiwianRpIjoiZWU1N2ExZjItNTEyOC00ZDg4LThjNDAtNzExZmNiM2E4NmQzIiwibmJmIjoxNzEwMzQxMjgyLCJzY3AiOlsib2ZmbGluZSJdLCJzdWIiOiI2NWYxYmM4ZDhjOTk4ZTU2M2UzNDlmODEifQ.jGOWuVB5gsKzC7_R0GeiN40vxrqJHWXRyNMpnXpsIs-ajzf-G6TDqeMZTJHy6Z_68Y-zWDQ9UsiBqy9aoUG5Bvci-bDf12Rfs7ZOeBEO3E3j3EBFY0y_mYDyMIP2HCAZNIYD8Oxp9wOj3WLvAh8hkhA9xW5JldYqoz9o7x72fDKftOZgVnhf2EyMGq7Dg4miuOHtsCrk2UmdEtoo0vlfh4TtkQ9v-N8lutqHtAq4z4cCxN-dBVpfWGGsDtL-r_3Bj4HsyNI7vqnjxx4OW-COEBvBoYPZpE833lpgpoP3EqD0VcJmdNy5irCxSPQsZKsst6Eygv6yfJFlpPKzXSpQpyOOF-oFhIyn9RtPh8WEIjUXqGsWncAZGfNrVU4OL0WVH4tkd4-cIT4YiKtbx8SLrWVLif6MfOmCWwRk029TA5Y99q_9eMcMYw03Pj6ktSlNsnNlGQj2AfmZEGNYA-CgGIM3sonJE2vtkw3gz1twEFVel54cV7p6O6XLHnJ3CDE2ZmZHssg0utbrZqCacc9OtIiH6EZkewc-UtvMRFf6qveh_f2RIYegv0WYjYdHPgY1eMA_RqPzZOdqau1Nh4StjJ4xapfMu5Ejvf95PmX0OJxHgIEKWDplD316R5zrqQmmdHvrB8qt2BwQocCjsPxyZzyHE381FjptoUeRijUpk-JI","expires_in": 3600,"refresh_token": "ory_rt_Vbtz4bfxjo5yG-l19DE34o1FKnFXASHuUQ7SyNkCykU.GqylnSfs7Rx0fo14kmcpUBwuvi-mXYyKWH-EIkjgRcA","scope": "offline","token_type": "bearer"}
Response fields
| Field name | Description | 
|---|---|
| access_token | The access token issued by Wolt. Use this token to authenticate against Wolt APIs. | 
| expires_in | The lifetime of the access token in seconds. For example, the value 3600 denotes that the access token will expire in one hour from the time the token was generated. | 
| refresh_token | Refresh token which can be used to obtain new access and refresh tokens. You should cache the refresh token and use it to obtain a new access token when the current access token expires. | 
| scope | Scope of the token. The value offline indicates that the token can be used to obtain new access and refresh tokens. | 
| token_type | Indicates how the token should be for authentication. Will be bearer, which means the token should be included in the Authorization header of the request. | 
Access token refresh
While you have a valid access token, avoid requesting a new one. Use the existing access token until it expires.
When your access token expires, you can use the refresh token to exchange it for a new access token. The refresh token can only be used once. Each time you exchange the refresh token for a new access token, a new refresh token will also be returned.
Important! that you store both of the new tokens. The new refresh token is required the next time you need a new access token.
If you lose the refresh token or it expires, the venue needs to re-integrated. To avoid disruption and ensure continued access to Wolt APIs, refresh token's validity must be proactively maintained. This is done by exchanging the refresh token for a new access token before the refresh token expires.
Please note that reusing the same refresh token in multiple requests will immediately deactivate and revoke the newly issued access and refresh tokens, a measure designed to prevent a security vulnerability known as replay attacks.
[TODO: add PIC]
1. Integration partner sends refresh token to Wolt auth service Your system sends the current refresh token, your client ID and client secret to Wolt’s auth service.
2. Wolt auth service returns a new access token Wolt’s auth service returns a new access token and a new refresh token. The previous access token and refresh token are invalidated and can no longer be used.
3. Integration partner stores the new refresh token Your system must store the new refresh token returned in the response. This new refresh token is then used the next time you need to exchange refresh token for a new access token.
Request URLs
| Environment | Base URL | 
|---|---|
| Development | https://integrations-authentication-service.development.dev.woltapi.com/oauth2/token | 
| Production | https://integrations-authentication-service.wolt.com/oauth2/token | 
Example request
curl -X POST https://integrations-authentication-service.wolt.com/oauth2/token \-H "Content-Type: application/x-www-form-urlencoded" \-u "{{client_id}}:{{client_secret}}" \-d "grant_type=refresh_token" \-d "refresh_token={{refresh_token}}"
Headers
| Header name | Description | 
|---|---|
| Authorization | Authorization header using basic auth. Must be Base64 encoding of client_id and client_secret joined by a single colon :.Example: client_id:client_secret -> Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQK | 
| Content-Type | Must be Content-Type: application/x-www-form-urlencoded. | 
All fields are required
Request fields
| Field name | Description | 
|---|---|
| grant_type | Must be set to refresh_token. | 
| refresh_token | The refresh token obtained from the previous refresh request, or from exchanging authorization code for access and refresh tokens. | 
All fields are required
Example response
{"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImVmMmY2MGE5LTI0NzItNDZjMC1iYWQyLTQ2NzNiZTMwYTFjMCIsInR5cCI6IkpXVCJ9.eyJhdWQiOltdLCJjbGllbnRfaWQiOiIxNGM5ZDFhMy04N2UzLTQ4NGMtODg5MS01MGJlMTJkNGU5ZDkiLCJleHAiOjE3MTAzNDQ4ODIsImV4dCI6e30sImlhdCI6MTcxMDM0MTI4MiwiaXNzIjoiaHR0cHM6Ly9pbnRlZ3JhdGlvbnMtYXV0aGVudGljYXRpb24tc2VydmljZS5kZXZlbG9wbWVudC5kZXYud29sdGFwaS5jb20vIiwianRpIjoiZWU1N2ExZjItNTEyOC00ZDg4LThjNDAtNzExZmNiM2E4NmQzIiwibmJmIjoxNzEwMzQxMjgyLCJzY3AiOlsib2ZmbGluZSJdLCJzdWIiOiI2NWYxYmM4ZDhjOTk4ZTU2M2UzNDlmODEifQ.jGOWuVB5gsKzC7_R0GeiN40vxrqJHWXRyNMpnXpsIs-ajzf-G6TDqeMZTJHy6Z_68Y-zWDQ9UsiBqy9aoUG5Bvci-bDf12Rfs7ZOeBEO3E3j3EBFY0y_mYDyMIP2HCAZNIYD8Oxp9wOj3WLvAh8hkhA9xW5JldYqoz9o7x72fDKftOZgVnhf2EyMGq7Dg4miuOHtsCrk2UmdEtoo0vlfh4TtkQ9v-N8lutqHtAq4z4cCxN-dBVpfWGGsDtL-r_3Bj4HsyNI7vqnjxx4OW-COEBvBoYPZpE833lpgpoP3EqD0VcJmdNy5irCxSPQsZKsst6Eygv6yfJFlpPKzXSpQpyOOF-oFhIyn9RtPh8WEIjUXqGsWncAZGfNrVU4OL0WVH4tkd4-cIT4YiKtbx8SLrWVLif6MfOmCWwRk029TA5Y99q_9eMcMYw03Pj6ktSlNsnNlGQj2AfmZEGNYA-CgGIM3sonJE2vtkw3gz1twEFVel54cV7p6O6XLHnJ3CDE2ZmZHssg0utbrZqCacc9OtIiH6EZkewc-UtvMRFf6qveh_f2RIYegv0WYjYdHPgY1eMA_RqPzZOdqau1Nh4StjJ4xapfMu5Ejvf95PmX0OJxHgIEKWDplD316R5zrqQmmdHvrB8qt2BwQocCjsPxyZzyHE381FjptoUeRijUpk-JI","expires_in": 3600,"refresh_token": "ory_rt_Vbtz4bfxjo5yG-l19DE34o1FKnFXASHuUQ7SyNkCykU.GqylnSfs7Rx0fo14kmcpUBwuvi-mXYyKWH-EIkjgRcA","scope": "offline","token_type": "bearer"}
Response fields
| Field name | Description | 
|---|---|
| access_token | The access token issued by Wolt. Use this token to authenticate against Wolt APIs. | 
| expires_in | The lifetime of the access token in seconds. For example, the value 3600 denotes that the access token will expire in one hour from the time the token was generated. | 
| refresh_token | Refresh token which can be used to obtain new access and refresh tokens. You should cache the refresh token and use it to obtain a new access token when the current access token expires. | 
| scope | Scope of the token. The value offline indicates that the token can be used to obtain new access and refresh tokens. | 
| token_type | Indicates how the token should be for authentication. Will be bearer, which means the token should be included in the Authorization header of the request. | 
Making API calls with access token
To call Wolt APIs, you need to include the access token in the Authorization request header. The format of the header should be Authorization: Bearer {{access_token}}.
curl -H "Authorization: Bearer {{access_token}}" \https://pos-integration-service.wolt.com/orders/{{order_id}}
For details about making requests to specific Wolt APIs, refer to our API references.
Extracting the Wolt venue ID from the access token
If the partner's system needs to programmatically access the Wolt venue ID of a venue integrated through one of the integration onboarding flows, it can be found in the decoded access token.
To extract the venue ID, you must first decode the access token. The token is a JWT (JSON Web Token), which can be split into three parts: header, payload, and signature. The venue ID is located within the payload, specifically under the integration claim.
Here’s a sample structure of a decoded access token (payload):
{"aud": [],"client_id": "c1dbd4af-7f74-4266-a991-ee95f81c65c0","exp": 1715077398,"iat": 1715073797,"integration": {"id": "6638c25240880a6de5848c6a","venue_id": "63fc7b2dd361f21d3475dbd7"},"iss": "https://integrations-authentication-service.development.dev.woltapi.com/","jti": "7c29ee83-dabf-46da-a85e-f8a9923c4529","nbf": 1715073797,"scp": ["offline"],"sub": "6638c25240880a6de5848c6a"}
In the example above, the venue_id (63fc7b2dd361f21d3475dbd7) is found within the integration claim. This venue ID is unique to the merchant's venue and can be used in subsequent API requests to interact with that specific venue.
Resetting integration for development purposes
Resetting integration is only available in the development environment.
When testing various integration onboarding flows, integrated venues become unavailable for re-integration. To reset venue's integration send a DELETE request to reset integration endpoint.
curl -X DELETE https://developer-gateway.development.dev.woltapi.com/integrations-middleware-service/integration-onboarding/venues/{{venue_id}} \-H "Authorization: Basic {{credentials}}"
| Request field | Description | 
|---|---|
| venue_id | The Wolt venue ID of the venue to reset | 
| credentials | Base64 encoding of client_id and client_secret joined by a single colon :. For example client_id:client_secret -> Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQK. |