Xero - beautiful accounting software

Xero Developer Help Center

Xero Developer Community

Community > API Authentication >

Simple example to connect to the API without a wrapper library.

Started by Eliot Muir -   in API Authentication

I've been trying unsuccessfully to connect to the Xero API using Lua.

I know this isn't a supported language. So I put together a simple shell script that runs on Mac OS X laptop running Mavericks. It doesn't work either but it's fairly transparent what it does and it doesn't use anything but the curl and openssl command line tools.

I tried to paste the script into this forum but the forum software complained about the formatting. Sigh. Not my day. Instead I have put the example code on our website:


Could someone at Xero please explain what I doing wrong?
Tried to see if I could copy-paste the shell script into this reply dialog but no joy.

Eliot Muir  

Hi Eliot,

You mentioned you were using a private application and it looks like you are making a request to get a request token. Public and Partner applications follow this workflow but Private applications do not.


Matthew Mortimer (Xero Staff)  

Hi Matt,

Thanks so much for your quick reply. I rewrote the script with the assumption I can use the consumer key as the oauth access token and sign the message. My new script is up at


Unfortunately I get a new error message - internal server error. What am I doing wrong?


Eliot Muir  

Any update on this. I've made an effort to make this into a one page complete code example to make it easy to reproduce the issue. I think it would be a valuable resource for other people trying to connect to Xero to have a very bare bones example of connecting to the API that makes all the steps very transparent.

Eliot Muir  

Hey Eliot,

Can you please give me the name of the application you set up in Xero so I can see if the calls are reaching our end. From the sound of things it's a configuration issue on you side that's stopping the requests leaving your system.


Matthew Mortimer (Xero Staff)  

It's called "test". It's targeted at the "demo company" under my login. Do you have access to a Mac?

If you want I could probably create an example bat script on windows that could do the same thing. The pain with that is that Curl and openssl don't come pre-installed on a windows machine so it's more effort to recreate the script - whereas the script I have given should work just by creating a test.sh file on a mac and running it.

But you probably have access to more information on your side in terms of what the error message means.

Eliot Muir  

Sorry, I don't have access to a Mac.

I can't see any logs for your application so it seems like something in your system must be stopping the requests from leaving.

Matthew Mortimer (Xero Staff)  

It is hitting something in your system because the error message coming back is from IIS. My read of it is that the web call is invoking some exception which may not be logged in an obvious place within your system. I can put together a script that you can test with your own windows machine. Few questions:

1) What version of windows are you running?
2) Do you have the openssl command line tool installed on it? If not can you install it?
3) Do you have the curl command line tool installed on it? If not can you install it? I can provide instructions if you need it.

If you have those tools installed on it then I can write a example batch file that does the same thing as the shell script I sent you. That should give you the easiest path I can think of being able to reproduce the same thing I see.

It will be a useful resource for anyone looking to connect to your API.

Eliot Muir  

I'm on Windows 7, and yes I have both of those tools installed on my machine so I can have a crack for you if you like but no promises that I'll have an answer for you quickly if the same issue can be reproduced.

Matthew Mortimer (Xero Staff)  

Okay - writing in batch script is beyond me. Too difficult with all the escaping required. I can write a simple one file example in a scripting language of your choice. Do you have any preference - I can port it to PHP, python, perl, powershell - what ever is convenient for you to paste and run.

Eliot Muir  

If you can put together a python script I can take a look at that for you.

Matthew Mortimer (Xero Staff)  

@Eliot - I've written up some more general notes with some links to useful resources here also - using one of the signature generator tools to get you going might be the best idea.

Ronan Quirke (Community Manager)  

Okay I've written a minimal python example of the problem:


The GIST plugin screws up the formatting of the script which is why I have a direct link to GITHUB with it.

Eliot Muir  

To run the script please make sure that openssl, curl and python are installed. This is what I get on my windows machine:

openssl version

OpenSSL 1.0.1k 8 Jan 2015

curl --version

curl 7.45.0 (x86_64-pc-win32) libcurl/7.45.0 OpenSSL/1.0.2d zlib/1.2.8 WinIDN libssh2/1.6.0
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile SSPI Kerberos SPNEGO NTLM SSL libz

python --version
Python 2.7.9


Eliot Muir  

You'll need to edit the script to set the right CONSUMER_KEY and make sure that the SSL certificates are in the same directory as the script. These should correspond to the uploaded certificate for the private application.

I saved the script as test.py.

Then just running:

python test.py

At the command line should run the script and reproduce the error I see. Hope this makes it easy to reproduce and see the problem.

Eliot Muir  

I'm emailing my private key etc. to you to make it even easier to reproduce the problem.

Eliot Muir  


The 'Complete Request' value is not what is being sent - you are url encoding the ampersands between values so they will not be interpreted correctly as query string values.

You are not supplying everything that is expected - most of the resources in the post I linked to document what these are, here is a direct link. In particular you are missing the nonce and timestamp values.

You had better check the timestamp generation also - it should be a whole second value. Everything else looks roughly ok, but I can't say for sure as I could only spend a minute on this.

This post contains all the resources you will need to compare your signature generation to other tools and see where you are going wrong if you run into further problems.

Ronan Quirke (Community Manager)  

Hi Ronan,

1) The URL sent to Xero doesn't have URL encoding of the ampersands. The URL encoding of the ampersands is done solely for the purposes of generating the text to be signed with the RSA-SHA1 signature. I am trying to follow the process suggested in the draft oauth1.1b spec that you gave in another post.

2) I've modified the script to use a rounded down integer for unix epoch time.

3) I added in oauth_once and oauth_timestamp parameters as you suggested.

It still fails with the same internal server error.


Eliot Muir  

Here's an update copy of the script with the consumer key removed.


I will send a copy of the same script to you by email with the consumer key etc.

If Xero had:
1) One simple page with step by step instructions that
2) Included a single file script that can be easily executed on a windows or Mac machine.

Then I think you would make your users much happier and take a lot off stress of yourself. I'm doing my best to work with you constructively here but it will take that step of saving three files into a directory and running the script. I can accept you might not be able to do that today but I hope Xero is able to find one of your co-workers who can take 5 minutes do that.

Eliot Muir  

If you run into environmental issues with running the script I will be more than happy to support you getting it running so you can see the same issue I do.

Eliot Muir  

So as advised by email that it isn't policy to support dealing with your API directly and only wrappers are supported I went ahead and got pyxero running. I don't plan on using it in production but I need to have at least one working example script with your API to make things work.

Getting pyxero working wasn't terribly smooth - this is what I needed to do in case anyone else is going through the same experience. Breaking this into a few messages since this forum software seems to break with some 'error formatting your answer'.

Eliot Muir  

I did it on windows 7 virtual machine rather than risk breaking my python install on my native mac.

I had python 2.7.9 installed already.

I had to install pip (or it could be that it just wasn't on my PATH - it still wasn't after the installation so I had to go into the Scripts directory under the python directory to run pip from there. (I would give the complete path but this forum software doesn't let me type it in)

My first attempt at installing pyxero with pip install pyxero failed because of a dependency on of all things Visual Studio 9.0.


Eliot Muir  

Turns out that Microsoft have a special version of Visual Studio that is required to install some of the crypto packages that pyxero depends on.


Gives me a squeamish feeling needing to install an 83.9 megabyte MSI package which modifies my operating system just to call a web API. Grateful that I am doing this on virtual machine I can trash if it screws up.

Did it and re-installed pyxero - this time successfully.

Eliot Muir  

Then on to the final hurdle. Running the test program failed with this message:

ImportError: No module named jwt.algorithms

(at the bottom of a big python stack dump - I can't paste it into this forum software.

Googling came up with:

I tried a couple of solutions - in the end, downgrading the version of oauth did the trick, with:

pip install oauthlib==0.7.2

After that my example worked.

Eliot Muir  

Here's a copy of example script with the consumer key removed for reference.


Eliot Muir  

Thanks for you help - I should be good from here.

Eliot Muir  

And I got my own implementation working...

Eliot Muir  

Alright so I made two Oauth examples and I've shared them on our website:


I did an example in Python which should run without to much fuss on windows and os x and Linux (although I have not tested Linux)


It makes use of the openssl and curl command line tools. This is not wrapper, so much as minimalist example of calling the Xero API without the need to install much beyond what a vanilla install of Linux or OS X has.

I'm not a python programmer - no points for elegance or efficiency here - just picking a common scripting language that is already available on many platforms.

If you are on Windows then you'll need to go to the trouble of installing openssl, python 2 and the curl command line.

I also did an example in Lua inside of our product Iguana:


Worthwhile reading since I attempted to do a step by step explanation of what the script does.

Hope it helps to make it easier to understand the Xero API without a lot of abstraction.

Eliot Muir