Xero - beautiful accounting software

Xero Developer Help Center

Xero Developer Community

Community > API Authentication >

Help with refreshing expired access token in OAuth 2.0

Started by Matthew Freire -   in API Authentication


I am querying the Xero API with the Python requests library and am using OAuth 2.0. When trying to refresh the access token when it has expired, I am getting the following response:

{'error': 'invalid_grant'}

This is the code I am using to refresh the token:

import base64
import requests

def refresh_xero_token(refresh_token):
basic_token = base64.urlsafe_b64encode(f"{CLIENT_ID}:{CLIENT_SECRET}".encode()).decode()
headers = {
'Authorization': f"Basic {basic_token}",
'content-Type': "application/x-www-form-urlencoded",
data = {
'grant_type': 'refresh_token',
'refresh_token': refresh_token
res = requests.post(XERO_REFRESH_URL, headers=headers, data=data)
return res.json()

Any help would be appreciated.
Official Xero Reply
Hi everyone,

The change is now live. I'll update the docs but just to clarify some of the questions from this thread:

- Refresh tokens expire after 30 days if not used. Your app will need to do a refresh at least every 30 days to keep the offline connection alive.
- If you perform a token refresh successfully you get a new refresh token with the new access token
- If, for whatever reason, you don't receive the response after performing the token refresh you can retry refreshing the old token for a grace period of 30 minutes.

We considered switching to immortal refresh tokens but we decided this was a safer compromise. Imagine, for example, a case where a developer accidentally uploads their secret and refresh token to their Github repo (it happens more than you'd think!). Refresh tokens with limited lifespans greatly reduce the likelihood that a mistake like that results in data actually being compromised.

For those who have an issue with the 30 days expiry for unused refreshed tokens - how long would you actually need?

Update: the refresh token lifetime has now been updated to 60 days

Adam Moore (Community Manager)