With our community of partners, you can get expert advice and training so you can be up and running in no time!

View setup partners

With our community of partners, you can get expert advice and training so you can be up and running in no time!

View setup partners

Get the Guide on Moving from spreadsheets to software.

Get the guide

Want to join us? Become a partner. 

Become a partner

OAuth2.0 for WorkflowMax & Xero Practice Manager

App Partner Migration to Xero API Guide

This guide is for developers migrating a WorkflowMax or Xero Practice Manager partner app to the v3 API using OAuth2.0. It will take you through the steps to easily create your new App in the Xero Developer Portal, and update your existing application to connect using OAuth2.0. While the migration process is quite straightforward, there is a fundamental change to how things work in OAuth2.0 that you’ll need to carefully plan for.


User-based OAuth

Our OAuth2.0 implementation issues access tokens on a per-user basis. This is a big change from OAuth1.0a where access tokens were issued for an individual tenant (organisation or practice). Users can still select which tenants an app can access but that will be handled separately to the token.


Decoupling the access token from the tenant is a significant change that opens up a range of benefits:

  • The ability to use Xero as a single sign-on provider for your app.
  • The ability to leverage OpenID Connect for smoother onboarding to your app from the Xero marketplace.
  • The ability for users to connect multiple Xero tenants (organisations or practices) to your app in a single authorisation flow.

Changes to how you store tokens

The data you need to store for Xero OAuth2.0 connections will be very similar to what you’re currently storing for OAuth1.0a. Instead of using an oauth_token you’ll have an access_token and instead of having an oauth_session_handle you’ll have a refresh_token. Both token types contain a JSON document encoded as a base64 string. The access token is transient, with a short lifetime, and therefore does not need to be stored in persistent storage. The refresh token is long lived and should be stored as a simple string in your preferred datastore. Please note that the refresh token should be considered very sensitive information and should be stored, and treated, as such (i.e. secured access, transmitted in an encrypted form and, ideally, encrypted at rest).

In the case where the same user has granted access to multiple accounts or practices you will use the same access and refresh tokens for accessing the API but will disambiguate access to a specific account’s resources by passing the relevant account identifier in a request header. See below for further information.

Third Party Access Authorisation

A new Staff Privilege has been added to control who has permission to connect your Account to 3rd Party Addons. 
Any Staff with Administrator Privileges can assign this new Privilege to themselves or other Administrators. 

Follow these steps for each Staff member you want to be able to authorise connections to 3rd Party Addons.

  1. Go to the Business > Settings > Staff page, or click on this link to go directly there.
  2. Search for the Staff Member that you would like to add this permission to.
  3. Ensure that the Staff has the Administrator Privilege.  If they do not, tick the checkbox for this and Save the Staff settings first.pasted image 0 (6)
  4. You will now see a new Heading appear at the bottom of the page, “API Access Privileges”.  Tick the checkbox for this and Save the Staff Settings to assign Authorise 3rd Party Full Access privilege.

pasted image 0 (7)


How to migrate your app

Step one: Create credentials

To generate a client id and client secret for your app you’ll need to go to My Apps and open your existing partner app. In the OAuth2.0 credentials section add at least one redirect URI and click save.redirect-uri

Note: In OAuth2.0 you need to provide the full callback URI including the callback domain. This URI will receive the relevant authorisation details that can be exchanged for access and refresh tokens.


You now have your client id and secret for making OAuth2.0 requests. Remember that your secret is sensitive information and should be stored and treated as such.


Step two: Build your integration

Once you have your application credentials you can start building your OAuth2.0 integration. We recommend you use one of our new OAuth 2.0 SDKs which will be maintained and updated by Xero. You’re welcome to fork your current SDK and add any standard OAuth2.0 or OIDC library but these will not be actively maintained by Xero in the future.

Read the documentation on our OAuth 2.0 flow to see how auth will differ from your current implementation. Make sure you familiarise yourself with scopes in OAuth2.0 - you will need either workflowmax or practicemanager.  Depending on your particular use case, you’re most likely going to be using one or more of the scopes listed in the appendix here.

A list of relevant service URLs that you’ll likely want to integrate with are listed below in the appendix.

Once you have OAuth2.0 working in your app we’d recommend putting new connections onto OAuth2.0 to make sure everything is working as expected. Your existing WorkflowMax API connections on v1 will continue to work as normal until further notice.

Step three: Invite customers to re-connect

When you’re confident that your OAuth2.0 implementation is running smoothly, you can start migrating your customers to the new connection. The customer will need to authorise their connections again.

The customer will authorise your application access to their data by visiting a specific URL (see the section ‘1. Send a user to authorize your app’ in the authorisation flow document) that will allow them to sign in with their Xero account (if they haven’t already) and to grant this consent.


OpenID Connect and Sign in with Xero

The OpenID Connect identity layer is a new feature of OAuth2.0 and consent to access a user’s profile information can’t be migrated from the previous version of the API.

A user will need to consent access to their profile information the first time they go through a Sign in with Xero flow and the scopes will be appended to their consent at that time. Remember to specify the scopes you require when building the request link!

An authorisation request link may look like:


Important: The user providing consent will require the ‘Authorise 3rd Party Full Access’ privilege for API calls to successfully complete. This setting can be found under Business > Settings > Staff, selecting the appropriate user and scrolling to the ‘API Access Privileges’ section. Note that only system administrators can grant this privilege.  

API Access Privileges

When the user clicks your application’s specific Xero login link they’ll be prompted with a dialog similar to one of the below. The dialog will differ depending upon which scopes you have requested access to e.g. a request without the refresh token scope (offline_access) will result in the prompt to only ‘Allow access for 30 minutes’.

Group 1-1                      


Can I still use my original API integration after we’ve moved to v3?

No, once you have migrated to v3, you will not be able to move back to v1. API v1 will be supported until the end of the year for any connections still on v1.

Is there a way to determine which Xero organisations an access token can be used with?

Yes - you can make a GET request to the /connections endpoint (see here), supplying the access token as a bearer token in the authorisation header, to retrieve the set of tenants for which the access token is valid.

How do I use a Refresh Token?

A refresh token should be used after an access token expires (30 minutes). You can retrieve the expiration time of the access token by decoding it and inspecting the ‘exp’ property (in seconds since Unix epoch). When an access token expires, your API calls will begin to fail.

Your application 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:

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


Each time you perform a token refresh, you should save the new refresh token returned in the response. If your app doesn't receive a response (for whatever reason) you can retry your existing token for a grace period of 30 minutes. The existing refresh token will become invalid after this time.

How do I get a WorkflowMax or Practice Manager scope?

The WorkflowMax scope is automatically given to any new Xero add-ons.
The Practice Manager scope needs to be requested via our support centre.


Sample code

Scenario 1: Creating a private internal machine to machine integration or console application.

We recommend using Identity Server to implement OAuth 2.0 integration. 

Scenario 2: Creating a public website integration with the WorkflowMax APIs

We recommend using one of the Xero SDKs to easily implement your integration. 
These SDKs will have ongoing support from our Xero API Development team and are provided in a range of different programming languages.  Link to SDKs here.

Check out our sample app here.


Relevant end-points



WorkflowMax v3 API root


Practice Manager v3 API root


Xero OAuth service


Xero Connections API



Common scopes






Required when accessing the WorkflowMax API

Practice Manager


Required when accessing the Practice Manager API

Open ID Connect


Required when accessing the user’s identity.



Used to return details about the user’s identity (first name, last name and xero user id)

E-mail address


User’s email address

Refresh token


Important: This scope is required to receive a refresh token. This should be used if access to the user’s account is required for longer than the immediate session (e.g. 30 minutes).