Skip to main content
Once the user has granted you access to his account you will be able to get a token that can be use to access Qonto API on his behalf.
New to OAuth 2.0? Check out these generic guides before diving in:
Already have an API key? If you only need to automate your own Qonto account, you may not need OAuth at all. Check the authentication introduction to pick the right method for your use case.

Step by step

Oauth 2 flow
1

Authorize

The first step is to redirect the user to the Qonto OAuth server. The Qonto user will be invited to authenticate.Oauth 2 flowThen they will have to allow your application to access one of the organizations they are part of.Oauth 2 flow
If you need your integration to run unattended (e.g. automations, scheduled tasks), include offline_access in your scope parameter. Without it, you will not receive a refresh token and your integration will stop working after 1 hour.
CSRF protection with state: Generate a unique, unpredictable value (e.g. a random 32-byte hex string), include it in the authorization URL as state, and store it in the user’s session. When the user is redirected back to your redirect_uri, verify that the received state matches what you stored. Reject the flow if they differ — this protects against cross-site request forgery.
Optional: restrict org selection. You can pass organization_id to lock the flow to a specific organization, or registration_id to pre-select an org from the onboarding flow. In both cases the org selection screen is skipped.
cf. this endpoint for a full technical description of the query parameters.
curl -G https://oauth.qonto.com/oauth2/auth \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "redirect_uri=https://your-app.com/callback" \
  --data-urlencode "response_type=code" \
  --data-urlencode "scope=offline_access organization.read" \
  --data-urlencode "state=YOUR_RANDOM_STATE"
# Copy the URL from the output and redirect the user to it
After consent, Qonto redirects the user to your redirect_uri with a temporary code and the state you provided: https://your-app.com/callback?code=AUTH_CODE&state=YOUR_STATE
Invalid client_id or redirect_uri in the authorization request.
2

Exchange the authorization code for an access token

Once user has granted access to his account, he will be rederected to your application via your redirect_uri with a temporary authorization code.On your backend, you will have to exchange this code for an access_token.
Do not use Authorization: Basic headers. Qonto requires client_id and client_secret as form body parameters. Sending them in the header will result in an invalid_client error.
Never expose your client_secret on the client side — this call must be made from your backend.
The redirect_uri must exactly match the value registered with Qonto, including trailing slashes and query strings. Pass it as a plain string and let your HTTP library handle the form encoding — do not manually pre-encode it (e.g. avoid https%3A%2F%2F...). A mismatch causes invalid_grant.
curl -X POST https://oauth.qonto.com/oauth2/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code' \
  -d 'code=YOUR_CODE' \
  -d 'client_id=YOUR_CLIENT_ID' \
  -d 'client_secret=YOUR_CLIENT_SECRET' \
  -d 'redirect_uri=https://your-app.com/callback'
The response contains an access_token (valid 1 hour) and, if offline_access was requested, a refresh_token (valid 90 days).
Store the refresh_token securely — use it to obtain new access tokens without user interaction. See the Refresh token endpoint.

Error responses

Causes: Missing required parameter (code, client_id, client_secret, redirect_uri, or grant_type), or wrong Content-Type header (must be application/x-www-form-urlencoded).
cf. API reference for full parameter details.
3

Use your access token

To perform authenticated requests on the Qonto API, you will have to provide the access_token in the Authorization header, as describe in this example:
curl GET 'https://thirdparty.qonto.com/organization' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
4

Refresh your access token

The access_token expires after 1 hour. Rather than restarting the entire OAuth flow, use the refresh_token to obtain a new one silently on your backend.
Refresh tokens are one-time use. Every refresh call invalidates the token you used and returns a new refresh_token in the response. You must store this new token immediately — using an old refresh token will result in an invalid_grant error. If two processes attempt to refresh the same token concurrently, the second request will always fail.
curl -X POST https://oauth.qonto.com/oauth2/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=refresh_token' \
  -H 'Accept: application/json' \
  -d 'refresh_token=YOUR_REFRESH_TOKEN' \
  -d 'client_id=YOUR_CLIENT_ID' \
  -d 'client_secret=YOUR_CLIENT_SECRET'
Token lifecycle at a glance:
TokenLifetimeWhat to do when it expires
access_token1 hourUse refresh_token to get a new one — no user action needed
refresh_token90 daysRestart the OAuth flow (user must re-authorize)
As long as you refresh before the 90-day window closes and correctly store the latest refresh_token after each call, your integration will run indefinitely without requiring user re-authorization.For full parameter details and error responses, see the Refresh token endpoint.

Resources