Skip to content

Qargo TMS API (1.2.0)

For support, please contact integrations@qargo.com.

Overview

Tenant API Documentation

You are currently viewing the Tenant API Documentation. This API provides access to tenant-level integrations and operational endpoints.

What's new — see the Changelog for recent additions and changes to the API.

Documentation for Other Parties

Subcontractor API

Fleet dispatch and subcontractor-specific endpoints for transportation management.

Customer API

Customer portal endpoints for order tracking, status monitoring, and customer-facing operations.

Authentication

The api requires oauth2 authentication with client id/secret. This should only be used for service to service communication.

Creating application credentials

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.

Obtaining an access token

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).

Understanding Basic Authentication

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.

The API Call to Request Tokens

The /auth/token endpoint is a POST request used to generate a JWT access token. You authenticate this request using Basic Auth with your provided client_id and secret_id.

Request Details

  • Method: POST
  • URL: https://api.qargo.com/v1/auth/token
  • Headers:
    • Content-Type: application/json
    • Authorization: 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>'

Webhook authentication

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 integrations@qargo.com to obtain them. They are separate from your API credentials and must be used exclusively for webhook endpoints.

API vs Webhook authentication summary

API endpointsWebhook endpoints
Auth methodOAuth2 (Client Credentials)Basic Authentication
CredentialsAPI client_id + secret_id → Bearer JWT tokenWebhook client_id + secret_id (directly in header)
Header formatAuthorization: Bearer <jwt_token>Authorization: Basic <base64(client_id:secret_id)>
Where to find credentialsConfiguration → Organisation Settings → API clientsProvisioned by Qargo — contact integrations@qargo.com
Token refresh needed?Yes (JWT expires)No (credentials sent with each request)

Common mistake

Webhook credentials can technically be used to obtain an OAuth token via the /auth/token endpoint, but this token will not work for authenticating webhook requests. Always use Basic Authentication with your webhook credentials directly in the Authorization header.

Example webhook request

curl -XPOST https://api.qargo.com/v1/webhook/order-import \
  -H 'Content-Type: application/json' \
  -u '<webhook_client_id>:<webhook_secret_id>' \
  -d '{ ... }'

Rate Limits

To maintain API stability and prevent abuse, we enforce rate limits on a per-tenant basis.

Limits

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.

CategoryScopeLimit
Authentication/auth/token5 requests per hour
General API UsageAll endpoints except authentication and webhooks2 requests per second (sustained); up to 3 per second (bursts)

Enforcement

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.

Timeline showing how to pace API requests, wait with jitter after a 429 response, and retry successfully

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 integrations@qargo.com.

API Best Practices

This section outlines recommended practices for efficiently working with the Qargo API.

Pagination

Some list endpoints support cursor-based pagination. Paginated responses contain items and next_cursor. When next_cursor is not null, pass its value unchanged as the cursor query parameter in the next request. Do not combine cursor with other query parameters.


How pagination works

  1. Initial request: Make a request to a paginated endpoint without a cursor parameter.
  2. Process the response: Read the current page from items.
  3. Subsequent requests: If next_cursor is not null, pass its value as the cursor parameter in the next request.
  4. Stop: Repeat until next_cursor is null.

Example usage

GET /v1/resources/resource

Response:

{
  "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.

Recommendations

  • Check that next_cursor is not null before making another request.
  • Treat cursors as opaque. Do not parse, modify, or construct them.
  • Do not combine cursor with other query parameters.

Backward compatibility

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 deprecated in 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.

Date and time formats

All date and time fields in the API follow ISO 8601:

TypeFormatExampleDescription
DateYYYY-MM-DD2024-12-31Calendar date without time component
DatetimeYYYY-MM-DDTHH:mm:ssZ2024-12-31T14:30:00ZTimestamp in UTC (indicated by Z suffix)
TimeHH:mm09:30Time 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.

Concepts

Company

A company in Qargo can be both a customer as well as a subcontractor (supplier). The entity will have a single id within Qargo. The api client can link companies by this id, or by the accounting code, which is a user defined code field.

Order

Transport order to execute. Also called job in other TMS systems. It contains all transport details:

  • Order references
  • Customer company
  • Consigments, with their stop locations, time windows, references
  • Definition of the goods to transport

Stop

  • 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.

Stop group

Stops can be grouped together according to their activity and location. This is called a stop group.

Trip

A trip contains stops from various orders, or standalone stops. It tracks how a certain transport is planned, and who will execute that transport.

Task

A task is the primary workflow concept in Qargo. Users can define their own flow, using both built-in tasks as well a custom defined ones. For the current accounting use case, we only expose the post invoice/credit note task, that allows users to send invoices to an accounting system.

Resource

A resource in Qargo is a vehicle, driver, trailer or other entity that can be assigned to a trip.

Unavailability

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.

Status update

A status update reflects a status change in an entity.

Document

A document in Qargo can be identified by a unique id. It has a type and is linked to a certain entity (for example an order).

Postman collection

We have a postman collection available with interactive examples (right click to download). Download this to a local folder, and import it into Postman for usage.

Instructions

  • 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

Functionality

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

Order management

Available functionality:

  • Create orders in Qargo and track order status.
  • Export any existing order to be used as a template for future order creation.

The api reference is available here: order api.

Trip information

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.

Resource management

Resource

Resources this should be used together with the endpoints to fetch unavailabilities as a resource unavailability is linked to a resource.

Unavailability

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 all unavailabilities for a resource

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.

Visibility

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) and COMPLETED (all stops for order completed).
  • Stop level
    • We send out a visibility event on AT_STOP (arrived at stop), COMPLETED (all activities completed for stop).
  • Position level (note: for every telematics update)
  • Trip level
    • We send a visibility event when a trip changes to PLANNED and when it transitions to COMPLETED.
  • Resource level
    • We send an event when a resource is assigned to a certain trip.

Order dispatch

It is also possible to subcontract trips to other parties. This is possible using two push endpoints:

Documents

We offer an interface to download documents. The documents can be fetched using the document endpoints.

Request additional endpoints

Please contact us for inqueries regarding additional api functionality.

Transport order creation & status

This sections details how to construct payloads to create transport orders using the order upload endpoint(/orders/order/upload).

Order creation metadata

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"
}

Order identifier

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.

Create 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.

Update an order

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_identifier field 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"
  }
}

Cancel an order

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"
  }
}

Export an existing order

It is possible to export a manually created order in the api. We first need to determine the technical id of this order.

Retrieve order id.

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.

Fetch order data and status

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.

Container orders

There are 2 types of container orders that can be created using the API, IMPORT and EXPORT.

Import

This scenario contains of 2 main stops additional optional stops.

  1. Pickup of a loaded container
  2. Unload container
  3. 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"
  }
}

Export

This scenario contains 2 main stops with additional optional stops:

  1. Pickup empty container (Optional, configured in setup_stops)
  2. Load empty container
  3. 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"
  }
}

Create a loaded container import transport order

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"
  }
}

Create a loaded container export transport order

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"
  }
}

Adding custom stops

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:

  1. Every stop needs to have a unique positive integer assigned to it. This will determine the sequence of the stops in the order.
  2. Every stops needs to have a custom_activity assigned 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"
  }
}

Examples

Basic order

{
  "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" }
}

Container IMPORT scenario

{
  "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" }
}

Container EXPORT scenario

{
  "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 with multiple stops example

{
  "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" }
}

Order with ADR goods

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 with pallets and custom barcodes

{
  "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" }
}

Status updates

The API supports status updates for specific entities. This can either be via an endpoint or webhook.

Task

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.

Order

You can change the status of an order via the webhook or endpoint.

Stop

This webhook allows you to either update:

  1. stops
  2. 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.

Booking

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.

Visibility

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) and COMPLETED (all stops for order completed).
  • Stop level
    • We send out a visibility event on AT_STOP (arrived at stop), COMPLETED (all activities completed for stop).
  • Position level (note: for every telematics update)
  • Trip level
    • We send a visibility event when a trip changes to PLANNED and when it transitions to COMPLETED.
  • Resource level
    • We send an event when a resource is assigned to a certain trip.

Accounting

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.

Synchronize invoices/credit notes

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.

Sync invoice/credit note flow

It is allowed to only process a subset of the available tasks and process the remaining invoices later.

Example

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": {....}}

Fetch updated customer information

Example

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.

Synchronize blocked status of customer

Example

Update the customer blocked status:

curl -X POST https://api.qargo.com/v1/company/*id_of_customer* -H 'Content-type: application/json' -H 'Authorization: Bearer *access_token*' -d  '{"is_blocked": true}'

Response:

{"id": "<id_of_customer>", "is_blocked": true, ....}

Creating contacts for a customer or subcontractor

You can create a contact for a customer or subcontractor by providing a contacts list in the payload.

Example

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"]}]}'

Updating contacts for a customer or subcontractor

To update a contact, you need to provide the id of the contact you want to update in the payload.

Example

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"]}]}'

Archiving a contact for a customer or subcontractor

To archive a contact, you need to provide the is_archived field in the payload along with the id of the contact you want to archive.

Example

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"]}]}'

Resources

Resource groups

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.

Looking up resource groups

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.

Reading a resource's groups

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" }
  ]
}

Updating a resource's group

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.

Errors

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.

Extras

Resources can be associated with stop extras (e.g. ADR, taillift, temperature control) to indicate which extras the resource is compatible with. Extras are specific to your environment — use the TMS UI or ask your Qargo contact to find the codes available.

Setting extras on create

Include extras in the POST body to set extras when creating a resource.

POST /resource
{
  "resource_type": "TRACTOR",
  "name": "Truck 01",
  "extras": [
    { "code": "ADR" },
    { "code": "TAIL" }
  ]
}

Response (all read endpoints)

{
  "extras": [
    { "id": "uuid-1", "code": "ADR", "name": "ADR Transport" },
    { "id": "uuid-2", "code": "TAIL", "name": "Taillift" }
  ]
}

Updating extras

Providing extras replaces the entire list. Omitting the field leaves existing extras untouched. Send an empty list to clear all extras.

PATCH /resource/{resource_id}
{ "extras": [{ "code": "TAIL" }] }

Error — duplicate code

If a code matches more than one extra in the tenant, the API returns an error.

HTTP 400
{ "message": "Multiple extras found with code 'TAIL'. Please ensure extra codes are unique, or contact support." }

Unavailabilities

Creating a unavailability

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

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"
}

Deleting an unavailability

Deleting a unavailability will remove the unavailability from the system. This is not reversable.

E-invoicing

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.

Peppol

For more information on Peppol E-invoicing, see https://help.qargo.com/en/articles/304774-invoices-peppol-in-qargo.

Workflows

Importing E-invoices into Qargo via webhook

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 and answers

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:

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": "DELIVERED",
                              "stop_location_code": "DEPOT-001",
                              "stop_match": {
                                "location": {
                                  "postal_code": { "matches_any": ["NW1 2AB"] }
                                }
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        ]
      }
    }
  ]
}

Document sync via question_paths

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"
    }
  }
]

Replacing a document

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"
    }
  }
]
FieldTypeRequiredDescription
remote_documentobjectNoObject with upload id of uploaded document
embedded_documentobjectNoDocument info with base64 encoded document
external_idstringNoIdentifier of the document in your system, used to replace it

remote_document fields

FieldTypeDescription
upload_idUUIDUpload id of document, received from the /document/upload_content endpoint

embedded_document fields

FieldTypeDescription
contentstringBase64 encoded document
content_typestringThe content type of the embedded document
filenamestringThe filename of the embedded document

Actions

Apart from updating fields and documents, question paths can be configured to trigger one of the following actions.

assign_resource

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-AB

Matching strips all non-alphanumeric characters and is case-insensitive, so VB-123-AB, VB 123 AB, and VB123AB all resolve to the same resource.

scan_barcode

Records a barcode scan event on a handling unit. An optional stop match is provided, which if matched will record which stop the scan is related to alongside the scan. If the stop is not matched the scan will still succeed, but the stop will not be recorded.

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"] }
      }
    }
  }
]
FieldTypeRequiredDescription
timestampISO 8601 datetimeYesTime of the scan event
statusstringNoScan status (see below)
barcodestringNoBarcode value; used to identify the handling unit. Optional as the unit will have been matched in the partial order update.
stop_matchobjectNoCriteria for matching the scan to a specific stop on the trip (see below)
stop_location_codestringNoLocation identifier code
descriptionstringNoFree-text description

stop_match fields

FieldTypeDescription
stop_typestringType of stop to match: PICKUP, DELIVERY, DEPOT_UNLOAD or DEPOT_LOAD
idobjectMatch by stop ID: { "matches_any": ["<id>"] }
reference_numberobjectMatch by stop reference number: { "matches_any": ["<reference>"] }
locationobjectMatch by the stop's location (see below)
legobjectMatch 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 left unlinked (or the update rejected) instead.

Scanstop_typeleg.leg_type
COLLECTION_DEPOT_SCANNED_INDEPOT_UNLOADPICKUP
COLLECTION_DEPOT_SCANNED_OUTDEPOT_LOADTRANSFER (2 legs: DELIVERY)
DELIVERY_DEPOT_SCANNED_INDEPOT_UNLOADTRANSFER (2 legs: n/a)
DELIVERY_DEPOT_SCANNED_OUTDEPOT_LOADDELIVERY

stop_match.leg fields

FieldTypeDescription
leg_typestringType of leg the stop bounds: PICKUP, TRANSFER, DELIVERY, DIRECT, EMPTY

stop_match.location fields

FieldTypeDescription
idobjectMatch by location ID: { "matches_any": ["<id>"] }
nameobjectMatch by location name: { "matches_any": ["<name>"] }
postal_codeobjectMatch by postal code: { "matches_any": ["<postal_code>"] }
country_codeobjectMatch by country code: { "matches_any": ["<country_code>"] }

Available status values:

ValueDescription
SCANNED_INHandling unit has been scanned in at a pickup stop or at a depot
STOREDHandling unit is in storage at a depot
SCANNED_OUTHandling unit has been scanned out of a depot or at a delivery stop

MCP

The Qargo MCP server lets an AI assistant call the Qargo API on behalf of a signed-in user, using the Model Context Protocol.

What it is

MCP is an open standard for connecting AI assistants to external systems. The Qargo MCP server implements it as a thin layer over this API. It exposes no separate data model, and every call it makes is an ordinary API call, subject to the same authentication and rate limits as any other.

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.

Endpoint

The server is at https://mcp.qargo.com/mcp, and appears in the client as Qargo.

Transport is MCP over streamable HTTP. Server-sent events are not supported.

Not the same as the documentation MCP

This site also publishes a documentation MCP server, offered through the Connect to Cursor and Connect to VS Code buttons at the top of each page. That server reads this API reference and nothing else. It has no access to tenant data and no relationship to mcp.qargo.com.

Prerequisites

Three conditions must be met before a connection succeeds.

RequirementScopeSet by
Qargo IntelligenceTenantQargo
External API accessTenantQargo
MCP access, read-only or read and writeIndividual user, per tenantQargo

MCP access defaults to disabled for every user. Enabling Qargo Intelligence on a tenant grants it to nobody.

For access requests, please contact us at integrations@qargo.com.

Connecting

Authorisation uses OAuth 2.1 with PKCE and dynamic client registration, so a compliant client needs no Qargo-specific configuration.

Flow

Point the client at the endpoint with no credentials. It discovers the authorisation server, registers itself, and opens a browser. The user signs in to Qargo, the browser returns an authorisation code, and the client exchanges it for tokens.

{
  "mcpServers": {
    "qargo": {
      "type": "http",
      "url": "https://mcp.qargo.com/mcp"
    }
  }
}

Clients that expose a connector UI rather than a config file need only the URL.

Authorisation server details

Most clients discover these automatically. They are documented for clients that ask for them explicitly.

SettingValue
Discoveryhttps://oauth.qargo.com/.well-known/oauth-authorization-server
Authorization endpointhttps://oauth.qargo.com/authorize
Token endpointhttps://oauth.qargo.com/token
PKCERequired. S256 only, plain is rejected
Client authenticationNone. Public clients only
Client registrationDynamic only, per RFC 7591
ScopesNot used. The scope parameter is ignored
RefreshSupported. grant_type=refresh_token

Clients requiring a pre-issued client_id and client_secret cannot connect, because Qargo issues neither. This rules out platforms whose configuration form demands static client credentials, including Gemini Enterprise.

Token model

The token the client holds identifies the user but carries no tenant claims. It can do nothing except list the tenants that user can reach. Every tenant-scoped call triggers a server-side exchange for a token carrying the user's Qargo role in that tenant.

TokenLifetimeNotes
Client token1 hourRefreshable
Tenant token1 hourMinted per tenant on demand

Authorisation is re-checked on every call and never cached, so revoking a user's MCP access takes effect on their next request.

Sessions

Sessions expire and require the user to sign in again, in practice about once a day. Expect re-authentication rather than treating it as an error.

Clients must send a stable Mcp-Session-Id header across a conversation. Production write approval is keyed on it, so a client that omits it or rotates it per request cannot complete a write. See limits and safeguards for the approval flow.

Client setup

Any MCP client supporting streamable HTTP and dynamic client registration can connect. Configuration for the clients Qargo tests against follows.

Claude Desktop and claude.ai

Add a custom connector under Settings > Connectors with the address https://mcp.qargo.com/mcp. Authorisation opens in a browser on first use.

Claude Code

claude mcp add --transport http qargo https://mcp.qargo.com/mcp

Then run /mcp and select qargo to authenticate. Tokens are stored per project unless the server is registered globally.

ChatGPT

Custom MCP connectors sit behind developer mode, on paid plans only. In Business, Enterprise and Education workspaces a workspace owner creates and publishes the app, and members cannot add it themselves. On Plus and Pro, an individual user adds it directly. Either way each user authenticates separately, so each gets their own Qargo permissions.

Enter the endpoint and select OAuth. Leave client ID and secret empty, since dynamic registration covers them.

Gemini

Gemini Enterprise is not supported. It requires a static client_id and client_secret in its custom MCP server configuration, and it requires a scope list. Qargo issues no client credentials and ignores the scope parameter. The consumer Gemini app has no custom MCP server option at all.

Gemini CLI can connect, because it supports dynamic discovery:

{
  "mcpServers": {
    "qargo": {
      "httpUrl": "https://mcp.qargo.com/mcp"
    }
  }
}

Run /mcp auth qargo to authenticate. OAuth requires a local browser and does not work over SSH.

Other clients

A client works if it supports streamable HTTP, PKCE with S256, dynamic client registration, and a stable Mcp-Session-Id. Test with tools/list before assuming write support.

Tools and access levels

The server exposes six generic tools rather than one tool per endpoint. Assistants discover operations at runtime from the OpenAPI description.

Tools

ToolPurpose
list_tenantsLists the tenants the caller can access, with their role in each. Available even with no access granted.
get_tenant_detailsReturns identity, locale and billing address details for one tenant.
external_api_discoverLists available operations, filterable by domain, method or free text.
external_api_schemaReturns the full request and response schema for one operationId, with references resolved inline.
external_api_callExecutes an operation by operationId, with path parameters, query parameters and a JSON body.
request_uploadReturns a presigned URL and a file_id for a file to be attached to a later call.

Every tenant-scoped tool accepts tenant_id or tenant_slug. Provide exactly one.

Tool annotations

Every tool carries MCP annotations, which clients use to decide when to prompt the user.

AnnotationApplied to
readOnlyHint: trueAll read operations. Most clients execute these without asking.
destructiveHint: falseOrdinary writes. Qargo write approval still applies.
destructiveHint: trueexternal_api_call and integration actions.

Operation allowlist

external_api_discover and external_api_call are restricted to an allowlist of approved operations. Anything outside it is neither listed nor callable.

DomainOperations
Accounting33
Resource17
Company14
Order7
Task3
Trip3
Document2
Identity1

Deprecated endpoints, webhook receivers and dispatch, authentication token generation, and webhook test utilities are excluded by design.

Access levels

Access is a server-side property of the user, not an OAuth scope. Clients request nothing and cannot influence it.

LevelGrants
DisabledNo tools. The default for every user.
Read-onlyEvery read-only operation.
Read and writeReads, plus every write and destructive operation.

Write access alone is not offered. external_api_call resolves each operation through a read-scoped client first, so a write-only user could not call it.

Errors

ClassWhat the assistant receives
Tool errorThe specific message plus a hint naming the next tool to call. Covers bad input, missing records, wrong tenant and insufficient access.
Write protection errorAn approval URL and instructions to retry after approval.
Internal errorA generic message only. Details are not exposed.

A 404 from the underlying API is returned as information, not as a failure.

Limits and safeguards

Calls made through MCP are ordinary API calls, so the rate limits apply unchanged. Additional constraints exist because the caller is an assistant rather than an application.

Production write protection

Writing to a production tenant requires explicit human approval before the first change in a session. The tool returns an approval URL:

https://app.qargo.com/<tenant_slug>/mcp/write-protection?sessionId=<id>&ttl=<minutes>

The user opens it, approves, and asks the assistant to retry. Approval is scoped to the user, the tenant and the assistant session together, so a new session requires a new approval.

Two conditions must hold. The user must open the link in a browser already signed in to app.qargo.com, and the client must send a stable Mcp-Session-Id. If the approval store is unavailable, production writes are refused. Reads are unaffected.

Rate limits

Limits are enforced per tenant on the credential, not per user, and are shared with any other API traffic that tenant generates. Exceeding them returns 429 Too Many Requests with a Retry-After header. See rate limits for current figures.

Response size and pagination

ConstraintBehaviour
List resultsCapped at 50 records per call, with a pagination hint in the response
Response sizePayloads above the response budget are written to temporary storage and returned as a signed URL rather than inline
File uploadsTwo-step through request_upload, 20 MB maximum. Tools never receive file bytes directly.

What is out of scope

  • Aggregated reporting, analytics and dashboard generation. Use the API directly, or the SQL based data warehouse connector.
  • Tenant configuration, feature flags and integration setup.
  • Any operation absent from the allowlist.

Operational guidance

Assistants are non-deterministic. Treat MCP as a supervised interface, not an unattended one:

  • Grant read-only by default, and read and write only where a change workflow requires it.
  • Review changes before approving a write session, particularly any change affecting more than one record.
  • Prefer the REST API for anything scheduled, repeated or business critical.

For any questions about these limits, please contact us at integrations@qargo.com.

Changelog

Recent additions and changes to the API, newest first.

2026-09-04

API

  • Added: Good schemas gain an optional hs_codes object on order create and order read, carrying count: the number of HS codes for the good, used for customs rate calculation.

Webhooks

  • Added: GoodData and GoodUpdateData gain an optional hs_codes object on the partial order update webhook (creating and updating a good), carrying count: the number of HS codes for the good, used for customs rate calculation.

Outgoing data

2026-09-01

API

  • Added: Packaged items gain an optional waste object and goods gain waste_category, for cargo classified under the European Waste Catalogue. waste carries the ewc code with its hazard flag and localized description, plus consistency, persistent_organic_pollutants, processing_operation and emitter_type. Available on order upload, partial order update and in order responses.

2026-08-28

API

  • Added: BarcodeSource gains APC and PALLETLINE_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.

2026-08-26

API

  • Added: Stop extras accept a custom_fields object on order upload, matching order- and good-level extras.
  • Added: Consignment.tracking_link is now returned on order responses: the public tracking page URL for each consignment. It is null when 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.

Webhooks

  • Added: TrackingUpdateData gains an optional voltage object, carrying external_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.

2026-08-24

Webhooks

  • Added: PackagedItemInput.barcodes accepts a list of barcode strings on packaged items, matching the existing packaged_items[].barcodes field on order upload. Previously the partial order update dropped the field.

2026-08-19

API

  • Added: PaymentTermCode gains END_OF_MONTH_0_NET_20, for a payment term of end of this month plus 20 days.

Webhooks

2026-08-14

API

  • Fixed: The /me response now includes active_tenant_slug for CUSTOMER-role tokens, matching other API roles.
    • Affects: System
    • Endpoints: GET /me

2026-08-13

Webhooks

  • Added: Document answers in question_answers now accept external_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.

2026-08-12

API

  • Changed: Charge status now reports INVOICE_POSTED for charges on a posted invoice and DO_NOT_INVOICE for charges excluded from invoicing. These were previously reported as CREATED, 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 to CREATED.
    • Affects: Order, Customer portal
    • Endpoints: GET /v1/orders/order/{order_id}/charges, POST /v1/orders/order/{order_id}/charges/approval

2026-08-11

Outgoing data

  • Added: VisibilityOrderStatus in operational visibility payloads gains BLOCKED, 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.

2026-08-10

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 over booking_reference.

2026-08-06

Webhooks

  • Added: The document-import webhook now accepts UK_EXPORTER_DRA and UK_IMPORTER_DRA as document_type values.

2026-08-05

API

  • Added: The intermodal booking payload now includes a trip object with the trip's id, name, status and custom_fields, so trip-level data (e.g. a customs procedure) can be used when dispatching bookings.
  • Deprecated: The root-level trip_name field on the intermodal booking payload is deprecated; use trip.name instead.
  • Fixed: Deleting a resource unavailability that is already deleted now reliably returns 204: the request no longer fails with a 500 when the unavailability is gone.
    • Affects: Resource
    • Endpoints: DELETE /v1/resources/resource/{resource_id}/unavailability/{id}

Outgoing data

  • Added: ResourceType in operational visibility payloads gains HANDLING, for handling equipment such as a forklift assigned to a stop, and SUBCONTRACTOR, 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.

2026-08-03

API

2026-07-31

API

  • Fixed: Deleting a resource unavailability that is already deleted now returns 204 instead of failing with a 400, so a retried delete no longer has to be special-cased. Updating an unavailability that does not exist now returns 404 naming the id, instead of a 400 reporting Instance matching query does not exist.
    • Affects: Resource
    • Endpoints: PUT /v1/resources/resource/{resource_id}/unavailability/{id}, DELETE /v1/resources/resource/{resource_id}/unavailability/{id}

2026-07-29

API

  • Added: Master data can now be looked up by filter instead of by paging through the full list. Companies accept code and accounting_customer_code, and accounts, tax rates and resource groups accept code. Every filter also has a batch form taking a comma-separated list, spelled code:in=A,B; the existing from_currency and to_currency filters 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_code holds 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_cursor on 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:in or resource_type:in is now reported as a validation error (422) rather than a bad request (400), matching how an invalid resource_type is already reported. An empty list such as external_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.name is 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 with name omitted. Treat the field as optional and fall back to address and city when it is absent.

2026-07-24

Webhooks

  • Added: Consignment updates now support CANCEL and UNCANCEL operations. CANCEL moves a consignment to CANCELLED and takes its stops off the active route while keeping the record for invoicing and audit, unlike DELETE, which removes it entirely. UNCANCEL reverts a cancelled consignment to a plannable state. Both require a consignment match, and UNCANCEL applies only to a consignment that is currently cancelled.

2026-07-23

API

  • Fixed: Updating a resource no longer returns a server error when note or external_id is omitted; the value is now stored as an empty string, matching create. Sending an explicit null for note, external_id, name, or locale is 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_type can now be BARGE or AIRPLANE, used by the resources that barge and air intermodal connections create.

Outgoing data

2026-07-22

API

  • Removed: Order status responses no longer include first_pickup_stop. The same information can be derived from the stops array, which is ordered by stop sequence: the first stop with a pickup activity_label is the first pickup stop, and likewise the last stop with a delivery activity_label is the last delivery stop.
    • Affects: Order
    • Endpoints: GET /v1/orders/order/{order_id}/status

2026-07-20

API

  • Added: Resource create, update and patch now accept is_archived. Sending is_archived: false reactivates a previously archived resource, restoring it with its existing data; sending true archives 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}

2026-07-14

API

  • Fixed: Payment status updates now accept UNPAID. Reporting an invoice as UNPAID reopens its payment task and clears the paid amount and date on the invoice; previously the documented UNPAID value 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, with eta_timestamp, actual_start_timestamp and actual_end_timestamp for the departure and arrival stops. The timestamps are only applied when the integration is configured to sync stop times.

2026-07-10

API

  • Added: Order status responses now include first_pickup_stop.
    • Affects: Order
    • Endpoints: GET /v1/orders/order/{order_id}/status
  • Changed: last_delivery_stop now uses the documented order-status stop shape.
    • Affects: Order
    • Endpoints: GET /v1/orders/order/{order_id}/status

2026-07-09

API

  • Added: GET /v1/resources/resource now documents the supported query filters: cursor, updated_after, external_id, external_id:in, resource_type and resource_type:in.
    • Affects: Resource
    • Endpoints: GET /v1/resources/resource

2026-07-07

API

  • Added: Sales invoice and sales credit note responses now include e_invoicing registration metadata.

2026-07-06

API

  • Changed: Validation error responses now return an errors array instead of the flat detail, field and path fields. Each item is a ValidationErrorDetail with message, field, path and detail; 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.

2026-07-03

API

  • Added: New GET /v1/resources/resource_groups endpoint lists the tenant's resource groups (id, name, code), cursor-paginated. Archived groups are excluded.
  • 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.
  • Added: PATCH /v1/resources/resource/{resource_id} accepts a resource_group reference to allocate the resource to a group, or null to remove it from its current group.
    • Affects: Resource
    • Endpoints: PATCH /v1/resources/resource/{resource_id}

2026-07-02

API

  • Added: Location objects now include customs_metadata (with customs_office_code) alongside terminal_metadata.

2026-07-01

API

  • Added: Added the Location master-data API to create, update and retrieve locations, including address and opening hours. New endpoints: POST and GET /v1/locations/location, and GET, PUT and PATCH /v1/locations/location/{location_id}.

2026-06-15

Outgoing data

  • Added: The location dispatch webhook now includes a per-consignment tracking_link.

2026-06-03

Outgoing data

2026-05-28

Outgoing data

  • Added: Outgoing data now includes ADR hazard labels and special_provisions for dangerous goods.

2026-05-23

API

  • Added: Booking now exposes vessel, voyage, IMO and the associated references for intermodal flows.

2026-05-20

API

  • Added: ContainerStandardSize gains the FEET_24 and FEET_26 values.

2026-05-19

API

  • Added: The DocumentType enum is synced with the TMS, adding 23 new document types.
    • Affects: Resource
    • Endpoints: POST /v1/resources/resource/{resource_id}/validity, PUT /v1/resources/resource/{resource_id}/validity/{id}

2026-05-18

API

  • Added: The TaskType enum gains DISPATCH, returned by the available-tasks and task endpoints.

2026-05-12

Outgoing data

  • Changed: compatible_extras has been renamed to extras for consistency across resource models.

2026-05-07

API

  • Added: Booking now exposes seal_number.

2026-05-05

API

2026-04-27

API

  • Added: Order models now expose is_consignment_info_validated, indicating whether consignment information has been validated.
  • Added: Goods and handling units now return their id in order output, and ContainerType exposes the container_iso_code.
  • Added: ShippingRoute now exposes custom_fields and modality.

2026-04-24

API

  • Added: ResourceTypeEnum gains CHASSIS, and TimeWindow exposes use_location_opening_hours.

2026-04-21

API

  • Added: Resource and equipment models (Container, Trailer, Vehicle and their resource variants) now expose their id, and driver resources expose start_stop_location.

2026-04-17

API

2026-04-14

Webhooks

  • Added: Added the /v1/webhook/e-invoicing inbound webhook.

2026-04-13

API

  • Changed: BookingDimensions now exposes cargo_weight, tare_weight and verified_gross_mass; the single weight field is deprecated.
  • Deprecated: Companies now use credit_policy; the credit_limit_total field is deprecated.

2026-04-08

API

  • Added: Added a /me endpoint returning the authenticated API user.

2026-04-07

API

  • Added: Added the /v1/accounting/exchange-rate endpoint.
  • Added: Consignments now expose import_export, and ContactType gains SALES, CUSTOMS, IT, QUALITY, CLAIMS_INSURANCE and CUSTOMER_CONTACT.
  • Added: Customs exposes has_customs_territory_crossing, PackagedItem exposes total_net_weight_kg, and PackagingType exposes export_alias.

Webhooks

  • Added: Added the /v1/webhook/tracking-update inbound webhook.

2026-03-23

Outgoing data

2026-03-17

API

2026-03-13

API

  • Changed: Company create and update inputs now accept archived_customer and archived_subcontractor, and these read-only fields are no longer returned on company output: purchase, sales, credit_limit_total and timestamp_updated.

2026-03-11

API

Webhooks

2026-03-10

Outgoing data

2026-02-27

API

2026-02-24

API

Webhooks

2026-02-16

API

  • Changed: Purchase e-invoice and e-credit-note inputs now accept attachments; the id and is_credit_note fields are removed.

2026-02-10

API

2026-01-23

API

  • Added: Companies can be flagged as buyer/seller via is_buyer_or_seller, and consignments now accept and return buyer and seller.
  • Added: Purchase e-invoices and e-credit-notes now include invoice_type.

2026-01-16

API

  • Changed: Fleet resource models now expose billing_entity; on partial resource inputs the company field is replaced by subcontractor and billing_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, BillingEntity exposes id and is_default, and ContactType gains PAYMENT_REMINDERS.
  • Removed: Removed the unused good_all field from partial order updates.

2026-01-09

API

  • Added: PaymentTermCode gains additional terms: NET_12, NET_20, NET_52, NET_75 and the END_OF_MONTH_0_NET_{1,7,14,21,25} variants.

Outgoing data

2026-01-05

API

  • Added: Added the /v1/accounting/sales-invoice/ and /v1/accounting/sales-credit-note/ endpoints for creating sales invoices and credit notes.
  • Added: LineItem now exposes dimension_4, dimension_5 and dimension_6.
Download OpenAPI description
Languages
Servers
https://api.qargo.com