Containers
Retrieve Container
Retrieve detailed information about a specific container, including its current status, tracking history, and related data using the id of the container.
Error Handling
If the container doesn't exist or belongs to a different organization:
List containers
Retrieve a paginated list of containers with comprehensive filtering, sorting, and search capabilities. The endpoint returns containers along with their associated data.
Basic Usage
Fetch a list of containers with default pagination and sorting:
Pagination
The API uses page-based pagination to manage large sets of results. Each response includes a pagination object with the following information:
Default pagination settings:
- Page: 1
- Limit: 10 items per page
Pass limit=all to request the largest available page size, which is 1000. This is a page size, not an unlimited response - if more than 1000 containers match, you still need to page through the results using page. Note that when a search value is also supplied, any limit above 100 is reduced to 100. See the Query Parameter Constraints table below for the accepted page and limit values.
Example request for the second page:
Filtering Options
The API supports multiple filtering parameters to help narrow down results:
- Location Filtering
Filter containers by their physical location:
location_id: Location identifierlayout_id: Specific layout within a locationlayout_path: Filter by layout hierarchy path
A malformed location_id or layout_id (one that isn't shaped like a short id at all) returns a 400 error. A well-formed but non-existent or wrong-prefix id (for example a bare UUID) passes validation and simply matches no containers, returning a 200 with an empty data array.
- Status Filtering
Filter containers by their current status:
status: Comma-separated list of tracking statuses (for exampledelivered,picked_up,in_transit)filter: Predefined status group filter. Allowed values are:completedoutstandingexception
Any filter value outside the three listed above is rejected with a 400 error (see List Endpoint Error Handling below).
- ID Filtering
Filter containers by their id using a comma-separated list. This lets you batch-retrieve several containers in a single call instead of calling GET /v1/containers/:container once per id:
A malformed id value (one that isn't shaped like a short id at all) returns a 400 error. However, a well-formed id that is never a ctnr_-prefixed one - for example a bare UUID - passes validation, since the validator only checks the shape and not the prefix in that case. It simply matches no containers, returning a 200 with an empty data array rather than a 400. The same is true of location_id and layout_id.
- Date Filtering
Filter containers by their updated_at timestamp. updated_at accepts an optional operator prefix followed by a colon and one or more comma-separated values:
The date-filter grammar also defines null and !null tokens (in place of an operator/value pair, for example updated_at=null) to filter on the presence or absence of a value. updated_at on containers is always set, so these two tokens are not useful on this particular field.
Use a colon to separate the operator from its value(s), and a comma to separate multiple values:
Accepted value formats:
- Epoch seconds, for example
1780000000 - Epoch milliseconds (13 or more digits), for example
1780000000000 - A full ISO datetime with a
Zsuffix, for example2026-06-01T00:00:00Zor2026-06-01T00:00:00.123Z - RFC 3339 with a UTC offset, for example
2026-06-01T00:00:00+05:00or2026-06-01T00:00:00.123+05:00
The fractional-seconds part of an ISO/RFC 3339 value, if present, must have exactly 3 digits (milliseconds) - 2026-06-01T00:00:00.123Z is accepted, but 2026-06-01T00:00:00.1Z, 2026-06-01T00:00:00.12Z and 2026-06-01T00:00:00.123456Z are all rejected with a 400 error. Omitting the fractional part entirely (2026-06-01T00:00:00Z) is also accepted.
A date-only value such as 2026-06-01 is rejected with a 400 param.invalid error. This is the most common integration mistake for this filter - always send a full ISO datetime or an epoch value, never a bare date.
A bare updated_at value with no operator prefix (for example ?updated_at=1780000000) is not the same as eq:1780000000: the bare form matches only the exact stored instant, while eq: matches the entire second (that is, [1780000000.000, 1780000000.999]). When in doubt, use an explicit operator.
- Metadata Filtering
Filter containers based on metadata fields using the metadata query parameter:
Sorting
Control the order of returned results using sort parameters:
Search
The API provides advanced full-text search capabilities through the search parameter, allowing you to search containers using fuzzy, typo-tolerant matching across multiple fields. The search functionality examines key container properties including:
tracking_numbermetadata
Each container in the search results includes a special _search object that provides detailed information about the match:
The _search object includes highlighted matches using <mark> tags, making it easy to emphasize matching text in user interfaces. It also provides a relevance score between 0 and 1, where higher values indicate better matches.
By default, search results are ordered by relevance score to show the best matches first. However, you can override this by specifying an order_by parameter to sort by other fields like created_at, updated_at, estimated_delivery_at. The search functionality can be combined with other filter parameters to refine your results further.
Search strategy
When search contains multiple words, search_strategy controls whether a container must match ANY of those words or ALL of them:
Because the default is match_some, a multi-word search value widens your result set (and pagination.total_count) compared to requiring every term to match. Pass search_strategy=match_all to restore ALL-terms matching.
Query Parameter Constraints
The following constraints are enforced on list requests. A request that violates any of them returns a 400 error - see List Endpoint Error Handling below.
List Endpoint Error Handling
Invalid list requests return HTTP 400 with one of two body shapes, depending on where the request fails:
Schema validation errors - for example an unlisted filter value, a non-integer page, or a search string over 255 characters:
errors is an array of the field paths that failed validation, and data contains a per-field issue dictionary with more detail.
Parameter-helper errors - for example a date-only updated_at value, or a bwi/bwe operator missing its second value:
On this path, message echoes the offending value and errors is always an empty array - inspect message rather than errors to see what was wrong.