NAV Navbar

Introduction to the Open Banking API

The Open Banking API is the gateway for third-parties to interact with Revolut customers and products.

Whether you are a regulated third-party provider or are looking to seamlessly integrate Revolut functionality into your own application, this documentation is the place to start.

API For Who What can you do
Open Banking API Third Party Developers Create applications for the Marketplace or integrate Revolut into your own app for Revolut customers.

You might be looking for the Business API or the Merchant API

Developers that can build with this API

PSDII regulated Third Party Providers

Third Party Providers (TPPs) are authorised online service providers that have been introduced as part of Open Banking. If you are engaged in the provision of the payment initiation or account information servives in the European Union (EU) or the United Kingdom (UK), you will have to be regulated by financial regulatory bodies in the relevant jurisdictions. In order to get access to our Open Banking API you will need to use a valid eIDAS certificate or Open Banking (OBIE) certificate to register your application on production.

Revolut Partners

For businesses that are not regulated under PSDII and would like to get access to our APIs - you can reach out to see if you qualify for access to our endpoints.

Get Started

The quickest way to get up and running with the Open Banking API.

Registering an application

The first step before you can start using our APIs is to register your application.

Registering using Developer Portal

This is the recommended and fastest way to get your application registered.

Sign up for a Developer Account

If you are in possession of an OBIE/eIDAS certificate, you can upload the certificate in the portal and register a production application without any further approval from Revolut. You will be returned a client_id which will be used for making requests to any of our APIs.

If you are looking to become a Revolut Partner, you must submit a request for your application to be approved via the portal. On successful approval of your application, we will issue you with production certificates that can be used on our APIs.

Registering using DCR

JWT Header

{
  "kid": "test-kid",
  "alg": "PS256"
}

JWT Payload

{
  "iss": "test-iss",
  "iat": 1591352490,
  "exp": 1591356090,
  "aud": "https://revolut.com",
  "scope": ["openid", "payments", "accounts", "fundsconfirmations"],
  "redirect_uris": ["http://url/one"],
  "token_endpoint_auth_method": "tls_client_auth",
  "application_type": "web",
  "id_token_signed_response_alg": "PS256",
  "request_object_signing_alg": "PS256",
  "tls_client_auth_dn": "test-dn",
  "software_statement": "ewogICJhbGciOiAibm9uZSIKfQ.ewogICJvcmdfaWQiOiAiNzc3NTgwMDAwMTAzVUF2QUFNIiwKICAib3JnX25hbWUiOiAiUmV2b2x1dCBUUFAiLAogICJzb2Z0d2FyZV9jbGllbnRfbmFtZSI6ICJSZXZvbHV0IFRQUCIsCiAgIm9yZ19qd2tzX2VuZHBvaW50IjogImh0dHA6Ly9vcGVuYmFua2luZy5vcmcudWsvZW5kcG9pbnQiLAogICJzb2Z0d2FyZV9yZWRpcmVjdF91cmlzIjogWwogICAgImh0dHA6Ly91cmwvb25lIgogIF0KfQ."
}

Register client

curl -X POST https://sandbox-oba.revolut.com/register \
--header 'Content-Type: application/jwt' \
--data-raw '<insert JWT>'
curl -X POST https://oba.revolut.com/register \
--header 'Content-Type: application/jwt' \ 
--data-raw '<insert JWT>'

The alternative registration method is to register an application using our /register endpoint (Dynamic Client Registration).

First, create a JWT with the details relevant to your application. This should be signed with your signing certificate's private key. Please see on the right hand side examples of a JWT Header and Payload.

Once you have a valid JWT, use the /register endpoint to dynamically register your application. In the response you will obtain your client_id.

Note: to check that your JWT is valid, please use this JWT debugging tool before attempting to register.

Note: for full detail on generating the software_statement and tls_client_auth_dn fields, please read the Identification and Authentication section of our documentation.

Open ID Configuration URLs

We use OpenID Connect: please ensure to include openid scope in your JWT payload. For more detail, please see configurations for Production and Sandbox environments:

Receiving Sandbox credentials

Generate RSA

openssl genrsa -out server.key 2048

Generate CSR

openssl req -sha256 -new -key server.key -out server.csr -outform der

To receive credentials that can be used in our Sandbox environment, first generate a private RSA key and CSR.

Upload this CSR in our Developer Portal and you will be able to download credentials that work in the Sandbox environment.

Creating test accounts

On top of your Sandbox credentials, you will also need test accounts which can be used to test your application. It is possible to create both Retail and Business test accounts:

Next steps

Now that you have your application registered, you are ready to start requesting user consents and make API calls to our various endpoints!

Please see our set of step by step tutorials to guide you through.

Identification and Authentication

Identification using your valid eIDAS certificate

For businesses that are a regulated third party provider (TPP) in one of the European Union (EU) member states, it is possible to use valid eIDAS QWAC certificates from any trusted QTSPs listed at https://webgate.ec.europa.eu/tl-browser/#/ to register your application/client. If you have any issues onboarding with eIDAS, please contact us and we will try to help.

Identification using your Open Banking certificates

If you have enrolled as a third party provider (TPP) on the UK open banking directory using your eIDAS certificate, you can then access our API using the following OBIE certificates: OBWAC (Open Banking QWAC-like certificates), OBSEAL (Open Banking QSEAL-like certificates) and OBIE non-eIDAS like certificates for transport and signing. OBIE certificates can be used to connect to customers of Revolut Ltd (UK).

In order to delete an Application you may use the DELETE registration endpoint. The DELETE endpoint is implemented as it is described in the official documentation.

Dynamic Client Registration

Register client

curl -X POST https://sandbox-oba.revolut.com/register
curl -X POST https://oba.revolut.com/register

In order to create an Application you will need to use Dynamic Registration.

The register endpoint is implemented as it is described in the official documentation.

Registration request

Registration request should satisfy the following format:

Example JWT header

{
  "kid": "test-kid",
  "alg": "PS256"
}
JWT Header Format Description Required
kid String key ID of a public key from JWKs file Yes
alg String signing algorithm, currently only PS256 is supported Yes

Example JWT payload

{
  "iss": "test-iss",
  "iat": 1591352490,
  "exp": 1591356090,
  "aud": "https://revolut.com",
  "scope": ["openid", "payments", "accounts", "fundsconfirmations"],
  "redirect_uris": ["http://url/one"],
  "token_endpoint_auth_method": "tls_client_auth",
  "application_type": "web",
  "id_token_signed_response_alg": "PS256",
  "request_object_signing_alg": "PS256",
  "tls_client_auth_dn": "test-dn",
  "software_statement": "ewogICJhbGciOiAibm9uZSIKfQ.ewogICJvcmdfaWQiOiAiNzc3NTgwMDAwMTAzVUF2QUFNIiwKICAib3JnX25hbWUiOiAiUmV2b2x1dCBUUFAiLAogICJzb2Z0d2FyZV9jbGllbnRfbmFtZSI6ICJSZXZvbHV0IFRQUCIsCiAgIm9yZ19qd2tzX2VuZHBvaW50IjogImh0dHA6Ly9vcGVuYmFua2luZy5vcmcudWsvZW5kcG9pbnQiLAogICJzb2Z0d2FyZV9yZWRpcmVjdF91cmlzIjogWwogICAgImh0dHA6Ly91cmwvb25lIgogIF0KfQ."
}

NOTE: You will need a valid JWT signature to register your client. You can debug your JWT header and payload using the debug tool.

JWT payload Format Description REQUIRED
iss String identifies the principal that issued the JWT Yes
iat Numeric identifies the time at which the JWT was issued Yes
exp Numeric JWT expiration time Yes
aud String identifies the recipients that the JWT is intended for Yes
scope String[] list of scopes, supported scopes are openid (required), accounts, payments, fundsconfirmations Yes
redirect_uris String[] list of allowed redirect URLs Yes
token_endpoint_auth_method String currently only tls_client_auth is supported Yes
application_type String application type Yes
id_token_signed_response_alg String signing algorithm, currently only PS256 is supported Yes
request_object_signing_alg String signing algorithm, currently only PS256 is supported Yes
tls_client_auth_dn String claim MUST contain the DN of the certificate that the TPP will use, how to obtain the DN of your certificate is described in next paragraph Yes
software_statement String software statement assertion issued by the issuer in JWT format Yes
Open Banking software statement

If you are registering with Open Banking certificate, you should use the software statement signed by Open Banking which you can obtain from Directory

Self-signed software statement

In order to directly register with eIDAS certificate, it’s possible to use a self-signed software statement. In such case software statement should satisfy the following format:

Example self-signed software statement header

{
  "alg": "none"
}
SSA header claim Description Required Schema
alg none value has to be used to indicate self-signed software statement Yes String

Example self-signed software statement payload

{
  "org_name": "Revolut TPP",
  "software_client_name": "Revolut TPP",
  "org_jwks_endpoint": "http://openbanking.org.uk/endpoint",
  "software_redirect_uris": ["http://url/one"]
}
SSA payload claim Description Required Schema
org_jwks_endpoint a JWKs endpoint, this endpoint has to contain a signing key (QSealC) matching with a kid provided in JWT header of the registration request Yes URL
org_name a name of a software (shown in the UI), alternatively software_client_name can be used Yes String
software_client_name a name of a software (shown in the UI) Yes String
software_redirect_uris a list of allowed redirect URLs, has to contain all redirect URLs from JWT redirect_uris claim Yes URL[]

Signature of self-signed software statement should be an empty string.

JWKs file format

JWKs (JWK Set) is a JSON data structure that represents a set of JWKs. A JSON Web Key (JWK) is a (JSON) data structure that represents a cryptographic key. Mandatory JWK parameters are described below.

JWK mandatory fields Description
kid (Key ID) is used to match a specific key
kty Identifies the cryptographic algorithm family used with the key
e Contains the exponent value for the RSA public key, represented as a Base64urlUInt-encoded value
n Contains the modulus value for the RSA public key, represented as a Base64urlUInt-encoded value
use Identifies the intended use of the public key (should always be set to sig)
x5c Equivalent to your signing key in .pem format.

Certificate DN for using in registration request

certificates in DER format:

openssl x509 -in /path/to/your/cert.der -inform der -noout -subject -nameopt RFC2253

Certificates in PEM format:

openssl x509 -in /path/to/your/cert.pem -inform pem -noout -subject -nameopt RFC2253

Use the commands to the right to obtain the DN from your certificates in either DER or PEM formats.

Updating a client

Update a Client

curl -X PUT https://sandbox-oba.revolut.com/register/17b2738f-26b1-46f9-a979-debbf1f39365
curl -X PUT https://oba.revolut.com/register/17b2738f-26b1-46f9-a979-debbf1f39365

Making a PUT request to the register endpoint allows you to update certain info for an existing client. You'll need to provide the Client ID as a parameter to repersent which client you want to update along with the access token in the request header. In the body you can pass the updated JWT for the specified client. For simplicity, you can use the same JWT you created for the registration request but with the updated fields as any additional fields will be ignored.

Fields for updating client
Client Property Corresponding JWT field
Application name org_name or software_client_name in respect to which field is present in the SSA
Redirect URIs redirect_uris field in the SSA
JWKs URL org_jwks_endpoint field in the SSA
Distinguished name tls_client_auth_dn field in the JWT payload

Deleting a client

Delete a Client

curl -X DELETE https://sandbox-oba.revolut.com/register/17b2738f-26b1-46f9-a979-debbf1f39365
--header 'Authorisation: Bearer <your token>'
curl -X DELETE https://oba.revolut.com/register/17b2738f-26b1-46f9-a979-debbf1f39365
--header 'Authorisation: Bearer <your token>'

Making a DELETE request to the register endpoint allows you to request deletion of an existing client. You need to provide the Client ID and access token to make a succesful request. On a successful request, you'll recieve a JSON payload that matched the Client ID of the client that client-credentials grant access token was issued. In the case that the Client Id is unknown, you will recieve a JSON payload with an Unauthorized status code.

In the case that you're having issues deleting a client, don't hesitate to reach out to support.

Open Banking Security Profile

We use OpenID Connect (OIDC) as a way to verify a client's identity. For OIDC, the open banking security profile must exist where you as the TPP is certified so we can correctly identify each participant. Only after you have certification can you use these endpoints -- unless explicitly stated. If you're interested in learning more about the Open Banking security profile, you can see the implementers draft on the official documentation.

Authorisation Endpoint

Authorize consent

https://sandbox-oba.revolut.com/ui/index.html
https://oba.revolut.com/ui/index.html

The authorisation flow redirects the user to the revolut login screen, where they can securely enter their credentials. As you continue to explore the API, you will also see how users are redirected to give consent for their accounts in a similar fashion.

Token Endpoint

As with the any typical OAuth 2.0 flow, there is the need to have an access token which you will need to supplement with each request. Open Banking specification for more information about the semantics of this API.

Get access token

curl -X POST https://sandbox-oba-auth.revolut.com/token
curl -X POST https://oba-auth.revolut.com/token

/token endpoint served via Revolut authorisation server. This endpoint requires client certificate authentication for MTLS.

Tutorials

Get account and transaction information

This tutorial will get you started with pulling account and transaction information out of Revolut.

In this example, you will be pulling data from the /accounts endpoint but the principles used apply to all of our Accounts and Transactions endpoints. See the API Reference for full functionality.

Before starting the tutorial, ensure that you have registered your application with the accounts scope.

1. Generating client credentials token

Get access token

curl -k --cert transport.pem --key server.key \
--location --request POST 'https://sandbox-oba-auth.revolut.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=accounts'
curl --cert transport.pem --key server.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'

Response

{
  "access_token":"eyJhbGciOiJQUzI1NiJ9.eyJjbGllbnRJZCI6IjFlYzFkYjJkLTNlNWItNGQ4Mi1iNDJlLTA2Nzk0NTYyZTIwZSIsInNjb3BlcyI6WyJhY2NvdW50cyJdLCJleHAiOjE2MDQ5MzAzOTh9.pMMtYxYh8_M8P0v9_yfJ29iq3h2x_1RT6BLJPbrJ6SSsai_fQmMNGWXtDapPCSvWtn-ol0aN8Pl725uSSJqWHFxdh0PwvKP1762s5jy7xcLTkb8tgg-AoTPm87-vsnHnw5z63yiDW1Migdx7vDN_jRe3WUSfE-u0Qv7W3SLVo8kB5-qxn2VHZTBSaBr5XReINBHJgh7Xi9LzqxqUh0yCiZSSRnu8o7-I_Q1K0jPK1D7ve7BxlkOb5fSR59CbtzfkZpI6jKDOWSqU_5mftqRRylle382nfS6AeY2eubdH6OS-lJRFcwsYplauE-tZ__54G4LTjPhUWQezvewCc5gq2Q",
  "token_type":"Bearer",
  "expires_in":2399
}

The first step is to request an access token using the /token endpoint and client_credentials grant type.

This token will allow you to update your application using the update endpoint and create a consent in the next step.

Create consent

curl --location --request POST 'https://sandbox-oba.revolut.com/account-access-consents' \
--header 'x-fapi-financial-id: 001580000103UAvAAM' \
--header 'Authorization: Bearer eyJhbGciOiJQUzI1NiJ9.eyJjbGllbnRJZCI6IjFlYzFkYjJkLTNlNWItNGQ4Mi1iNDJlLTA2Nzk0NTYyZTIwZSIsInNjb3BlcyI6WyJhY2NvdW50cyJdLCJleHAiOjE2MDQ5MzAzOTh9.pMMtYxYh8_M8P0v9_yfJ29iq3h2x_1RT6BLJPbrJ6SSsai_fQmMNGWXtDapPCSvWtn-ol0aN8Pl725uSSJqWHFxdh0PwvKP1762s5jy7xcLTkb8tgg-AoTPm87-vsnHnw5z63yiDW1Migdx7vDN_jRe3WUSfE-u0Qv7W3SLVo8kB5-qxn2VHZTBSaBr5XReINBHJgh7Xi9LzqxqUh0yCiZSSRnu8o7-I_Q1K0jPK1D7ve7BxlkOb5fSR59CbtzfkZpI6jKDOWSqU_5mftqRRylle382nfS6AeY2eubdH6OS-lJRFcwsYplauE-tZ__54G4LTjPhUWQezvewCc5gq2Q' \
--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": {}
}'
curl --location --request POST 'https://oba.revolut.com/account-access-consents' \
--header 'x-fapi-financial-id: 001580000103UAvAAM' \
--header 'Authorization: Bearer eyJhbGciOiJQUzI1NiJ9.eyJjbGllbnRJZCI6IjFlYzFkYjJkLTNlNWItNGQ4Mi1iNDJlLTA2Nzk0NTYyZTIwZSIsInNjb3BlcyI6WyJhY2NvdW50cyJdLCJleHAiOjE2MDQ5MzAzOTh9.pMMtYxYh8_M8P0v9_yfJ29iq3h2x_1RT6BLJPbrJ6SSsai_fQmMNGWXtDapPCSvWtn-ol0aN8Pl725uSSJqWHFxdh0PwvKP1762s5jy7xcLTkb8tgg-AoTPm87-vsnHnw5z63yiDW1Migdx7vDN_jRe3WUSfE-u0Qv7W3SLVo8kB5-qxn2VHZTBSaBr5XReINBHJgh7Xi9LzqxqUh0yCiZSSRnu8o7-I_Q1K0jPK1D7ve7BxlkOb5fSR59CbtzfkZpI6jKDOWSqU_5mftqRRylle382nfS6AeY2eubdH6OS-lJRFcwsYplauE-tZ__54G4LTjPhUWQezvewCc5gq2Q' \
--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.revolut.com/account-access-consents"
  },
  "Meta": {
    "TotalPages": 1
  }
}

Create a consent for specific permissions using the consent endpoint.

The example to the right is creating a consent for two permissions ReadAccountBasic and ReadAccountsDetail. To see the full set of permissions supported, please see the API reference.

3. Create a JWT URL parameter

Now that you have created a consent, you need the user to authorise it so that you can use Revolut's APIs to access data on their behalf.

Header

{
  "alg": "PS256",
  "kid": "NYFYY-XV88A1NN6KBIRWLmATd18"
}

Body

{
  "response_type": "code id_token",
  "client_id": <insert client_id>,
  "redirect_uri": <insert redirect_uri>,
  "scope": "accounts",
  "claims": {
    "id_token": {
      "openbanking_intent_id": {
        "value": <insert ConsentId>
      }
    }
  }
}

Firstly, create a JWT request parameter with header and body in the format to the right, signed by your signing certificate’s private key. This signature will be validated using the JWKs endpoint you specified during registration of your app.

Note: client_id , redirect_uri , kid and scope should correspond to the values for your specific application and consent request. openbanking_intent_id is the ConsentId field generated from the previous step.

Sample URL

https://sandbox-oba.revolut.com/ui/index.html?response_type=code%26id_token&scope=accounts&redirect_uri=<insert redirect URL>&client_id=<insert client_id>&request=<insert JWT>
https://oba.revolut.com/ui/index.html?response_type=code%26id_token&scope=accounts&redirect_uri=<insert redirect URL>&client_id=<insert client_id>&request=<insert JWT>

Next, redirect the user to https://oba.revolut.com/ui/index.html with the parameters on the URL as detailed below.

Parameter Description Required
response_type Always set to code&id_token yes
client_id client_id for your application yes
redirect_uri One of the redirect URI's you defined during client creation yes
scope The scope you are requesting eg accounts or payments yes
request The encoded JWT generated in previous step yes

Sample redirect after successful response

https://www.revolut_redirect.com/?code=oa_sand_sPoyVs-oMhyR36j5N-ZEVLfK9rQWPNssgIQqsOFZQ-c&id_token=eyJraWQiOiJxRlFQaTRPVkJVLVNaVk5iMjJ5VjVHQVZDN1UiLCJhbGciOiJQUzI1NiJ9.eyJpc3MiOiJodHRwczovL29iYS5yZXZvbHV0LmNvZGVzIiwiaWF0IjoxNjA0OTM2ODUzLCJzdWIiOiI0NjdiYzg3MC1jOTllLTQ0MzQtYTk1OS1iOGM1NmVlNmEwMjciLCJhY3IiOiJ1cm46b3BlbmJhbmtpbmc6cHNkMjpzY2EiLCJvcGVuYmFua2luZ19pbnRlbnRfaWQiOiI0NjdiYzg3MC1jOTllLTQ0MzQtYTk1OS1iOGM1NmVlNmEwMjciLCJhdWQiOiIxZWMxZGIyZC0zZTViLTRkODItYjQyZS0wNjc5NDU2MmUyMGUiLCJub25jZSI6Im4tMFM2X1d6QTJNaiIsImV4cCI6MTYwNDkzNzQ1MywiY19oYXNoIjoiTXNfRnRwdWs0U2VDNW4zdUNMTTc0ZyIsInNfaGFzaCI6IlM2YVhOY3BUZGw3V3B3bnR0V3h1b2cifQ.m-EvhggqLg7ZXh0we_PLKNsc248p8Bn_o5nj7_6CQHkiRI23ZrYjJLlz_1BhvZ_iY1Tll2gybq_0eSKRgHpvOPnhvCbcSAyfkE8YERZoVkIe-64cyiomhaqBzMzjQyghaL4KrnKH667wR1gTjVhwyJyztalTKidoLZ5OFVWRSHkqW3YLm-_q51wP0k7HHvJ-fnkGcIoCv2TYXpb9xykvgGRJv9KIISbQtM_bLBpo5Q6Q1fxNc-LK2iT-o22xQzLhzvGHtXLTl7Kn5xYf8quDjA5zG0iCAGLJ-Fo9NuTobcKjJOaNYpQ_Y2ilKMmtXqRdgAF_in4Lydt2dn9duxFvJA&state=state

On successful completion of the authorisation flow, you will receive an authorisation code as a URL parameter in the redirect. See example to the right for how this looks.

This code is only valid for two minutes.

5. Exchanging request token for access token

Exchange Token

curl -k --key private.key --cert transport.pem \
--location --request POST 'https://sandbox-oba-auth.revolut.com/token' \ 
--header 'Content-Type:application/x-www-form-urlencoded' \
--data-encoded grant_type=authorization_code \
--data-encoded code=<insert auth_code>
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-encoded grant_type=authorization_code \
--data-encoded code=<insert auth_code>

Response

{
  "access_token":"oa_sand_tP1Nofi1ixsRfBmVBtVPdIVN0J5x91imqmheQIWTS5s",
  "token_type":"Bearer",
  "expires_in":7775999,
  "id_token":"eyJraWQiOiJxRlFQaTRPVkJVLVNaVk5iMjJ5VjVHQVZDN1UiLCJhbGciOiJQUzI1NiJ9.eyJpc3MiOiJodHRwczovL29iYS5yZXZvbHV0LmNvZGVzIiwic3ViIjoiNDY3YmM4NzAtYzk5ZS00NDM0LWE5NTktYjhjNTZlZTZhMDI3IiwiYXVkIjoiMWVjMWRiMmQtM2U1Yi00ZDgyLWI0MmUtMDY3OTQ1NjJlMjBlIiwibm9uY2UiOiJuLTBTNl9XekEyTWoiLCJleHAiOjE2MDQ5Mzc0Nzk1NjksImlhdCI6MTYwNDkzNjg3OX0.NrcI6qSwmkTC4zhVP7S9Se1RD8Mnwfz5D3RyGp_5CI7MN6-GLqGHnIBNPNzbUBjlmer8ecCvhm0j9tkScT0xDMSZUdMjRyvb7qrsXYTVbj0ogDPthZSe-45tiq3y4oOsIusIwMPFWGHzI2zq_wzxYY8h6QXFIK6TB_oC93jM6J5JEUUQwvDR23ntcCoH_9uNaGM2PXO2ppxhxZiJe92TYcoZFCIMxqrcVxuUYM1VLQ8d7TcpoIDWdOmtOVqDYmblUHyjFpO3IcBHalua0LRGmU3ZuaEv2iG3YzpqV0OMIHFUe9fQ95z_jID4rGIWwxRL6URIdzw6ZSSyxRXKRWNh3g"
}

If the user has successfully authorised your consent, return to the /token endpoint, this time with grant_type=authorization_codeto obtain the access token that can be used against our Accounts APIs.

Note: auth_code here is the authorisation code generated from the previous step

6. Get list of Accounts

Get list of accounts

curl -X GET https://sandbox-oba.revolut.com/accounts \ 
--header 'Authorization: Bearer <insert access_token>' \
--header 'x-fapi-financial-id: 001580000103UAvAAM'
curl -X GET https://oba.revolut.com/accounts \
--header 'Authorization: Bearer <insert access_token>' \
--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.revolut.com/accounts/"
  },
  "Meta": {
    "TotalPages": 1
  }
}

Now that you have generated your final access token, you can start making requests to the API. Make a call to the /accounts endpoint to retrieve a list of the customer's accounts.

Congratulations! You have successfully made your first API request to one of our Accounts and Transactions endpoints.

What’s next

Initiate your first payment

This tutorial will get you started with building integrations to our Payments endpoints.

In this example, you will initiate a domestic-payment but the principles used apply to all of our Payments endpoints. See the API Reference for the different types of payments supported.

Before starting the tutorial, ensure that you have registered your application with the payments scope.

In addition your jwks_url specified during registration must have an x5c claim specified. This is equivalent to your signing key in .pem format.

1. Generating client credentials token

Get access token

curl -k --cert transport.pem --key server.key \
--location --request POST 'https://sandbox-oba-auth.revolut.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=payments'
curl --cert transport.pem --key server.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=payments'

Response

{
  "access_token":"eyJhbGciOiJQUzI1NiJ9.eyJjbGllbnRJZCI6IjFlYzFkYjJkLTNlNWItNGQ4Mi1iNDJlLTA2Nzk0NTYyZTIwZSIsInNjb3BlcyI6WyJhY2NvdW50cyJdLCJleHAiOjE2MDQ5MzAzOTh9.pMMtYxYh8_M8P0v9_yfJ29iq3h2x_1RT6BLJPbrJ6SSsai_fQmMNGWXtDapPCSvWtn-ol0aN8Pl725uSSJqWHFxdh0PwvKP1762s5jy7xcLTkb8tgg-AoTPm87-vsnHnw5z63yiDW1Migdx7vDN_jRe3WUSfE-u0Qv7W3SLVo8kB5-qxn2VHZTBSaBr5XReINBHJgh7Xi9LzqxqUh0yCiZSSRnu8o7-I_Q1K0jPK1D7ve7BxlkOb5fSR59CbtzfkZpI6jKDOWSqU_5mftqRRylle382nfS6AeY2eubdH6OS-lJRFcwsYplauE-tZ__54G4LTjPhUWQezvewCc5gq2Q",
  "token_type":"Bearer",
  "expires_in":2399
}

The first step in this guide is to request an access token using the /token endpoint and client_credentials grant type.

This token will allow you to update your application using the update endpoint and create a payment consent in the next step.

Create consent

curl --location --request POST 'https://sandbox-oba.revolut.com/domestic-payment-consents' \
--header 'x-fapi-financial-id: 001580000103UAvAAM' \
--header 'Content-Type: application/json' \
--header 'x-idempotency-key: 123' \
--header 'Authorization: Bearer <insert client_credentials token>' \
--header 'x-jws-signature: <insert jws signature>' \
--data '
{
  "Data": {
    "Initiation": {
      "InstructionIdentification": "ID412",
      "EndToEndIdentification": "E2E123",
      "InstructedAmount": {
        "Amount": "55.00",
        "Currency": "GBP"
      },
      "CreditorAccount": {
        "SchemeName": "UK.OBIE.SortCodeAccountNumber",
        "Identification": "11223321325698",
        "Name": "Receiver Co."
      },
      "RemittanceInformation": {
        "Reference": "ReceiverRef",
        "Unstructured": "Shipment fee"
      }
    }
  },
  "Risk": {
    "PaymentContextCode": "EcommerceGoods",
    "MerchantCategoryCode": "5967",
    "MerchantCustomerIdentification": "1238808123123",
    "DeliveryAddress": {
      "AddressLine": ["7"],
      "StreetName": "Apple Street",
      "BuildingNumber": "1",
      "PostCode": "E2 7AA",
      "TownName": "London",
      "Country": "UK"
    }
  }
}'
curl --location --request POST 'https://oba.revolut.com/domestic-payment-consents' \
--header 'x-fapi-financial-id: 001580000103UAvAAM' \
--header 'Content-Type: application/json' \
--header 'x-idempotency-key: 123' \
--header 'Authorization: Bearer <insert client_credentials token>' \
--header 'x-jws-signature: <insert jws signature>' \
--data '
{
  "Data": {
    "Initiation": {
      "InstructionIdentification": "ID412",
      "EndToEndIdentification": "E2E123",
      "InstructedAmount": {
        "Amount": "55.00",
        "Currency": "GBP"
      },
      "CreditorAccount": {
        "SchemeName": "UK.OBIE.SortCodeAccountNumber",
        "Identification": "11223321325698",
        "Name": "Receiver Co."
      },
      "RemittanceInformation": {
        "Reference": "ReceiverRef",
        "Unstructured": "Shipment fee"
      }
    }
  },
  "Risk": {
    "PaymentContextCode": "EcommerceGoods",
    "MerchantCategoryCode": "5967",
    "MerchantCustomerIdentification": "1238808123123",
    "DeliveryAddress": {
      "AddressLine": ["7"],
      "StreetName": "Apple Street",
      "BuildingNumber": "1",
      "PostCode": "E2 7AA",
      "TownName": "London",
      "Country": "UK"
    }
  }
}

Response

{
  "Data": {
    "Status": "AwaitingAuthorisation",
    "StatusUpdateDateTime": "2020-11-20T08:35:53.523806Z",
    "CreationDateTime": "2020-11-20T08:35:53.523806Z",
    "ConsentId": "6686e444-c103-4077-8085-8e094200c425",
    "Initiation": {
      "InstructionIdentification": "ID412",
      "EndToEndIdentification": "E2E123",
      "InstructedAmount": {
        "Amount": "55.00",
        "Currency": "GBP"
      },
      "CreditorAccount": {
        "SchemeName": "UK.OBIE.SortCodeAccountNumber",
        "Identification": "11223321325698",
        "Name": "ReceiverCo."
      },
      "RemittanceInformation": {
        "Reference": "ReceiverRef",
        "Unstructured": "Shipmentfee"
      }
    }
  },
  "Risk": {
    "PaymentContextCode": "EcommerceGoods",
    "MerchantCategoryCode": "5967",
    "MerchantCustomerIdentification": "1238808123123",
    "DeliveryAddress": {
      "AddressLine": [
        "7"
      ],
      "StreetName": "AppleStreet",
      "BuildingNumber": "1",
      "PostCode": "E27AA",
      "TownName": "London",
      "Country": "UK"
    }
  },
  "Links": {
    "Self": "https://oba.revolut.com/domestic-payment-consents/6686e444-c103-4077-8085-8e094200c425"
  },
  "Meta": {
    "TotalPages": 1
  }
}

Create a consent to initiate a domestic payment on behalf of a Revolut customer.

Use your client_credentials token from the previous step for the Authorization field.

As part of the API requirement you must pass x-jws-signature header in your request. The signature must be generated from the request body with the TPP signing key that is specified in the JWS header. As specified in the OBIE documentation, you must only pass head and signature in .. format.

x-idempotency-key is a field specified by you in the case that there is a network failure and you do not receive the ID in response. It allows you to retry the request if needed.

3. Create a JWT URL parameter

Now that you have created a consent, you need the user to authorise it so that you can initiate a payment on behalf of the user.

Header

{
  "alg": "PS256",
  "kid": "NYFYY-XV88A1NN6KBIRWLmATd18"
}

Body

{
  "response_type": "code id_token",
  "client_id": <insert client_id>,
  "redirect_uri": <insert redirect_uri>,
  "scope": "payments",
  "claims": {
    "id_token": {
      "openbanking_intent_id": {
        "value": <insert ConsentId>
      }
    }
  }
}

Firstly, create a JWT request parameter with header and body in the format to the right, signed by your signing certificate’s private key. This signature will be validated using the JWKs endpoint you specified during registration of your app.

Note: client_id , redirect_uri , kid and scope should correspond to the values for your specific application and consent request. openbanking_intent_id is the ConsentId field generated from the previous step.

Sample URL

https://sandbox-oba.revolut.com/ui/index.html?response_type=code%26id_token&scope=payments&redirect_uri=<insert redirect URL>&client_id=<insert client_id>&request=<insert JWT>
https://oba.revolut.com/ui/index.html?response_type=code%26id_token&scope=accounts&redirect_uri=<insert redirect URL>&client_id=<insert client_id>&request=<insert JWT>

Next, redirect the user to https://oba.revolut.com/ui/index.html with the parameters on the URL as detailed below.

Parameter Description Required
response_type Always set to code&id_token yes
client_id client_id for your application yes
redirect_uri One of the redirect URI's you defined during client creation yes
scope The scope you are requesting eg accounts or payments yes
request The encoded JWT generated in previous step yes

Sample redirect after successful response

https://www.revolut_redirect.com/?code=oa_sand_sPoyVs-oMhyR36j5N-ZEVLfK9rQWPNssgIQqsOFZQ-c&id_token=eyJraWQiOiJxRlFQaTRPVkJVLVNaVk5iMjJ5VjVHQVZDN1UiLCJhbGciOiJQUzI1NiJ9.eyJpc3MiOiJodHRwczovL29iYS5yZXZvbHV0LmNvZGVzIiwiaWF0IjoxNjA0OTM2ODUzLCJzdWIiOiI0NjdiYzg3MC1jOTllLTQ0MzQtYTk1OS1iOGM1NmVlNmEwMjciLCJhY3IiOiJ1cm46b3BlbmJhbmtpbmc6cHNkMjpzY2EiLCJvcGVuYmFua2luZ19pbnRlbnRfaWQiOiI0NjdiYzg3MC1jOTllLTQ0MzQtYTk1OS1iOGM1NmVlNmEwMjciLCJhdWQiOiIxZWMxZGIyZC0zZTViLTRkODItYjQyZS0wNjc5NDU2MmUyMGUiLCJub25jZSI6Im4tMFM2X1d6QTJNaiIsImV4cCI6MTYwNDkzNzQ1MywiY19oYXNoIjoiTXNfRnRwdWs0U2VDNW4zdUNMTTc0ZyIsInNfaGFzaCI6IlM2YVhOY3BUZGw3V3B3bnR0V3h1b2cifQ.m-EvhggqLg7ZXh0we_PLKNsc248p8Bn_o5nj7_6CQHkiRI23ZrYjJLlz_1BhvZ_iY1Tll2gybq_0eSKRgHpvOPnhvCbcSAyfkE8YERZoVkIe-64cyiomhaqBzMzjQyghaL4KrnKH667wR1gTjVhwyJyztalTKidoLZ5OFVWRSHkqW3YLm-_q51wP0k7HHvJ-fnkGcIoCv2TYXpb9xykvgGRJv9KIISbQtM_bLBpo5Q6Q1fxNc-LK2iT-o22xQzLhzvGHtXLTl7Kn5xYf8quDjA5zG0iCAGLJ-Fo9NuTobcKjJOaNYpQ_Y2ilKMmtXqRdgAF_in4Lydt2dn9duxFvJA&state=state

On successful completion of the authorisation flow, you will receive an authorisation code as a URL parameter in the redirect. See example to the right for how this looks.

This authorisation code is only valid for two minutes.

5. Exchanging request token for access token

Exchange Token

curl -k --key private.key --cert transport.pem \
--location --request POST 'https://sandbox-oba-auth.revolut.com/token' \ 
--header 'Content-Type:application/x-www-form-urlencoded' \
--data-encoded grant_type=authorization_code \
--data-encoded code=<insert auth_code>
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-encoded grant_type=authorization_code \
--data-encoded code=<insert auth_code>

Response

{
  "access_token":"oa_sand_tP1Nofi1ixsRfBmVBtVPdIVN0J5x91imqmheQIWTS5s",
  "token_type":"Bearer",
  "expires_in":7775999,
  "id_token":"eyJraWQiOiJxRlFQaTRPVkJVLVNaVk5iMjJ5VjVHQVZDN1UiLCJhbGciOiJQUzI1NiJ9.eyJpc3MiOiJodHRwczovL29iYS5yZXZvbHV0LmNvZGVzIiwic3ViIjoiNDY3YmM4NzAtYzk5ZS00NDM0LWE5NTktYjhjNTZlZTZhMDI3IiwiYXVkIjoiMWVjMWRiMmQtM2U1Yi00ZDgyLWI0MmUtMDY3OTQ1NjJlMjBlIiwibm9uY2UiOiJuLTBTNl9XekEyTWoiLCJleHAiOjE2MDQ5Mzc0Nzk1NjksImlhdCI6MTYwNDkzNjg3OX0.NrcI6qSwmkTC4zhVP7S9Se1RD8Mnwfz5D3RyGp_5CI7MN6-GLqGHnIBNPNzbUBjlmer8ecCvhm0j9tkScT0xDMSZUdMjRyvb7qrsXYTVbj0ogDPthZSe-45tiq3y4oOsIusIwMPFWGHzI2zq_wzxYY8h6QXFIK6TB_oC93jM6J5JEUUQwvDR23ntcCoH_9uNaGM2PXO2ppxhxZiJe92TYcoZFCIMxqrcVxuUYM1VLQ8d7TcpoIDWdOmtOVqDYmblUHyjFpO3IcBHalua0LRGmU3ZuaEv2iG3YzpqV0OMIHFUe9fQ95z_jID4rGIWwxRL6URIdzw6ZSSyxRXKRWNh3g"
}

If the user has successfully authorised your consent, return to the /token endpoint, this time with grant_type=authorization_codeto obtain the access token that can be used against the /domestic-payments endpoint.

Note: auth_code here is the authorisation code generated from the previous step

6. Initiate domestic payment

Create a domestic payment

curl --location --request POST 'https://sandbox-oba.revolut.com/domestic-payments' \
--header 'x-fapi-financial-id: 001580000103UAvAAM' \
--header 'Content-Type: application/json' \
--header 'x-idempotency-key: 123' \
--header 'Authorization: Bearer <insert acces_token>' \
--header 'x-jws-signature: <insert jws signature>' \
--data '
{
  "Data": {
    "ConsentId":<insert consent_id>
    "Initiation": {
      "InstructionIdentification": "ID412",
      "EndToEndIdentification": "E2E123",
      "InstructedAmount": {
        "Amount": "55.00",
        "Currency": "GBP"
      },
      "CreditorAccount": {
        "SchemeName": "UK.OBIE.SortCodeAccountNumber",
        "Identification": "11223321325698",
        "Name": "Receiver Co."
      },
      "RemittanceInformation": {
        "Reference": "ReceiverRef",
        "Unstructured": "Shipment fee"
      }
    }
  },
  "Risk": {
    "PaymentContextCode": "EcommerceGoods",
    "MerchantCategoryCode": "5967",
    "MerchantCustomerIdentification": "1238808123123",
    "DeliveryAddress": {
      "AddressLine": ["7"],
      "StreetName": "Apple Street",
      "BuildingNumber": "1",
      "PostCode": "E2 7AA",
      "TownName": "London",
      "Country": "UK"
    }
  }
}
curl --location --request POST 'https://oba.revolut.com/domestic-payments' \
--header 'x-fapi-financial-id: 001580000103UAvAAM' \
--header 'Content-Type: application/json' \
--header 'x-idempotency-key: 123' \
--header 'Authorization: Bearer <insert acces_token>' \
--header 'x-jws-signature: <insert jws signature>' \
--data '
{
  "Data": {
    "ConsentId":<insert consent_id>
    "Initiation": {
      "InstructionIdentification": "ID412",
      "EndToEndIdentification": "E2E123",
      "InstructedAmount": {
        "Amount": "55.00",
        "Currency": "GBP"
      },
      "CreditorAccount": {
        "SchemeName": "UK.OBIE.SortCodeAccountNumber",
        "Identification": "11223321325698",
        "Name": "Receiver Co."
      },
      "RemittanceInformation": {
        "Reference": "ReceiverRef",
        "Unstructured": "Shipment fee"
      }
    }
  },
  "Risk": {
    "PaymentContextCode": "EcommerceGoods",
    "MerchantCategoryCode": "5967",
    "MerchantCustomerIdentification": "1238808123123",
    "DeliveryAddress": {
      "AddressLine": ["7"],
      "StreetName": "Apple Street",
      "BuildingNumber": "1",
      "PostCode": "E2 7AA",
      "TownName": "London",
      "Country": "UK"
    }
  }
}

Response

{
  "Data": {
    "DomesticPaymentId": "dd817a13-3198-48ca-a5dc-f22b09ee82c0",
    "Status": "AcceptedSettlementInProcess",
    "StatusUpdateDateTime": "2020-11-20T08:54:30.115047Z",
    "CreationDateTime": "2020-11-20T08:54:30.115047Z",
    "ConsentId": "6686e444-c103-4077-8085-8e094200c425",
    "Initiation": {
      "CreditorAccount": {
        "Name": "ReceiverCo.",
        "SchemeName": "UK.OBIE.SortCodeAccountNumber",
        "Identification": "11223321325698"
      },
      "InstructedAmount": {
        "Amount": "55.00",
        "Currency": "GBP"
      },
      "RemittanceInformation": {
        "Reference": "ReceiverRef",
        "Unstructured": "Shipmentfee"
      },
      "EndToEndIdentification": "E2E123",
      "InstructionIdentification": "ID412"
    }
  },
  "Links": {
    "Self": "https://oba.revolut.com/domestic-payments/dd817a13-3198-48ca-a5dc-f22b09ee82c0"
  },
  "Meta": {
    "TotalPages": 1
  }
}


Now that you have generated your final access token, you can initiate the payment on the user's behalf. Make a call to the /domestic-payments endpoint to initiate the payment on their behalf.

As part of the API requirement you must pass x-jws-signature header in your request. The signature must be generated from the request body with the TPP signing key that is specified in the JWS header. As specified in the OB documentation, you must only pass head and signature in .. format.

Congratulations! You have successfully initiated your first payment

What’s next

Create your first draft payment

To request approval to use our draft payments endpoint, please first register your application in our Developer Portal.

Note: draft payment functionality is only available for Revolut Business customers.

1. Get authorisation from user

Draft Payments authorisation URL

https://sandbox-business.revolut.com/partner-confirm?response_type=code&state=state&scope=draft_payments&client_id=your_client_id&redirect_uri=your_redirect_uri
https://business.revolut.com/partner-confirm?response_type=code&state=state&scope=draft_payments&client_id=your_client_id&redirect_uri=your_redirect_uri

Response

https://www.revolut_redirect.com/revolut_redirect?code=oa_sand_kiLg3m7xrNua0rbShC1GQZfbk0DthUhOpVA9xX2oRY0&state=state

Before you can start creating draft payments, you'll need to get authorisation from the user to make draft payments on their behalf. By redirecting the user to the authorisation URL, you will get authorisation in the form of an authorisation code.

Authorisation URL Parameters
Paramater Description Required
scope Scope for authorisation that's required from the user yes
client_id client_id for your application yes
redirect_uri One of the redirect URI's you defined during client creation yes
state A generated string to verify the response is initiated by the same user yes

2. Exchanging authorisation code for access token

Token request via MTLS

curl -k --key your_private.key --cert your_transport.pem \
--location --request POST 'https://sandbox-mtls-auth.revolut.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=<insert authorisation_code>' 
curl  --key your_private.key --cert your_transport.pem \
--location --request POST 'https://mtls-auth.revolut.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=<insert authorisation_code>' 

MTLS response

{"access_token":"oa_sand_tG6kRPb2LAYJZx1c3w1NZ7ntuscssWqsC6WkaW9jbER-E","token_type":"Bearer","expires_in":7775999}

Next, exchange your authorisation code for an access token using the https://mtls-auth.revolut.com/token endpoint.

3. Create Draft Payment

Create Draft Payment

curl --location --request POST 'https://sandbox-apis.revolut.com/draft-payments' \
--header 'Authorization: Bearer <insert access_token.' \
--header 'Content-Type: text/csv' \
--data-binary @draft_payments.csv
curl --location --request POST 'https://apis.revolut.com/draft-payments' \
--header 'Authorization: Bearer <insert access_token.' \
--header 'Content-Type: text/csv' \
--data-binary @draft_payments.csv

Response

{"DraftPaymentId":"4bc0a477-2c81-4f49-bf5b-c6705bb7a6d9"}

Now you have an access token, you can use the /draft_payments endpoint to create a draft payment on behalf of the customer. Please include a CSV with the below fields, columns with optional values can be omitted in the uploaded file.

Once created, a draft payment will appear in their Revolut Business account, which the user can then either approve or reject.

Note: maximum number of rows in a file is 1000 and all payments must be in the same currency

Parameters
Name Located in Description Required Schema
scheduledDate query All transfers in csv will be created as a scheduled payment with this date as the execution date No date in "YYYY-MM-DD" format
CSV Format
Field Required Description
Name Yes Can contain up to 80 characters. If INDIVIDUAL recipient type is provided this field must contain first and last name separated by white space
Recipient type Yes Can be either INDIVIDUAL or COMPANY
Account number For UK transfers Must contain valid account number if provided
Sort code or Routing number For UK transfers Must contain valid sort code or routing number if provided
IBAN For SEPA transfers Must contain valid IBAN if provided
BIC For SEPA transfers Must contain valid BIC if provided
Recipient bank country Yes Must contain valid ISO 3166-1 country code
Currency Yes Must contain valid ISO 4217 currency code
Amount Yes Must match following pattern [0-9]*(\\.[0-9]*)?
Payment reference Yes Can contain up to 100 characters
Recipient country No Must contain valid ISO 3166-1 country code if provided
State or province No Can contain up to 50 characters
Address line 1 No Can contain up to 50 characters
Address line 2 No Can contain up to 50 characters
City No Can contain up to 50 characters
Postal code No Can contain up to 50 characters

4. Get Draft Payment

Get Draft Payment Details

curl -X GET https://sandbox-apis.revolut.com/draft-payments/{DraftPaymentId} \
--header 'Authorization: Bearer <insert access_token>'
curl -X GET https://apis.revolut.com/draft-payments/{DraftPaymentId} \ 
--header 'Authorization: Bearer <insert access_token>'

Response

{
    "Status": "Processed",
    "Transfers": [
        {
            "InstructedAmount": {
                "Amount": "10.00",
                "Currency": "GBP"
            },
            "Reference": "User comment",
            "Status": "Created",
            "Index": 1
        },
        {
            "InstructedAmount": {
                "Amount": "20.00",
                "Currency": "GBP"
            },
            "Reference": "User reference",
            "Status": "Failed",
            "FailedReason": "Something went wrong",
            "FailedReasonCode": 3067,
            "Index": 2
        }
    ]
}

By supplying a DraftPaymentID, you can request details related to a specific draft payment that has been created. Index indicates which row number from the CSV file this transfer represents.

5. Working with Draft Payments

Now that your first draft payment has been created, there are some important considerations to take into account when building your integration.

Payment Orders vs Transfers

When you create a bulk draft payment, it consists of a draft payment order which in turn contains a set of transfers, these concepts have independent states.

A draft payment order is what the user will either approve or delete from the UI. There are four states that the order can appear in:

Draft Payment Order Status Description
Awaiting Draft payment order has been created and awaiting approval from user
Approved Draft payment order has been approved by the user and the transfers are in the process of being executed
Processed Draft payment order has been processed
Deleted Draft payment order has been deleted by the user

Once a draft payment order has been approved, each transfer is then executed individually. There are five states that the transfer can appear in:

Transfer Status Description
Created Transfer has been created but is yet to be executed
Pending Transfer is the queue to be executed
Completed Transfer has successfully completed and a payment has been made from the users account
Failed Transfer has failed and no payment has been made. Accompanying failure reason code and message are returned in GET endpoint.
Deleted Transfer has been deleted by the user
Failure Codes

There are a number of different reasons that transfers can fail. Please see the table below as a reference for different values of FailedReasonCode:

Failure Code Description
1003 Recipient is unable to receive funds.
1006 User has insufficient balance to execute the payment.
4000 Internal transfer error. Typically occurs when a user is trying to send a payment to a sub-account or sending to an account with the incorrect currency.
4032 Invalid transfer reference. The transfer reference that was detailed in the payment was invalid.
3067 Unknown error. Please ask user to reach out to support

Each FailedReasonCode is accompanied by a custom FailedReasonMessage to give detail on the failure.

What’s next

API Metrics

You can view the latest API metrics for Mobile, Business and Open Banking APIs here. You can also review detailed Open Banking metrics here.

We update these reports daily and keep them for the last 90 days.

Usage and limits

In order to ensure safe and fair resource sharing, we define the following usage limits:

Please make sure to stay under this limit. Should you estimate this limit to be a problem for your use case of our API, please reach out to us directly.

Glossary

For the complete list of Open Banking terms, we recommend viewing the official glossary.

Name Term Definition
TPP Third Party Provider Third Party Providers are organisations or natural persons that use APIs developed to Standards to access customer’s accounts, in order to provide account information services and/or to initiate payments. Third Party Providers are either/both Payment Initiation Service Providers (PISPs) and/or Account Information Service Providers (AISPs).
AISP Account Information Service Provider An Account Information Service provides account information services as an online service to provide consolidated information on one or more payment accounts held by a payment service user with one or more payment service provider(s).
ASPSP Account Servicing Payment Service Provider Account Servicing Payment Service Providers provide and maintain a payment account for a payer as defined by the PSRs and, in the context of the Open Banking Ecosystem are entities that publish Read/Write APIs to permit, with customer consent, payments initiated by third party providers and/or make their customers’ account transaction data available to third party providers via their API end points.





Errors

The API uses the following error codes:

CODE MEANING
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your access token is wrong.
403 Forbidden -- Access to the requested resource or action is forbidden.
404 Not Found -- The requested resource could not be found.
405 Method Not Allowed -- You tried to access an endpoint with an invalid method.
406 Not Acceptable -- You requested a format that isn't JSON.
429 Too Many Requests -- You're sending too many requests.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.