Skip to content

API overview

View as Markdown

The Horizon API lets your own systems work with your Horizon account without someone at a screen: read your orders, shipments, returns, address checks and stock, send new orders in, and download labels and shipping documents. Use it when an ERP, a warehouse system or a script of your own needs that data.

The API cannot spend money or change anything your customers or your stores see. It does not buy labels, refund, issue store credit, move a return through its lifecycle, record tracking scans, or edit or delete an order. Those actions charge your wallet, write to your live store or email your customers, so they stay in the app, where a signed-in person makes them.

What it covers

The reference pages in this section list every endpoint that is supported for integrations, grouped by area:

  • Orders: list, read and export orders, filter values in use, create an order, ask for its tracking to be refreshed, and download the labels and shipping documents an order already has.
  • Shipments: read your shipments, their labels and their tracking events.
  • Returns: read the returns worklist and a return, download a return label that was already bought, and export the list.
  • Address checks: read the check Horizon ran on an order’s delivery address.
  • Inventory: stock per product and location, and your stock locations.

The app itself calls other endpoints as well. They are not part of this reference, and an API key is refused on them.

To hear about changes as they happen instead of polling, register a webhook endpoint: Horizon then sends you a signed POST when a shipment or a return changes. See Webhooks.

Base URL

Every request goes to:

https://api.horizonlogistics.eu

Endpoint paths start with /api/, for example https://api.horizonlogistics.eu/api/orders/. Always use HTTPS.

Authentication

Every request carries an API key. Create one in the app under API keys & webhooks in Settings (see API keys), then send it in either header:

Authorization: Api-Key <your key>
X-API-Key: <your key>

Use one or the other. If you send both, the X-API-Key header is the one that counts.

Terminal window
export HORIZON_API_KEY="paste-your-key-here"
curl https://api.horizonlogistics.eu/api/orders/ \
-H "Authorization: Api-Key $HORIZON_API_KEY"

A key acts for your whole account. It has no scopes: everything in this reference, a key can do for every store and location on the account. Keep keys out of source control, browser code and shared documents, give each integration its own key, and revoke a key the moment you cannot account for it. Authentication and keys covers what a key can and cannot reach.

Requests and responses

  • Send request bodies as JSON, with Content-Type: application/json. The few endpoints that take a file upload say so on their reference page.
  • Responses are JSON.
  • Write clients that ignore fields they do not recognise. Horizon adds fields to responses as the product grows, and a client that rejects an unknown key will break on an ordinary release.

Pagination

List endpoints answer a page at a time. A paginated list looks like this:

{
"count": 1824,
"next": "…",
"previous": null,
"results": [ … ]
}
  • count is the total number of matching items.
  • results holds this page.
  • next and previous are null on the last and first page.
  • Ask for a page with ?page= (starting at 1) and for a different page size with ?page_size=. The server has a maximum page size; asking for more returns the maximum, not an error.
  • Asking for a page past the end answers 404.

To read everything, request page=1, then increase page until next is null. Filters and sorting go in the same query string and stay the same from page to page.

A few lists are short by nature and come back as a plain JSON array without these keys. The reference page for each list endpoint shows which shape it returns.

Errors

Errors use standard HTTP status codes, with a JSON body that explains what went wrong and, for most refusals, a machine-readable code. See Errors for the shapes and the codes you are most likely to meet.

Rate limiting

Horizon limits how many requests an account can make in a period. Requests made with your keys count together with the account owner’s own use of the app. When you go over, the API answers 429 Too Many Requests with:

  • a Retry-After header giving the number of seconds to wait, and
  • a body with "code": "throttled" and the same wait in retry_after.

Wait at least that long before retrying. Some endpoints have tighter limits of their own; they answer the same way. Spread bulk jobs out rather than sending them in one burst.

Versioning

There is no global API version. Apart from the v1 in the shipping endpoints’ paths, URLs carry no version number, and there is no version header to send. The reference pages are generated from Horizon’s code, so they describe what the API does today rather than a frozen contract. Horizon adds endpoints and response fields over time: build your client to tolerate additions, and check the reference when you change your integration.

The OpenAPI file

The reference is also available as a single OpenAPI file at /openapi/horizon-api.yaml on this site. Load it into an API client or a code generator to get every supported endpoint, parameter and schema in one place.