Sign in with Xero

Allow users to sign in to your app with their Xero account. It's simple and secure.

Sign in with Xero leverages security features including two step authentication, anomalous login detection, email address verification and more. It conforms to the OpenId Connect specification and will work with any certified client library. Getting up and running is just a case of:

  1. Create an OAuth2.0 app to get your client id and secret
  2. Adding a Sign in with Xero button to your login screen
  3. Handle the auth flow to get an ID token
  4. Use the ID token to verify the user

1. Create your OAuth2.0 app

Go to My Apps and create an app. Give your app a name, a url and at least one redirect URI. The redirect URI is where we will send users after they complete the authorization step below. Once you save your app details you will be given a client id and secret. Make sure you save your secret somewhere secure because it will only be displayed once.

2. Create your Sign in with Xero button

The easiest way to add a Sign in with Xero button to your site is to use our sign in widget. With only a few lines of code, you can add a button that complies with our brand guidlines and can be customised to fit your existing look and feel.

To initiate the OpenId Connect flow, you'll need to send an Authorization Request to Xero's Identity system. Most web application frameworks will have an OpenId plugin that builds this request automatically, but our Sign in with Xero button can also create one for you.

Using the button with your web framework

If you're using a web application framework with an OpenId plugin, use the data-href option to point the button at the sign-in URL you've configured in your app:
    <meta charset="UTF-8">
    <title>My App</title>
    <span data-xero-sso data-href="/sign-in/xero" data-label="Sign in with Xero"></span>
    <script src="" async defer></script>
This also works great if you have separate URLs for kicking off sign-in and sign-up actions:
    <meta charset="UTF-8">
    <title>My App</title>
    <span data-xero-sso data-href="/sign-in/xero" data-label="Sign in with Xero"></span>
    <span data-xero-sso data-href="/sign-up/xero" data-label="Sign up using Xero"></span>
    <script src="" async defer></script>

Using the button stand-alone

To create a sign in button that uses the default OpenId settings, add an element with the data attribute data-xero-sso to your sign in page, along with the following meta tags:

    <meta charset="UTF-8">
    <meta name="xero-client-id" content="YOUR_CLIENT_ID">
    <meta name="xero-scopes" content="openid,profile,email">
    <meta name="xero-redirect-uri" content="YOUR_CALLBACK_URL">
    <!-- optional -->
    <meta name="xero-state" content="YOUR_REQUEST_STATE">
    <title>My App</title>
    <span data-xero-sso data-label="Sign in with Xero"></span>
    <script src="" async defer></script>

The default button will look like: and direct the user to: profile email&state=123
with parameters for:

  • response_type=code
  • scope the permissions you're requesting (see below)
  • client_id the client id for your app
  • redirect_uri the URL on your server that the user will be redirected back to once they've completed authorization. This must match the one saved against your app.
  • state (optional) a unique string to be passed back on completion (see below)


Scopes are the permissions that your app is requesting approval for. You can pass in a list of scopes separated by a space.

For the purpose of signing the user in you will probably need to ask for:

  • openid to indicate that your application intends to use the user's identity
  • profile to access the user's name and unique identifier
  • email to access the user's email address

Find out more about how scopes work with the Xero API here.


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

3. The auth flow

User authorization

When the user clicks on your Sign on with Xero button they will be sent over to Xero. They need to log in and approve access to their identity details. If they allow access they will be sent back to your redirect_uri with a verification code parameter. If you used a state parameter this will also be returned for you to verify.

Retrieving the ID token

Now that you have a verification code you can request an ID token that will give you the user's identity details. To do this you will need to make a POST request to our token endpoint:

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
authorization: "Basic " + base64encode(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded


4. Using the ID token

The id token contains the user’s identity information in the form of a JWT (JSON Web Token). The JWT is a JSON payload signed with your client secret and the RS256 signing algorithm. The payload of the JWT contains some standard claims as defined in the ​OIDC spec​ification:

  • iss ​The issuer of the token (i.e.
  • sub​ ​The unique identifier for the end user
  • aud​ The client_id of your app
  • exp​ The expiry time
  • iat​ The issue time

If your app requested the ​email​ scope it will also include:

  • email​ The user’s email address

If your app requested the ​profile​ scope it will also include:

  • given_name​ The user’s given name
  • family_name​ The user’s family name

Congratulations! You've now securely confirmed the user’s identity you can log them into your app

Customising the Sign in with Xero button

You can modify the Xero sign in button to fit with the rest of your application.


The text to display in the button. Must contain the word Xero. We check this when the button loads – you'll get a console warning and a default message if you forget to include “Xero”.

<span data-xero-sso data-label="The text to display"></span>


Can be light, mono, or dark, depending on what suits your site design

<!-- dark theme -->
<span data-xero-sso data-theme="dark"></span>
<!-- mono theme -->
<span data-xero-sso data-theme="mono"></span>
<!-- light theme -->
<span data-xero-sso data-theme="light"></span>


Can be small (12px text), normal (13px text), large (15px text). The button will default to normal if you don't specify a value:

<span data-xero-sso data-theme="dark" data-size="large"></span>
<span data-xero-sso data-theme="dark" data-size="normal"></span>
<span data-xero-sso data-theme="light" data-size="small"></span>


If you're using the large size, you can set the height of the button to anything taller than 40px. The button uses flexbox, so the text and wording will remain vertically centered. The value must be set in pixels as shown below:

<span data-xero-sso data-size="large" data-height="100"></span>


You can display the button inline with text, or as a block level element if your layout suits a "stack" of buttons:

<span data-xero-sso data-theme="dark" data-size="large" data-layout="block"></span>
<span data-xero-sso data-theme="light" data-size="small" data-layout="inline"></span>


Chances are, your designer has carefully chosen a border radius for your app's buttons. You can set a border radius in pixels as shown below. Values can be between 0 and 30.

<span data-xero-sso data-border-radius="10"></span>


You can set the border width between 0 and 10 pixels:

<span data-xero-sso data-border-width="10"></span>
<span data-xero-sso data-border-width="0"></span>


You can set the border color to an rgb, rgba, hsl or hex value:

<span data-xero-sso data-border-color="#beeeef"></span>
<span data-xero-sso data-border-color="rgba(0,0,0,0.5)"></span>


Modify the box-shadow to suit your theme:

<span data-xero-sso data-box-shadow="0 2px 2px rgba(0,0,0,0.2)"></span>


You may want to the button to inherit the background from a parent block-level element. With any of the button themes, you can switch off the xero-specified background:

<span data-xero-sso data-layout="block" data-transparent="true"></span>


By default, we'll use Xero's font family for the button. If you'd like to use your brand typeface, switch the font property to inherit

<span data-xero-sso data-font="inherit" ></span>


When the button renders, we send the host name of the website (, along with a timestamp, to Xero's telemetry system. This helps us keep track of where the button is deployed, no user information or PII is collected. If you'd like to opt out of this tracking, you can switch it off:

<span data-xero-sso data-no-track="true"></span>


If you're using an OIDC framework, redirect the user to the URL you've set up to start the OIDC flow.

<span data-xero-sso data-href="/sign-in/xero"></span>