This guide shows you how to connect Xero to API2Cart in a few clear steps. Xero uses OAuth 2.0, so the setup takes a little more preparation than a simple API key. However, you only have to do it once per organisation.

To integrate with the Xero platform, follow the instructions below. Before you start, create a Xero developer account. You also need access to the Xero organisation that you want to sync.

What You Need Before You Connect Xero to API2Cart

API2Cart stores only three Xero credentials. Therefore, the whole setup boils down to producing these values:

  • xero_client_id - the Client ID of your Xero app.
  • xero_client_secret - the Client Secret generated in the app configuration.
  • xero_refresh_token - the refresh token returned after a merchant authorises your app.

API2Cart refreshes the access token automatically. As a result, you never have to store or rotate the short-lived access token yourself. The next four steps produce these three values. After that, you connect Xero to API2Cart with them.

Step 1: Create a Xero Application

First, open the Xero Developer portal and click New app. Xero asks you to choose an integration type. Select Web app, because this is the only type that supports the standard authorization code flow with refresh tokens.

Then fill in the app name, your company URL and the redirect URI. The redirect URI is the address that Xero calls after a merchant approves your app. Therefore, it must be a page that you control.

Xero offers several integration types, and each one has its own capabilities and limits. The table in the portal explains the differences. For an integration such as API2Cart, the Web app type is the correct choice.

Xero integration types and their connection limits

Step 2: Copy the Client ID and Generate a Client Secret

After you create the app, open its Configuration page. There you will find the Client ID and the redirect URI that you entered earlier. Copy the Client ID, because you need it both for the authorization URL and for the API2Cart connection form.

On the same page, click Generate a secret. Xero shows the Client Secret only once, so store it in a safe place immediately. If you lose it, you can generate a new one, but the old secret stops working.

Xero app configuration page with the Client ID and Client Secret needed to connect Xero to API2Cart

Step 3: Check the Xero App Limits Before You Connect Xero to API2Cart

Xero applies limits at two levels, and both of them affect how many merchants you can onboard. Consequently, it is better to plan for them before you go live.

  • 5 to 50 connections per app. The maximum number of organisations an uncertified Xero app can be installed on depends on your plan, ranging from 5 to 50. To remove this cap, you must pass Xero app partner certification.
  • 2 uncertified apps per organisation. A merchant can keep only two uncertified apps connected at the same time. If the merchant already uses two, they have to disconnect one first.

You can find more details about application limitations here.

Step 4: Choose the OAuth Scopes

Scopes define what your app may read and write. Moreover, they decide which API2Cart methods will work after you connect Xero to API2Cart. API2Cart checks the granted scopes before every call. As a result, a missing scope returns a clear error instead of a silent failure. The full mapping between API2Cart methods and Xero scopes is in the table at the end of this guide.

Always include offline_access. Without it, Xero does not return a refresh_token. In that case, API2Cart cannot keep the connection alive after the first hour.

Step 5: Build the Authorization URL

Next, assemble the URL that a merchant opens to grant access. Use the Client ID and the redirect URI from Step 2, and separate the scopes with spaces:

https://login.xero.com/identity/connect/authorize
  ?response_type=code
  &client_id=<CLIENT_ID>
  &redirect_uri=<REDIRECT_URI>
  &scope=openid profile email offline_access accounting.settings accounting.contacts accounting.invoices accounting.payments accounting.banktransactions
  &state=123

The redirect_uri value must match one of the redirect URIs saved in the app configuration character for character. Otherwise, Xero rejects the request. The state parameter is optional, but it protects the flow against CSRF attacks, so it is worth using.

Step 6: Authorize the App for an Organisation

Now open the authorization URL in a browser. Xero asks the merchant to sign in and to pick the organisation that the app will access. After that, Xero shows the list of permissions that correspond to your scopes.

Keep in mind that a Xero account may own several organisations. The merchant authorises the app for each organisation separately. So a merchant with three companies repeats this step three times.

Authorize the Xero app for an organisation before you connect Xero to API2Cart

Once the merchant confirms access, Xero redirects the browser to your redirect URI. The address bar then contains the authorization code, for example ?code=abc123&state=123. This code is single-use and expires in five minutes, so exchange it right away.

Step 7: Exchange the Code for a Refresh Token

Then send a server-to-server request to the Xero identity service. Authenticate it with HTTP Basic auth. The user name is the Client ID, and the password is the Client Secret:

curl -X POST https://identity.xero.com/connect/token \
-H "Authorization: Basic $(echo -n '<CLIENT_ID>:<CLIENT_SECRET>' | base64)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=<CODE>" \
-d "redirect_uri=<REDIRECT_URI>"

A successful response contains access_token, refresh_token, expires_in and the granted scope list. Save the refresh_token, because this is the last value that you need in order to connect Xero to API2Cart.

Xero OAuth token response with the refresh token used to connect Xero to API2Cart

If the response has no refresh_token, then offline_access was missing from your scope list. In that case, repeat Step 5 and Step 6 with the corrected URL.

Step 8: Connect Xero to API2Cart

Finally, open the API2Cart connection form, select Xero and fill in the three fields below:

  • xero_client_id - for example 811AD782822249B33D1311WE4A550CEE
  • xero_client_secret - for example rXYZVpJyud1NguACRxZiu_BN2tp8mgIhod_6222PZz4sn12k
  • xero_refresh_token - for example EHGCzGm11csIOdF0C5_tOR6-_CPOH_hDZE4jPKg3DSe
API2Cart connection form used to connect Xero to API2Cart

How API2Cart Uses Your Xero API Quota

Once you connect Xero to API2Cart, every unified call consumes a part of the merchant's Xero quota. Xero applies its rate limits per organisation and per app. The current limits are 60 calls per minute, 5,000 calls per day and 5 concurrent calls. On top of that, a single app may send 10,000 calls per minute across all organisations.

It is important to understand that one API2Cart request is not always one Xero request. Under the hood, API2Cart may perform several native calls to build a unified response or to validate the input data. For example:

  • item.list reads Items, and it also reads Accounts to resolve account codes and Organisation to resolve the time zone.
  • bill.add reads Accounts, TaxRates and Items to validate the line items. Then it creates the invoice. Finally, it sends a second update when you pass a bill number.
  • bill.payment.update may probe Payments, Prepayments and Overpayments in turn, because it has to detect the record type first.

API2Cart reduces this overhead by caching organisation and connection data. In addition, it handles HTTP 429 for you. It waits for the period given in the Retry-After header, and then it retries the call. Even so, plan your daily volume with a margin, especially for bulk imports.


Table of Required Xero OAuth Scopes for API2Cart Methods

Below is the comprehensive list of Xero OAuth scopes required to execute specific API2Cart methods. Use it as a checklist before you connect Xero to API2Cart. Read the table with these rules in mind:

  • Scopes joined by or are alternatives, so any one of them is enough.
  • Groups joined by + are cumulative, so you need at least one scope from every group.
  • offline_access appears in every row on purpose. API2Cart runs connection.validate automatically before other methods, and that check needs a valid token pair.
  • Methods that return date fields also read the organisation time zone. For that reason, they require a settings scope even when the entity itself lives elsewhere.
API2Cart Method Required Xero OAuth Scopes
connection.validate offline_access
connection.add offline_access
connection.update offline_access
connection.delete -
organization.list offline_access + (accounting.settings.read or accounting.settings)
account.list offline_access + (accounting.settings.read or accounting.settings)
account.add offline_access + accounting.settings
account.update offline_access + accounting.settings
account.delete offline_access + accounting.settings
tax.rate.list offline_access + (accounting.settings.read or accounting.settings)
item.list offline_access + (accounting.settings.read or accounting.settings)
item.add offline_access + (accounting.settings or accounting.invoices) + (accounting.settings.read or accounting.settings)
item.update offline_access + (accounting.settings or accounting.invoices) + (accounting.settings.read or accounting.settings)
item.delete offline_access + (accounting.settings or accounting.invoices)
contact.list offline_access + (accounting.contacts.read or accounting.contacts) + (accounting.settings.read or accounting.settings)
contact.add offline_access + accounting.contacts
contact.update offline_access + accounting.contacts
bill.list offline_access + (accounting.transactions.read or accounting.transactions or accounting.invoices.read or accounting.invoices) + (accounting.settings.read or accounting.settings)
bill.add offline_access + (accounting.transactions or accounting.invoices) + (accounting.contacts.read or accounting.contacts) + (accounting.settings.read or accounting.settings)
bill.update offline_access + (accounting.transactions or accounting.invoices) + (accounting.contacts.read or accounting.contacts) + (accounting.settings.read or accounting.settings)
bill.credit_note.list offline_access + (accounting.transactions.read or accounting.transactions or accounting.invoices.read or accounting.invoices) + (accounting.settings.read or accounting.settings)
bill.credit_note.add offline_access + (accounting.transactions or accounting.invoices) + (accounting.contacts.read or accounting.contacts) + (accounting.settings.read or accounting.settings)
bill.credit_note.update offline_access + (accounting.transactions or accounting.invoices) + (accounting.contacts.read or accounting.contacts) + (accounting.settings.read or accounting.settings)
bill.payment.list offline_access + (accounting.transactions.read or accounting.transactions or accounting.payments.read or accounting.payments) + (accounting.transactions.read or accounting.transactions or accounting.invoices.read or accounting.invoices) + (accounting.settings.read or accounting.settings)
bill.payment.add offline_access + (accounting.transactions or accounting.payments) + (accounting.transactions or accounting.banktransactions) + (accounting.transactions.read or accounting.transactions or accounting.invoices.read or accounting.invoices) + (accounting.contacts.read or accounting.contacts) + (accounting.settings.read or accounting.settings)
bill.payment.update offline_access + (accounting.transactions or accounting.payments) + (accounting.transactions or accounting.banktransactions) + (accounting.transactions.read or accounting.transactions or accounting.invoices.read or accounting.invoices) + (accounting.settings.read or accounting.settings)

The methods connection.list and connection.supported_integrations return data from API2Cart itself. For this reason, they do not call the Xero API and need no scopes at all.

Troubleshooting

Most problems appear right after you connect Xero to API2Cart, and they usually come from a handful of causes. Therefore, check these first:

  • "Some parameters are invalid! Please check your xero_client_id and xero_client_secret." - the credential pair does not match the app, or the secret was regenerated.
  • "Some parameters are invalid! Please check your xero_refresh_token." - the token was already rotated, or the merchant revoked access in Xero.
  • "Missing required scopes: ..." - the merchant approved the app before you added a scope. Consequently, they have to re-authorise the app through a new authorization URL.
  • "Access to your Xero account has been revoked." - the app was disconnected in Xero, or the trial period of the organisation expired.