caret

The OAuth2.0 flow


OAuth 2.0 is a protocol that lets your app request authorization to access data in a user's account without accessing their password. Your app requests specific permission scopes and is granted an access token upon a user's approval.

You'll need to create an OAuth2.0 app before getting started. Each app is assigned a unique Client ID and Client Secret which will be used in the OAuth flow. The Client Secret is private and should not be shared.


The OAuth flow

Introducing Tenant Ids

Xero is a multi-tenanted platform. Tenants can be organisations (small businesses) or practices (accounting firms). A given user may have access to multiple tenants and will choose which ones to connect to your app.

At the successful completion of an OAuth flow you will be granted an access token to act on behalf of the user. It includes the scopes that the user has authorized. You will then use that access token to find out which tenants the user has connected to your app. From there, you can make API calls by providing both a valid access token and authorized tenant id with each request.


1. Send a user to authorize your app

Your app should direct users to the following url:

https://login.xero.com/identity/connect/authorize?response_type=code&client_id=YOURCLIENTID&redirect_uri=YOURREDIRECTURI&scope=openid profile email accounting.transactions&state=123

The following values should be passed in as parameters:

  • response_type=code
  • client_id issued when you create your app
  • scope permissions to request (see below)
  • redirect_uri the URL on your server to redirect back to
  • state a unique string to be passed back on completion (optional) (see below)

Note: you will be redirected to the main Xero dashboard after logging in if there is a problem with one the parameters provided. Check that your redirect_uri matches the redirect URI saved against your app, your client id is correct and the scopes are valid.

Scopes

The scope parameter is a space-separated list of OAuth scopes, indicating what data you'd like your app to be able to access. You should request the minimum scopes required for whatever the user is doing at the time. The complete list of scopes can be found here.

State

The state parameter should be used to avoid forgery attacks. Pass in a value that's unique to the user you're sending through authorisation. It will be passed back after the user completes authorisation.


2. Users are redirected back to you with a code

If the user authorizes your app, Xero will redirect back to your specified redirect_uri with:

  • code a temporary code that may only be exchanged once and expires 12 minutes after issuance.
  • state (if you provided one). If the states don't match, the request may have been created by a third party and you should abort the process.

If any errors occur or the user denies the request, we redirect back to your redirect_uri with an error parameter.


3. Exchange the code

You can now exchange the verification code for an access token. You will also receive an identity token if you’ve requested OpenID Connect scopes and a refresh token if you’ve requested the offline_access scope.

To do this you will need to make a POST request to our token endpoint:

https://identity.xero.com/connect/token

The request will require an authorization header containing your app’s client_id and client_secret

  • Authorization: "Basic " + base64encode(client_id + ":" + client_secret)

The request body will need to contain the grant type (authorization_code), code and redirect_uri

  • grant_type=authorization_code
  • code=The authorization code you received in the callback
  • redirect_uri=The same redirect URI that was used when requesting the code
POST https://identity.xero.com/connect/token
authorization: "Basic " + base64encode(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=xxxxxx
&redirect_uri=https://myapp.com/redirect

4. Receive your tokens

The token endpoint will verify all the parameters in the request, ensuring the code hasn’t expired and that the client ID and secret match. If everything checks out, it will generate your tokens and return them in the response.

It will contain the following parameters:

  • access_token The token used to call the API.
  • id_tokenThe token containing user identity details (only returned if OpenID Connect scopes are requested).
  • expires_inThe amount of seconds until the access token expires.
  • token_type: Bearer
  • refresh_tokenThe token used to refresh the access token once it has expired (only returned if the offline_access scope is requested).

5. Check the full set of tenants you've been authorized to access

You can verify all the tenants that the user has authorized your app to access by calling the connections endpoint. If the user has authorized your app previously, they may have existing tenant connections. All of the connected tenants can now be accessed with your most recent access token.

GET https://api.xero.com/connections
Authorization: "Bearer " + access_token
Content-Type: application/json

Response:
[
  {
    "id": "e82447cc-ce78-468f-b2c6-9af74c519ead",
    "tenantId": "83299b9e-5747-4a14-a18a-a6c94f824eb7",
    "tenantType": "ORGANISATION"
  },
  {
    "id": "077a50b2-b95c-4a22-8a89-47b0cff2485e",
    "tenantId": "45e4708e-d852-4111-ab3a-dd8cd03913e1",
    "tenantType": "ORGANISATION"
  }
]

6. Call the API

Make calls against the Xero APIs by simply adding the following headers to your request:

  • Authorization: "Bearer " + access_token
  • xero-tenant-id: tenantId

GET ../api.xro/2.0/Invoices
Authorization: "Bearer " + access_token
Accept: application/json
Xero-tenant-id: 83299b9e-5747-4a14-a18a-a6c94f824eb7

Refreshing access tokens

An access tokens expire after 12 minutes. Your app can refresh an access token without user interaction by using a refresh token. You get a refresh token by requesting the offline_access scope during the initial user authorization.

To refresh your access token you need to POST to the token endpoint:

https://identity.xero.com/connect/token

The request will require an authorization header containing your app’s client_id and client_secret

  • Authorization: "Basic " + base64encode(client_id + ":" + client_secret)

The request body will need to contain the grant type and refresh token

  • grant_type=refresh_token
  • refresh_token=Your refresh token
POST https://identity.xero.com/connect/token
authorization: "Basic " + base64encode(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=xxxxxx