Qargo TMS API (1.2.0)
For support, please contact success@qargo.com.
Fleet dispatch and subcontractor-specific endpoints for transportation management.
Customer portal endpoints for order tracking, status monitoring, and customer-facing operations.
The api requires oauth2 authentication with client id/secret. This should only be used for service to service communication.
Application client credentials can be created by users with the Super admin role in the Qargo application. Users can create and remove application clients by navigating to Configuration -> Organisation Settings (API clients sections).
Applications need to be linked to a valid integration id, identifying the Qargo approved integrator. Please contact us if you don't have an id yet.
To interact with the API, you need a valid access token in JWT (JSON Web Token) format. This token authenticates your requests and authorizes access to protected endpoints. The process involves using Basic Authentication to request the token via the /auth/token endpoint.
The /auth/token endpoint can be used to generate an access token (JWT):
This token will need to be refreshed after expiration (we provide the 'expires_in' in the token response to check validity).
Basic Authentication is a simple HTTP authentication scheme that allows clients to provide credentials (such as a client ID and secret) directly in the request header. It works by encoding the credentials in Base64 and including them in the Authorization header of the HTTP request. For example:
- Format:
Authorization: Basic <base64-encoded-credentials> - Credentials Encoding: The client ID and secret are concatenated with a colon (e.g.,
client_id:secret_id) and then Base64-encoded.
- Method: POST
- URL:
https://api.qargo.com/v1/auth/token - Headers:
Content-Type: application/jsonAuthorization: Basic <base64-encoded-client_id:secret_id>
- Body: Empty.
- Parameters: None.
Example using curl:
curl -XPOST https://api.qargo.com/v1/auth/token -H 'Content-type: application/json' -u '<client_id:secret_id>'Important: Webhook endpoints use a different authentication method than regular API endpoints. Do not use OAuth tokens for webhooks.
Qargo webhooks, such as those for order import and status updates, use Basic Authentication instead of OAuth. See Understanding Basic Authentication for details on the Basic Auth scheme.
Webhook credentials (client id and secret id) are provisioned by Qargo when your webhook integration is configured — contact success@qargo.com to obtain them. They are separate from your API credentials and must be used exclusively for webhook endpoints.
| API endpoints | Webhook endpoints | |
|---|---|---|
| Auth method | OAuth2 (Client Credentials) | Basic Authentication |
| Credentials | API client_id + secret_id → Bearer JWT token | Webhook client_id + secret_id (directly in header) |
| Header format | Authorization: Bearer <jwt_token> | Authorization: Basic <base64(client_id:secret_id)> |
| Where to find credentials | Configuration → Organisation Settings → API clients | Provisioned by Qargo — contact success@qargo.com |
| Token refresh needed? | Yes (JWT expires) | No (credentials sent with each request) |
To maintain API stability and prevent abuse, we enforce rate limits on a per-tenant basis.
The limits below are estimates based on normal operating conditions. Under increased system load, these limits may be tightened without prior notice to protect API stability.
| Category | Scope | Limit |
|---|---|---|
| Authentication | /auth/token | 5 requests per hour |
| General API Usage | All endpoints except authentication and webhooks | 2 requests per second (sustained); up to 3 per second (bursts) |
Rate limits are enforced by tracking requests over several sliding time windows-per second, per 10 minutes, and per hour. Exceeding any of these limits will result in an HTTP 429 Too Many Requests response. The response includes a Retry-After header specifying the number of seconds your application should wait before making a new request.
Example response:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 58
{"error":"Rate limit exceeded"}Applications must handle this response correctly by treating Retry-After as the minimum delay, regardless of whether the request appeared to be within the estimated limits. If multiple workers or processes can make requests for the same tenant, add a small positive random delay (jitter) after Retry-After before retrying. Never subtract jitter or retry earlier than indicated. If another 429 response is returned, repeat this process using the latest Retry-After value.
For any concerns about these limits, please contact us at success@qargo.com.
This section outlines recommended practices for efficiently working with the Qargo API.
- Initial request: Make a request to a paginated endpoint without a
cursorparameter. - Process the response: Read the current page from
items. - Subsequent requests: If
next_cursoris notnull, pass its value as thecursorparameter in the next request. - Stop: Repeat until
next_cursorisnull.
GET /v1/resources/resourceResponse:
{
"items": [
{
"name": "Truck 142",
"row_id": "3f9e6b1c-3333-4d2e-b1a4-7c8f9e0a1b03"
}
],
"next_cursor": "eyJwYXJhbWV0ZXJzIjp7fSwic3RhdGUiOiJhYmMxMjM0NSIsImN1cnNvcl9zb3J0IjoiMjAyNi0wOC0xMlQxMDowMDowMFoiLCJjdXJzb3JfaWQiOiIzZjllNmIxYy0zMzMzLTRkMmUtYjFhNC03YzhmOWUwYTFiMDMifQ=="
}Next request:
GET /v1/resources/resource?cursor=eyJwYXJhbWV0ZXJzIjp7fSwic3RhdGUiOiJhYmMxMjM0NSIsImN1cnNvcl9zb3J0IjoiMjAyNi0wOC0xMlQxMDowMDowMFoiLCJjdXJzb3JfaWQiOiIzZjllNmIxYy0zMzMzLTRkMmUtYjFhNC03YzhmOWUwYTFiMDMifQ==The next page can be empty. Continue until the response returns next_cursor as null.
The Qargo API follows these backward compatibility principles:
- New fields may be added to response payloads at any time. Adding new fields is not considered a breaking change.
- Integrators should ignore unknown fields when parsing responses. Do not fail on unexpected properties.
- Deprecated fields and endpoints are marked as
deprecatedin this specification. They continue to work but may be removed in a future version. Migrate to the recommended replacement as soon as possible. - Existing fields will not be renamed or removed without prior notice and a deprecation period.
All date and time fields in the API follow ISO 8601:
| Type | Format | Example | Description |
|---|---|---|---|
| Date | YYYY-MM-DD | 2024-12-31 | Calendar date without time component |
| Datetime | YYYY-MM-DDTHH:mm:ssZ | 2024-12-31T14:30:00Z | Timestamp in UTC (indicated by Z suffix) |
| Time | HH:mm | 09:30 | Time of day in 24-hour format |
- Datetime fields are always in UTC. Convert to local time on the client side.
- Date fields have no timezone. They represent a calendar date (e.g. a planned delivery date).
- Time fields are used for time windows (e.g. delivery windows) and are in 24-hour format without seconds.
- A stop is a part of a transport, at a certain date, optional timeslot and location. In addition to the planned times, it also tracks the actual times for a completed stop. Stops can be linked to orders, or can be defined standalone (for example a cleaning stop). All stops are linked to a Trip.
A resource in Qargo is a vehicle, driver, trailer or other entity that can be assigned to a trip.
An unavailability indicates that a specific resource is not available for use for a given time range. An unavailability has a reason to indicate why the resource is not available.
The unavailability endpoints exclude validities and automatically generated planning blocks.
- Make sure you have a Postman client available. This can either be a local installed version or the web based version.
- Request credentials for the Qargo API for order creation
- Download and import the collection
- Set the collection variables username and password with the credentials received
- Execute the Request Access token request in the Authentication folder. You have now a valid access key for 1 hour. If you get the error message that the key is no longer valid, please refresh the access key by invoking this endpoint again.
- You can now explore the different order endpoints
The api exposes the following functionality:
- Order management: create/update and get the status of transport orders.
- Retrieve trip information: retrieve information about Qargo trips.
- Visibility: send events to an external system using webhooks.
- Order dispatch: send transport orders to a 3rd party using webhooks.
- Accounting: interface an accounting system using the api endpoints.
- Documents: interface to download documents
Trips can't be manipulated yet through the api, but it is possible to retrieve trip information. We currently have an endpoint available to retrieve the charge information for a certain endpoint.
You can update the status of stops and stop groups of a trip using a webhook.
Resources this should be used together with the endpoints to fetch unavailabilities as a resource unavailability is linked to a resource.
Resource unavailabilities can be managed through the API. The following operations are supported:
- Creating an unavailability for a resource
- Updating an unavailability for a resource
- Deleting an unavailability for a resource
- Fetching an unavailability for a resource
- Fetching unavailabilities for a resource
These endpoints exclude validities and automatically generated planning blocks.
The goal of these endpoints is to allow external systems to manage the availability of resources in Qargo. An external_id is stored alongside the unavailability to allow for easy linking between the external system and Qargo. This external_id should be provided if a referential link is needed between the external system and Qargo.
See the examples on how to use the unavailability endpoints.
We support visibility (sending messages triggered by Qargo system events) in the api as well. These messages can be send out as a webhook, or an EDI connection.
For most endpoints, visibility only trigger on status changes (for example, from stop IN_PROGRESS -> COMPLETED). There are a few exceptions, these will be indicated in the overview:
- Order level
- We send out a visibility event on
ACCEPTED(order created),REJECTED(order skipped) andCOMPLETED(all stops for order completed).
- We send out a visibility event on
- Stop level
- We send out a visibility event on
AT_STOP(arrived at stop),COMPLETED(all activities completed for stop).
- We send out a visibility event on
- Position level (note: for every telematics update)
- Trip level (not sent by default: requires a custom setup configured by Qargo). Contact success@qargo.com to discuss setting this up.
- We send a visibility event when a trip changes to
PLANNEDand when it transitions toCOMPLETED.
- We send a visibility event when a trip changes to
- Resource level
- We send an event when a resource is assigned to a certain trip.
It is also possible to subcontract trips to other parties. This is possible using two push endpoints:
- Outgoing dispatched trip payload.
- Incoming message format to update subcontracted status.
We offer an interface to download documents. The documents can be fetched using the document endpoints.
Please contact us for inqueries regarding additional api functionality.
This sections details how to construct payloads to create transport orders using the order upload endpoint(/orders/order/upload).
Orders are not created synchronously via the API. When creating orders via the POST /orders/order/upload endpoint, you will receive the following response when creating an order.
{
"upload_id": "<UPLOAD UUID>",
"upload_status": "IN_PROGRESS",
"upload_url": "v1/orders/order/upload/<UPLOAD UUID>",
"order_id": null,
"order_url": null
}You need to store the upload_id so you can fetch the status of the order creation by calling GET /orders/order/upload/<UPLOAD UUID>
Based on the status of the upload (upload_status), you can know if the order is still in the progress of being created or has already been created. Both order_id and order_url will be filled in when the order has been created. The order_id will be filled in with the order id, which can then be used to fetch the order data and status from the system.
Example payload GET /orders/order/upload/e01b3db1-4e49-4241-a91e-7534da884d46 with a created order
{
"upload_id": "e01b3db1-4e49-4241-a91e-7534da884d46",
"upload_status": "COMPLETED",
"upload_url": "v1/orders/order/upload/e01b3db1-4e49-4241-a91e-7534da884d46",
"order_id": "a2a84715-0027-49af-ad30-494c0ccf75cc",
"order_url": "v1/orders/order/a2a84715-0027-49af-ad30-494c0ccf75cc"
}The order_identifier is used to uniquely identify orders that are being created via the API. This means that the same order_identifier needs to be used when updating orders. Multiple identical updates after each other are idempotent and will not fail the request.
The order_identifier main usage is for deduplication, you cannot use the order_identifier to fetch an order.
The first example is a simple transport from our london office to our Ghent office. Please note that the transport service will need to be matched with the one in your system.
{
"operation": "CREATE",
"consignments": [
{
"delivery_stop": {
"date": "2022-05-03",
"location": {
"name": "Qargo Ghent office",
"address": "Gaston Crommenlaan 4",
"postal_code": "9050",
"city": "Ghent",
"country": "BE"
},
"reference_number": "D12345"
},
"pickup_stop": {
"date": "2022-04-21",
"location": {
"name": "Qargo London office",
"address": "71-91 Aldwych",
"postal_code": "WC2B 4HN",
"city": "London",
"country": "UK"
},
"reference_number": "P123456"
}
}
],
"customer_reference_number": "T12345",
"customer": {
"code": "00020"
},
"order_identifier": "T1234393",
"transport_service": {
"name": "General"
}
}Note: it is possible to 'export' existing orders in the api to use as examples/templates. See the Export existing orders section.
The following order is an update of an existing order. Note the UPDATE value of the operation field.
Important remarks:
- Not all the fields of the order can be updated
- the
order_identifierfield is used to identify the order to update
Example of an order update
{
"order_identifier": "QARGO_TEST_0001",
"operation": "UPDATE",
"customer": {
"name": "UPS SCS Coventry"
},
"consignments": [
{
"pickup_stop": {
"location": {
"name": "Qargo HQ",
"address": "Gaston Crommenlaan 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "Qargo HQ building"
},
"note": "Pickup 4 boxes of pasta",
"date": "2024-08-20",
"reference_number": "QACOLLI001",
"planning_instructions": "If closed, call mobile number",
"email": "info@qargo.com",
"phone_number": "+0912341431",
"mobile_number": "+324567890"
},
"delivery_stop": {
"location": {
"name": "Grocery store",
"address": "Resedastraat 20",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "Grocery store"
},
"note": "Don't forget to sign the documents",
"date": "2024-08-21",
"reference_number": "QADELIV001",
"planning_instructions": "Alarm code: 123456",
"email": "info@qargo.com",
"phone_number": "02123456",
"mobile_number": "+329998888"
},
"goods": [
{
"description": "4 boxes of pasta",
"quantity": 4
}
]
}
],
"customer_reference_number": "QARGO_TEST_0001",
"transport_service": {
"code": "CONTAINER_BOOKING"
}
}To cancel an order, pass DELETE as operation value. This will cancel the order. If the order has already been cancelled, this will not result in an error. Executing multiple cancellations is a idempotent operation and will not fail the request.
A cancelled order cannot be uncancelled. If you need to revert the cancel, you will need to recreate the original order using a different order identifier. Using the same order identifier will cause the system to try to update the cancelled order, which results in an error.
{
"operation": "DELETE",
"consignments": [
{
"delivery_stop": {
"date": "2022-05-03",
"location": {
"name": "Qargo Ghent office",
"address": "Gaston Crommenlaan 4",
"postal_code": "9050",
"city": "Ghent",
"country": "BE"
},
"reference_number": "D12345"
},
"pickup_stop": {
"date": "2022-04-21",
"location": {
"name": "Qargo London office",
"address": "71-91 Aldwych",
"postal_code": "WC2B 4HN",
"city": "London",
"country": "UK"
},
"reference_number": "P123456"
}
}
],
"customer_reference_number": "T12345",
"customer": {
"code": "00020"
},
"order_identifier": "T1234393",
"transport_service": {
"name": "General"
}
}It is possible to export a manually created order in the api. We first need to determine the technical id of this order.
.
The order can be exported with the following endpoint: Export order. The output of this endpoint corresponds to the order creation format. Just make sure to use a different order_identifier, otherwise the 'new' order will be interpreted as an update.
With the GET /orders/order/<ORDER UUID> endpoint, you can fetch the data related to the order. This contains the current status of the order along with other data.
This scenario contains of 2 main stops additional optional stops.
- Pickup of a loaded container
- Unload container
- Drop off empty container (Optional, configured in
teardown_stops)
The container_scenario property is set as IMPORT and the drop off location of the container is specified in the the teardown_stops property. The optional teardown_stops describe the stops of the container after the consignment has been completed
Example IMPORT container scenario
{
"order_identifier": "QARGO_TEST_0002",
"operation": "CREATE",
"customer": {
"name": "UPS SCS Coventry"
},
"teardown_stops": [
{
"location": {
"name": "Container yard",
"address": "Scheepzatestraat 1",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE"
},
"note": "Drop off the container on the designated location",
"date": "2024-08-20",
"reference_number": "CONT0001",
"planning_instructions": "Put next to the red container",
"email": "info@qargo.com",
"phone_number": "+0912341431",
"mobile_number": "+324567890"
}
],
"consignments": [
{
"pickup_stop": {
"location": {
"name": "Container pickup location",
"address": "Gaston Crommenlaan 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "This is the container pickup location"
},
"note": "Pick up the green container",
"date": "2024-08-20",
"reference_number": "CONT0002",
"planning_instructions": "Code of the container is 1234",
"email": "info@qargo.com",
"phone_number": "+0912341431",
"mobile_number": "+324567890"
},
"delivery_stop": {
"location": {
"name": "Sports store",
"address": "Resedastraat 20",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "This is the delivery location of the container goods"
},
"note": "1000 boxes of shoes",
"date": "2024-08-21",
"reference_number": "CONT0003",
"planning_instructions": "Use mobile number if gate is closed",
"email": "info@qargo.com",
"phone_number": "02123456",
"mobile_number": "+329998888"
}
}
],
"container": {
"container_scenario": "IMPORT"
},
"customer_reference_number": "QARGO_TEST_0002",
"transport_service": {
"code": "CONTAINERS"
}
}This scenario contains 2 main stops with additional optional stops:
- Pickup empty container (Optional, configured in
setup_stops) - Load empty container
- Drop off loaded container
The container_scenario is set as EXPORT and the setup_stops property allows to define additional optional stops.
Example of an EXPORT container_scenario
{
"order_identifier": "QARGO_TEST_0003",
"operation": "CREATE",
"customer": {
"name": "UPS SCS Coventry"
},
"setup_stops": [
{
"location": {
"name": "Container yard",
"address": "Scheepzatestraat 1",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE"
},
"note": "Pickup empty container on the designated location",
"date": "2024-08-20",
"reference_number": "CONT0001",
"planning_instructions": "Blue container, next to the red container",
"email": "info@qargo.com",
"phone_number": "+0912341431",
"mobile_number": "+324567890"
}
],
"consignments": [
{
"pickup_stop": {
"location": {
"name": "Container loading location",
"address": "Gaston Crommenlaan 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "Qargo HQ, has a container loading bay"
},
"note": "Fill with 1000 boxes of Qargo shirts",
"date": "2024-08-20",
"reference_number": "CONT0002",
"planning_instructions": "Code of the container is 1234",
"email": "info@qargo.com",
"phone_number": "+0912341431",
"mobile_number": "+324567890"
},
"delivery_stop": {
"location": {
"name": "Train station container hub",
"address": "Resedastraat 20",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "This is the dropoff location of the loaded container"
},
"note": "1000 boxes of shoes",
"date": "2024-08-21",
"reference_number": "CONT0003",
"planning_instructions": "Use mobile number if gate is closed",
"email": "info@qargo.com",
"phone_number": "02123456",
"mobile_number": "+329998888"
}
}
],
"container": {
"container_scenario": "EXPORT"
},
"customer_reference_number": "QARGO_TEST_0003",
"transport_service": {
"code": "CONTAINERS"
}
}The following order picks up a filled container, delivers it to our office, and returns the empty container. This examples also demonstrates how to model ADR information.
{
"operation": "CREATE",
"consignments": [
{
"delivery_stop": {
"location": {
"name": "Qargo Ghent office",
"address": "Gaston Crommenlaan 4",
"postal_code": "9050",
"city": "Ghent",
"country": "BE"
},
"note": "unloading address comments",
"reference_number": "D123956"
},
"pickup_stop": {
"location": {
"address": "Europaweg",
"city": "Rotterdam",
"country": "NL",
"name": "APM terminals Maasvlakte II"
},
"reference_number": "P123956"
},
"goods": [
{
"good_items": {
"adr": {
"name": "DISINFECTANT, LIQUID, CORROSIVE, N.O.S.",
"un_number": "1903"
}
},
"ordered_quantity": 100,
"ordered_total_volume_value": 43000,
"packaging_type": {
"code": "PYZ"
}
}
]
}
],
"container_number": "MSCU5285725",
"container_scenario": "IMPORT",
"container_type": {
"code": "22G0"
},
"customer": {
"code": "00083"
},
"customer_reference_number": "C2325995",
"order_identifier": "ord-12332423",
"teardown_input": [
{
"location": {
"address": "Butaanweg 52-54",
"city": "Rotterdam",
"country": "NL",
"name": "OCC Overbeek Cont. Control."
}
}
],
"transport_service": {
"name": "Container"
}
}This example shows how to create a transport that exports a loaded container. The setup section specifies the empty container pickup.
{
"operation": "CREATE",
"consignments": [
{
"delivery_stop": {
"location": {
"address": "Europaweg",
"city": "Rotterdam",
"country": "NL",
"name": "APM terminals Maasvlakte II"
},
"reference_number": "3432423908987"
},
"pickup_stop": {
"location": {
"name": "Qargo Ghent office",
"address": "Gaston Crommenlaan 4",
"postal_code": "9050",
"city": "Ghent",
"country": "BE"
},
"reference_number": "3432441"
},
"goods": [
{
"absolute_max_temperature_value": "-8.0",
"description": "Plastic buckets",
"ordered_quantity": 1500,
"packaging_type": {
"code": "PE"
}
}
]
}
],
"container_number": "MSCU5285725",
"container_scenario": "EXPORT",
"container_type": {
"code": "22RE"
},
"customer": {
"code": "00007"
},
"customer_reference_number": "PUC-888315",
"order_identifier": "d18f8309-0f26-4687-b32b-749008a0cb8e",
"setup_input": [
{
"location": {
"address": "Butaanweg 52-54",
"city": "Rotterdam",
"country": "NL",
"name": "OCC Overbeek Cont. Control."
}
}
],
"transport_service": {
"name": "Container"
}
}In Qargo you can define custom stop actions. These stops can be added to configure additional stops related to the order.
These stops can be defined in the standalone_stops property.
Using standalone_stops to configure stops adds the following requirements to the order:
- Every stop needs to have a unique positive integer assigned to it. This will determine the sequence of the stops in the order.
- Every stops needs to have a
custom_activityassigned to it. This will determine the type of stop that is being added to the order.
Example custom stops for an order
{
"import_configuration": {
"code": "API"
},
"transport_service": {
"code": "YOUR_TRANSPORT_SERVICE_CODE"
},
"customer": {
"code": "CUSTOMER_CODE"
},
"operation": "CREATE",
"order_identifier": "EXT-ORDER-001",
"customer_reference_number": "CUST-REF-001",
"consignments": [
{
"pickup_stop": {
"activity": "PICKUP",
"date": "2026-04-01",
"location": {
"name": "Warehouse Antwerp",
"address": "Kaai 100",
"city": "Antwerp",
"postal_code": "2000",
"country": "BE"
},
"position": {
"optimal": true,
"position": 1
}
},
"delivery_stop": {
"activity": "DELIVERY",
"date": "2026-04-01",
"location": {
"name": "Distribution Center Ghent",
"address": "Industrieweg 50",
"city": "Ghent",
"postal_code": "9000",
"country": "BE"
},
"position": {
"optimal": true,
"position": 3
}
},
"standalone_stops": [
{
"activity": "CUSTOM",
"custom_activity_label": "WEEG",
"date": "2026-04-01",
"location": {
"name": "Weigh Station Mechelen",
"address": "Weegbrug 1",
"city": "Mechelen",
"postal_code": "2800",
"country": "BE"
},
"position": {
"optimal": true,
"position": 2
}
}
],
"goods": [
{
"description": "Palletized goods",
"quantity": 10,
"package_type": "EURO_PALLET",
"total_weight": 5000
}
]
}
]
}Example custom stops for an container order
{
"order_identifier": "QARGO_TEST_0005",
"operation": "CREATE",
"customer": {
"name": "UPS SCS Coventry"
},
"setup_stops": [
{
"location": {
"name": "Stop 1",
"address": "Scheepzatestraat 1",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE"
},
"note": "Stop 1 notes",
"date": "2024-08-20",
"reference_number": "Stop 1 reference number",
"planning_instructions": "Stop 1 instructions",
"email": "info@qargo.com",
"phone_number": "+0912341431",
"mobile_number": "+324567890",
"activity": "COLLECT_EMPTY_CONTAINER",
"position": {
"position": 1
}
}
],
"consignments": [
{
"standalone_stops": [
{
"location": {
"name": "Stop 2",
"address": "Vlierstraat 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "HQ"
},
"note": "Stop 2 notes",
"date": "2024-08-20",
"reference_number": "Stop 2 number",
"planning_instructions": "Stop 2 instructions",
"email": "info@qargo.com",
"phone_number": "+0912341431",
"mobile_number": "+324567890",
"custom_activity": "WEGEN",
"position": {
"position": 2
}
},
{
"location": {
"name": "Stop 6",
"address": "Vlierstraat 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "HQ"
},
"note": "Stop 6 notes",
"date": "2024-08-20",
"reference_number": "Stop 6 number",
"planning_instructions": "Stop 6 instructions",
"email": "info@qargo.com",
"phone_number": "+0912341431",
"mobile_number": "+324567890",
"custom_activity": "WEGEN",
"position": {
"position": 6
}
},
{
"location": {
"name": "Stop 3",
"address": "Corbiestraat 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE"
},
"note": "Stop 3 notes",
"date": "2024-08-22",
"reference_number": "Stop 3 reference number",
"planning_instructions": "Stop 3 instructions",
"email": "info@qargo.com",
"phone_number": "+0912341431",
"mobile_number": "+324567890",
"custom_activity": "INKLAREN",
"position": {
"position": 3
}
}
],
"pickup_stop": {
"location": {
"name": "Stop 4",
"address": "Gaston Crommenlaan 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "HQ"
},
"note": "Stop 4 notes",
"date": "2024-08-20",
"reference_number": "Stop 4 reference number",
"planning_instructions": "Stop 4 instructions",
"email": "info@qargo.com",
"phone_number": "+0912341431",
"mobile_number": "+324567890",
"activity": "PICKUP_EXPORT",
"position": {
"position": 4
}
},
"delivery_stop": {
"location": {
"name": "Stop 5",
"address": "Resedastraat 20",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "Delivery"
},
"note": "Stop 5 notes",
"date": "2024-08-21",
"reference_number": "Stop 5 reference number",
"planning_instructions": "Stop 5 instructions",
"email": "info@qargo.com",
"phone_number": "02123456",
"mobile_number": "+329998888",
"activity": "DELIVERY_EXPORT",
"position": {
"position": 5
}
}
}
],
"container": {
"container_scenario": "EXPORT"
},
"customer_reference_number": "QARGO_TEST_0005",
"transport_service": {
"code": "CONTAINER_BOOKING"
}
}{
"order_identifier": "DEFAULT_ORDER",
"operation": "CREATE",
"customer": { "name": "Qargo" },
"import_configuration": { "code": "API" },
"consignments": [
{
"pickup_stop": {
"location": {
"name": "Qargo",
"address": "Gaston Crommenlaan 4",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "HQ"
},
"note": "Collection notes",
"date": "2024-07-19",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
},
"delivery_stop": {
"location": {
"name": "Qargo London",
"address": "71-91 Aldwych",
"postal_code": "WC2B 4HN",
"city": "London",
"country": "GB",
"description": "Delivery"
},
"note": "Delivery notes",
"date": "2024-07-19",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
},
"goods": [{ "quantity": 1 }]
}
],
"customer_reference_number": "QARGO-123",
"transport_service": { "code": "QARGO" },
"service_level": { "code": "QARGO_NEXT_DAY" }
}{
"order_identifier": "CONTAINER_IMPORT_ORDER",
"operation": "CREATE",
"customer": { "name": "QARGO" },
"import_configuration": { "code": "API" },
"teardown_stops": [
{
"location": {
"name": "Ghent Container Yard",
"address": "Scheepzatestraat 1",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE"
},
"note": "Empty container drop-off",
"date": "2024-08-24",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
}
],
"consignments": [
{
"pickup_stop": {
"location": {
"name": "Qargo Ghent",
"address": "Gaston Crommenlaan 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": ""
},
"note": "",
"date": "2024-08-20",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
},
"delivery_stop": {
"location": {
"name": "Qargo London",
"address": "71-91 Aldwych",
"postal_code": "WC2B 4HN",
"city": "London",
"country": "GB",
"description": "Delivery"
},
"note": "Delivery notes",
"date": "2024-08-22",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
}
}
],
"container": { "container_scenario": "IMPORT", "seal_number": "SEAL12345" },
"customer_reference_number": "QARGO-01",
"transport_service": { "code": "CONTAINER_TRANSPORT_SERVICE" }
}{
"order_identifier": "CONTAINER_EXPORT_ORDER",
"operation": "CREATE",
"customer": { "name": "QARGO" },
"import_configuration": { "code": "API" },
"setup_stops": [
{
"location": {
"name": "Ghent Container Yard",
"address": "Scheepzatestraat 1",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE"
},
"note": "Empty container pickup location",
"date": "2024-08-20",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
}
],
"consignments": [
{
"pickup_stop": {
"location": {
"name": "Qargo Ghent",
"address": "Gaston Crommenlaan 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": ""
},
"note": "",
"date": "2024-08-20",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
},
"delivery_stop": {
"location": {
"name": "Qargo London",
"address": "71-91 Aldwych",
"postal_code": "WC2B 4HN",
"city": "London",
"country": "GB",
"description": "Delivery"
},
"note": "Delivery notes",
"date": "2024-08-22",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
}
}
],
"container": { "container_scenario": "EXPORT", "seal_number": "SEAL12345" },
"customer_reference_number": "QARGO-00003",
"transport_service": { "code": "CONTAINER_TRANSPORT_SERVICE" }
}{
"order_identifier": "MULTIPLE_STOPS_ORDER",
"operation": "CREATE",
"customer": { "name": "QARGO" },
"consignments": [
{
"standalone_stops": [
{
"location": {
"name": "Customs Ghent",
"address": "Sint-Lievenslaan 27",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "Customs office location"
},
"note": "",
"date": "2024-08-20",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": "",
"custom_activity": "CUSTOMS",
"position": { "position": 1 }
},
{
"location": {
"name": "Truck weight station",
"address": "Belgicastraat 10",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": "HQ"
},
"note": "",
"date": "2024-08-20",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": "",
"custom_activity": "WEIGHT_STATION",
"position": { "position": 2 }
},
{
"location": {
"name": "Truckwash Ghent",
"address": "Traktaatweg 23",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE"
},
"note": "",
"date": "2024-08-23",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": "",
"custom_activity": "WASHING",
"position": { "position": 5 }
}
],
"pickup_stop": {
"location": {
"name": "Qargo Ghent",
"address": "Gaston Crommenlaan 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": ""
},
"note": "",
"date": "2024-08-20",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": "",
"activity": "PICKUP",
"position": { "position": 3 }
},
"delivery_stop": {
"location": {
"name": "Qargo London",
"address": "71-91 Aldwych",
"postal_code": "WC2B 4HN",
"city": "London",
"country": "GB",
"description": "Delivery"
},
"note": "Delivery notes",
"date": "2024-08-22",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": "",
"activity": "DELIVERY",
"position": { "position": 4 }
}
}
],
"customer_reference_number": "QARGO_001",
"transport_service": { "code": "FULL_LOADS" }
}technical_name_by_locale is writable; use it to provide localized technical names for the dangerous goods. Each key must be a supported locale code, and each value is the technical name for that locale. adr_name_by_locale is read-only; the API generates this field automatically and ignores any submitted value. The example below provides technical names for four locales.
{
"order_identifier": "DANGEROUS_GOODS_ORDER",
"operation": "CREATE",
"customer": { "name": "QARGO" },
"import_configuration": { "code": "API" },
"consignments": [
{
"pickup_stop": {
"location": {
"name": "Qargo Ghent",
"address": "Gaston Crommenlaan 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": ""
},
"note": "",
"date": "2024-08-20",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
},
"delivery_stop": {
"location": {
"name": "Qargo London",
"address": "71-91 Aldwych",
"postal_code": "WC2B 4HN",
"city": "London",
"country": "GB",
"description": "Delivery"
},
"note": "Delivery notes",
"date": "2024-08-22",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
},
"goods": [
{
"packaged_items": [
{
"adr": {
"un_number": "1956",
"packaging_type": "BOX",
"emergency_phone_number": "+32456789010",
"technical_name_by_locale": {
"de-DE": "NEG Stoffname",
"en": "NEG Substance name",
"fr-FR": "NEG Nom de la substance",
"nl-BE": "NEG Stofnaam"
}
},
"quantity": 5,
"total_volume_l": 100,
"total_weight_kg": 100,
"description": "Dangerous and flammable goods"
}
],
"description": "Fuel",
"quantity": 1,
"product_name": "FUEL"
}
]
}
],
"customer_reference_number": "QARGO-001",
"transport_service": { "code": "HAZARDOUS" },
"service_level": { "code": "NEXT_DAY" }
}{
"order_identifier": "PALLETS_WITH_BARCODES_ORDER",
"operation": "CREATE",
"customer": { "name": "QARGO" },
"import_configuration": { "code": "API" },
"consignments": [
{
"pickup_stop": {
"location": {
"name": "Qargo Ghent",
"address": "Gaston Crommenlaan 4,",
"postal_code": "9000",
"city": "Gent",
"state": "Oost-Vlaanderen",
"country": "BE",
"description": ""
},
"note": "",
"date": "2024-08-20",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
},
"delivery_stop": {
"location": {
"name": "Qargo London",
"address": "71-91 Aldwych",
"postal_code": "WC2B 4HN",
"city": "London",
"country": "GB",
"description": "Delivery"
},
"note": "Delivery notes",
"date": "2024-08-22",
"reference_number": "",
"planning_instructions": "",
"email": "",
"phone_number": "",
"mobile_number": ""
},
"goods": [
{
"quantity": 1,
"packaging_type": {
"name": "Full Pallet",
"packaging_size": { "code": "FP" }
},
"handling_units": [
{ "barcode": { "value": "01J93R8V517R7133FVCM3ZCJNN" } }
]
},
{
"quantity": 2,
"packaging_type": {
"name": "Half Pallet",
"packaging_size": { "code": "HP" }
},
"handling_units": [
{ "barcode": { "value": "01J93R9024CNTJJPQG8WDP2PVX" } },
{ "barcode": { "value": "01J93R9PKY3A5C9S6T4VV12C8B" } }
]
}
]
}
],
"customer_reference_number": "QARGO-0001",
"transport_service": { "code": "PALLETS" },
"service_level": { "code": "PREMIUM_NEXT_DAY" }
}The API supports status updates for specific entities. This can either be via an endpoint or webhook.
This endpoint allows you to update the status of a task. A task in Qargo is linked to a side effect in an external system.
This webhook allows you to either update:
- stops
- stop groups
Using this webhook you can provide status updates for stops or stop groups. You can also provide additional information in the payload which can be mapped to different fields in Qargo. Status update date-time values, including event_time, eta_start, and eta_end, must include a timezone offset such as Z or +02:00.
This webhook allows an external intermodal booking system to report status updates for a booking, including its lifecycle status, execution statuses, and estimated and actual stop times. Date-time values must include a timezone offset such as Z or +02:00.
We support visibility (sending messages triggered by Qargo system events) in the api as well. These messages can be send out as a webhook, or an EDI connection.
For most endpoints, visibility only trigger on status changes (for example, from stop IN_PROGRESS -> COMPLETED). There are a few exceptions, these will be indicated in the overview:
- Order level
- We send out a visibility event on
ACCEPTED(order created),REJECTED(order skipped) andCOMPLETED(all stops for order completed).
- We send out a visibility event on
- Stop level
- We send out a visibility event on
AT_STOP(arrived at stop),COMPLETED(all activities completed for stop).
- We send out a visibility event on
- Position level (note: for every telematics update)
- Trip level (not sent by default: requires a custom setup configured by Qargo). Contact success@qargo.com to discuss setting this up.
- We send a visibility event when a trip changes to
PLANNEDand when it transitions toCOMPLETED.
- We send a visibility event when a trip changes to
- Resource level
- We send an event when a resource is assigned to a certain trip.
The following section details how to use our api for accounting integrations. You can push/pull accounting information between Qargo and the accounting system.
Please note that this is not suitable for BI/analytics purposes. We offer a SQL based data warehouse connector to support this use case.
The flow for sales/purchase invoices and sales credit notes is the same, with a different payload. We will show an example of syncing a sales invoices below
We use a task oriented approach to indicate which invoice to sync (post in the accounting software). The implementer should take the following steps:
- Fetch a list of available tasks (tasks in a TODO state)
- For each available task:
- Fetch the payload in the task details
- Sync the data to the accounting system.
- Report the status back, this result can be success or failure.
It is allowed to only process a subset of the available tasks and process the remaining invoices later.
Fetch the Invoice/Credit notes to sync using sync tasks endpoint
curl https://api.qargo.com/v1/accounting/sync-tasks -H 'Content-type: application/json' -H 'Authorization: Bearer *access_token*'Response:
{ "tasks": [{ "id": "*id_of_first_task*" }] }Note that as long as an endpoint is not marked as completed/failed, it will still show up as an available POST task.
Fetch the first payload:
curl https://api.qargo.com/v1/accounting/sync-tasks/*id_of_first_task* -H 'Content-type: application/json' -H 'Authorization: Bearer *access_token*'
Response:
{"id": "", "status": "TODO", "task_type": "POST_INVOICE", "payload": {....}}
curl https://api.qargo.com/v1/company/*id_of_customer* -H 'Content-type: application/json' -H 'Authorization: Bearer *access_token*'Response:
{"id": "<id_of_customer>", ...}Note: since we embed the customer/supplier company in the invoice payload, it is possible to synchronise these companies as part of the invoice posting flow.
curl -X PATCH https://api.qargo.com/v1/company/*id_of_customer* -H 'Content-type: application/json' -H 'Authorization: Bearer *access_token*' -d '{"contacts":[{"name":"Contact name","note":"Notes on the contact","phone_number":"+32456789016","email":"hello@qargo.com","roles":["BILLING","OPERATIONS"]}]}'curl -X PATCH https://api.qargo.com/v1/company/*id_of_customer* -H 'Content-type: application/json' -H 'Authorization: Bearer *access_token*' -d '{"id": "3ba86d22-0183-4575-804d-60e0a6fa2f74", "contacts":[{"name":"Contact name","note":"Notes on the contact","phone_number":"+32456789016","email":"hello@qargo.com","roles":["BILLING","OPERATIONS"]}]}'curl -X PATCH https://api.qargo.com/v1/company/*id_of_customer* -H 'Content-type: application/json' -H 'Authorization: Bearer *access_token*' -d '{"is_archived": true, "id": "3ba86d22-0183-4575-804d-60e0a6fa2f74", "contacts":[{"name":"Contact name","note":"Notes on the contact","phone_number":"+32456789016","email":"hello@qargo.com","roles":["BILLING","OPERATIONS"]}]}'Use an explicit type filter to return only subcontractor resources:
GET /resource?resource_type=SUBCONTRACTORResource lists include subcontractor resources by default. Use resource_type or resource_type:in to restrict the returned types. The type filter is retained by the next-page cursor. Other filters, such as external_id and updated_after, continue to narrow the result.
For a company, list subcontractor resources and identify the intended resource by its returned company.id, external_id, or other known fields. PATCH that resource by its resource ID. When following a page, send only the returned cursor; its saved filters define the continuation scope. Start a new first-page request to change the scope.
An explicit mixed type filter can include subcontractors alongside other resource types:
GET /resource?resource_type:in=VAN,SUBCONTRACTOR&external_id:in=carrier-a,carrier-bThe returned rows still have to satisfy both filters.
POST requires a name and a reference to an existing subcontractor company. Each request creates an additional resource, even when company setup has already created one. Use the returned resource ID when updating the intended resource.
POST /resource
{
"name": "Carrier A pallet service",
"external_id": "carrier-a-pallet",
"company": { "id": "c23a91d5-79ae-40c4-8a17-66898c70f1b7" },
"subcontractor": {
"skip_route_calculation": true,
"is_pallet_network": true
}
}The company must be visible to the caller and have the subcontractor role. The API does not create or promote companies. An archived company can receive a new, nonarchived resource. The subcontractor key identifies the resource type, so always include it; an empty object or null uses skip_route_calculation=false and is_pallet_network=false.
POST always creates an additional resource. It is not idempotent: do not blindly retry a request when the result is uncertain, because the retry can create another resource.
The response keeps the company reference separate from the resource settings:
{
"id": "c63f3150-7066-4e6c-a6ab-58a8d6280fb5",
"name": "Carrier A pallet service",
"company": { "id": "c23a91d5-79ae-40c4-8a17-66898c70f1b7" },
"subcontractor": {
"skip_route_calculation": true,
"is_pallet_network": true
}
}Use PUT with the full resource input to replace its writable values. On PUT, an empty subcontractor object or null resets both values. PATCH can change common fields alone or only the supplied fields inside subcontractor:
PATCH /resource/c63f3150-7066-4e6c-a6ab-58a8d6280fb5
{ "subcontractor": { "is_pallet_network": false } }skip_route_calculation=true skips route calculation for shipments planned on this resource. On creation, or when enabling it on a resource without a fixed duration, the duration is zero. If the resource already has a positive fixed duration, PUT and PATCH preserve that duration when sending true. Sending false clears it and enables route calculation. Omitting the setting on PATCH preserves it; an empty property object or null on PUT still resets it.
The response also reports true for existing positive fixed durations. Their numeric value is not exposed by this API, and the boolean may differ from the Routing control shown in Qargo. Sending true does not reset a positive duration to zero.
is_pallet_network enables pallet network planning. It requires skip_route_calculation to be true, either in the request or already on the resource, and cannot be enabled while the resource is part of an active resource combination. An empty PATCH property object or null changes neither value.
Set is_archived to true to archive a resource and false to restore it; DELETE also archives. Archived resources remain available by detail lookup and in Resource lists. Creating another resource for the same company can affect existing automatic subcontractor network selection: selection considers nonarchived resources ordered by resource id (not creation order) and, when an integration state is requested, chooses the first resource whose integration state matches. Skipping route calculation also affects planning when pallet network planning is disabled. Existing planning is not recalculated when these values change.
Enabling pallet network planning without skipping route calculation returns HTTP 400:
{
"message": "Duration override is required for pallet networks",
"errors": [
{
"message": "Duration override is required for pallet networks",
"field": "duration_override_seconds",
"path": "$.duration_override_seconds"
}
]
}The response uses duration_override_seconds to identify the routing prerequisite; this is not a writable field in this API. Set skip_route_calculation=true with is_pallet_network=true. On PATCH, you can omit skip_route_calculation if it is already true on the resource. PUT must include it because omitted properties use their defaults.
Resource groups represent the depot or site a resource (vehicle, driver, trailer) is allocated to, and they determine where the resource appears on the planning board. Use the API to keep group allocations in sync when resources move between sites — for example from a telematics or fleet management system.
Resource group ids are specific to your environment. Use the lookup endpoint to find the id of the group you want to allocate to. Archived resource groups are not included.
GET /resource_groups
{
"items": [
{ "id": "7f0c1e2a-1111-4a6e-9c2b-3d5f8e7a9b01", "name": "Oswestry", "code": "OSW" },
{ "id": "a4b8d990-2222-4c1f-8e3a-6b9d0c4e5f02", "name": "Leeds", "code": "LDS" }
],
"next_cursor": null
}Lookups by name or code are not supported, since names and codes are not guaranteed to be unique.
All resource read endpoints return resource_groups: the groups the resource is currently allocated to. This is a list — a resource can be allocated to more than one group at the same time (for example through rotating schedules). For most resources it contains a single element; it is empty when the resource is not in any group.
GET /resource/{resource_id}
{
"id": "3f9e6b1c-3333-4d2e-b1a4-7c8f9e0a1b03",
"name": "Truck 142",
"resource_groups": [
{ "id": "7f0c1e2a-1111-4a6e-9c2b-3d5f8e7a9b01", "name": "Oswestry", "code": "OSW" }
]
}Set the group with a PATCH on the resource, referencing the group by id. One resource per call — there is no bulk update.
PATCH /resource/{resource_id}
{ "resource_group": { "id": "a4b8d990-2222-4c1f-8e3a-6b9d0c4e5f02" } }Send an explicit null to remove the resource from its group. Omitting the field leaves the allocation unchanged.
PATCH /resource/{resource_id}
{ "resource_group": null }Note the asymmetry: you set a single group, but read a list. The PATCH manages the resource's own (fixed) allocation; allocations coming from combinations of multiple resources or from rotating schedules are not affected by it and stay managed in the TMS UI.
HTTP 400
{ "message": "Resource group with id a4b8d990-2222-4c1f-8e3a-6b9d0c4e5f02 not found" }Returned when the referenced group does not exist in your environment, or is archived.
Changing a group does not trigger notifications in Qargo and does not adjust planning rules or auto-assign logic tied to the previous group.
Creating an unavailability is always for a single resource. Currently no bulk unavailability creation is supported.
{
"reason": "DRIVER_HOLIDAY",
"start_time": "2025-01-08T00:00:00+00:00",
"end_time": "2025-01-12T00:00:00+00:00",
"description": "HR reference HR00001",
"external_id": "YOUR_REFERENCE_00001"
}Updating an unavailability is always for a single resource. Currently no bulk unavailability updates are supported.
{
"reason": "DRIVER_HOLIDAY",
"start_time": "2025-01-09T00:00:00+00:00",
"end_time": "2025-01-12T00:00:00+00:00",
"description": "HR reference HR00002, correction 1 day",
"external_id": "YOUR_REFERENCE_00001"
}E-invoicing refers to the automated, digital exchange of structured invoice data between businesses (e.g., suppliers and buyers) in a standardized format.
We support receiving purchase invoices and credit notes in multiple formats:
- JSON — Qargo's own structured purchase invoice/credit note schema
- XML (UBL) — Peppol-compliant UBL documents
- Multipart — JSON data combined with file attachments (PDF, XML, etc.)
- Custom formats — CSV, EDIFACT, fixed-width, or other proprietary formats via the Qargo integration framework
Attachments (e.g. the invoice PDF, CMR documents) can be included either via the attachments[].document object in JSON (with base64-encoded content), or as additional parts in a multipart upload.
This endpoint allows importing e-invoices into Qargo. The e-invoice can either be a purchase invoice or a purchase credit note. See the endpoint documentation for detailed format examples and attachment handling.
Question paths are a configuration mechanism that maps fields in incoming data to specific fields, documents or actions in Qargo. A question_answers dict can be included on updates in two webhooks:
- Status update — on stop or stop group updates
- Partial order update — on order, consignment, stop, good, or handling unit updates
The keys of this dict correspond to question paths configured on an integration; the values are the answers.
Status update example
{
"updates": [
{
"event_time": "2024-08-20T10:00:00Z",
"stop": {
"id": "a2a84715-0027-49af-ad30-494c0ccf75cc",
"status": "COMPLETED",
"question_answers": {
"trailer_number": "VB-123-AB"
}
}
}
]
}Partial order update example
{
"updates": [
{
"match": {
"matches_all": [
{
"order": {
"customer_reference_number": { "matches_any": ["T1234393"] }
}
}
]
},
"consignment": {
"updates": [
{
"question_answers": {
"consignee_signature": {
"embedded_document": {
"content": "IkhlbGxvLCB3b3JsZC4gSGVsbG8sIHdvcmxkLiBIZWxsbywgd29ybGQuIg==",
"content_type": "image/svg+xml",
"filename": "a_file_name.svg"
}
}
},
"good": {
"updates": [
{
"handling_unit": {
"updates": [
{
"match": {
"matches_all": [
{
"handling_unit": {
"barcode": { "matches_any": ["ABC123"] }
}
}
]
},
"question_answers": {
"scan_barcode": [
{
"timestamp": "2024-08-20T10:00:00Z",
"status": "SCANNED_OUT",
"stop_location_code": "DEPOT-001",
"stop_match": {
"location": {
"postal_code": { "matches_any": ["NW1 2AB"] }
}
}
}
]
}
}
]
}
}
]
}
}
]
}
}
]
}Adds a document to its relevant subject (e.g. POD/CMR -> consignment). The document can either be embedded or referenced. Exactly one of remote_document or embedded_document must be defined per document object.
Answer format: JSON array of document objects.
[
{
"remote_document": {
"upload_id": "6f223c71-5758-4a31-b2e8-84ba91a90dd1"
}
}
][
{
"embedded_document": {
"content": "IkhlbGxvLCB3b3JsZC4gSGVsbG8sIHdvcmxkLiBIZWxsbywgd29ybGQuIg==",
"content_type": "image/png",
"filename": "a_file_name.png"
}
}
]Include an external_id to give the document a stable identity in your own system. Sending a document again under an external id that was used before on the same subject replaces the earlier one: the new document is added and the one it supersedes is removed. This is how a regenerated document (e.g. a pallet label reprinted after the pallet count changed) is kept as a single document instead of accumulating versions.
The external id must identify a single document. It is scoped to the subject the document is attached to, so the same value can be reused across orders, consignments or stops, but reusing one value for two documents on the same subject (e.g. a proof of delivery and a CMR) means the second one replaces the first.
[
{
"external_id": "LABEL-4471",
"embedded_document": {
"content": "IkhlbGxvLCB3b3JsZC4gSGVsbG8sIHdvcmxkLiBIZWxsbywgd29ybGQuIg==",
"content_type": "image/png",
"filename": "pallet_label.png"
}
}
]| Field | Type | Required | Description |
|---|---|---|---|
remote_document | object | No | Object with upload id of uploaded document |
embedded_document | object | No | Document info with base64 encoded document |
external_id | string | No | Identifier of the document in your system, used to replace it |
Assigns a resource (trailer, container, or full trailer) to an order or trip based on a plain-text identifier. If no matching resource is found the answer is silently ignored.
Answer format: plain string — the resource's name, code, licence plate, or container number.
VB-123-ABMatching strips all non-alphanumeric characters and is case-insensitive, so VB-123-AB, VB 123 AB, and VB123AB all resolve to the same resource.
Records a barcode scan event on a handling unit. Use stop_match to identify the stop the scan belongs to. The matched stop determines the handling unit's resulting status, so a scan whose stop cannot be matched is rejected.
Answer format: JSON array of scan objects.
[
{
"timestamp": "2024-08-20T10:00:00Z",
"status": "SCANNED_IN",
"stop_location_code": "DEPOT-001",
"stop_match": {
"location": {
"postal_code": { "matches_any": ["NW1 2AB"] }
}
}
}
]| Field | Type | Required | Description |
|---|---|---|---|
timestamp | ISO 8601 datetime | Yes | Time of the scan event |
status | string | No | Scan status (see below). Required for scans at a depot. |
barcode | string | No | Barcode value; used to identify the handling unit. Optional as the unit will have been matched in the partial order update. |
stop_match | object | No | Criteria for matching the scan to a specific stop on the trip (see below) |
stop_location_code | string | No | Location identifier code |
description | string | No | Free-text description |
| Field | Type | Description |
|---|---|---|
stop_type | string | Type of stop to match: PICKUP, DELIVERY, DEPOT_UNLOAD or DEPOT_LOAD |
id | object | Match by stop ID: { "matches_any": ["<id>"] } |
reference_number | object | Match by stop reference number: { "matches_any": ["<reference>"] } |
location | object | Match by the stop's location (see below) |
leg | object | Match by the leg (stage) the stop bounds (see below) |
A depot is modelled as two stops: the goods are unloaded off the inbound leg (DEPOT_UNLOAD) and later loaded onto the outbound leg (DEPOT_LOAD). Direct consignments have no depot stops, so neither depot stop type matches anything there — use PICKUP / DELIVERY instead.
From three legs onwards each depot stop type occurs more than once per consignment, so stop_type alone is ambiguous and leg must be supplied as well. Ambiguous matches are not resolved by guessing: the scan is rejected instead.
| Scan | stop_type | leg.leg_type |
|---|---|---|
COLLECTION_DEPOT_SCANNED_IN | DEPOT_UNLOAD | PICKUP |
COLLECTION_DEPOT_SCANNED_OUT | DEPOT_LOAD | TRANSFER (2 legs: DELIVERY) |
DELIVERY_DEPOT_SCANNED_IN | DEPOT_UNLOAD | TRANSFER (2 legs: n/a) |
DELIVERY_DEPOT_SCANNED_OUT | DEPOT_LOAD | DELIVERY |
| Field | Type | Description |
|---|---|---|
id | object | Match by location ID: { "matches_any": ["<id>"] } |
name | object | Match by location name: { "matches_any": ["<name>"] } |
postal_code | object | Match by postal code: { "matches_any": ["<postal_code>"] } |
country_code | object | Match by country code: { "matches_any": ["<country_code>"] } |
Available status values:
| Value | Description |
|---|---|
ARRIVED | Handling unit has arrived at the stop |
SCANNED_IN | Handling unit has been scanned in |
STORED | Handling unit is in storage at a depot |
SCANNED_OUT | Handling unit has been scanned out |
DEPARTED | Handling unit has departed from the stop |
Which values are accepted depends on the matched stop:
| Matched stop | Accepted values | Default when status is omitted |
|---|---|---|
| Pickup | ARRIVED, SCANNED_IN, DEPARTED | SCANNED_IN |
| Delivery | ARRIVED, SCANNED_OUT, DEPARTED | SCANNED_OUT |
| Stop at a depot | ARRIVED, SCANNED_IN, STORED, SCANNED_OUT, DEPARTED | None, status is required |
Any other combination is rejected.
The Qargo MCP server lets an AI assistant work with Qargo data on behalf of a signed-in user, using the Model Context Protocol.
The server exposes the external API via four tools. There is no tool per endpoint: the assistant searches for an operation, reads its schema, then runs it.
| Tool | Purpose |
|---|---|
external_api_discover | Search the available API operations |
external_api_schema | Get the request and response schema of one operation |
external_api_call_read | Run a read (GET) operation |
external_api_call_write | Run a write (POST, PUT, PATCH, DELETE) operation |
These calls go through the external API, with the same authentication and permissions as any other API client. They have the same rate limits, counted separately from your integrations, so using MCP never uses up your integrations' allowance.
The tools reach a subset of the external API operations, not every endpoint. Webhooks and the token endpoint are never exposed. Use external_api_discover to see which operations are available.
The server also offers three MCP-only tools. These are not external API calls.
| Tool | Purpose |
|---|---|
list_tenants | List the tenants the user can access, with their role per tenant |
get_tenant_details | Get identity, locale and billing address details for one tenant |
find_entity | Resolve a name or reference number to an entity type and UUID |
Use it when an assistant should answer questions about live tenant data, or perform routine changes under human supervision. Use the REST API directly for integrations, scheduled jobs, and anything needing deterministic behaviour.
Three conditions must be met before a connection succeeds. Only the first one needs Qargo.
| Requirement | Scope | Set by |
|---|---|---|
| Qargo Intelligence | Tenant | Qargo |
| External API access | Tenant | Qargo, on by default |
| MCP access, read-only or read and write | Individual user, per tenant | A Super admin in your tenant |
MCP access defaults to disabled for every user. Enabling Qargo Intelligence on a tenant grants it to nobody.
A Super admin sets MCP access per user in Configuration > Organisation settings > Users. The setting appears only once Qargo Intelligence is on. No request to Qargo is needed. Full steps: Connect an AI assistant to Qargo over MCP.
If your tenant does not have Qargo Intelligence, contact your Account Manager.
API
- Fixed: Company create and update requests return an HTTP 400 error instead of an HTTP 500 error when an entry in
sales.billing_entitiesorpurchase.billing_entitieshas nocode, or acodethat matches no billing entity. Billing entities are identified bycode;idis ignored on create and update.- Affects: Company
API
- Fixed: Task
statuscan now also beSKIPPED. Accounting and Task endpoints that read a skipped task failed with an HTTP 500 error instead.- Affects: Accounting, Task
- Added: Added endpoints to create, update, archive and retrieve products and product types. Product types can be linked to transport services through
transport_services, andGET /v1/transport-services/transport-servicelists the transport services to link them to. Added product validities to manage CAP and MSDS certificates on a product.- Affects: Product, Product type, Transport service
- Added: Resource validities of type
DRIVER_OTHER,VEHICLE_OTHERandSUBCONTRACTOR_OTHER(the app's 'Other' category) are now listed, returned and accepted.- Affects: Resource
- Endpoints:
GET /v1/resources/resource/{resource_id}/validity,GET /v1/resources/resource/{resource_id}/validity/{id},GET /v1/resources/resource/{resource_id}/validity/{id}/documents,POST /v1/resources/resource/{resource_id}/validity,PUT /v1/resources/resource/{resource_id}/validity/{id},DELETE /v1/resources/resource/{resource_id}/validity/{id}
- Fixed: Unavailability endpoints no longer return or change validities or automatically generated planning blocks. For their ids, get and update return 404 and delete returns 204 without deleting anything, so a validity is no longer converted or deleted through an unavailability endpoint. Resource and company validity get, documents and delete treat an unavailability id as unknown: get returns 404, documents returns 404 for a resource and 400 for a company, and delete returns 400.
- Affects: Resource, Company
- Endpoints:
GET /v1/resources/resource/{resource_id}/unavailability,GET /v1/resources/resource/{resource_id}/unavailability/{id},PUT /v1/resources/resource/{resource_id}/unavailability/{id},DELETE /v1/resources/resource/{resource_id}/unavailability/{id},GET /v1/resources/resource/{resource_id}/validity/{id},GET /v1/resources/resource/{resource_id}/validity/{id}/documents,DELETE /v1/resources/resource/{resource_id}/validity/{id},GET /v1/companies/company/{company_id}/validity/{id},GET /v1/companies/company/{company_id}/validity/{id}/documents,DELETE /v1/companies/company/{company_id}/validity/{id}
API
- Fixed: Resource and company validity responses now include the stored Valid to date (
legal_end_time) and planning setting (generate_unavailability).
API
- Changed: Companies can now be created and updated with the
CUSTOM_DUE_DATEpayment term onpayment_term,sales.payment_termandpurchase.payment_term, instead of failing with an HTTP 400 error. A sales invoice for such a customer uses the due date given on it, and defaults to its invoice date.- Affects: Company
- Endpoints:
POST /v1/companies/company,PUT /v1/companies/company/{id},PATCH /v1/companies/company/{id}
- Added: Documents stored on a resource without a validity can now be listed and added.
GET /v1/resources/resource/{resource_id}/documentsreturns them, andPOST /v1/resources/resource/{resource_id}/documentsattaches an uploaded file to the resource by itsupload_id. Documents attached to a validity remain available through the validity documents endpoint.- Affects: Resource
- Endpoints:
GET /v1/resources/resource/{resource_id}/documents,POST /v1/resources/resource/{resource_id}/documents
Webhooks
- Added: Trip imports can now reference resources and planning groups without Qargo IDs.
primary_resourcesentries gaintype(DRIVER,VEHICLEorCONTAINER),name,license_plateandcontainer_number, and a resource sent without anidmust state itstype. The trip gainsplanning_groupandresource_group, each identified byid,nameorcode, withcodetaking precedence overname.- Affects: Trip import
- Endpoints: POST /v1/webhook/trip-import
API
- Fixed: Validity documents are now matched on the validity alone, so documents attached through imports are returned as well as the ones uploaded in the app.
GET /v1/resources/resource/{resource_id}/validity/{id}/documentsreturns an empty list instead of HTTP 404 when a validity has no documents. - Added: Resource endpoints now expose reusable subcontractor resources with a
companyreference and asubcontractorsettings object. POST creates an additional resource linked to an existing subcontractor company.- Affects: Resource
- Endpoints:
GET /v1/resources/resource,GET /v1/resources/resource/{resource_id},POST /v1/resources/resource,PUT /v1/resources/resource/{resource_id},PATCH /v1/resources/resource/{resource_id},DELETE /v1/resources/resource/{resource_id}
- Changed: Resource lists now include subcontractor resources by default. This changes the response types for existing unfiltered requests; use explicit resource type filters to restrict the results.
- Affects: Resource
- Endpoints:
GET /v1/resources/resource
API
- Fixed:
TaxRateTypeandTaxTypeEnumgainUK_REVERSE_CHARGE. Invoices, tax rates, companies and orders using a UK reverse charge tax type are now returned instead of failing with an HTTP 500 error, and tax rates and companies can now be created or updated with it. Treat the tax type as an open set and ignore values you do not recognise.- Affects: Accounting, Company, Order, Task, Trip
API
- Added: Orders gain an optional
recurring_route_name, the name of the recurring route the order belongs to, used to match the order to an order template. It can be set when creating an order, is returned when reading one and is carried on dispatch payloads.- Affects: Order, Fleet dispatch, Subcontractor dispatch, Location booking
Webhooks
- Added:
OrderUpdateDatagains an optionalrecurring_route_nameon the partial order update webhook, so the recurring route of an existing order can be set or changed.- Affects: Order
- Endpoints: POST /v1/webhook/partial-order-update
API
- Fixed: The OpenAPI schema for HTTP 422 validation errors now documents the optional
inputandctxfields already returned by the API. Response behavior is unchanged. - Fixed: Refund status updates now accept
OPEN. Reporting a credit note asOPENreopens its refund task and clears the refunded amount and date on the credit note; previously the documentedOPENvalue was rejected with a validation error.- Affects: Accounting
- Endpoints:
POST /v1/accounting/sales-credit-note/{id}/refund/update-status,POST /v1/accounting/purchase-credit-note/{id}/refund/update-status
API
- Added: Vehicles gain
co2_emission_class(CLASS_1toCLASS_5) for toll calculation.emission_classgainsNONE,EURO_0,EURO_EEV,EURO_6C,EURO_6D,EURO_6D_TEMP,EURO_6EandEURO_7, andfuel_typegainsLNGandCNG. Treat both as open sets and ignore values you do not recognise.- Affects: Resource, Order, Trip, Intermodal, Location booking, Fleet dispatch, Subcontractor dispatch
API
- Added: Resources of type trailer, full trailer, chassis and container now carry a
uirr_codesobject with aninterunit_code, the UIRR interunit code of the loading unit. It can be read and written on the resource endpoints, and is included in the resource data sent with intermodal bookings.- Affects: Resource
Outgoing data
- Added:
shipping_route.start_stopandshipping_route.end_stopon the intermodal booking payload now carrystop_id, the Qargo id of the stop.- Affects: Intermodal
Webhooks
- Added: Intermodal status updates now accept
references.departure_voyage_referenceandreferences.arrival_voyage_reference, the conveyance reference identifying the vessel voyage. Each port numbers the same crossing its own way, so send the loading port's number as the departure value and the discharge port's as the arrival value.- Affects: Intermodal
- Endpoints: POST /v1/webhook/intermodal-status
Outgoing data
- Added: Intermodal booking payloads now carry
references.departure_voyage_referenceandreferences.arrival_voyage_reference, the conveyance reference for the vessel voyage at the port of loading and the port of discharge.- Affects: Intermodal
API
- Added: Good schemas gain an optional
hs_codesobject on order create and order read, carryingcount: the number of HS codes for the good, used for customs rate calculation.- Affects: Order
Webhooks
- Added:
GoodDataandGoodUpdateDatagain an optionalhs_codesobject on the partial order update webhook (creating and updating a good), carryingcount: the number of HS codes for the good, used for customs rate calculation.- Affects: Order
- Endpoints: POST /v1/webhook/partial-order-update
Outgoing data
- Added: Goods in outbound order payloads — operational visibility, fleet and subcontractor dispatch, intermodal and location bookings — gain an optional
hs_codesobject, carryingcount: the number of HS codes for the good. The field is omitted when not set on the good.
API
- Added: Packaged items gain an optional
wasteobject and goods gainwaste_category, for cargo classified under the European Waste Catalogue.wastecarries theewccode with its hazard flag and localized description, plusconsistency,persistent_organic_pollutants,processing_operationandemitter_type. Available on order upload, partial order update and in order responses.- Affects: Order
API
- Added:
BarcodeSourcegainsAPCandPALLETLINE_OPTIMA, identifying barcodes originating from the APC and Palletline Optima network integrations. Treat the barcode source as an open set and ignore values you do not recognise rather than rejecting the order.- Affects: Order
API
- Added: Stop extras accept a
custom_fieldsobject on order upload, matching order- and good-level extras.- Affects: Order
- Added:
Consignment.tracking_linkis now returned on order responses: the public tracking page URL for each consignment. It isnullwhen the consignment has no tracking link, for example when the tracking link integration is not enabled on the tenant or the link has been revoked.- Affects: Order
- Endpoints: GET /v1/orders/order/{order_id}, GET /v1/orders/order/{order_id}/status
Webhooks
- Added:
TrackingUpdateDatagains an optionalvoltageobject, carryingexternal_power_supply_voltage_mv: the external supply voltage of a unit in millivolts. Report the voltage of the external power line rather than the internal battery, so that a unit running on its own battery reports a value at or near zero. This lets Qargo derive whether a temperature-controlled unit is plugged in to external power.- Affects: Tracking
- Endpoints: POST /v1/webhook/tracking-update
Webhooks
- Added:
PackagedItemInput.barcodesaccepts a list of barcode strings on packaged items, matching the existingpackaged_items[].barcodesfield on order upload. Previously the partial order update dropped the field.- Affects: Order
- Endpoints: POST /v1/webhook/partial-order-update
API
- Added:
PaymentTermCodegainsEND_OF_MONTH_0_NET_20, for a payment term of end of this month plus 20 days.- Affects: Accounting, Company, Order, Task, Trip
Webhooks
- Added: Stop matching now reaches depot stops.
StopMatch.stop_typeacceptsDEPOT_UNLOADandDEPOT_LOAD, and the newStopMatch.legobject narrows a match to the leg a stop bounds vialeg_type(PICKUP,TRANSFER,DELIVERY,DIRECT,EMPTY). From three legs onwards each depot stop type occurs more than once per consignment, solegmust be supplied alongsidestop_type; ambiguous matches are left unresolved rather than guessed.
API
- Fixed: The
/meresponse now includesactive_tenant_slugfor CUSTOMER-role tokens, matching other API roles.- Affects: System
- Endpoints:
GET /me
Webhooks
- Added: Document answers in
question_answersnow acceptexternal_id, the document's identifier in your own system. A document sent again under an external id that was used before on the same order, consignment or stop replaces the earlier one instead of being added next to it. The identifier must point at a single document, not at the order or consignment it belongs to.- Affects: Order
- Endpoints: POST /v1/webhook/partial-order-update
API
- Changed: Charge
statusnow reportsINVOICE_POSTEDfor charges on a posted invoice andDO_NOT_INVOICEfor charges excluded from invoicing. These were previously reported asCREATED, including on existing charges, so invoiced and uninvoiced charges can now be told apart. Treat the status as an open set and map unrecognised values toCREATED.- Affects: Order, Customer portal
- Endpoints:
GET /v1/orders/order/{order_id}/charges,POST /v1/orders/order/{order_id}/charges/approval
Outgoing data
- Added:
VisibilityOrderStatusin operational visibility payloads gainsBLOCKED, for an order that is blocked or on hold. Treat the order status as an open set and ignore values you do not recognise rather than rejecting the event.- Affects: Customer portal, Order, Visibility
Webhooks
- Added: Intermodal status updates now accept
external_id, the booking's identifier in your own system. When supplied, it is stored as the identifier for the booking, taking precedence overbooking_reference.- Affects: Intermodal
- Endpoints: POST /v1/webhook/intermodal-status
Webhooks
- Added: The document-import webhook now accepts
UK_EXPORTER_DRAandUK_IMPORTER_DRAasdocument_typevalues.- Affects: Document import
- Endpoints:
POST /v1/webhook/document-import
API
- Added: The intermodal booking payload now includes a
tripobject with the trip'sid,name,statusandcustom_fields, so trip-level data (e.g. a customs procedure) can be used when dispatching bookings.- Affects: Intermodal
- Deprecated: The root-level
trip_namefield on the intermodal booking payload is deprecated; usetrip.nameinstead.- Affects: Intermodal
- Fixed: Deleting a resource unavailability that is already deleted now reliably returns
204: the request no longer fails with a500when the unavailability is gone.- Affects: Resource
- Endpoints:
DELETE /v1/resources/resource/{resource_id}/unavailability/{id}
Outgoing data
- Added:
ResourceTypein operational visibility payloads gainsHANDLING, for handling equipment such as a forklift assigned to a stop, andSUBCONTRACTOR, which the payload has been able to carry for some time but was undocumented. Treat the resource type as an open set and ignore values you do not recognise rather than rejecting the event.- Affects: Customer portal, Order, Visibility
API
- Added:
pricingnow includesby_currency, holding the pricing totals per currency keyed by currency code. Each entry covers only the charges in that currency, so an order charged in more than one currency reports a correct total per currency.- Affects: Order
- Endpoints: GET /v1/orders/order/{order_id}, GET /v1/orders/order/{order_id}/status
API
- Fixed: Deleting a resource unavailability that is already deleted now returns
204instead of failing with a400, so a retried delete no longer has to be special-cased. Updating an unavailability that does not exist now returns404naming the id, instead of a400reportingInstance matching query does not exist.- Affects: Resource
- Endpoints:
PUT /v1/resources/resource/{resource_id}/unavailability/{id},DELETE /v1/resources/resource/{resource_id}/unavailability/{id}
API
- Added: Master data can now be looked up by filter instead of by paging through the full list. Companies accept
codeandaccounting_customer_code, and accounts, tax rates and resource groups acceptcode. Every filter also has a batch form taking a comma-separated list, spelledcode:in=A,B; the existingfrom_currencyandto_currencyfilters on exchange rates gain the same batch form. The exact and the batch spelling of the same filter cannot be combined, and a batch list accepts at most 100 values.accounting_customer_codeholds the code of the default billing entity.- Affects: Accounting, Company, Resource
- Endpoints:
GET /v1/accounting/accounts,GET /v1/accounting/company,GET /v1/accounting/exchange-rate,GET /v1/accounting/tax-rates,GET /v1/companies/company,GET /v1/resources/resource_groups
- Fixed: Following
next_cursoron a filtered list request now keeps the filters applied. The second and later pages previously returned the full unfiltered list.- Affects: Accounting, Company, Resource
- Endpoints:
GET /v1/accounting/company,GET /v1/accounting/exchange-rate,GET /v1/companies/company,GET /v1/resources/resource,GET /v1/resources/resource_groups
- Changed: An invalid value in
external_id:inorresource_type:inis now reported as a validation error (422) rather than a bad request (400), matching how an invalidresource_typeis already reported. An empty list such asexternal_id:in=is rejected as a bad request (400) instead of silently matching nothing, and a list accepts at most 100 values.- Affects: Resource
- Endpoints:
GET /v1/resources/resource
Outgoing data
- Changed:
location.nameis no longer guaranteed in operational visibility payloads. A location without a name, such as an address-only one created automatically by an order import, previously blocked the entire visibility event from being sent; it is now sent withnameomitted. Treat the field as optional and fall back toaddressandcitywhen it is absent.- Affects: Customer portal, Order, Visibility
Webhooks
- Added: Consignment updates now support
CANCELandUNCANCELoperations.CANCELmoves a consignment toCANCELLEDand takes its stops off the active route while keeping the record for invoicing and audit, unlikeDELETE, which removes it entirely.UNCANCELreverts a cancelled consignment to a plannable state. Both require a consignment match, andUNCANCELapplies only to a consignment that is currently cancelled.- Affects: Order
- Endpoints: POST /v1/webhook/partial-order-update
API
- Fixed: Updating a resource no longer returns a server error when
noteorexternal_idis omitted; the value is now stored as an empty string, matching create. Sending an explicitnullfornote,external_id,name, orlocaleis now rejected with a validation error (422) instead of failing with a server error on update, or being silently ignored on create.- Affects: Resource
- Endpoints:
POST /v1/resources/resource,PUT /v1/resources/resource/{resource_id},PATCH /v1/resources/resource/{resource_id}
- Added: Stops in order status responses now include
stop_type, identifying the consignment pickup (PICKUP) and delivery (DELIVERY) stops. The field is empty for other stops.- Affects: Order
- Endpoints:
GET /v1/orders/order/{order_id}/status
- Added:
resource_typecan now beBARGEorAIRPLANE, used by the resources that barge and air intermodal connections create.- Affects: Order, Resource, Trip
- Endpoints: GET /v1/orders/order/{order_id}/status,
GET /v1/resources/resource, GET /v1/trips/trip/{trip_id}
Outgoing data
- Added: Resources in visibility events can now report the
BARGEandAIRPLANEtypes.- Affects: Customer portal, Order, Visibility
API
- Removed: Order status responses no longer include
first_pickup_stop. The same information can be derived from thestopsarray, which is ordered by stop sequence: the first stop with a pickupactivity_labelis the first pickup stop, and likewise the last stop with a deliveryactivity_labelis the last delivery stop.- Affects: Order
- Endpoints:
GET /v1/orders/order/{order_id}/status
API
- Added: Resource create, update and patch now accept
is_archived. Sendingis_archived: falsereactivates a previously archived resource, restoring it with its existing data; sendingtruearchives it. Omitting the field leaves the archive state unchanged.- Affects: Resource
- Endpoints:
POST /v1/resources/resource,PUT /v1/resources/resource/{resource_id},PATCH /v1/resources/resource/{resource_id}
API
- Fixed: Payment status updates now accept
UNPAID. Reporting an invoice asUNPAIDreopens its payment task and clears the paid amount and date on the invoice; previously the documentedUNPAIDvalue was rejected with a validation error.- Affects: Accounting
- Endpoints:
POST /v1/accounting/sales-invoice/{id}/payment/update-status,POST /v1/accounting/purchase-invoice/{id}/payment/update-status
Webhooks
- Added: Intermodal booking status updates can report estimated and actual stop times via
stop_timestamps, witheta_timestamp,actual_start_timestampandactual_end_timestampfor thedepartureandarrivalstops. The timestamps are only applied when the integration is configured to sync stop times.- Affects: Intermodal partner
- Endpoints: POST /v1/webhook/intermodal-status
API
- Added:
GET /v1/resources/resourcenow documents the supported query filters:cursor,updated_after,external_id,external_id:in,resource_typeandresource_type:in.- Affects: Resource
- Endpoints:
GET /v1/resources/resource
API
- Added: Sales invoice and sales credit note responses now include
e_invoicingregistration metadata.- Affects: Accounting, Task
API
- Changed: Validation error responses now return an
errorsarray instead of the flatdetail,fieldandpathfields. Each item is aValidationErrorDetailwithmessage,field,pathanddetail; the array is always present and non-empty, so a single failure is a one-item array and integrators can handle one and many failures the same way.- Affects: Accounting, Authentication, Company, Document, Order, Resource, Task, Trip
API
- Added: New
GET /v1/resources/resource_groupsendpoint lists the tenant's resource groups (id,name,code), cursor-paginated. Archived groups are excluded.- Affects: Resource
- Added: Resource responses now include
resource_groups, the groups the resource currently belongs to (deduplicated and sorted by name). A resource can belong to more than one group.- Affects: Resource
- Added:
PATCH /v1/resources/resource/{resource_id}accepts aresource_groupreference to allocate the resource to a group, ornullto remove it from its current group.- Affects: Resource
- Endpoints:
PATCH /v1/resources/resource/{resource_id}
API
- Added: Added the Location master-data API to create, update and retrieve locations, including address and opening hours. New endpoints:
POSTandGET/v1/locations/location, andGET,PUTandPATCH/v1/locations/location/{location_id}.- Affects: Location
Outgoing data
- Added: The location dispatch webhook now includes a per-consignment
tracking_link.- Affects: Location booking
Outgoing data
- Added: Operational order visibility now includes goods information.
- Affects: Customer portal, Order, Visibility
Outgoing data
- Added: Outgoing data now includes ADR hazard labels and
special_provisionsfor dangerous goods.- Affects: Order
API
- Added:
Bookingnow exposesvessel,voyage,IMOand the associated references for intermodal flows.- Affects: Intermodal
API
- Added: The
TaskTypeenum gainsDISPATCH, returned by the available-tasks and task endpoints.- Affects: Accounting, Task
API
- Added: Order models now expose
is_consignment_info_validated, indicating whether consignment information has been validated.- Affects: Order
- Added: Goods and handling units now return their
idin order output, andContainerTypeexposes thecontainer_iso_code.- Affects: Order
- Added:
ShippingRoutenow exposescustom_fieldsandmodality.- Affects: Intermodal
API
- Added: Resource and equipment models (
Container,Trailer,Vehicleand their resource variants) now expose theirid, and driver resources exposestart_stop_location.- Affects: Resource
API
- Added:
PartialOrderUpdatenow accepts anupdateobject carrying order entity changes.- Affects: Order
- Endpoints: POST /v1/webhook/partial-order-update
API
- Changed:
BookingDimensionsnow exposescargo_weight,tare_weightandverified_gross_mass; the singleweightfield is deprecated.- Affects: Intermodal
- Deprecated: Companies now use
credit_policy; thecredit_limit_totalfield is deprecated.- Affects: Accounting, Company
API
- Added: Added the
/v1/accounting/exchange-rateendpoint.- Affects: Accounting
- Added: Consignments now expose
import_export, andContactTypegainsSALES,CUSTOMS,IT,QUALITY,CLAIMS_INSURANCEandCUSTOMER_CONTACT.- Affects: Accounting, Company, Order, Trip
- Added:
Customsexposeshas_customs_territory_crossing,PackagedItemexposestotal_net_weight_kg, andPackagingTypeexposesexport_alias.- Affects: Order
Webhooks
- Added: Added the
/v1/webhook/tracking-updateinbound webhook.- Affects: Tracking
Outgoing data
- Added: Fleet and subcontractor dispatch payloads now include
custom_fields.- Affects: Fleet dispatch, Subcontractor dispatch
API
- Added: Location output now includes
latitudeandlongitude.- Affects: Accounting, Company, Order, Task, Trip
API
- Changed: Company create and update inputs now accept
archived_customerandarchived_subcontractor, and these read-only fields are no longer returned on company output:purchase,sales,credit_limit_totalandtimestamp_updated.- Affects: Accounting, Company, Order, Trip
API
- Added:
PackagedItemnow exposesimport_export.- Affects: Order
- Endpoints: GET /v1/orders/order/{order_id}/export, POST /v1/orders/order/upload, POST /v1/webhook
Webhooks
- Added: Added the
/v1/webhook/document-importinbound webhook.- Affects: Document import
- Added: Fleet status-update webhooks accept stop-group ETA windows via
eta_startandeta_end.- Affects: Fleet dispatch
- Endpoints: POST /v1/webhook/fleet-status-update
Outgoing data
- Added: Operational order visibility now includes stop ETA times (
eta_start_time,eta_end_time).- Affects: Customer portal, Order, Visibility
API
- Changed: Partial order updates now accept
consignment; the top-levelidfield is deprecated.- Affects: Order
- Endpoints: POST /v1/webhook/partial-order-update
API
- Deprecated: Deprecated
container_load_unload_stopon order models.- Affects: Order
- Added:
PackagedItemnow exposesbarcodes,packaging_typeand unit dimensions (unit_height_m,unit_length_m,unit_width_m).- Affects: Order
- Endpoints: GET /v1/orders/order/{order_id}/export, POST /v1/orders/order/upload, POST /v1/webhook
Webhooks
- Added: Fleet status-update webhooks accept stop ETA windows via
eta_startandeta_end.- Affects: Fleet dispatch, Subcontractor dispatch
- Endpoints: POST /v1/webhook/fleet-status-update, POST /v1/webhook/subco-status-update
API
- Changed: Purchase e-invoice and e-credit-note inputs now accept
attachments; theidandis_credit_notefields are removed.- Affects: E-invoicing
- Endpoints: POST /v1/webhook/e-invoicing
API
- Added: Location output now includes the location
id.- Affects: Accounting, Company, Order, Task, Trip
API
- Added: Companies can be flagged as buyer/seller via
is_buyer_or_seller, and consignments now accept and returnbuyerandseller.- Affects: Accounting, Company, Order
- Added: Purchase e-invoices and e-credit-notes now include
invoice_type.- Affects: E-invoicing
- Endpoints: POST /v1/webhook/e-invoicing
API
- Changed: Fleet resource models now expose
billing_entity; on partial resource inputs thecompanyfield is replaced bysubcontractorandbilling_entity.- Affects: Resource
- Endpoints:
PATCH /v1/resources/resource/{resource_id},POST /v1/resources/resource,PUT /v1/resources/resource/{resource_id}
- Added: Companies now expose their
billing_entities,BillingEntityexposesidandis_default, andContactTypegainsPAYMENT_REMINDERS. - Removed: Removed the unused
good_allfield from partial order updates.- Affects: Order
- Endpoints: POST /v1/webhook/partial-order-update
API
- Added:
PaymentTermCodegains additional terms:NET_12,NET_20,NET_52,NET_75and theEND_OF_MONTH_0_NET_{1,7,14,21,25}variants.- Affects: Accounting, Company, Order, Task, Trip
Outgoing data
- Added: Operational order visibility now includes the customer
id.- Affects: Customer portal, Order, Visibility
API
- Added: Added the
/v1/accounting/sales-invoice/and/v1/accounting/sales-credit-note/endpoints for creating sales invoices and credit notes.- Affects: Accounting
- Added:
LineItemnow exposesdimension_4,dimension_5anddimension_6.- Affects: Accounting, Task