Xero - beautiful accounting software

Xero Developer Help Center

Xero Developer Community

Community > API Endpoints >

Options for Machine to Machine OAuth2 flow

Started by Kynd DEV SANDBOX -   in API Endpoints


A per now the XERO api does not support `client_credentials` OAuth2 grant, which makes the M2M (Machine to Machine) auth painful and unreliable using the workaround provided in the FAQ (https://developer.xero.com/faq/all/machine-to-machine)

- The machine/process integrating with xero api has to store the refresh token/access token pair. Keep check the expiry of the access token and refresh it before expiry. This could be avoided using `client_credentials` OAuth2 grant, is there any way this will be supported in the future?

- If there is any failure in this process we can likely end up with a stale refresh token, leading to `invalid_grant` error when requesting (refresh) a new token pair. How then can we automate the request of a new token pair in this case? I could not find any example of this in the documentation besides the manual steps using postman (https://developer.xero.com/documentation/tools/postman)

Thanks for your help,

Thierry R.
I would also appreciate further updates about the possibility of client_credentials support in OAuth2. Currently we automate our billing process by integrating our backend server (which does not have a web interface) to Xero on our own behalf, not that of the end user, so the code grant type is not really compatible with the way we use the API. We need to be able to rely on our integration to work 100% of the time without having to manually check up on it and refresh the token if it expires or becomes invalid.


Geoff Mazzolini  

The method described in that link is really not a good way to manage machine to machine especially if your company, like mine, makes a Xero integration that is then used by many different clients. Using that I would have to track up to 10 different keys and make sure they are all refreshed every 30 days, no thanks.

I would suggest this type gets added quickly else i can see a lot of integration developers wanting to move away from using Xero. Also any app devs will be tearing their hairs out as well as they are now expected to keep client secret keys secure on platforms such as Javascript.

Clystnet Support  

Being forced to move to Oauth 2.0 and can't even automate the processes to do our integrations. Has there been any improvements on this, at the moment i have to run an ETL process by manually clicking ok in the browser every day

Andrew Bennett  

I'm currently building an app that my client wants integrated with Xero. This could potentially be a deal breaker for them.

Shail Akhil  

According to Xero:

On the newer version of the API (https://devblog.xero.com/release-round-up-march-2020-8cfc0af216fb)

OAuth 2.0 from the command line
We’ve introduced a CLI tool that allows you to trigger and complete the OAuth flow directly from the command line. This helps developers build integrations that don’t have easy access to a web browser. https://github.com/XeroAPI/xoauth

It seems more like a workaround rather than a proper M2M OAuth flow support/implementation. It does not work for a serverless environment.



Doe's not work from a Linux server either as it needs a browser to auth.

Really getting me done. We have a private app to 3 of our OWN companies.

Has been working fine and now we have to use OAuth2 but xoauth2 does not work.


Any response from Xero team? PLEASE

Gary Hill  

As far as I am aware, Xero's development team does not actually understand the problem, as has no plans to fix this in any way.

Please read https://community.xero.com/developer/discussion/109207632 for more details.

Ricardo Nolde  

I've implemented a solution using xoauth on my development system to get a token set with sufficient permissions. Then the token set is simply copied to the live system and used without user intervention, automatically refreshing the tokens. Perhaps not ideal, but it gets the job done. The max time between refresh is currently 60 days, so that's unlikely to be an issue.

David Nye  

I have a couple of companies with automated billing, creating invoices and the like. I managed to get one of them up and running using oauth2, and I refresh the token every 20 mins, which is so inefficient, as I only need to connect to xero occasionally. Developing it was terrible, with rubbish documentation and its turned me from a Xero lover to a hater. I really really hate the solution for M2M connections. It requires intervention, whereas before it was working just fine.

David Leeming  

What I resolved to was:

Create a table in our db to hold the creds for each of our companies (we have 7).

One of the fields is expired_time, which is 30 mins from the last call.

When I make a post to Xero, I check the expired_time and refresh it before I make the API call and update the expired time in the db table.

As the key expires in 60 days (if memory serves) I have a cronjob that runs on the first day of the month to refresh the 60 day token thing ....

I agree the support and docs for CFML/Linux is non-existent/poor


Gary Hill  

Mine is a simple case; since we only need to connect to Xero occasionally, I did not bother with the 30 minute access token expiry at all. We just use the refresh token immediately before each API call without checking any expiry times. Since we are posting invoices, we can almost guarantee that there will be a few calls each month, so we also do not need to worry too much about the 60 day refresh token expiry.

But one day, perhaps years in future, the token set will inevitably become invalidated for some reason, so I have also provided my client with a button which runs "xoauth connect" (which prompts the user to authorise access in Xero), and this automatically replaces the token set. This covers all scenarios where the refresh token is lost or invalidated, not just token expiry. Edit: As at February 2021 the client has never needed to use this function, nor have I needed to re-authorise.

It does not currently seem worthwhile to automate "xoauth setup", since this only needs to be done once immediately after installing xoauth, so I have simply included this step in the installation instructions.

This seems to me the simplest and most robust solution for low volume applications. Of course if the volume of API calls increases significantly then it will be necessary to reduce the number of refreshes by storing and checking the (30 minute) access token expiry time. A bit more work, but easy enough.

David Nye  

Adding my voice to this post - the workround mentioned above is useless for any automated system, as it still depends on a user logging in via a browser. I need to be able to extract invoice information in a fully-automated process as part of an EDI interface, and this cannot require the periodic presence of a user in order to run. I would be unable to advise any customers requiring automation to use Xero at the moment for exactly this reason. As mentioned in the initial post, the client_credentials OAUTH2 grant seems to be the industry-standard way of handling this - its absence from Xero is very poor.

Martin Gordon-Kerr  

Martin, Ours is completely automated a human does not need to auth each time. As my previous post says we use a cronjob on the server to refresh the token monthly (just in case) but with each request to Xero it checks the expiry time and gets a new one if required.

A user NEVER has to auth the app to use Xero

Gary Hill  

Hi Gary - thanks for the response. I understand the renewal of the access token from the token endpoint - we do something similar to yourselves for other systems to keep track of the expiry time and renew when required. However, according to the Xero API instructions, that access token renewal from the token endpoint not only requires client ID and client secret but also the callback code from the user authorisation section - and the documentation specifically says that this callback code expires after 5 minutes. How do you handle the access token without the renewal of the callback code, which requires a manual intervention via a browser and therefore cannot be automated? Or is it that the callback code doesn't actually expire as it says it does?

Martin Gordon-Kerr  

If memory serves the only thing I need to refresh is the id_token, access_token and refresh_token.

You do not need client/web browser intervention.


Gary Hill  

There seems to be a lot of confusion caused by the very poor documentation. Essentially someone somewhere has to give the Xero authority to create a token set. This plain text token set can then be transferred to the production system, which then only has to ensure it does a refresh within 60 days. Apart from the 60 day timeout, the token set could be invalidated by someone authorising again, for example, but usually it can be used indefinitely. So, in my case, I have the required access to the live Xero Organisation, so I can generate the token set here, then simply copy it from my laptop to my client's file server. No-one on site has ever had to authorise and the posting to Xero is completely background. This has been running since June.

David Nye  

Yes - that's it David - that's pretty much what I have done.

It's been working without a hitch for many months- I do 'refresh' every 30 days no matter what, that's my paranoia kicking in!

Gary Hill  

Is there anywhere a tutorial on how to set up this bizarre token transfer from laptop to server + eternal periodical token refresh? I have to create a tiny automation and I'm very confused on the mere authentication part :(

Simone Scarduzio  

I have not seen a tutorial, but I can send you my own brief documentation and VBA code examples if that will help? Others have been able to use this to resolve their issues.

David Nye  

I'm pretty new to Oauth2, but a few weeks ago I managed to get one of my clients up and running without intervention on an M2M basis. I use XOauth to get an initial set of tokens + expiration and store them in my db. The token I get back has an lifetime of 30 minutes, so I don't understand the 60 days being mentioned here?

My application checks if 30 minutes has passed since the last posting, if so I use the Refresh Token to get a new set of tokens etc.

This all seems to work fine, but now I have a second client to set up, and despite the code being the same, as soon as the first token set (the one I create manually using XOauth) expires, and my code tries to use the Refresh Token, it fails on 'Invalid-Grant'.

The exact steps I went through with the second client were:
1. Log into the Developer area to grab my application's client ID.
2. Whilst there, generate a new Client Secret and grab that.
3. Store these in my new client's database.
4. Use XOauth to create a new Connection for the new client, using the retrieved Client ID and Secret and the usual scopes.
5. Store the retrieved Access Token, Refresh Token and expiration in my new client's database.

Everything runs fine until the expiration is passed, at which point, unlike for the first client that uses this application, the call to get a new set of tokens fails.

I'm sure I must be getting something wrong. Can anyone point me in the right direction?


Reg Jackson