OAuth Reference#
OAuth allows you to act on behalf of other GoCardless accounts. Once a user connects their account to your app, you can use the GoCardless API on their behalf and receive their webhooks.
The GoCardless OAuth API conforms to the OAuth 2.0 spec and works with standard OAuth client libraries available in most languages.
For a step-by-step integration walkthrough see Connect Your Merchants.
Base URLs#
| Environment | Base URL |
|---|---|
| Live | https://connect.gocardless.com |
| Sandbox | https://connect-sandbox.gocardless.com |
The OAuth flow#
- Send the user to
GET /oauth/authorizewith yourclient_id, requestedscope, andredirect_uri. - The user logs in (or signs up) to GoCardless and agrees to connect their account.
- GoCardless redirects to your
redirect_uriwith a short-livedcode. - Exchange the
codefor a permanentaccess_tokenviaPOST /oauth/access_token. - Use the
access_tokento make API requests on the user's behalf and receive their webhooks.
Creating an app#
Create your app from the developer section of your GoCardless dashboard. You will be issued a client_id and client_secret (each 64 characters) which identify your integration.
GET /oauth/authorize#
Redirect your user to this endpoint to start the OAuth flow. Use a GET request.
Parameters#
| Parameter | Required | Description |
|---|---|---|
response_type | Yes | Must be code. |
client_id | Yes | Your app's client_id. |
scope | Yes | read_write or read_only. |
redirect_uri | Yes | Must exactly match one of the redirect_uris registered on your app. Used for both success and error redirects. |
state | No | An arbitrary string returned to you unchanged in the redirect. Use it for a CSRF token. Note: can be tampered with by the user, so do not trust implicitly. |
prefill[email] | No | Pre-fills the user's email on the login/signup form. |
prefill[given_name] | No | Pre-fills the user's first name on the signup form. |
prefill[family_name] | No | Pre-fills the user's last name on the signup form. |
prefill[organisation_name] | No | Pre-fills the organisation name on the signup form. |
prefill[country_code] | No | Pre-fills the organisation country in ISO 3166-1 alpha-2 format. |
language | No | Language for the login/signup form in ISO 639-1 format. Falls back to the most appropriate language if unsupported. |
initial_view | No | signup or login. Defaults to login for read_only scope and signup for read_write. |
Handling the redirect#
On success, GoCardless redirects to your redirect_uri with a code (and state if you provided one). Exchange the code within 5 minutes.
Redirect errors#
If the user denies the request, or an error occurs, GoCardless redirects to your redirect_uri with error and error_description parameters.
| Error | Description |
|---|---|
access_denied | The user chose not to connect their account to your app. |
invalid_request | scope or response_type was not provided. |
invalid_scope | scope was not read_only or read_write. |
unsupported_response_type | response_type was not code. |
POST /oauth/access_token#
Exchange an authorisation code for a permanent access token. If the user has connected before, a new token is issued and any existing token is disabled.
Parameters#
| Parameter | Required | Description |
|---|---|---|
grant_type | Yes | Must be authorization_code. |
code | Yes | The authorisation code from the redirect. Expires after 5 minutes. |
redirect_uri | Yes | Must match the redirect_uri used in the authorisation request. |
client_id | Yes | Your app's client_id. |
client_secret | Yes | Your app's client_secret. |
Response#
| Field | Description |
|---|---|
access_token | Permanent token for authenticating as the user. Store this. |
scope | read_write or read_only, as originally requested. |
token_type | Always bearer. |
organisation_id | The GoCardless account ID. Store this to match webhooks to your users. |
email | Contact email for the connected account. |
Errors#
| Error | Description |
|---|---|
invalid_request | A required parameter is missing or the wrong type. |
unsupported_grant_type | grant_type was not authorization_code. |
invalid_client | client_id and client_secret are invalid or refer to a disabled app. |
invalid_grant | The code has already been used, has expired, or redirect_uri does not match. |
Making requests#
Pass the access token in an Authorization header using the bearer scheme:
Errors from requests using an access token follow the standard GoCardless error structure, not the OAuth error format above.
401 Unauthorized#
If the access token is invalid you will receive a 401 response. The error body will include a reason:
| Reason | Description |
|---|---|
access_token_not_found | The token was not recognised. |
access_token_revoked | The user has revoked your access. |
access_token_not_active | The token is inactive for another reason. |
The user must go through the authorisation flow again before you can obtain a new token.
Restricted endpoints#
Always restricted:
- Creditor — create and update
- Creditor Bank Account — all endpoints
Restricted unless your app's payment pages are approved as scheme-rules compliant:
- Customer — create
- Customer Bank Account — create
- Mandate — create and reinstate
If your app is authorised to access an endpoint but you receive an unexpected 403 Forbidden, the user's account may be under review. GoCardless will have informed them directly.
Receiving webhooks#
If your app has a configured webhook URL, GoCardless sends you events for all connected organisations. Events are identical to the standard event format, with one addition: a links.organisation field identifying which connected account the event belongs to.
Store the organisation_id you receive when exchanging an access token — you will need it to map incoming webhook events to the correct connected account.
App fees#
If your app creates payments on behalf of connected users, you can charge an app fee on top of the GoCardless fee.
Pass app_fee alongside amount when creating a payment or subscription. The fee is deducted from what the merchant receives and must be no more than 50% of the total payment amount. App fee payouts are created and paid out daily.
POST /oauth/introspect#
Validate an access token and retrieve details about it. Useful when you need to confirm a token is active or look up the associated organisation_id.
Parameters#
| Parameter | Required | Description |
|---|---|---|
token | Yes | The access token to look up. |
client_id | Yes | Your app's client_id. |
client_secret | Yes | Your app's client_secret. |
Response#
Follows the OAuth token introspection spec.
| Field | Description |
|---|---|
active | Boolean — whether the token is valid and active. |
scope | read_write or read_only. Only returned if active. |
token_type | Always bearer. Only returned if active. |
organisation_id | The GoCardless account this token gives access to. Only returned if active. |
email | Contact email for the connected account. Only returned if active. |
An inactive or unrecognised token returns { "active": false } with a 200 status — not a 4xx.
Errors#
| Error | Description |
|---|---|
invalid_request | A required parameter is missing or the wrong type. |
invalid_client | client_id and client_secret are invalid or refer to a disabled app. |
POST /oauth/revoke#
Programmatically invalidate an access token. Users can also revoke access from their GoCardless dashboard.
Parameters#
| Parameter | Required | Description |
|---|---|---|
token | Yes | The access token to revoke. |
client_id | Yes | Your app's client_id. |
client_secret | Yes | Your app's client_secret. |
Response#
Returns 200 OK with no body — regardless of whether the token was successfully revoked. This follows the OAuth token revocation spec.
Errors#
| Error | Description |
|---|---|
invalid_request | A required parameter is missing or the wrong type. |
invalid_client | client_id and client_secret are invalid or refer to a disabled app. |