OpenAPI Download API

General concepts

Standards

This API is build using industry standards like REST, JSON, OAuth2 (ClientCredentials) and OpenAPI. Before using this API we suggest you read up on these subjects.

Resource selection

All GET methods accept the optional "fields" parameter. This is a comma separated string of field names to select. You should always specify which fields you want to retrieve and only retrieve the fields you need. This can dramatically improve the response time and size. Combine this functionality with resource expansion, using parentheses, to retrieve the exact data you need in every situation. e.g. use /api/products/1?fields=id,description&expand=categories(id,description) to only select the product id and description with the id and description of the products categories.

Resource expansion

All GET methods accept the optional "expand" parameter. This is a comma separated string of field names to expand. Prefer expansion over an extra api call when available and required. e.g. use /api/products/1?expand=fields instead of /api/products/1 + /api/products/1/fields. Use nested resources to load extra data on demand when possible. e.g. call /api/products/1 for an initial product page and call /api/products/1/fields async when the user clicked "show more data.." Only expand what you need, when retrieving a list of orders for a specific customer, do not expand this with customer because then you will get the same customerdata for each order.
In short; Do use Expand to prevent multiple calls, but only if it does not retrieve more data than you need. In order to limit the size of the requested responses there is a maximum expand depth of 5. Not all resources have expansion-options, check the resource contracts or the specific documentation to find which options you have to expand.
You can also expand on an expanded resource, for example when retrieving a customer order with lines, and you also need the productnumber for the given lines use: /api/customer-orders/1?expand=orderlines(id, quantity, product(number)). Note the open and closing parentheses for each resource you expand.
When expanding over multiple levels, you have to specify all fields you need otherwise only the expanded resource on the lowest level is returned. For example /api/customer-orders/1?expand=orderlines(id,quantity,product(number)) without the id and quantity would only return the product number, and nothing else from the orderline.

Resource filtering

Some GET methods accept filter parameters within the optional expand parameters. These filters can be applied by using a '$' mark as prefix, and will not have impact on the provided fields in the expand. The logic behind each filter is explained in the corresponding endpoint documentation, because this is very dependent on the type of data that is retrieved. Example:/api/products/1?expand=discounts($startDateTime=2022-10-20T08:07:20.212Z,$endDateTime=2022-10-25T08:07:20.212Z,$categories=[MixMatch,Product])

Backwards compatibility

The services are backwards compatible, new versions will not break existing endpoint. It is, however, possible new fields will be added to contracts. To prevent performance decrease, use Resource Selection to make sure you only retrieve data you need.
Parameters can also be added in new versions, but these will be optional. Fields with limited possible values can also be extended with new possible values.
Use defensive programming techniques to prevent issues.

StoreId

Most methods accept the optional "storeId" parameter to limit the response data to the given store. Also, a StoreId can be provided by adding header "X-Store-Id" to the request. The StoreId parameter takes precedence over the header. If both parameter and header left empty the StoreId linked to your API Key is used. Many (parts of) resources, like a product's price, can be specified on store-level, which means this parameter can greatly impact the response data. The StoreId is also used on the 'expanded' resources. StoreId is also a property on different (result)-contracts, in some cases this property is nullable. If it does not have a value, this means the object is the fallback value if no specific store has a value.

Localization

Most methods accept the optional "locale" parameter to localize the response data when available.
Currently supported values are nl-NL, fr-FR, de-DE and en-GB, if left empty the default language is used. The locale is also used on 'expanded' resources.

PATCH requests

PATCH requests are used to update objects. Every object should be updated separately, 'expanded' objects are not updated. Only non-null value will be updated, unless specified otherwise by the documentation. Only send the properties you actually want to change, even Required fields can be omitted in PATCH requests

POST requests

POST requests are used to create objects. Some 'expanded' resources can be created in one request. For example a Customer with CustomerContacts can be created at once, the documentation will tell you which resources can be expanded.

Paging

When you retrieve lists of objects, most methods support paging. This means you can use the following parameters to specify which items you want to return. In most cases the objects are ordered by id, sometimes it's on a date field. In that case you also have 'start' and 'end' date filters.

Response time (and size) is linked to the amount of objects you retrieve. Retrieving 50 products should not be a problem, but if you expand them with a lot of subresources we advise you to lower the 'limit'.

Ordering

Some endpoints allow ordering by using the OrderBy parameter. This parameter allows asceding (ASC) and descending (DESC) ordering by adding ASC or DESC after the fieldname. Ascending ordering is the default when no ordering is specified.

Default values

When retrieving objects, properties are only returned when the value is not the default value of the property type. For example: properties of type String are not returned when the value is null, and properties of type Int are not returned when the value is 0.

Responses

Unless specified otherwise you can expect the following status codes responses:
200 OK: The resource is found. Or in case of PATCH and DELETE requests, the resource is successfully updated or deleted.
201 Created: In case of POST requests, the resource is successfully created. The body will contain the new id.
400 Bad Request: The request is invalid, this can be caused by invalid parameters but also for trying to retrieve subresources of a resource that does not exist or you do not have access to.
403 Forbidden: The endpoint you are trying to use is not accessible for the clientId you're using. Contact us if you need to use it.
404 Not Found: The main resource is not found.
429 Too many requests: Some requests can only be executed once at a time, when this status returns you should try again after a minute or more. The documentation will show on which requests this could happen.
500 Internal Server Error: Only happens when something is wrong on our side. The body will contain an unique errorId which you can send to us to find out what happened. You should also sent us the complete request if possible.

Dates and times

All datetime fields are returned in the following format: 2019-01-15T11:36:02.617Z
Values ending with a "Z" are UTC(+0) date times. Other values can be treated as timezone independent.
Incomming datetimes are always treated as Utc+0 as this format does not support timezone information.
Please note that datetimes may have a 3.33 milliseconds deviation.
For example, a provided date of 0001-01-01T23:59:59.999 may be rounded up to 0001-01-02T00:00:00.000

Caching

All data retrieved from our services is live data or cached for a limited time (5 minutes or less), unless specified otherwise.
If you do not need live data, please cache the data you retrieve in you own application. Data like web nodes, customer groups, brands, payment methods, price lists and stores will not change frequently, so we advise you to cache this data and not expand this data every time you retrieve, for example, a product.
For example: In most cases it's better to retrieve all brands and cache them for a while, than to expand every request to retrieve products with 'brand'.

File upload

An example cURL for file uploading:

POST /api/customer-order-files/[YOUR_FILE_ID]/upload HTTP/1.1
Host: [YOUR_HOST]
accept: */*
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Authorization: Bearer [YOUR_BEARER_TOKEN]

----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="[YOUR_FILE_LOCATION]"
Content-Type: [YOUR_FILE_CONTENT-TYPE]

(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW