Become an Accounting Developer

Access and develop using the API

to develop add-ons and connect your app

Getting Started with the Accounting API

The Accounting API is an interface for accessing Accounting data. The API also exposes a lot of the functionality available in Accounting.

Accounting customers can use the API to integrate with their existing websites and internal systems or the API can be used by 3rd party integrators to extend their own products or create new products using Accounting as the accounting engine.

To use the Accounting API, you will need to obtain an API Key to uniquely identify your application. To obtain this key, you will need to have an Accounting account.


API Support

We provide API support via email ([email protected]) and our Google Group (https://groups.google.com/forum/#!forum/sageoneapi_southafrica). We aim to answer queries within 48 hours. API support is limited to API related issues only and does not include tutoring in programming principles or specific code issues.

Request your API Key

Simply fill in your details below and we will get back to you as soon as possible. Please note that API keys may take up to 2 working days to be issued.

Contact Name:
Company Name:
Name of Solution:
Solution Description:
Telephone Number:
Email Address:
Website Address:
Country:
Contact Me
API Overview

To view the full API Specification click here.

Format

The current supported format is JSON.

URL Structure

The service URLs are built up as follows:

[API URL]/api/[ver]/[service name]/[method name]/[ID (when required)]?[required query string parameters]

API Url: https://accounting.sageone.co.za

Current Version: 1.1.2

All Calls require the API Key to be included as a query string parameter. This key will be issued by Pastel.

Any functions dealing with company specific data require the companyid parameter.

URL Examples:

  • Company Get List Example:
    • http://[API URL]/api/[ver]/Company/Get?apikey={39478ac6-ac2a-44d8-a31c-7e7e14af4de3}
  • Individual Company Get Example:
    • http://[API URL]/api/[ver]/Company/Get/1?apikey={39478ac6-ac2a-44d8-a31c-7e7e14af4de3}
  • Individual Customer Get Example:
    • http://[API URL]/api/[ver]/Customer/get/1?apikey={39478ac6-ac2a-44d8-a31c-7e7e14af4de3}&CompanyId=1
Services

There are over 100 API services. Please refer to the API Specification and ask the Accounting developer forum if you get stuck.

Request Limits

All Accounting user accounts have a request limit of 5000 API requests per day. A maximum of 100 results will be returned for list methods, regardless of the parameter sent through.

API Response Codes

HTTP Code

Description

Occurs When:

200

OK

Everything performs as expected.

201

Created

A new entity has been created.

202

Accepted

The call to the method was accepted and will be handled at the servers discretion.

204

No Content

The call to the method was successful but there is not data that this method will return.

400

Bad Request

A malformed request was sent through or when a validation rule failed. Validation messages will be returned in the response body.

401

Unauthorized

The user is not correctly authenticated and the call requires authentication.
The user does not have access rights for this method.

402

Payment Required

The registration has expired.

404

Not Found

The requested entity was not found. Entities are bound to companies. Ensure the entity belongs to the company.

405

Method Not Allowed

HTTP Verb is not specified or incorrect verb is used.

Or The user does not have access to the specified method. This applies to invited users.

409

Conflict

When attempting to delete an item that is currently in use.

415

Incorrect or Missing Content-Type header

A valid Content-Type header such as application/json is required on all requests.

429

Request Limit Reached

The limit of 100 requests per minute per company is exceeded or more there are more than 20 failed login attempts.

Requests per Minute

A limit of 100 requests can be made per minute per company. If this request limit is exceeded, the API will return HTTP 429 (Request Limit Reached) with the message “Your IP address has exceeded the allowed number of transactions per minute and has been blocked for 1 hour”. Your IP address will be blocked for 1 hour. It is advisable to make no more than one request per second to avoid this.

Failed Login Attempts

A limit of 20 failed login attempts can be made per hour through the API. If this request limit is exceeded, the API will return HTTP 429 (Request Limit Reached) with the message “Your Username has exceeded the allowed number of login attempts and has been blocked for 24 hours”. The Username will be blocked for 24 hours.

Encountering a rate limit

Accounts are temporarily blocked if a request limit is exceeded. Accounts will be blocked based on the API Key, Company Id and User. Being blocked in one company will not block you from making calls in other companies.

Accounts are automatically unblocked within an hour. Do not continue to make requests as this may extended the blocking period.

If you encounter a limit, do not continue to make requests as this may extend the blocking period. Queue Requests until the block is lifted.

500

Internal Sever Error

A server side error occurred.

503

Service Unavailable

The service is unavailable due to scheduled maintenance.

API Authentication

This API uses basic webforms authentication. To authenticate a user prior to calling a method, you will need to add a standard HTTP authorization header to the request.

This will require the username and password, separated by a colon(:) and Base64 encoded.

Here is an example:

Username: [email protected]
Password: Password123

Authorization header: Basic ZGVtb0BwYXN0ZWxteW1vbmV5LmNvLnphOlBhc3N3b3JkMTIz

API Methods
Save Methods

The save method requires that the request body contains the entity in JSON (XML is not currently supported).

Once validation has been completed, and the entity have been saved, the entity is returned and the new location url is specified as a response header.

Get Methods

Result limit of 100 applies to all queryable methods.

Get() method calls support a subset of the OData protocol.

Supported functions are listed below.

For example, the following Url returns the first three products, ordered by name:
http://[API URL]/api/[ver]/products?$top=3&$orderby=Name

NOTE:
Filter and Orderby will not work for string values of any kind. Specific methods are exposed to allow querying on string values where applicable.

Pagination

All arrays of objects that get returned are wrapped with the total count for the relevant query and the number of returned results in the current call.

The Get methods support pagination by using the skip and top key works in the url. If no default order clause is specified, you will need to provide one.

  • Examples of call where you supply the sort order:
    • http://[API URL]/api/[ver]/customer/Get?$skip=2&$top=20&$orderby=ID&apikey=39478ac6-ac2a-44d8-a31c-7e7e14af4de3& companyid=1
    •  http://[API URL]/api/[ver]/customer/Get?$skip=40&$top=2&$orderby=ID&apikey=39478ac6-ac2a-44d8-a31c-7e7e14af4de3& companyid=1
  • Examples of call without the sort order:
    • http://[API URL]/api/[ver]/Customer/Get?$skip=2&$top=20&apikey=39478ac6-ac2a-44d8-a31c-7e7e14af4de3& companyid=1
    • http://[API URL]/api/[ver]/Customer/Get?$skip=40&$top=2&apikey=39478ac6-ac2a-44d8-a31c-7e7e14af4de3&companyid=1
Delete Methods

Delete operation will only be allowed if no other item/entity or transaction is making use of the item trying to be deleted.

API Samples

These samples cannot be used as they are not suitable for production code.

C# Sample

       //NB: This is not production Code
        static void Main(string[] args)
        {
            string baseUrl = "http://[API URL]/api/[ver]/";

            string apikey = "xxx-xxx";
            int companyId = 0;
            string userName = "[email protected]";
            string password = "xx";

            var requestUrl = baseUrl + "customer/get?APIKey=" + apikey + "&companyid=" + companyId;

            var req = WebRequest.Create(requestUrl);

            //Option 1 to authenticate 
            req.Credentials = new NetworkCredential(userName, password);

            //Option 2 to authenticate 
            //string encodedCredentials;
            //encodedCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(myBusinessUserName + ":" + myBusinessPassword));
            //req.Headers.Add("Authorization", "Basic " + encodedCredentials);

            req.Method = "GET";

            try
            {
                var response = req.GetResponse();

                if (response != null)
                {
                    var responseStream = response.GetResponseStream();
                    if (responseStream != null)
                    {
                        var resultString = new StreamReader(responseStream).ReadToEnd();

                        var retrievedData = "Data: " + resultString + Environment.NewLine;
                        Console.WriteLine(retrievedData);
                    }
                }
            }
            catch (WebException ex)
            {
                HttpWebResponse errorResponse = ex.Response as HttpWebResponse;
                Console.WriteLine("StatusCode: " + errorResponse.StatusCode);
                Console.WriteLine("StatusMessage: " + errorResponse.StatusDescription);
            }
            Console.Read();
        }

Javascript / JqQuery Sample


     var baseUrl = 'http://[API URL]/api/[ver]/';

    function getAuthorisation() {
        return "Basic " + $.base64Encode($('#txtUsername').val() + ":" + $('#txtPassword').val());
    }

    function getCompanyId() {
        return $('#txtCompanyId').val();
    }

    function getAPIKey() {
        return $('#txtApiKey').val();
    }

    function GetTransactions() {
        $.support.cors = true;

        $.ajax({
            type: "GET",
            contentType: "application/json; charset=utf-8",
            url: baseUrl + "/customer/Get?apikey=" + getAPIKey() + "&companyid=" +
                 getCompanyId(),
            beforeSend: function (xhr) {
                xhr.setRequestHeader("Authorization", getAuthorisation());
            },
            success: function (data) {
                //Do something
            },
            error: function (data) {
                //Do something else
            }
        });
    }
                        
Request Limits
Requests per Minute

A limit of 100 requests can be made per minute per company. If this request limit is exceeded, the API will return HTTP 429 (Request Limit Reached) with the message “Your IP address has exceeded the allowed number of transactions per minute and has been blocked for 1 hour”. Your IP address will be blocked for 1 hour. It is advisable to make no more than one request per second to avoid this.

Failed Login Attempts

A limit of 20 failed login attempts can be made per hour through the API. If this request limit is exceeded, the API will return HTTP 429 (Request Limit Reached) with the message “Your Username has exceeded the allowed number of login attempts and has been blocked for 24 hours”. The Username will be blocked for 24 hours.

Encountering a rate limit

Accounts are temporarily blocked if a request limit is exceeded. Accounts will be blocked based on the API Key, Company Id and User. Being blocked in one company will not block you from making calls in other companies.

Accounts are automatically unblocked within an hour. Do not continue to make requests as this may extended the blocking period.

If you encounter a limit, do not continue to make requests as this may extend the blocking period. Queue Requests until the block is lifted.

Request Limit FAQ
What if I need more than 100 calls a minute?

Quite often, applications that you might believe would exceed the usage limits, can in fact work within the limits by analysing how the API is being utilized.

A local data cache can be maintained and synchronised using the various OData calls available together with the Modified and Created properties available in the API.

It is also recommended that requests be queued so that limits are locally enforced.

What is the best way to handle requests on my side?

It is recommended that applications queue requests to the Accounting API. This will allow you to ensure requests are within the supported limits, and will also allow your application to function even in the event that it cannot reach the Accounting API temporarily.

What if I need to retrieve large amounts of data from Accounting?

One function which can cause an application to exceed the usage limits is extracting data from Accounting.

Although a default paging limit of 100 is applied to all API keys, this limit can be adjusted reducing the number of calls required to retrieve data.

Does my application only have 100 requests per minute for all my users?

No, limits are per user and per company, if multiple users are making use of your application limits are handled accordingly.

What if my application still cannot function correctly within the API Usage Limits?

While the current API limits are not flexible, we can advise on making calls more efficient. Click here to contact us.