xero-node
NodeJS Client for the Xero API. Works with ES5, ES6+ and TypeScript.
API Reference
Supports all application types:
- Private - apps that can only connect to a single organisation
- Public - apps that can connect to any organisation, but only for 30 minutes at a time
- Partner - approved apps that can automatically refresh tokens
Version 3 has been rebuilt fron the ground-up using TypeScript, to make it
more maintainable and to take advantage of modern JavaScript features.
Features/Change Log
- v3.0.6
- Thanks brucem1976 who added History to the endpoints that support History #206
- v3.0.4
- Thanks nickngsr #203
- escape filename to ensure it is url safe for attachments
- add ability to save purchase order pdf
- fix typo on purchase order number in get request
- v3.0.3
- Thanks gslisrael. Enable getting creditNotes by CreditNoteNumber #199
- v3.0.2
- v3.0.1
- Reimplmented how to make generic API calls in BaseAPI layer. See examples below
- v3.0.0
Installation
This SDK is published as an npm package called xero-node
.
npm install --save xero-node
Usage Example for Private Apps
Create a config.json
file:
{
"appType": "private",
"consumerKey": "your_consumer_key",
"consumerSecret": "your_consumer_secret",
"callbackUrl": null,
"privateKeyPath": "C:\\keys\\your_private_key.pem"
}
Then add the following JavaScript (example works in NodeJS version 8 and above):
const XeroClient = require('xero-node').AccountingAPIClient;
const config = require('./config.json');
(async () => {
let xero = new XeroClient(config);
const result = await xero.invoices.get();
console.log('Number of invoices:', result.Invoices.length);
})();
Usage Example for Public and Partner Apps
Create a config.json
file:
{
"appType": "public",
"consumerKey": "your_consumer_key",
"consumerSecret": "your_consumer_secret",
"callbackUrl": null,
"privateKeyPath": "C:\\keys\\your_private_key.pem"
}
Then add the following JavaScript (example works in NodeJS version 8 and above):
const XeroClient = require('xero-node').AccountingAPIClient;
const config = require('./config.json');
(async () => {
let xero = new XeroClient(config);
const requestToken = await xero.oauth1Client.getRequestToken();
console.log('Received Request Token:', requestToken);
authUrl = xero.oauth1Client.buildAuthoriseUrl(requestToken);
console.log('Authorisation URL:', authUrl);
const oauth_verifier = 123456;
const savedRequestToken = {
oauth_token: 'aaa',
oauth_token_secret: 'bbb'
};
const accessToken = await xero.oauth1Client.swapRequestTokenforAccessToken(savedRequestToken, oauth_verifier);
console.log('Received Access Token:', accessToken);
const result = await xero.invoices.get();
console.log('Number of invoices:', result.Invoices.length);
if((new Date) - accessToken.oauth_expires_at > 60*30*1000){
let newToken = await xero.oauth1Client.refreshAccessToken();
}
const result1 = await xero.invoices.get();
console.log('Number of invoices:', result1.Invoices.length);
const storedAccessToken = {
oauth_token: 'aaa',
oauth_token_secret: 'bbb',
oauth_session_handle: 'ccc',
oauth_expires_at: '2018-01-01T01:02:03'
};
const xero2 = new XeroClient(config, storedAccessToken);
const invoices = await xero2.invoices.get();
console.log('Number of invoices:', invoices.Invoices.length);
})();
Further Examples
Migration from V2
The biggest change is the number of function calls you have to make to complete your task. This is consistant across all endpoints. It's not JSON in and JSON out. your object never gets modified:
Example:
// V2
let invoiceObj = xero.core.invoices.newInvoice(invoiceJSON);
let result = await invoiceObj.save()
becomes:
// V3
let result = await xero.invoices.create(invoiceJSON);
Please also review the documentation around how to construct the client object. You no longer have to use specifc constructors for your App Type. Instead this information is passed in with your config object. For example, rather than Xero.PublicApplication
you use new Xero.AccountingAPIClient
and specify the appType in the config passed in.
In addition the oAuth1.0a related methods are in their own namespace now, and there are some changes from z
to s
to align with Xero API naming.
Please see related blog post here: https://devblog.xero.com/the-new-xero-node-sdk-2c69dcab4a2f
Contributing
Local development
There are lots of TODOs in code and on our GitHub Projects kanban board - feel free to pick one off.
After you clone the repository, run npm install
to install required dependencies.
Running the tests
We need two private Apps to get around the ratelimits. They can be connected to the same Org.
- Copy
private-config-example.json
to private-config.json
in the integration test directory. - Copy it again to
1private-config.json
in the integration test directory. - Overwrite the example values with your own from the Developer Portal.
- (Do the same for
partner-config-example.json
if required.) - Run
npm test
Project Philosophies
-
A simple and intuitive interface.
eg:
PUT https://api.xero.com/api.xro/2.0/ContactGroups/b05466c8-dc54-4ff8-8f17-9d7008a2e44b/Contacts
becomes:
xero.contacts.contactGroups.create(contact)
Matching SDK methods names to endpoints, allows consumers to read the official API documentation and translate it to SDK method calls quickly.
That rather than using HTTP verbs (.put()
, .post()
etc) the SDK will use actions. Example get()
, create()
,delete()
, update()
. This abstracts away Xero's funny PUT
vs POST
.
-
A simple and single OAuth flow. Rather than automatically refreshing tokens, the SDK we will expose methods which allow the OAuth methods eg Refreshing Tokens etc. Consideration is also being made to OAuth2.
-
Abstracted underlyting OAuth/HTTP lib. This will allow swapping it out if we needed. The SDK won't bleed the OAuth libs exception types onto the consumer when it hits a 500/400 etc. Having a OAuth/HTTP layer will allow reuse and extension to other APIs (Payroll, Expenses etc).
-
Minimal to no entity/request/response validation. A consumer will pass in JSON and get JSON out. There will be no manipulation of data along the way. Helper methods if asked for will be provided by a separate module. This will reduce maintenance costs.
-
Unit tests!
-
Writing the SDK in Typescript will allow us to provide TS types for the API's contracts, and it's what we use internally at Xero. This will also aid in self-generated docs.
Maintainers
@philals @iamam34 @bryanlloydtee @dannyvincent @dupski