GoCardlessDeveloper Docs
Create a sandbox account

OAuth Reference#

View as Markdown

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#

EnvironmentBase URL
Livehttps://connect.gocardless.com
Sandboxhttps://connect-sandbox.gocardless.com

The OAuth flow#

  1. Send the user to GET /oauth/authorize with your client_id, requested scope, and redirect_uri.
  2. The user logs in (or signs up) to GoCardless and agrees to connect their account.
  3. GoCardless redirects to your redirect_uri with a short-lived code.
  4. Exchange the code for a permanent access_token via POST /oauth/access_token.
  5. Use the access_token to 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.

GET https://connect.gocardless.com/oauth/authorize?
  response_type=code&
  client_id=sx6WHUAVMUrinkJNJn8DotVFm&
  scope=read_write&
  redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&
  state=q8wEr9yMohTP&
  prefill[email]=tim%40acme.com&
  prefill[given_name]=Tim&
  prefill[family_name]=Rogers&
  prefill[organisation_name]=Acme%20Ltd&
  prefill[country_code]=GB

Parameters#

ParameterRequiredDescription
response_typeYesMust be code.
client_idYesYour app's client_id.
scopeYesread_write or read_only.
redirect_uriYesMust exactly match one of the redirect_uris registered on your app. Used for both success and error redirects.
stateNoAn 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]NoPre-fills the user's email on the login/signup form.
prefill[given_name]NoPre-fills the user's first name on the signup form.
prefill[family_name]NoPre-fills the user's last name on the signup form.
prefill[organisation_name]NoPre-fills the organisation name on the signup form.
prefill[country_code]NoPre-fills the organisation country in ISO 3166-1 alpha-2 format.
languageNoLanguage for the login/signup form in ISO 639-1 format. Falls back to the most appropriate language if unsupported.
initial_viewNosignup 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.

GET https://example.com/callback?code=6NJiqXzT7HcgEGsAZXUmaBfB&state=q8wEr9yMohTP

Redirect errors#

If the user denies the request, or an error occurs, GoCardless redirects to your redirect_uri with error and error_description parameters.

GET https://example.com/callback?error=access_denied&error_description=The%20user%20cancelled%20the%20authorisation%20process.
ErrorDescription
access_deniedThe user chose not to connect their account to your app.
invalid_requestscope or response_type was not provided.
invalid_scopescope was not read_only or read_write.
unsupported_response_typeresponse_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.

POST https://connect.gocardless.com/oauth/access_token HTTP/1.1
 
grant_type=authorization_code&
code=6NJiqXzT7HcgEGsAZXUmaBfB&
redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&
client_id=sx6WHUAVMUrinkJNJn8DotVFm&
client_secret=exaxerfrWrPdxADDUBWVqGbPbF

Parameters#

ParameterRequiredDescription
grant_typeYesMust be authorization_code.
codeYesThe authorisation code from the redirect. Expires after 5 minutes.
redirect_uriYesMust match the redirect_uri used in the authorisation request.
client_idYesYour app's client_id.
client_secretYesYour app's client_secret.

Response#

{
  "access_token": "e72e16c7e42f292c6912e7710c123347ae178b4a",
  "scope": "read_write",
  "token_type": "bearer",
  "email": "accounts@acme.com",
  "organisation_id": "OR123"
}
FieldDescription
access_tokenPermanent token for authenticating as the user. Store this.
scoperead_write or read_only, as originally requested.
token_typeAlways bearer.
organisation_idThe GoCardless account ID. Store this to match webhooks to your users.
emailContact email for the connected account.

Errors#

ErrorDescription
invalid_requestA required parameter is missing or the wrong type.
unsupported_grant_typegrant_type was not authorization_code.
invalid_clientclient_id and client_secret are invalid or refer to a disabled app.
invalid_grantThe 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:

Authorization: Bearer e72e16c7e42f292c6912e7710c123347ae178b4a

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:

{
  "error": {
    "code": 401,
    "type": "invalid_api_usage",
    "errors": [
      {
        "reason": "access_token_revoked",
        "message": "The access token you provided has been revoked"
      }
    ]
  }
}
ReasonDescription
access_token_not_foundThe token was not recognised.
access_token_revokedThe user has revoked your access.
access_token_not_activeThe 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.

{
  "events": [
    {
      "id": "EV123",
      "action": "confirmed",
      "resource_type": "payments",
      "links": {
        "payment": "PM123",
        "organisation": "OR123"
      }
    }
  ]
}

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 https://api.gocardless.com/payments HTTP/1.1
Authorization: Bearer e72e16c7e42f292c6912e7710c123347ae178b4a
Content-Type: application/json
 
{
  "payments": {
    "amount": 100,
    "app_fee": 10,
    "currency": "GBP",
    "links": { "mandate": "MD123" }
  }
}
POST https://api.gocardless.com/subscriptions HTTP/1.1
Authorization: Bearer e72e16c7e42f292c6912e7710c123347ae178b4a
Content-Type: application/json
 
{
  "subscriptions": {
    "amount": 2500,
    "app_fee": 10,
    "currency": "GBP",
    "name": "Monthly Magazine",
    "interval_unit": "monthly",
    "day_of_month": "1",
    "links": { "mandate": "MA123" }
  }
}

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.

POST https://connect.gocardless.com/oauth/introspect HTTP/1.1
Content-Type: application/x-www-form-urlencoded
 
client_id=jBo8XCUJLN01Mzya9vYS-7X5D&client_secret=hzBBiZTWnx8glPLwvJoVIJa1&token=live_y7VPTOdgFZtFaAS9V8HT3

Parameters#

ParameterRequiredDescription
tokenYesThe access token to look up.
client_idYesYour app's client_id.
client_secretYesYour app's client_secret.

Response#

Follows the OAuth token introspection spec.

{
  "active": true,
  "scope": "read_write",
  "token_type": "bearer",
  "email": "accounts@acme.com",
  "organisation_id": "OR123"
}
FieldDescription
activeBoolean — whether the token is valid and active.
scoperead_write or read_only. Only returned if active.
token_typeAlways bearer. Only returned if active.
organisation_idThe GoCardless account this token gives access to. Only returned if active.
emailContact 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#

ErrorDescription
invalid_requestA required parameter is missing or the wrong type.
invalid_clientclient_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.

POST https://connect.gocardless.com/oauth/revoke HTTP/1.1
Content-Type: application/x-www-form-urlencoded
 
client_id=jBo8XCUJLN01Mzya9vYS-7X5D&client_secret=hzBBiZTWnx8glPLwvJoVIJa1&token=live_y7VPTOdgFZtFaAS9V8HT3

Parameters#

ParameterRequiredDescription
tokenYesThe access token to revoke.
client_idYesYour app's client_id.
client_secretYesYour 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#

ErrorDescription
invalid_requestA required parameter is missing or the wrong type.
invalid_clientclient_id and client_secret are invalid or refer to a disabled app.

What's next#