This tutorial presents how to pull the data of a user's account from the /accounts
endpoint.
Similar steps apply to all the Accounts and Transactions endpoints; therefore, after you complete this tutorial, you will know how to use all those endpoints.
Before you begin, ensure that you have:
accounts
scope in the Developer Portalclient_id
from the Developer Portaltransport.pem
and signing.pem
certificates from the Developer Portal or from a QTSP issuing bodyjwks_url
that is specific to your signing.pem
certificateIf unsure, head to Get Started and review the setup process.
Request an access token for client credentials using the /token
endpoint and the client_credentials
grant type:
curl --cert transport.pem --key private.key \
--location --request POST 'https://oba-auth.revolut.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=accounts' \
--data-urlencode 'client_id=<your client_id>'
Response:
The response returns a new client credentials access token, with its expiry (expires_in
) provided in seconds:
{
"access_token":"<JWT client credentials>",
"token_type":"Bearer",
"expires_in": 2399
}
You use this token to:
When your token expires and you need a new one, repeat this procedure to generate a new token.
Create a consent for specific permissions using the /account-access-consents
endpoint.
In this tutorial, you create a consent for the following permissions:
ReadAccountBasic
ReadAccountsDetail
curl --location --request POST 'https://oba-auth.revolut.com/account-access-consents' \
--header 'x-fapi-financial-id: 001580000103UAvAAM' \
--header 'Authorization: Bearer <insert JWT client credentials from step 1.>' \
--header 'Content-Type: application/json' \
--data-raw '
{
"Data": {
"Permissions": [
"ReadAccountsBasic",
"ReadAccountsDetail"
],
"ExpirationDateTime": "2020-12-02T00:00:00+00:00",
"TransactionFromDateTime": "2020-09-03T00:00:00+00:00",
"TransactionToDateTime": "2020-12-03T00:00:00+00:00"
},
"Risk": {}
}'
Response:
{
"Data": {
"Status": "AwaitingAuthorisation",
"StatusUpdateDateTime": "2020-11-05T16:07:46.506182Z",
"CreationDateTime": "2020-11-05T16:07:46.506182Z",
"TransactionToDateTime": "2017-12-03T00:00:00+00:00",
"ExpirationDateTime": "2021-05-02T00:00:00+00:00",
"Permissions": [
"ReadAccountsBasic",
"ReadAccountsDetail"
],
"ConsentId": "d19ec758-22fd-4f34-9ad4-7437f8628987",
"TransactionFromDateTime": "2017-05-03T00:00:00+00:00"
},
"Risk": {},
"Links": {
"Self": "https://oba-auth.revolut.com/account-access-consents"
},
"Meta": {
"TotalPages": 1
}
}
To check all the supported permissions and the dependencies:
After you create a consent, you need the user to authorise the consent so that you can access the data on their behalf.
Create a JWT request parameter with the header and body format presented below, signed by your signing certificate's private key. This signature is validated using the JWKs endpoint that you specified during the registration of your application.
client_id
, redirect_uri
, kid
, and scope
should correspond to those for your specific application and consent request.openbanking_intent_id
is the value of the ConsentId
field returned in the consent creation response.state
is an OAuth parameter that lets you restore the state of the application after redirection.
If provided, this value is returned in the redirect URI.nbf
and exp
should contain the Unix timestamps before and after which the JWT is not valid.For more details on these parameters, see the guide: Work with JSON Web Tokens.
Header:
{
"alg": "PS256",
"kid": "<insert kid>"
}
Body:
{
"response_type": "code id_token",
"client_id": "<insert client_id>",
"redirect_uri": "<insert redirect_uri>",
"aud": "https://oba-auth.revolut.com",
"scope": "accounts",
"state": "<insert state>",
"nbf": <insert nbf>,
"exp": <insert exp>,
"claims": {
"id_token": {
"openbanking_intent_id": {
"value": "<insert ConsentId>"
}
}
}
}
Redirect the user to the authorisation URL with the following parameters. Make sure they are URL-encoded.
Parameter | Description | Required |
---|---|---|
response_type | Always set to code id_token . | yes |
client_id | The client ID for your application. | yes |
redirect_uri | One of the redirect URIs that you defined during the application creation. | yes |
scope | The scope that you are requesting, for example, accounts or payments . For accounts and transaction information, use the scope accounts . | yes |
request | The encoded JWT generated in the previous step. | yes |
response_mode | If set to fragment parameters will be passed in fragment section of redirect URI. Otherwise, parameters are passed in URI query. Passing parameters in fragment is considered to be more secure. | no |
A sample authorisation URL looks like this:
https://oba.revolut.com/ui/index.html?response_type=code%20id_token&scope=accounts&redirect_uri=<insert redirect URL>&client_id=<insert client_id>&request=<insert JWT from step 3.>
Once you have redirected the user to the authorisation URL, they will need to provide their Revolut credentials and complete the payment authorisation.
After authorising the payment, the user will be redirected back to the redirect URL (redirect_uri
) containing the authorisation code (code
) as a URL parameter, as in the below example:
https://example.com/?code=oa_sand_sPoyVs-oMhyR36j5N-ZEVLfK9rQWPNssgIQqsOFZQ-c&id_token=<JWT id_token>&state=example_state
Use this authorisation code in the next step.
The code
is valid only for two minutes.
After the user authorises your consent, you use the /token
endpoint with grant_type=authorization_code
to get the access token that you can use to access the Accounts and Transactions endpoints:
The value of auth_code
is the authorisation code (code
) generated in the previous step.
curl --key private.key --cert transport.pem \
--location --request POST 'https://oba-auth.revolut.com/token' \
--header 'Content-Type:application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=<insert auth_code>'
Response:
Starting from 7 April 2025, apart from an access token (access_token
), the response will also return a refresh token (refresh_token
).
In the interim period, from 7 April until 3 Aug 2025, access tokens will be issued with the same expiry as that of refresh tokens.
From 4 August 2025, all new access tokens will expire after 60 minutes. To obtain a new access token and extend (refresh) your access, you will need to use the refresh token.
The response returns a new access token, with its expiry (expires_in
) provided in seconds, and a refresh token, with its expiry (refresh_token_expires_at
) provided as a timestamp:
{
"access_token":"oa_sand_tP1Nofi1ixsRfBmVBtVPdIVN0J5x91imqmheQIWTS5s",
"access_token_id":"3d3ef8a1-f920-4d6d-9106-e7fcf350125c",
"token_type":"Bearer",
"expires_in":3599,
"id_token":"<JWT id_token>",
"refresh_token":"oa_sand_mV1NoTBtVPdfi1ixsRfBmS5sqmheQIWIVN0J5x91itP",
"refresh_token_expires_at":1759051135
}
Once you have a valid access token, you can use it to send requests to the API. Make a call to the /accounts
endpoint to retrieve a list of the user's accounts.
curl -X GET https://oba-auth.revolut.com/accounts \
--header 'Authorization: Bearer <insert access_token from step 5.>' \
--header 'x-fapi-financial-id: 001580000103UAvAAM'
Response:
{
"Data": {
"Account": [
{
"AccountId": "A1086696-D134-472D-B83E-A3F4D201C058",
"Currency": "GBP",
"AccountType": "Personal",
"AccountSubType": "CurrentAccount",
"Nickname": "Bills",
"Account": [
{
"SchemeName": "UK.OBIE.SortCodeAccountNumber",
"Identification": "80200110203345",
"Name": "Mr Kevin",
"SecondaryIdentification": "00021"
}
]
}
]
},
"Links": {
"Self": "https://oba-auth.revolut.com/accounts/"
},
"Meta": {
"TotalPages": 1
}
}
For more details about this call:
You have successfully made your first API request to one of our Accounts and Transactions endpoints.
When the access token expires, you won't be able to access the Accounts and Transactions endpoints.
To regain access, you must first request a new access token using the refresh token (returned in step 5), your Client ID (returned in substep 7 of Upload your certificate), and your certificate and key.
To request a new access token, make a request to the /token
endpoint with grant_type=refresh_token
and a valid refresh token:
Refreshing an access token invalidates the previous access token.
This means that if you have an access token that hasn't expired yet, and you refresh it with the refresh token, the existing access token will no longer work, and you will need to switch to the new access token.
curl --cert transport.pem --key private.key \
--location --request POST 'https://oba-auth.revolut.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=<your client_id>' \
--data-urlencode 'refresh_token=<your refresh_token>'
Response:
The response returns a refreshed access token, with its expiry (expires_in
) provided in seconds:
{
"access_token":"oa_prod_fBmVQP91imqmhetP1NofixsBtVIVN0J5xRi1IdWTS5s",
"token_type":"Bearer",
"expires_in":3599
}
When refreshing an access token, its expiry will always be bound by the expiry of the refresh token.
This means that if you refresh an access token but the refresh token is expiring in 10 minutes, you will obtain a new access token with an expiry of just 10 minutes instead of 60 minutes.
To regain access after the refresh token expires, you must repeat the steps 1-5 from this guide and generate a new access token and refresh token.