API Overview

REST services

Our services are REST services which means that we use http as transport protocol. It is what it is, all of the services are proprietary. This has its advantages and disadvantages. Our development cycle is quite short so adding new resources happens every week.

We apologize in advance, most of the services are lacking any explanation whatsoever. This is an ongoing process and hopefully we’ll have a completely documented api next year. (This statement is valid every year ;))

The other articles in this section explain the general workings and behaviour. The actual APIs can be found here:


We have three different environments. development is used for developing your connector. The url for this is https://api-development.ons.io.

Staging is used to test your connector against using the test environment of the customer. The url for this environment is https://api-staging.ons.io

Production can be contacted through https://api.ons.io.


In the past, Ons API was offered in different contexts resulting in different base paths. Only the technical context, with base path /t/ is being used now. For backwards compatability, all endpoints must still be prepended with the /t/ base path (except for the /ping endpoint). Thus, the /clients/{id} endpoint on development will look like api-development.ons.io/t/clients/3.

HTTP Methods

Our APIs support the REST verbs as expected.


Used to retrieve resources and related data. Query parameters are used to select a sub-set or apply some sort of filtering. Query parameters are almost always optional. Requests do not change server state. Common urls include:

/resource                             #request all entries
/resource/42                          #request a particular entry
/resource/42/sub_resource             #request all entries related to an entry
/resource/x-stream-connect/data.xml   #request all entries in a streaming matter


Used to create new resources or perform some kind of action. POST requests are also used when sensitive data is transferred (like a login). For a 200 return status thee same resource is returned with some updated fields. Requests change server state.

/resource                     #create a new resource
/resource/42/sub_resource     #create a new sub-resource for resource
/resource/42/action           #perform action for resource


Used to update an existing resource. Same stuff for POST applies for PUT.

/resource/42                  #update resource


Removes a particular resource or removes a relation between resources.

/resource/42                  #delete resource


For each http request a bunch of headers can be added. For our APIs only three headers are required or of interest.


This header is required and defines the returned format. For most cases requesting json or xml will be enough. Some APIs return octet-streams (bytes) and the /ping returns text/plain. If you request something that can’t be given, you’ll receive a 406 status code. You can enter multiple formats. The first one indicates your preference. Weights should also be supported.

Accept: application/json,application/xml


Required for POST and PUT calls. This header indicates the format used in the http body. You can only have one. The charset is optional but recommended.

Content-Type: application/xml;charset=utf-8


The User-Agent header is optional but it would help us to identify your requests when something goes wrong.

User-Agent: connector/1.1+http://your-domain.com

Where connector can be replaced with the name of your connector.

HTTP Response codes

Below you can find a table with http response codes you can expect.

Status Text Description
200 OK GET: valid response with your requested data in the response body. POST/PUT: valid response with your given resource enriched with some extra data in the response body.
201 Created POST: object created, response has no body. There’s a Location header with the path where you can find the resource.
202 Accepted PUT: changes are accepted, no response body.
204 No Content POST: used for actions which were successful. GET: resource requested had no content.
400 Bad request GET: the combination of query params is invalid. POST/PUT: the given content is incorrect. You’ll receive an ErrorResponse body indicating what was wrong.
401 Unauthorized You have insufficient rights to access the resource
402 Payment required Reserved for future use
403 Forbidden Authentication unsuccessful
404 Not found The requested resource was not found
406 Not acceptable Wrong Accept header
409 Conflict POST: The given resource already exists or was changed by another call
423 Locked GET: The given resource is not yet ready. This is the case for delayed jobs that take some time to process.
429 Too many requests You are being rate limited
500 Internal server error Something blew up on our side. We most likely got an error report, but it doesn’t hurt to report it.
502 Bad gateway invalid upstream, this happens during updates
503 Service unavailable A service is down, this happens during updates.
504 Gateway timeout A timeout somewhere in our infrastructure. This could happen due to updates or when our network is congested. It can also happen when your network is congested or broken.

Rate limiting

Currently we limit requests per connector to the following:

  • 4 requests in parallel
  • 100 requests per second
  • 10.000 seconds of request time per day

The latest is measured as a sum for all requests being done. This can be 100.000 requests that take 100 milliseconds each or 1 request that takes 10.000 seconds. This is currently not enforced but will be in the future. If you go over the limit, you’ll receive a 429 status code.


All of our APIs do not have versions. We rather rely on marking resources as deprecated and adding resources without notice. This means that you have to be prepared for models getting extra fields. Strict xml validation will fail when applied.

The reason for abandoning versions is quite simple. Given our way of working and fast release cycle, we would have to release a version every week for additional APIs and models. Resources that are removed are problematic in the way that mapping a new structure on an old one is not always possible which could result in the same structure for a model but with empty fields. Versions or no versions, action from you is required either way.

Keep an eye on the deprecation article and be prepared to adjust your connector.