Getting Data Out

The Trackberry API

Read shipments, tracking and documents from your systems, upload documents, share tracking links, pre-allocate boxes, add notes, label and archive.

131 min read

Last updated

Goal

Read your organization’s shipment data from a script, a spreadsheet tool, a BI dashboard or your own system, without exporting files by hand.

The API is read-only, with a few exceptions: a token you create as “Read and write” can also make and revoke the tracking links you give your customers (see Customer links), upload documents for Trackberry to read (see Documents to data), pre-allocate boxes to your customers (see Pre-allocations) and add notes to a shipment (see Shipment notes), plus a few reversible actions on a shipment (see Shipment actions). Everything else returns what you can already see in Trackberry, as JSON, for one organization at a time. Changing or approving shipments still happens by email, upload or in the app.

For AI agents and code generators

The whole API is described in one OpenAPI 3.1 file that needs no token: https://trackberry.com/api/v1/openapi.json. Give that URL to your coding agent, or load it into a code generator or an API client such as Postman or Insomnia. It has every endpoint, parameter, enum value and field, each with a plain-language description of what it means for the business (for example how effective_eta, eta, original_eta and predicted_eta differ). It always describes the latest API version.

A few facts worth knowing before generating code:

  • Every field is always present. A field with no value is null, never missing, so declare nullable types instead of optional ones.
  • Ignore fields and enum values you don’t recognize. New ones are added without a new version.
  • Lists of shipments, alerts, checks, companies, products, purchase orders and expected containers are paged with limit and starting_after; the other lists are not paged.
  • The file is also linked from llms.txt, for agents that start there.

The rest of this page is the same contract written for people.

Create a token

  1. Go to Organization settings → API & webhooks (API if you are not an admin), at /your-slug/settings/api.
  2. Click Create token, give it a name that says where it will live (“Power BI refresh”, “ERP sync”), pick when it expires and choose its access (below).
  3. Copy the token. It is shown once. Trackberry only keeps a fingerprint of it, so nobody, including our team, can show it to you again. If you lose it, revoke it and create a new one.

A token belongs to you and to one organization. It can read everything you can read in that organization. Its access is one of:

  • Read only (the default): it can call every GET endpoint.
  • Read and write: it can also create and revoke customer tracking links, upload documents, pre-allocate boxes and write shipment notes, and nothing else; no other part of the API writes yet. Choose it only for the system that needs it, such as your ERP, and keep Power BI and other readers on read-only tokens.

A read-and-write token is only as powerful as you are. If an admin makes you a read-only member, its write calls stop working while its reads continue. The settings list shows each token’s access.

Members can create tokens for themselves; Viewers can’t. Admins and owners can see and revoke every token in the organization.

You can hold up to 10 live tokens per organization. Expired and revoked tokens don’t count. If you try to create an 11th, the form shows “You already have 10 active tokens for this organization. Revoke one first.” Click Revoke next to a token you no longer use, then try again.

A token stops working when:

  • it expires (30 days, 90 days, 1 year, or never, chosen when you create it),
  • someone revokes it in settings,
  • you leave the organization or are removed from it.

Tokens start with tb_ followed by 40 letters and digits. If you run a secret scanner, this pattern finds them: \btb_[A-Za-z0-9]{40}\b. Treat a token like a password: keep it in your secret store, never in a spreadsheet cell or a public repository.

Make a request

The base URL is https://trackberry.com/api/v1. Send the token in the Authorization header:

bash
curl https://trackberry.com/api/v1/organization \
  -H "Authorization: Bearer tb_your_token"
json
{
  "object": "organization",
  "id": "org_42",
  "name": "Fresh Imports Ltd",
  "slug": "fresh-imports",
  "api_version": "2026-10-01",
  "token": { "id": "tok_7", "name": "ERP sync", "scopes": ["read"], "expires_at": "2027-09-29T10:00:00Z", "user_email": "[email protected]" }
}

There is no organization slug in the URLs: the token already says which organization you are reading.

Versions

The API is versioned, so an integration you write today keeps working as the API grows.

  • Each version is named after the day it was released, such as 2026-10-01.
  • Your organization is pinned to the latest version the first time it calls the API without a Trackberry-Version header. Every later response uses that shape until an admin moves the organization forward from Organization settings → API & webhooks.
  • To try a newer version before switching, send it with a single request: Trackberry-Version: 2026-10-01. That does not change the pin.
  • Successful responses include a Trackberry-Version header with the version they were built for.

New fields, new endpoints and new values in a status list are added to every version, so your code should ignore fields it doesn’t recognize. Anything that removes, renames or changes the meaning of a field gets a new version, dated like the ones above, and the change is announced in these docs. There have been no breaking changes since 2026-10-01, the first version.

IDs, lists and formats

  • IDs are strings with a prefix that names the kind of object: shp_ for shipments, ctr_ containers, doc_ documents, alr_ alerts, chk_ checks, pkl_ packing lists, lbl_ labels, org_ organizations, cmp_ companies, tok_ tokens, leg_ route legs, evt_ tracking events, eta_ ETA revisions, plt_ pallets, pln_ packing lines, shl_ customer links, whs_ warehouses, wcl_ warehouse closures, prd_ products, por_ purchase orders, pol_ purchase order lines and exs_ expected containers. Treat them as opaque; pass them back exactly as you received them. An id with the wrong prefix, or from another organization, is a 404 when it is in the path.
  • Lists come back as { "object": "list", "data": [...], "has_more": true }, newest first. Ask for up to 100 items with limit (default 25). To get the next page, pass the id of the last item you received as starting_after, and stop when has_more is false. Items that arrive while you page don’t cause gaps or repeats.
  • Times are UTC in ISO 8601 (2026-09-29T14:03:00Z); calendar days are 2026-09-29. Filters accept either.
  • Weights are kilograms (net_weight_kg), even for an organization that shows pounds on screen. Temperatures are Celsius (temperature_celsius), and statuses are lowercase strings (in_transit).
  • Fields with no value are null, never missing. Empty lists are [].

Endpoints

All endpoints are GET, except the two that make and revoke customer links, the one that uploads a document, the three that change pre-allocations and the two that write a shipment’s notes, and the ones listed under Shipment actions.

Endpoint Returns
/organization Your organization, its pinned version, and the token you used
/shipments Shipments, newest first, with filters (below)
/shipments/{id} One shipment: status, ETA, route, carrier, tracking, containers, cargo totals, labels, check counts
/shipments/{id}/timeline Route legs, tracking events and every ETA revision
/shipments/{id}/map Route, ports, vessel position and track, to draw the voyage on a map
/shipments/{id}/free_time Demurrage and detention clocks for the shipment
/shipments/{id}/documents Documents attached to the shipment
/shipments/{id}/packing_lists Current packing lists with pallets, lines and totals
/shipments/{id}/inspections Inspection reports with per-pallet scores, defects and remarks (photos are counted, not served)
/shipments/{id}/messages The emails filed on the shipment: category, sender, subject and summary, never the body
/shipments/{id}/claim_notices The notices of damage sent to a carrier or forwarder about the shipment, without their text
/claim_notices/{id} One sent notice with its text, the record of what was said and when
/shipments/{id}/share_links GET lists a shipment’s customer links; POST creates one (needs a read-and-write token)
/share_links/{id} GET returns one customer link; DELETE revokes it (needs a read-and-write token)
/shipments/{id}/preallocations Every pre-allocation on the shipment: customer, boxes, price and value
/packing_lines/{id}/preallocations POST pre-allocates boxes of a line to a customer (needs a read-and-write token)
/preallocations/{id} PATCH changes a pre-allocation; DELETE removes it (needs a read-and-write token)
/shipments/{id}/notes POST adds a paragraph to the notes; PUT replaces them (needs a read-and-write token)
/documents POST uploads a document for Trackberry to read (needs a read-and-write token)
/documents/{id} One document’s details
/documents/{id}/data The fields Trackberry extracted from the document
/documents/{id}/file The document’s original file
/free_time/at_risk Containers close to or past their free time, most urgent first
/companies Suppliers, forwarders and customers; role and q (name or alias) filter them
/companies/{id} One company: roles, aliases, country, ERP code and live shipment counts
/shipments/{id}/labels POST puts one of the organization’s labels on a shipment (needs a read-and-write token)
/shipments/{id}/labels/{label} DELETE takes a label off a shipment (needs a read-and-write token)
/shipments/{id}/check_runs POST runs the shipment’s checks again (needs a read-and-write token)
/shipments/{id}/tracking_refreshes POST asks for fresh tracking, at most every 5 minutes per shipment (needs a read-and-write token)
/shipments/{id}/archive POST archives a shipment; DELETE brings it back (needs a read-and-write token)
/shipments/{id}/warehouse_arrival POST marks a shipment as received at the warehouse; admins and owners only (needs a read-and-write token)
/checks/{id}/acknowledgement POST accepts a failing check with a reason, DELETE withdraws that; admins and owners only (needs a read-and-write token)
/alerts/{id}/snooze POST hides an alert for 1, 3 or 7 days (needs a read-and-write token)
/alerts/{id}/dismissal POST hides an alert while the problem lasts (needs a read-and-write token)
/alerts/{id}/restoration POST brings a snoozed or dismissed alert back (needs a read-and-write token)
/alerts Open monitoring alerts; shipment filters to one shipment
/checks Failed and warning document checks; status and shipment filter them
/labels The organization’s labels, newest first
/carrier_free_times The organization’s negotiated free-time terms per carrier
/products The product catalogue with each supplier’s reference and description; q, status and supplier (a company id from /companies) filter it
/products/{id} One product
/purchase_orders Purchase orders with their lines, open ones by default: ordered, received, invoiced and packed quantities; status, q and supplier (a company id from /companies) filter them
/expected_shipments Containers suppliers have agreed to send, with the documents received and the shipment each was matched to; status, q and supplier (a company id from /companies) filter them
/warehouses The organization’s warehouses: weekdays open and holiday calendar
/warehouses/{id}/closures A warehouse’s closures, upcoming by default
/warehouses/{id}/delivery_days Which days in a range the warehouse can receive containers, and why not
/feed/shipments Every shipment as one flat table, as CSV or JSON, for Power BI and Excel
/feed/events Every tracking event as one flat table, as CSV or JSON
/feed/kpis The Statistics page’s KPIs as rows of metric, period, dimension and value, as CSV or JSON

Searching shipments

/shipments accepts these parameters, all optional:

Parameter Example Meaning
q MSCU1234567 Reference, B/L, AWB, container number or produce
status in_transit,arrived One or more of draft, validated, in_transit, arrived, in_warehouse
labels lbl_3,lbl_9 Shipments that carry all of these labels
archived true false (default), true, or any
created_after, created_before 2026-09-01 When the shipment was created
eta_after, eta_before 2026-10-01T00:00:00Z Expected arrival
supplier, forwarder, customer cmp_41 Shipments linked to this company, from /companies
limit, starting_after 50, shp_812 Paging, as above
bash
curl "https://trackberry.com/api/v1/shipments?status=in_transit&eta_before=2026-10-07" \
  -H "Authorization: Bearer tb_your_token"

Every shipment object has a public_tracking_url: the shipment’s public tracking page, which anyone with the link can open without logging in. Send it to a customer or partner instead of giving them access to Trackberry. It is the English page; put /es before /track to get the Spanish one (https://trackberry.com/es/track/...).

The field is null when your organization has public tracking pages turned off (in the organization’s settings), or when the shipment is archived or not yet validated, because the page does not show those. The link can’t be guessed, and it changes if someone regenerates the shipment’s link in Trackberry, so read it from the API when you need it rather than storing it.

A customer link is a tracking link made for one of your own customers. It opens the ordinary public tracking page, but leads with the customer’s own order number (“Your order: PO-4471”) instead of a container number they never asked about. It can be switched off on its own without touching the generic link or any other customer’s. You can make them by hand from the shipment page; the API lets your ERP do it for you.

A typical flow for an importer whose ERP holds the sales orders:

  1. When the order is confirmed or the delivery note is printed, find the shipment: GET /shipments?q=MSCU1234567 with the container number or B/L from the order, and take the id of the match.
  2. Make the link with that id and your order number:
bash
   curl -X POST https://trackberry.com/api/v1/shipments/shp_812/share_links \
     -H "Authorization: Bearer tb_your_write_token" \
     -H "Content-Type: application/json" \
     -d '{"customer_reference": "PO-4471", "label": "Fresh Direct"}'

The response is the link, and its url is what you give the customer. 3. Store the url on the sales order or print it on the delivery note. You can read it again at any time with GET /share_links/{id}. 4. If the order is cancelled, DELETE /share_links/{id} revokes it. The URL stops opening at once and the customer’s tracking emails through it stop.

Creating is safe to repeat. If the shipment already has an active link with the same customer_reference (compared after trimming extra spaces, and case-sensitive), you get that link back with a 200 instead of a second one with a 201, so a retry after a timeout never doubles up. A repeat returns the existing link unchanged: its label is not updated, and a different label on the retry is ignored. Revoke a link and ask again and you get a new one. label is a note for your own team; the customer never sees it.

Creating needs public tracking pages to be turned on for your organization and a shipment that is live (validated or further along, and not archived), the same rules as the button on the shipment page. Otherwise the call is a 400 with code not_shareable. Every link made or revoked this way is recorded in the shipment’s activity log, marked as made through the API, with the member who owns the token. An admin or owner can revoke any link; a member can revoke only links made with their own tokens or on the shipment page.

Pre-allocations

A pre-allocation sets boxes of one packing line aside for a customer, with an optional tentative price, the same as the “Pre-allocate” action on a packing table in Trackberry. The API lets a script or an assistant see what is taken and change it.

  1. Read the packing lists with GET /shipments/{id}/packing_lists. Each line has a box_count and a preallocated_boxes, the boxes already set aside; the difference is what is still free.
  2. See who holds what with GET /shipments/{id}/preallocations: every pre-allocation on the shipment, with the packing_line_id and pallet_id it belongs to.
  3. Set boxes aside with POST /packing_lines/{packing_line_id}/preallocations:
bash
   curl -X POST https://trackberry.com/api/v1/packing_lines/pln_5521/preallocations \
     -H "Authorization: Bearer tb_your_write_token" \
     -H "Content-Type: application/json" \
     -d '{"allocatee": "Fresh Direct", "boxes": 40, "unit_price": 12.5, "currency": "EUR"}'

The boxes on a line cannot add up to more than its box_count; if they would, the call is a 400 naming boxes that says how many are left. unit_price is the price per box, or, with "price_basis": "total", the total for these boxes (it is stored as a price per box). Without a price there is no currency and no value. 4. Change or release it with PATCH /preallocations/{id} (only the fields you send change; "unit_price": null removes the price) and DELETE /preallocations/{id}.

Each POST adds one pre-allocation: sending it twice sets the boxes aside twice (or fails if there are not enough boxes), so after a timeout list the shipment’s pre-allocations before you retry. Every change is recorded in the activity log of the pallet, marked as made through the API, with the member who owns the token. A token owned by a read-only member can read pre-allocations but not change them (403 read_only_member).

Shipment notes

Every shipment has free-text notes, written in Markdown, shown on its page and returned as notes on GET /shipments/{id}. Two calls write them:

  • POST /shipments/{shipment_id}/notes with {"text": "..."} adds a paragraph after what is there, separated by a blank line. It never removes anything, so a script or an assistant cannot wipe what a colleague wrote. Sending the same text twice adds it twice.
  • PUT /shipments/{shipment_id}/notes with {"notes": "..."} replaces the whole text, and an empty string clears it. Use it only when you hold the full text and mean to overwrite it.

Both answer with the notes as they now stand. The notes are limited to 20,000 characters (a 400 naming text or notes otherwise). A change is recorded in the shipment’s activity log as a notes change made through the API, and, like edits in the app, several changes by the same person within two minutes are shown as one entry.

Shipment actions

A few reversible actions on a shipment, its checks and its alerts need a “Read and write” token, and are what the same buttons do in the app:

  • Labels. POST /shipments/{shipment_id}/labels with {"label": "urgent"} (the words a person would use, which find “🔥 Urgent”, or an id from GET /labels) and DELETE /shipments/{shipment_id}/labels/{label}. Labels are not created through the API; an unknown name is a 404 that lists the existing ones, and one that fits several is a 400 ambiguous_label naming them with their ids. Both are idempotent.
  • Checks. POST /shipments/{shipment_id}/check_runs queues the shipment’s checks again. POST /checks/{check_id}/acknowledgement with a reason accepts a failing check and DELETE on it withdraws that (admins and owners only, like the app); there is no “skip”, which overwrites the result.
  • Tracking. POST /shipments/{shipment_id}/tracking_refreshes asks for fresh tracking. Each refresh costs a request to the tracking service, so a shipment is refreshed at most once every 5 minutes (429 refresh_too_soon with Retry-After).
  • Alerts. POST /alerts/{alert_id}/snooze (days: 1, 3 or 7), /dismissal and /restoration hide an alert for a while, for as long as the problem lasts, and bring it back.
  • Archive and warehouse. POST and DELETE /shipments/{shipment_id}/archive, and POST /shipments/{shipment_id}/warehouse_arrival (admins and owners only), which sets the status to in_warehouse.

Repeating a call that already took effect answers the same and changes nothing. Changes to labels, archiving, acknowledgements and warehouse arrivals are recorded in the shipment’s activity log as made through the API, with the member who owns the token; snoozing, dismissing and restoring an alert are recorded as alert.snoozed, alert.dismissed and alert.restored. A token owned by a read-only member can read but not change anything (403 read_only_member).

Documents to data

Trackberry reads loading sheets, packing lists, invoices and bills of lading and turns them into fields your ERP can import, the same way it reads the documents you email in. The API lets your system send it files directly, whether or not you track the shipment with Trackberry.

A typical flow for an importer whose ERP needs the figures from a supplier’s loading sheet:

  1. Upload the file with the container number it belongs to, and a key of your own so a retry is safe:
bash
   curl https://trackberry.com/api/v1/documents \
     -H "Authorization: Bearer tb_your_write_token" \
     -H "Idempotency-Key: 6f1c2a9e-1b7d-4c55-9a43-3f0e8d2b7c10" \
     -F [email protected] \
     -F container_number=MSCU1234566

The response is the document, with parse_status pending and data_available false. Keep its id. 2. Trackberry scans the file for viruses, works out what kind of document it is and reads it, usually within a few minutes. Poll GET /documents/{id} every 30 seconds or so until data_available is true (stop if parse_status becomes failed), or subscribe to the document.processed webhook instead of polling. 3. Read the fields with GET /documents/{id}/data.

Where the document goes depends on what you send with it:

  • shipment_id: on that shipment. An id that isn’t one of your shipments is a 400 naming shipment_id.
  • container_number: on the live, unarchived shipment carrying that container, as one of its containers or as its reference. If none does, Trackberry makes a new draft shipment with the container number as its reference. If two shipments carry it, the call is a 400 with code ambiguous_container; send shipment_id instead.
  • Neither: on a new draft shipment.

A shipment made this way is not tracked. It holds the documents and their checks, and Trackberry doesn’t follow a vessel or container for it. It counts toward your bill like any other shipment once its first document has been read. If your organization’s billing doesn’t allow a new shipment, the upload is refused with a 403 and code billing_blocked, and nothing is saved; see Billing.

The extracted figures reach your ERP export only after the same checks and review as any other document’s; see Ready for ERP.

Send an Idempotency-Key header with every upload, such as a UUID or your own line id. Repeating a key within 24 hours with the same file and the same shipment_id or container_number returns the first document with a 200 instead of making a second one with a 201. Using a key again for a different file or target is a 400 with code idempotency_key_reused. Without a key, sending the same file to the same shipment again also returns the first document, but an upload with neither shipment_id nor container_number makes a new draft shipment every time.

Files can be PDFs (digital or scanned), JPEG, PNG or TIFF images, Excel workbooks (.xlsx, .xls) or CSV files, up to 50 MB. Trackberry reads the type from the file’s contents, not its name. Each token can upload 120 files an hour. Every upload is recorded in the shipment’s activity log, marked as made through the API, with the member who owns the token.

BI feeds

Three endpoints return a whole table in one response, ready for Power BI, Excel or any tool that reads CSV or JSON from a URL. They use the same token as the rest of the API.

Feed One row per Default window
/feed/shipments Shipment Everything, archived included
/feed/events Tracking event The last 90 days of events (everything up to to if you pass only to)
/feed/kpis Metric, period and breakdown The last 12 calendar months

The metrics in the KPI feed are listed under What the KPI feed measures.

Add .csv or .json to the path (/feed/shipments.csv); with no extension you get JSON. Column names are snake_case and stable, new columns are only ever added at the end, and dates are ISO 8601. Narrow a feed with from and to (dates or date-times); the shipments feed also takes status and archived. The response is streamed, so a large organization is not a problem, and a feed is not paged. In JSON it is { "object": "feed", "name": "shipments", "columns": [...], "data": [...] } with one flat object per row. A CSV cell that starts with =, +, - or @ gets a leading apostrophe so a spreadsheet will not run it as a formula.

Prefer JSON for Power BI. Numbers arrive typed and no regional setting can misread a decimal point. CSV works too: it is UTF-8 with a byte order mark, line breaks inside a cell become spaces, and in Power BI you should pick Using locale → English (United States) when you change a column’s type.

The KPI periods are the month a shipment was created in, not the month it sailed or arrived, and the figures include archived and orphaned shipments, exactly as the Statistics page does.

Feeds are heavy, so an organization can run one at a time (a second request while one is running is a 429 with code feed_in_progress and a Retry-After header) and a token may request at most 6 feeds a minute. A feed that fails while it streams ends the connection abnormally, so your tool sees an error rather than a short table. Columns are only ever added at the end; Power BI ignores a new column until you edit the query.

Create one token per report, and name it after the report. The token is stored inside the .pbix file, so don’t share the file; if it leaks, revoke the token under Organization settings → API & webhooks. Always send the token in the Authorization header, never in the URL, where it would end up in logs and browser history. That page has these URLs ready to copy.

Power BI template

The quickest start is our ready-made report. Download the Power BI template (trackberry.pbit), open it in Power BI Desktop, and paste a read-only token when it asks for TrackberryToken. It loads all three feeds into four pages:

  • Overview: shipments in transit and arriving in the next 7 days, containers close to or past their last free day, shipments created and on-time arrivals by month, and every shipment in transit sorted by ETA.
  • Carriers and lanes: on-time arrivals by carrier and by lane, and every lane with its shipment count, average transit and average delay.
  • Free time: containers on the demurrage clock with their days left, and median days in each destination port.
  • Incidents and CO2: incidents by month and type, incidents per 100 shipments by carrier and by forwarder, and CO₂ by month.

The template holds no data and no token, so it is safe to pass around. Once you have pasted a token, save your report as a .pbix and keep it as private as the token itself. Power BI loads the three tables at the same time while Trackberry runs one feed per organization at a time, so the template waits and asks again when a feed is busy, which can add a few seconds to a refresh. Days left on the Free time page are calendar days, so they can differ by a day from Trackberry’s count when your free time is counted in working days. To change the token later, use Transform data → Edit parameters.

To build your own report instead, connect to the feeds directly.

Power BI Desktop

  1. Get data → Web → Advanced. Start with a .json URL.
  2. In URL parts paste https://trackberry.com/api/v1/feed/shipments.json.
  3. Under HTTP request header parameters add the header Authorization with the value Bearer tb_your_token.
  4. Click OK. If Power BI asks how to connect, choose Anonymous: the header already carries the token.
  5. Check the preview, then Load (or Transform Data; for JSON, expand the data list to a table and then its records).

For a scheduled refresh in the Power BI service, publish the report and open the semantic model’s settings. Set the data source credentials to Anonymous, its privacy level to Organizational, and tick Skip test connection. The header is stored with the query. Create a token that never expires, or put a reminder in your calendar before it does.

Excel

  1. Data → Get Data → From Other Sources → From Web, then choose Advanced.
  2. Paste the feed URL and add the Authorization header with the value Bearer tb_your_token.
  3. Choose Anonymous if asked, then Load. Data → Refresh All pulls fresh rows.

What the KPI feed measures

The KPI feed carries the figures of the Statistics page, computed by the same code, so a number in Power BI is the number on screen. Each row has the columns metric, period_start, period_end, dimension, dimension_value, value and unit. A monthly metric has one row per calendar month. A window metric has one row per carrier, lane, country or port, covering the whole window from the first day of the first month to today. The feed covers the last 12 months by default, and from reaches back up to 24.

Metric What it counts dimension Period unit
shipments_created Shipments created transport_type: ocean or air Monthly shipments
shipments_by_produce Shipments per produce type, top 8 produce Monthly shipments
shipments_by_supplier Shipments per supplier, top 8 supplier Monthly shipments
shipments_by_carrier Shipments per carrier, top 10. Carriers under 2% of shipments are grouped as Other carrier Window shipments
shipments_by_lane Shipments per port-to-port lane (Origin > Destination), top 10 lane Window shipments
shipments_by_origin_country, shipments_by_destination_country Shipments per country origin_country, destination_country Window shipments
arrivals_on_time, arrivals_late_up_to_5_days, arrivals_late_over_5_days Confirmed arrivals against the original ETA, top 10 carrier, lane Window shipments
on_time_arrival_pct Share of confirmed arrivals on or before the original ETA None Monthly percent
arrivals_measured Confirmed arrivals behind that percentage None Monthly shipments
port_dwell_median_days, port_dwell_q1_days, port_dwell_q3_days, port_dwell_p10_days, port_dwell_p90_days Days a container sits in the destination port between discharge and gate-out destination_port Window days
port_dwell_containers Containers behind the dwell figures, those still in port included destination_port Window containers
co2_tonnes CO₂ from tracked ocean and air shipments None Monthly tonnes
incidents Incidents by type: delay, rollover, free_time_breach, document_error or customs_hold incident_type Monthly incidents
incidents_by_carrier, incidents_by_forwarder, incidents_by_supplier Incidents, top 10 carrier, forwarder, supplier Window incidents
shipments_with_incidents_by_carrier, _by_forwarder, _by_supplier Shipments with at least one incident carrier, forwarder, supplier Window shipments
incident_rate_by_carrier, _by_forwarder, _by_supplier Incidents per 100 shipments carrier, forwarder, supplier Window per_100_shipments

For the long tail behind a top 10, build it from the shipments feed, which has every shipment. How incidents are detected is in the Statistics guide.

Errors

Errors have one shape, whatever went wrong:

json
{ "error": { "type": "invalid_request_error", "code": "invalid_parameter", "message": "limit must be an integer between 1 and 100", "param": "limit" } }
Status code What to do
400 invalid_parameter Fix the parameter named in param
400 invalid_version Send a published version in Trackberry-Version, or none
400 not_shareable Turn on public tracking pages, or choose a shipment that is live and not archived, then create the link again
400 file_empty The uploaded file has no content. Check the file and send it again
400 file_too_large The file is over 50 MB. Split it or reduce its resolution
400 unsupported_file_type Send a PDF, a JPEG, PNG or TIFF image, or an Excel (.xlsx, .xls) or CSV file
400 ambiguous_label The label you named fits several labels. The message lists them with their ids: send the id of the one you mean
400 ambiguous_container More than one live shipment carries this container number. Send shipment_id instead
400 idempotency_key_reused This Idempotency-Key was already used for a different file or target. Use a new key
400 not_trackable The shipment has no transport reference or has arrived: there is nothing to refresh
400 nothing_to_acknowledge The check is not failing or warning, so there is nothing to accept
400 cannot_mark_in_warehouse A shipment waiting for approval, or in error, cannot be marked as received at the warehouse
401 missing_token Add the Authorization: Bearer header
401 invalid_token The token is wrong, expired, revoked, or you left the organization. Create a new one
403 insufficient_scope The token can’t use this endpoint. Creating and revoking customer links, uploading documents, changing pre-allocations, writing shipment notes and the shipment actions need a “Read and write” token
403 read_only_member The member who owns the token is now a read-only member of the organization, so its write calls are refused. Reads still work
403 revoke_not_allowed Only an admin, or the member who made the link, can revoke it
403 billing_blocked The upload needed a new shipment and your organization’s billing doesn’t allow one. Check Organization settings → Billing, or send the shipment_id of an existing shipment
403 admin_required Accepting a check and marking a shipment as received at the warehouse are for admins and owners, as in the app
404 resource_missing No such object in this organization, or no such endpoint
429 rate_limited Slow down; wait the number of seconds in Retry-After
429 feed_in_progress Another BI feed for your organization is still running; wait the number of seconds in Retry-After and try again
429 refresh_too_soon The shipment’s tracking was refreshed in the last 5 minutes; wait the number of seconds in Retry-After

Limits

Each token can make 600 requests every 5 minutes, which is plenty for a sync that runs every few minutes. Requests from one IP address are capped at 1,200 every 5 minutes across all tokens, and requests with no token at all (including a fetch of openapi.json) are capped at 30 every 5 minutes per IP address. On top of these, each token can upload 120 documents an hour. When you hit a limit you get a 429 with a Retry-After header.

Endpoint reference

Every request takes the optional Trackberry-Version header described under Versions. Every response body below shows all of its fields: a field with no value is null, never missing. Times are UTC. Successful responses carry a Trackberry-Version header, and a 404 or 400 caused by a parameter does too. Errors have the shape described under Errors.

Get the organization and token behind the request

GET /organization (operation get_organization)

Use this first to check that a token works and to learn which organization it reads, which API version that organization is pinned to, and when the token expires. Read-only and cheap.

No parameters.

Example response, 200:

json
{
  "object": "organization",
  "id": "org_42",
  "name": "Fresh Imports Ltd",
  "slug": "fresh-imports",
  "api_version": "2026-10-01",
  "token": {
    "id": "tok_7",
    "name": "ERP sync",
    "scopes": [
      "read"
    ],
    "expires_at": "2027-09-29T10:00:00Z",
    "user_email": "[email protected]"
  }
}

Errors: 400, 401, 429.

List and search shipments

GET /shipments (operation list_shipments)

Use this to find shipments, to sync all shipments, or to answer questions like “what is arriving next week” (eta_after and eta_before) or “which shipments are in transit” (status). Newest first, keyset paged. Shipments still waiting for approval are never listed. Archived shipments are left out unless archived says otherwise. Each item is the full shipment object, the same as get_shipment. All parameters are optional and combine with AND.

Parameter In Type Description
q query string Free-text search. Case-insensitive, partial matches on the shipment reference, the ERP reference, the transport reference (bill of lading or air waybill number), the consignor and consignee names (also tolerant of small spelling differences), container numbers, and produce names (common aliases are understood). Spaces and dashes are ignored when matching transport references and container numbers, so MSCU 123456-7 finds MSCU1234567. An empty value means no search. Example: MSCU1234567.
status query comma-separated list Only shipments in one of these statuses. One comma-separated value. Repeating the parameter is not supported (only the last occurrence is used) and status[]= is a 400. The status error exists on shipments but cannot be filtered on. Omit to get every status. One of draft, validated, in_transit, arrived, in_warehouse. Example: in_transit,arrived.
labels query comma-separated list Only shipments that carry all of these labels (AND, not OR). One comma-separated value of label ids (lbl_ prefix), as found in labels[].id on shipments. A malformed id is a 400. Example: lbl_3,lbl_9.
archived query string Whether to include archived shipments. false (the default) lists only active ones, true only archived ones, any both. One of false, true, any. Default false. Example: any.
created_after query date-time or date string Only shipments created at or after this moment (inclusive). ISO 8601 date-time, or a bare date meaning midnight UTC at the start of that day. Example: 2026-09-01.
created_before query date-time or date string Only shipments created at or before this moment (inclusive). ISO 8601 date-time, or a bare date, which means midnight UTC at the start of that day: created_before=2026-09-30 excludes everything created after 00:00 UTC on 30 September. To include a whole day, pass the following day or a full date-time. Example: 2026-09-30T23:59:59Z.
eta_after query date-time or date string Only shipments whose effective_eta is at or after this moment (inclusive). Shipments with no ETA at all never match once either eta_after or eta_before is given. ISO 8601 date-time or bare date (midnight UTC). Example: 2026-10-01T00:00:00Z.
eta_before query date-time or date string Only shipments whose effective_eta is at or before this moment (inclusive). Same rules as eta_after, including the midnight rule for a bare date. Example: 2026-10-07.
supplier query string Only shipments supplied by this company. A company id (cmp_ prefix) from list_companies; anything else is a 400. A well-formed id that is not in this organization simply matches nothing. Example: cmp_41.
forwarder query string Only shipments handled by this forwarder. A company id (cmp_ prefix) from list_companies; anything else is a 400. A well-formed id that is not in this organization simply matches nothing. Example: cmp_41.
customer query string Only shipments for this customer. A company id (cmp_ prefix) from list_companies; anything else is a 400. A well-formed id that is not in this organization simply matches nothing. Example: cmp_41.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last shipment of the previous page. Must start with shp_; anything else is a 400. Example: shp_812.

Example response, 200:

json
{
  "object": "list",
  "has_more": true,
  "data": [
    {
      "object": "shipment",
      "id": "shp_812",
      "reference": "SHIP-20260915-K7QX",
      "erp_reference": "PO-88231",
      "transport_reference": "MEDURU156671",
      "transport_reference_type": "bill_of_lading",
      "transport_type": "ocean",
      "load_type": null,
      "house_bl": null,
      "forwarder_reference": null,
      "forwarder_eta": null,
      "cargo_type": "reefer",
      "temperature_celsius": 2.0,
      "status": "in_transit",
      "archived": false,
      "archived_at": null,
      "validated_at": "2026-09-16T08:30:00Z",
      "approved_at": "2026-09-15T12:05:00Z",
      "origin": {
        "location": "Callao",
        "country": "Peru",
        "timezone": "-05:00",
        "code": "PECLL"
      },
      "destination": {
        "location": "Rotterdam",
        "country": "Netherlands",
        "timezone": "+02:00",
        "code": "NLRTM"
      },
      "etd": "2026-09-10T18:00:00Z",
      "eta": "2026-10-05T06:00:00Z",
      "effective_eta": "2026-10-05T06:00:00Z",
      "original_eta": "2026-10-02T06:00:00Z",
      "predicted_eta": null,
      "availability_date": "2026-10-07",
      "carrier": {
        "name": "MSC",
        "scac": "MSCU"
      },
      "tracking": {
        "state": "available",
        "status": "in_transit",
        "unavailable_reason": null,
        "halted_reason": null,
        "last_tracked_at": "2026-09-29T09:41:00Z",
        "carrier_updated_at": "2026-09-29T06:12:00Z"
      },
      "parties": {
        "consignor": "Agro Andes SAC",
        "consignee": "Fresh Imports Ltd",
        "notify_party": null
      },
      "supplier": {
        "id": "cmp_41",
        "name": "Agro Andes SAC"
      },
      "forwarder": null,
      "customer": {
        "id": "cmp_57",
        "name": "Fresh Imports Ltd"
      },
      "produce": [
        "Grapes"
      ],
      "organic": false,
      "cargo": {
        "pallets": 20,
        "boxes": 2400,
        "net_weight_kg": 9600.0,
        "gross_weight_kg": 10320.0
      },
      "containers": [
        {
          "object": "container",
          "id": "ctr_1301",
          "number": "MSCU1234567",
          "seal_numbers": ["ES123456"],
          "vessel": "MSC AURORA",
          "voyage": "2609W",
          "port_of_loading": "Callao",
          "port_of_discharge": "Rotterdam",
          "etd": "2026-09-10T18:00:00Z",
          "eta": "2026-10-05T06:00:00Z",
          "cargo_type": "reefer",
          "temperature_celsius": 2.0
        }
      ],
      "labels": [
        {
          "object": "label",
          "id": "lbl_3",
          "name": "Priority",
          "color": "red",
          "color_hex": "#ef4444"
        }
      ],
      "checks": {
        "total": 6,
        "passed": 4,
        "failed": 1,
        "warnings": 1,
        "skipped": 0,
        "pending": 0,
        "acknowledged": 0
      },
      "notes": null,
      "public_tracking_url": "https://trackberry.com/track/acme-produce/shipments/Qw3rTy9uIoPaSdFgHjKlZxCvBnM4s7Ab",
      "created_at": "2026-09-15T12:00:00Z",
      "updated_at": "2026-09-29T09:41:00Z"
    }
  ]
}

Errors: 400, 401, 429.

Get one shipment

GET /shipments/{id} (operation get_shipment)

Use this when you already have a shipment id and want its current state: status, ETAs, route, carrier, tracking health, parties, produce, cargo totals, containers, labels and check counts. Archived shipments are still found. For tracking events and ETA history use get_shipment_timeline; for demurrage and detention use get_shipment_free_time.

Parameter In Type Description
id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Example response, 200:

json
{
  "object": "shipment",
  "id": "shp_812",
  "reference": "SHIP-20260915-K7QX",
  "erp_reference": "PO-88231",
  "transport_reference": "MEDURU156671",
  "transport_reference_type": "bill_of_lading",
  "transport_type": "ocean",
  "load_type": null,
  "house_bl": null,
  "forwarder_reference": null,
  "forwarder_eta": null,
  "cargo_type": "reefer",
  "temperature_celsius": 2.0,
  "status": "in_transit",
  "archived": false,
  "archived_at": null,
  "validated_at": "2026-09-16T08:30:00Z",
  "approved_at": "2026-09-15T12:05:00Z",
  "origin": {
    "location": "Callao",
    "country": "Peru",
    "timezone": "-05:00",
    "code": "PECLL"
  },
  "destination": {
    "location": "Rotterdam",
    "country": "Netherlands",
    "timezone": "+02:00",
    "code": "NLRTM"
  },
  "etd": "2026-09-10T18:00:00Z",
  "eta": "2026-10-05T06:00:00Z",
  "effective_eta": "2026-10-05T06:00:00Z",
  "original_eta": "2026-10-02T06:00:00Z",
  "predicted_eta": null,
  "availability_date": "2026-10-07",
  "carrier": {
    "name": "MSC",
    "scac": "MSCU"
  },
  "tracking": {
    "state": "available",
    "status": "in_transit",
    "unavailable_reason": null,
    "halted_reason": null,
    "last_tracked_at": "2026-09-29T09:41:00Z",
    "carrier_updated_at": "2026-09-29T06:12:00Z"
  },
  "parties": {
    "consignor": "Agro Andes SAC",
    "consignee": "Fresh Imports Ltd",
    "notify_party": null
  },
  "supplier": {
    "id": "cmp_41",
    "name": "Agro Andes SAC"
  },
  "forwarder": null,
  "customer": {
    "id": "cmp_57",
    "name": "Fresh Imports Ltd"
  },
  "produce": [
    "Grapes"
  ],
  "organic": false,
  "cargo": {
    "pallets": 20,
    "boxes": 2400,
    "net_weight_kg": 9600.0,
    "gross_weight_kg": 10320.0
  },
  "containers": [
    {
      "object": "container",
      "id": "ctr_1301",
      "number": "MSCU1234567",
      "seal_numbers": ["ES123456"],
      "vessel": "MSC AURORA",
      "voyage": "2609W",
      "port_of_loading": "Callao",
      "port_of_discharge": "Rotterdam",
      "etd": "2026-09-10T18:00:00Z",
      "eta": "2026-10-05T06:00:00Z",
      "cargo_type": "reefer",
      "temperature_celsius": 2.0
    }
  ],
  "labels": [
    {
      "object": "label",
      "id": "lbl_3",
      "name": "Priority",
      "color": "red",
      "color_hex": "#ef4444"
    }
  ],
  "checks": {
    "total": 6,
    "passed": 4,
    "failed": 1,
    "warnings": 1,
    "skipped": 0,
    "pending": 0,
    "acknowledged": 0
  },
  "notes": null,
  "public_tracking_url": "https://trackberry.com/track/acme-produce/shipments/Qw3rTy9uIoPaSdFgHjKlZxCvBnM4s7Ab",
  "created_at": "2026-09-15T12:00:00Z",
  "updated_at": "2026-09-29T09:41:00Z"
}

Errors: 400, 401, 404, 429.

Get the route, tracking events and ETA revisions of a shipment

GET /shipments/{shipment_id}/timeline (operation get_shipment_timeline)

Use this to answer “where is it and what happened” and “how has the ETA moved”. Returns the route legs in order, every tracking event (both events that happened and estimated ones, oldest first) and every recorded revision of the estimated arrival, oldest first. Not paged.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Example response, 200:

json
{
  "object": "timeline",
  "shipment_id": "shp_812",
  "legs": [
    {
      "object": "shipment_leg",
      "id": "leg_5501",
      "position": 0,
      "transport_type": "ocean",
      "carrier": "MSC",
      "transport_reference": "MEDURU156671",
      "origin": {
        "location": "Callao",
        "country": "Peru",
        "timezone": "-05:00",
        "code": "PECLL"
      },
      "destination": {
        "location": "Rotterdam",
        "country": "Netherlands",
        "timezone": "+02:00",
        "code": "NLRTM"
      },
      "etd": "2026-09-10T18:00:00Z",
      "eta": "2026-10-05T06:00:00Z"
    }
  ],
  "events": [
    {
      "object": "tracking_event",
      "id": "evt_90211",
      "milestone": "loaded",
      "actual": true,
      "occurred_at": "2026-09-10T14:20:00Z",
      "occurred_at_local": "2026-09-10T09:20:00-05:00",
      "container_number": "MSCU1234567",
      "leg_index": 1,
      "location": {
        "name": "Callao",
        "code": "PECLL",
        "country_code": "PE"
      },
      "vessel": {
        "name": "MSC AURORA",
        "imo": "9876543",
        "voyage": "2609W"
      },
      "flight_number": null,
      "position": {
        "latitude": -12.05,
        "longitude": -77.15
      }
    },
    {
      "object": "tracking_event",
      "id": "evt_90233",
      "milestone": "arrived",
      "actual": false,
      "occurred_at": "2026-10-05T06:00:00Z",
      "occurred_at_local": "2026-10-05T08:00:00+02:00",
      "container_number": "MSCU1234567",
      "leg_index": 1,
      "location": {
        "name": "Rotterdam",
        "code": "NLRTM",
        "country_code": "NL"
      },
      "vessel": {
        "name": "MSC AURORA",
        "imo": "9876543",
        "voyage": "2609W"
      },
      "flight_number": null,
      "position": {
        "latitude": null,
        "longitude": null
      }
    }
  ],
  "eta_revisions": [
    {
      "object": "eta_revision",
      "id": "eta_4401",
      "observed_at": "2026-09-11T05:00:00Z",
      "previous_eta": null,
      "new_eta": "2026-10-02T06:00:00Z",
      "slip_seconds": null,
      "first_estimate": true,
      "backfilled": false
    },
    {
      "object": "eta_revision",
      "id": "eta_4470",
      "observed_at": "2026-09-25T05:00:00Z",
      "previous_eta": "2026-10-02T06:00:00Z",
      "new_eta": "2026-10-05T06:00:00Z",
      "slip_seconds": 259200.0,
      "first_estimate": false,
      "backfilled": false
    }
  ]
}

Errors: 400, 401, 404, 429.

Get the map data of a shipment

GET /shipments/{shipment_id}/map (operation get_shipment_map)

Use this to draw a shipment’s voyage on a map: the sea or air route split into the part already travelled and the part remaining, the carrier’s ports, the vessel’s upcoming calls, the recorded position trail and the vessel marker. It is the data behind the map on the shipment’s page in Trackberry. Long lines are thinned and coordinates rounded to four decimals. When the carrier has published nothing to draw, map has the same shape and draws the shipment’s legs between the places its own located tracking events put their ends; it is null only when nothing can be placed. Not paged.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Example response, 200:

json
{
  "object": "shipment_map",
  "shipment_id": "shp_812",
  "map": {
    "routeSegments": [
      {
        "path": [
          {
            "lat": -12.05,
            "lng": -77.15
          },
          {
            "lat": 8.9,
            "lng": -79.5
          },
          {
            "lat": 51.95,
            "lng": 4.14
          }
        ],
        "routeType": "SEA"
      }
    ],
    "locations": [
      {
        "name": "Callao",
        "type": "pol",
        "locode": "PECLL",
        "country": "Peru",
        "coordinates": {
          "lat": -12.05,
          "lng": -77.15
        }
      },
      {
        "name": "Rotterdam",
        "type": "pod",
        "locode": "NLRTM",
        "country": "Netherlands",
        "coordinates": {
          "lat": 51.95,
          "lng": 4.14
        }
      }
    ],
    "vesselCalls": [],
    "routeSplit": {
      "segmentIndex": 0,
      "pointIndex": 1,
      "position": {
        "lat": 8.9,
        "lng": -79.5
      }
    },
    "positionTrail": [
      {
        "lat": 8.2,
        "lng": -79.3,
        "label": "about 3 hours ago"
      }
    ],
    "vesselMarker": {
      "lat": 8.2,
      "lng": -79.3,
      "source": "fix",
      "seenAt": "about 3 hours ago",
      "heading": 12
    },
    "vesselName": "MSC AURORA",
    "airRoute": false
  }
}

Errors: 400, 401, 404, 429.

Get the demurrage and detention clocks of a shipment

GET /shipments/{shipment_id}/free_time (operation get_shipment_free_time)

Use this to answer “how many free days are left on this shipment” or “what will demurrage cost us”. Returns one demurrage clock and one detention clock per container, plus the clock that matters most right now (active_clock). Clocks only exist for ocean shipments, for each container that has loading, discharge, gate-out or empty-return events, and stay not_started until the container is discharged. For any other shipment the clock lists are empty and active_clock is null. Free days come from the shipment itself, the latest arrival notice, or the organization’s carrier terms, in that order (see free_days_source).

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Example response, 200:

json
{
  "object": "free_time_summary",
  "shipment_id": "shp_790",
  "shipment_reference": "SHIP-20260901-B2MD",
  "transport_reference": "MAEU123456789",
  "at_risk": true,
  "terms_unknown": false,
  "demurrage": [
    {
      "object": "free_time_clock",
      "kind": "demurrage",
      "container_number": "TGHU7654321",
      "state": "running",
      "free_days": 5,
      "free_days_source": "carrier",
      "free_days_basis": "calendar",
      "started_on": "2026-09-25",
      "ended_on": null,
      "last_free_day": "2026-09-29",
      "days_left": 1,
      "elapsed_days": null,
      "used_days": null,
      "overdue_days": null,
      "carrier": "Maersk"
    }
  ],
  "detention": [
    {
      "object": "free_time_clock",
      "kind": "detention",
      "container_number": "TGHU7654321",
      "state": "not_started",
      "free_days": 10,
      "free_days_source": "carrier",
      "free_days_basis": "calendar",
      "started_on": null,
      "ended_on": null,
      "last_free_day": null,
      "days_left": null,
      "elapsed_days": null,
      "used_days": null,
      "overdue_days": null,
      "carrier": "Maersk"
    }
  ],
  "active_clock": {
    "object": "free_time_clock",
    "kind": "demurrage",
    "container_number": "TGHU7654321",
    "state": "running",
    "free_days": 5,
    "free_days_source": "carrier",
    "free_days_basis": "calendar",
    "started_on": "2026-09-25",
    "ended_on": null,
    "last_free_day": "2026-09-29",
    "days_left": 1,
    "elapsed_days": null,
    "used_days": null,
    "overdue_days": null,
    "carrier": "Maersk"
  },
  "collect_by": "2026-09-29",
  "collect_by_calendars": [
    "DE-BY",
    "DE-HH"
  ]
}

Errors: 400, 401, 404, 429.

List the documents of a shipment

GET /shipments/{shipment_id}/documents (operation list_shipment_documents)

Use this to see which paperwork Trackberry holds for a shipment (bill of lading, packing list, invoice, certificates) and whether each was read successfully. Only current documents are listed: replaced versions, reference-only attachments and internal page-split records are left out. Oldest first, not paged. Download a file with download_document_file when its downloadable is true.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "document",
      "id": "doc_301",
      "shipment_id": "shp_812",
      "type": "packing_list",
      "filename": "PL_MEDURU156671.xlsx",
      "content_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      "byte_size": 48211,
      "source": "email_upload",
      "parse_status": "parsed",
      "downloadable": true,
      "page_range": null,
      "data_available": true,
      "created_at": "2026-09-15T12:01:00Z",
      "updated_at": "2026-09-15T12:03:00Z"
    }
  ]
}

Errors: 400, 401, 404, 429.

List the packing lists of a shipment with pallets and lines

GET /shipments/{shipment_id}/packing_lists (operation list_shipment_packing_lists)

Use this to read what is physically in the shipment: for each current packing list, its declared totals, its pallets, and each pallet’s produce lines (produce, variety, calibre, box counts and weights). Only current packing lists (not replaced by a newer document) are listed, oldest first, not paged. Pallets that belong to no packing list are not reachable here (they still count in cargo.pallets of the shipment).

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "packing_list",
      "id": "pkl_55",
      "shipment_id": "shp_812",
      "document_id": "doc_301",
      "container_id": "ctr_1301",
      "reference": "PL-2026-0915",
      "declared_box_count": 240,
      "declared_net_weight_kg": 960.0,
      "totals": {
        "pallets": 2,
        "boxes": 240,
        "net_weight_kg": 960.0
      },
      "pallets": [
        {
          "object": "pallet",
          "id": "plt_9001",
          "pallet_number": "PAL0001",
          "container_id": "ctr_1301",
          "lines": [
            {
              "object": "packing_line",
              "id": "pln_70001",
              "line_index": 1,
              "produce_name": "Grapes",
              "produce_type": "Organic",
              "variety": "Sweet Globe",
              "calibre": "L",
              "quality_category": "Class I",
              "pack_format": "4.0 kg carton",
              "label": "Andes Gold",
              "ggn": "4049929123456",
              "comment": null,
              "box_count": 120,
              "preallocated_boxes": 40,
              "box_weight_kg": 4.0,
              "net_weight_kg": 480.0,
              "gross_weight_kg": 522.0
            }
          ]
        },
        {
          "object": "pallet",
          "id": "plt_9002",
          "pallet_number": "PAL0002",
          "container_id": "ctr_1301",
          "lines": [
            {
              "object": "packing_line",
              "id": "pln_70002",
              "line_index": 1,
              "produce_name": "Grapes",
              "produce_type": "Organic",
              "variety": "Sweet Globe",
              "calibre": "L",
              "quality_category": "Class I",
              "pack_format": "4.0 kg carton",
              "label": "Andes Gold",
              "ggn": "4049929123456",
              "comment": null,
              "box_count": 120,
              "preallocated_boxes": 0,
              "box_weight_kg": 4.0,
              "net_weight_kg": 480.0,
              "gross_weight_kg": 522.0
            }
          ]
        }
      ]
    }
  ]
}

Errors: 400, 401, 404, 429.

GET /shipments/{shipment_id}/share_links (operation list_shipment_share_links)

Use this to see which customers already have a tracking link for a shipment, and which links were switched off. Active and revoked links are listed, newest first, with keyset paging. Needs the read scope.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.
limit query integer Maximum number of items in the page, 1 to 100. Default 25.
starting_after query string The id of the last link of the previous page. Example: shl_41.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "share_link",
      "id": "shl_41",
      "shipment_id": "shp_812",
      "customer_reference": "PO-4471",
      "label": "Fresh Direct",
      "url": "https://trackberry.com/acme/s/Zk3p9QmT7vXw2LrB5nHc8DfGaJ4yEsUe",
      "active": true,
      "revoked_at": null,
      "created_at": "2026-10-02T09:15:00Z"
    }
  ]
}

Errors: 400, 401, 403, 404, 429.

POST /shipments/{shipment_id}/share_links (operation create_shipment_share_link)

Use this when an order is confirmed or a delivery note is printed, to get a tracking link carrying the customer’s own order number. It is idempotent by customer_reference: if the shipment already has an active link for the same reference (compared after trimming and collapsing spaces, case-sensitive) that link is returned with a 200 and left unchanged (the label is not updated, even if the retry sends a different or too long one), so a retry never makes a second one. A new link is a 201. Needs the write scope. Refused with not_shareable (400) unless the organization has public tracking pages switched on and the shipment is live and shared publicly. Recorded in the audit log as made through the API.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Send the body as JSON with Content-Type: application/json:

Field Type Description
customer_reference string, required The customer’s own reference for this order, such as a purchase order or sales order number, up to 100 characters. Shown to the customer on the tracking page.
label string A note to tell your links apart, up to 100 characters. Only your team sees it; the customer never does.

Example request body:

json
{
  "customer_reference": "PO-4471",
  "label": "Fresh Direct"
}

Example response, 201 (a 200 with the same body when the link already existed):

json
{
  "object": "share_link",
  "id": "shl_41",
  "shipment_id": "shp_812",
  "customer_reference": "PO-4471",
  "label": "Fresh Direct",
  "url": "https://trackberry.com/acme/s/Zk3p9QmT7vXw2LrB5nHc8DfGaJ4yEsUe",
  "active": true,
  "revoked_at": null,
  "created_at": "2026-10-02T09:15:00Z"
}

Errors: 400, 401, 403, 404, 429.

GET /share_links/{id} (operation get_share_link)

Use this to check whether a customer link is still active and to read its URL again. A revoked link stays readable, with active false and url null. Needs the read scope.

Parameter In Type Description
id path string, required The customer link id (shl_ prefix). An id from another organization, or with another prefix, is a 404. Example: shl_41.

The response is the same object as above.

Errors: 400, 401, 403, 404, 429.

DELETE /share_links/{id} (operation revoke_share_link)

Use this when an order is cancelled or the customer should stop seeing the shipment. The link stops opening at once and the customer’s tracking emails through it stop. It is a soft delete: the link is returned with active false and url null. Revoking a link that is already revoked returns it again and changes nothing. Needs the write scope. An admin or owner may revoke any link; a member only the ones their own token made (403 revoke_not_allowed otherwise). Recorded in the audit log as made through the API.

Parameter In Type Description
id path string, required The customer link id (shl_ prefix). An id from another organization, or with another prefix, is a 404. Example: shl_41.

Example response, 200:

json
{
  "object": "share_link",
  "id": "shl_41",
  "shipment_id": "shp_812",
  "customer_reference": "PO-4471",
  "label": "Fresh Direct",
  "url": null,
  "active": false,
  "revoked_at": "2026-10-09T16:40:00Z",
  "created_at": "2026-10-02T09:15:00Z"
}

Errors: 400, 401, 403, 404, 429.

List the pre-allocations of a shipment

GET /shipments/{shipment_id}/preallocations (operation list_shipment_preallocations)

Use this to see which customers have boxes of a shipment set aside, on which packing line and pallet, and at what tentative price. Every pre-allocation on the shipment is listed, oldest first, with the line and pallet it belongs to. Rows on lines merged into another, or on a superseded packing list, are left out. Not paged: bounded by one shipment. Needs the read scope.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "preallocation",
      "id": "pre_96",
      "packing_line_id": "pln_5521",
      "pallet_id": "plt_3310",
      "allocatee": "Fresh Direct",
      "boxes": 40,
      "unit_price": 12.5,
      "currency": "EUR",
      "value": 500,
      "created_at": "2026-10-05T08:30:00Z",
      "updated_at": "2026-10-05T08:30:00Z"
    }
  ]
}

Errors: 400, 401, 403, 404, 429.

Pre-allocate boxes of a packing line to a customer

POST /packing_lines/{packing_line_id}/preallocations (operation create_packing_line_preallocation)

Use this to set boxes of one packing line aside for a customer, with an optional tentative price. The same rules as the web app apply: the boxes allocated on a line cannot add up to more than the line’s box_count (a 400 naming boxes says how many are left). A price is unit_price per box, or, with price_basis total, the total for these boxes, which is stored as a price per box. currency is a three-letter code, required with a price (a price without one is a 400 naming currency) and ignored without one. A line merged into another, or on a superseded packing list, cannot be pre-allocated (404). Each call adds one pre-allocation; there is no idempotency, so do not retry a request that may have succeeded without listing first. Needs the write scope and a token owner who is not a read-only member (403 read_only_member otherwise). Recorded in the audit log as made through the API.

Parameter In Type Description
packing_line_id path string, required The packing line id (pln_ prefix), as given by list_shipment_packing_lists. An id from another organization, or with another prefix, is a 404. Example: pln_5521.

Send the body as JSON with Content-Type: application/json:

Field Type Description
boxes integer, required How many boxes to set aside. At most the line’s boxes that are still free.
allocatee string or null The customer the boxes are set aside for. Free text; reuse the same spelling to group boxes by customer.
unit_price number, string or null The tentative price per box, or the total for these boxes when price_basis is total. A number or a numeric string; at most 6 decimals, below 100,000,000. Omit or send null for no price.
currency string or null The three-letter currency code of the price, such as EUR. Lowercase is accepted. A price without a currency is a 400 naming currency; without a price the currency is ignored.
price_basis string box (the default) or total: whether unit_price is per box or the total for these boxes.

Example request body:

json
{
  "allocatee": "Fresh Direct",
  "boxes": 40,
  "unit_price": 12.5,
  "currency": "EUR"
}

Example response, 201:

json
{
  "object": "preallocation",
  "id": "pre_96",
  "packing_line_id": "pln_5521",
  "pallet_id": "plt_3310",
  "allocatee": "Fresh Direct",
  "boxes": 40,
  "unit_price": 12.5,
  "currency": "EUR",
  "value": 500,
  "created_at": "2026-10-05T08:30:00Z",
  "updated_at": "2026-10-05T08:30:00Z"
}

Errors: 400, 401, 403, 404, 429.

Change a pre-allocation

PATCH /preallocations/{id} (operation update_preallocation)

Use this to change the customer, the boxes or the price of a pre-allocation. Only the fields you send change; send unit_price as null to remove the price (its currency goes with it). Send at least one field. price_basis is only accepted together with unit_price (400 naming price_basis otherwise). The boxes are checked against the line again, as when creating. Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as made through the API.

Parameter In Type Description
id path string, required The pre-allocation id (pre_ prefix). An id from another organization, or with another prefix, is a 404. Example: pre_96.

Send the body as JSON with Content-Type: application/json:

Field Type Description
allocatee string or null The customer the boxes are set aside for.
boxes integer How many boxes are set aside.
unit_price number, string or null The tentative price per box, or the total for these boxes when price_basis is total. Null removes the price.
currency string or null The three-letter currency code of the price, such as EUR.
price_basis string box (the default) or total: whether unit_price is per box or the total for these boxes.

Example request body:

json
{
  "boxes": 60,
  "unit_price": 12,
  "currency": "EUR"
}

Example response, 200:

json
{
  "object": "preallocation",
  "id": "pre_96",
  "packing_line_id": "pln_5521",
  "pallet_id": "plt_3310",
  "allocatee": "Fresh Direct",
  "boxes": 60,
  "unit_price": 12,
  "currency": "EUR",
  "value": 720,
  "created_at": "2026-10-05T08:30:00Z",
  "updated_at": "2026-10-06T10:02:00Z"
}

Errors: 400, 401, 403, 404, 429.

Remove a pre-allocation

DELETE /preallocations/{id} (operation delete_preallocation)

Use this to release the boxes a pre-allocation set aside. It is a hard delete: the pre-allocation is returned one last time, as it was, and is gone afterwards (a second delete is a 404). Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as made through the API.

Parameter In Type Description
id path string, required The pre-allocation id (pre_ prefix). An id from another organization, or with another prefix, is a 404. Example: pre_96.

The response, 200, is the same object as when creating.

Errors: 400, 401, 403, 404, 429.

Add a paragraph to a shipment’s notes

POST /shipments/{shipment_id}/notes (operation append_shipment_note)

Use this to leave a note on a shipment without touching what is already there: the text is trimmed and added after the existing notes, separated by a blank line (or becomes the notes when there are none), so a colleague’s notes are never wiped. text cannot be blank (400) and the notes together are limited to 20,000 characters. Notes are Markdown. Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as shipment.notes_changed, made through the API. Not idempotent: sending the same text twice adds it twice.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Send the body as JSON with Content-Type: application/json:

Field Type Description
text string, required The paragraph to add, as Markdown. Surrounding whitespace is removed.

Example request body:

json
{
  "text": "Customs cleared, delivery booked for Thursday."
}

Example response, 200:

json
{
  "object": "shipment_notes",
  "shipment_id": "shp_812",
  "notes": "Call the forwarder about the seal.\n\nCustoms cleared, delivery booked for Thursday."
}

Errors: 400, 401, 403, 404, 429.

Replace a shipment’s notes

PUT /shipments/{shipment_id}/notes (operation replace_shipment_notes)

Use this when you hold the whole text and mean to overwrite it, for example after reading the notes from get_shipment and editing them. It replaces everything: whatever a colleague added since is lost, so prefer append_shipment_note for adding. notes must be present and a string; an empty string clears the notes (they read back as null). Limited to 20,000 characters. Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as shipment.notes_changed, made through the API.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Send the body as JSON with Content-Type: application/json:

Field Type Description
notes string, required The whole new text, as Markdown. An empty string clears the notes.

Example request body:

json
{
  "notes": "Call the forwarder about the seal.\n\nCustoms cleared, delivery booked for Thursday."
}

The response, 200, is the same object as above.

Errors: 400, 401, 403, 404, 429.

Put a label on a shipment

POST /shipments/{shipment_id}/labels (operation add_shipment_label)

Use this to tag a shipment with one of the organization’s labels, for example “Urgent”. Pass the label as label: its id (lbl_ prefix) or the words a person would use. The id wins; then the exact name (case and spaces ignored); then the name with emoji, punctuation and case set aside, so “urgent” finds “🔥 Urgent”; then a name that holds every word given. The first step that finds exactly one label is used. Several at the same step is a 400 ambiguous_label naming them with their ids: pick one by id. Nothing found is a 404 whose message lists the organization’s label names. Labels are never created here. list_labels (with q) is only needed to show what exists. Idempotent: a shipment that already has the label answers the same and is not audited a second time. Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as shipment.label_added, made through the API.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Send the body as JSON with Content-Type: application/json:

Field Type Description
label string, required The label’s id (lbl_ prefix) or its name as a person would say it, such as urgent for “🔥 Urgent”. See the operation for how it is matched.

Example request body:

json
{
  "label": "Urgent"
}

Example response, 200:

json
{
  "object": "shipment_labels",
  "shipment_id": "shp_812",
  "labels": [
    {
      "object": "label",
      "id": "lbl_12",
      "name": "Urgent",
      "color": "red",
      "color_hex": "#ef4444"
    }
  ]
}

Errors: 400, 401, 403, 404, 429.

Take a label off a shipment

DELETE /shipments/{shipment_id}/labels/{label} (operation remove_shipment_label)

Use this to remove a label from a shipment, naming it by its id or by its name (URL-encoded), matched as in add_shipment_label (400 ambiguous_label when several fit). Idempotent: a shipment that does not carry the label answers the same and nothing is audited. The label stays in the organization’s catalogue. Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as shipment.label_removed, made through the API.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.
label path string, required The label’s id (lbl_ prefix) or its name, URL-encoded, such as Urgent or Retail%20programme. The name is matched as in add_shipment_label: case, emoji and punctuation do not matter. Several matches are a 400 ambiguous_label; anything that is not one of this organization’s labels is a 404 listing its label names. Example: Urgent.

Example response, 200:

json
{
  "object": "shipment_labels",
  "shipment_id": "shp_812",
  "labels": []
}

Errors: 400, 401, 403, 404, 429.

Run a shipment’s checks again

POST /shipments/{shipment_id}/check_runs (operation run_shipment_checks)

Use this after documents changed, or to refresh list_checks on one shipment. It queues the same quality checks the Run checks button does and answers at once; the results appear in list_checks when the job has run, usually within a minute. Changes no data itself and is safe to repeat. Needs the write scope and a token owner who is not a read-only member.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

The body is empty: send {}, or nothing.

Example response, 200:

json
{
  "object": "check_run",
  "shipment_id": "shp_812",
  "status": "queued"
}

Errors: 400, 401, 403, 404, 429.

Ask for fresh tracking on a shipment

POST /shipments/{shipment_id}/tracking_refreshes (operation refresh_shipment_tracking)

Use this when the user wants the latest carrier information now, as the Check now button does. It queues the refresh and answers at once; read the shipment again shortly after. Each refresh costs a request to the tracking service, so a shipment is refreshed at most once every 5 minutes, whoever asks, and one that was tracked in the last 5 minutes by the regular sweep counts too: inside that window the answer is a 429 refresh_too_soon with Retry-After. A shipment with no transport reference, or that has arrived, is a 400 not_trackable. Needs the write scope and a token owner who is not a read-only member.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

The body is empty: send {}, or nothing.

Example response, 200:

json
{
  "object": "tracking_refresh",
  "shipment_id": "shp_812",
  "status": "queued"
}

Errors: 400, 401, 403, 404, 429.

Archive a shipment

POST /shipments/{shipment_id}/archive (operation archive_shipment)

Use this to take a finished shipment off the active lists. It stays readable (archived shipments are still found by id and listed with archived) and unarchive_shipment brings it back. Idempotent: an archived shipment answers the same and is not audited again. Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as shipment.archived, made through the API.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

The body is empty: send {}, or nothing.

The response, 200, is the shipment, as GET /shipments/{id} gives it.

Errors: 400, 401, 403, 404, 429.

Bring an archived shipment back

DELETE /shipments/{shipment_id}/archive (operation unarchive_shipment)

Use this to put an archived shipment back on the active lists. Idempotent: a shipment that is not archived answers the same and is not audited. Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as shipment.unarchived, made through the API.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

The response, 200, is the shipment, as GET /shipments/{id} gives it.

Errors: 400, 401, 403, 404, 429.

Mark a shipment as received at the warehouse

POST /shipments/{shipment_id}/warehouse_arrival (operation mark_shipment_in_warehouse)

Use this when the user says the cargo has been received. The shipment’s status becomes in_warehouse, as when an admin presses the button on the shipment page, and nothing here moves it back. Admins and owners only: another member’s token is a 403 admin_required. A shipment already in the warehouse answers the same and is not audited again; one still waiting for approval, or in error, is a 400 cannot_mark_in_warehouse. Needs the write scope. Recorded in the audit log as shipment.in_warehouse, made through the API.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

The body is empty: send {}, or nothing.

The response, 200, is the shipment, as GET /shipments/{id} gives it.

Errors: 400, 401, 403, 404, 429.

Accept a failing check, with a reason

POST /checks/{check_id}/acknowledgement (operation acknowledge_check)

Use this when the user has looked at a failed or warning check from list_checks and decided it is acceptable, and tells you why. The check keeps saying what it said; it stops holding the shipment back until it says something else. reason is required, up to 1,000 characters. Admins and owners only: another member’s token is a 403 admin_required. A check that is passed or skipped is a 400 nothing_to_acknowledge. Repeating the same reason changes nothing and is not audited again. Needs the write scope. Recorded in the audit log as shipment.check_acknowledged, made through the API.

Parameter In Type Description
check_id path string, required The check result id (chk_ prefix), as list_checks gives it. An id from another organization, or with another prefix, is a 404. Example: chk_5120.

Send the body as JSON with Content-Type: application/json:

Field Type Description
reason string, required The reason, in the user’s words. Up to 1,000 characters; blank is a 400.

Example request body:

json
{
  "reason": "The supplier confirmed the box count by phone."
}

Example response, 200:

json
{
  "object": "check_acknowledgement",
  "check_id": "chk_5120",
  "shipment_id": "shp_812",
  "acknowledged_at": "2026-10-01T09:30:00Z",
  "reason": "The supplier confirmed the box count by phone."
}

Errors: 400, 401, 403, 404, 429.

Withdraw the acceptance of a check

DELETE /checks/{check_id}/acknowledgement (operation unacknowledge_check)

Use this when the user asks to undo an acceptance made with acknowledge_check or in Trackberry: the failing check holds the shipment back again. Admins and owners only: another member’s token is a 403 admin_required. A check that is not accepted answers the same and is not audited. Needs the write scope. Recorded in the audit log as shipment.check_unacknowledged, made through the API.

Parameter In Type Description
check_id path string, required The check result id (chk_ prefix), as list_checks gives it. An id from another organization, or with another prefix, is a 404. Example: chk_5120.

Example response, 200:

json
{
  "object": "check_acknowledgement",
  "check_id": "chk_5120",
  "shipment_id": "shp_812",
  "acknowledged_at": null,
  "reason": null
}

Errors: 400, 401, 403, 404, 429.

Hide an alert for a few days

POST /alerts/{alert_id}/snooze (operation snooze_alert)

Use this when the user wants an alert out of the way for now. It disappears from the issues page for days (1, 3 or 7) and comes back on its own, or sooner if it escalates to critical. Snoozing again replaces the earlier snooze. restore_alert undoes it. Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as alert.snoozed, made through the API.

Parameter In Type Description
alert_id path string, required The alert id (alr_ prefix), as list_alerts gives it. An id from another organization, a resolved alert, or an id with another prefix, is a 404. Example: alr_2210.

Send the body as JSON with Content-Type: application/json:

Field Type Description
days integer, required How many days to hide the alert for: 1, 3 or 7. A JSON integer; anything else is a 400.

Example request body:

json
{
  "days": 3
}

Example response, 200:

json
{
  "object": "monitoring_alert",
  "id": "alr_2210",
  "shipment_id": "shp_812",
  "shipment_reference": "SHIP-20260915-K7QX",
  "key": "eta_drift",
  "group": "schedule",
  "severity": "warning",
  "title": "ETA has slipped",
  "summary": "ETA has moved 3 days later than first quoted (2026-10-02 → 2026-10-05).",
  "since": "2026-10-02T06:00:00Z",
  "first_detected_at": "2026-09-25T03:00:00Z",
  "last_detected_at": "2026-09-29T03:00:00Z",
  "resolved_at": null,
  "dismissed_at": null,
  "snoozed_until": "2026-10-04T09:30:00Z"
}

Errors: 400, 401, 403, 404, 429.

Hide an alert while the problem lasts

POST /alerts/{alert_id}/dismissal (operation dismiss_alert)

Use this when the user says an alert is not worth acting on. It stays hidden on the issues page for as long as the problem persists, and does not come back as new. It is not deleted: restore_alert brings it back, and it is still listed by list_alerts with dismissed_at. Dismissing a dismissed alert changes nothing. Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as alert.dismissed, made through the API.

Parameter In Type Description
alert_id path string, required The alert id (alr_ prefix), as list_alerts gives it. An id from another organization, a resolved alert, or an id with another prefix, is a 404. Example: alr_2210.

The body is empty: send {}, or nothing.

Example response, 200:

json
{
  "object": "monitoring_alert",
  "id": "alr_2210",
  "shipment_id": "shp_812",
  "shipment_reference": "SHIP-20260915-K7QX",
  "key": "eta_drift",
  "group": "schedule",
  "severity": "warning",
  "title": "ETA has slipped",
  "summary": "ETA has moved 3 days later than first quoted (2026-10-02 → 2026-10-05).",
  "since": "2026-10-02T06:00:00Z",
  "first_detected_at": "2026-09-25T03:00:00Z",
  "last_detected_at": "2026-09-29T03:00:00Z",
  "resolved_at": null,
  "dismissed_at": "2026-10-01T09:30:00Z",
  "snoozed_until": null
}

Errors: 400, 401, 403, 404, 429.

Bring a snoozed or dismissed alert back

POST /alerts/{alert_id}/restoration (operation restore_alert)

Use this to undo snooze_alert or dismiss_alert: the alert is back on the issues page. An alert that was neither answers the same. Needs the write scope and a token owner who is not a read-only member. Recorded in the audit log as alert.restored, made through the API.

Parameter In Type Description
alert_id path string, required The alert id (alr_ prefix), as list_alerts gives it. An id from another organization, a resolved alert, or an id with another prefix, is a 404. Example: alr_2210.

The body is empty: send {}, or nothing.

Example response, 200:

json
{
  "object": "monitoring_alert",
  "id": "alr_2210",
  "shipment_id": "shp_812",
  "shipment_reference": "SHIP-20260915-K7QX",
  "key": "eta_drift",
  "group": "schedule",
  "severity": "warning",
  "title": "ETA has slipped",
  "summary": "ETA has moved 3 days later than first quoted (2026-10-02 → 2026-10-05).",
  "since": "2026-10-02T06:00:00Z",
  "first_detected_at": "2026-09-25T03:00:00Z",
  "last_detected_at": "2026-09-29T03:00:00Z",
  "resolved_at": null,
  "dismissed_at": null,
  "snoozed_until": null
}

Errors: 400, 401, 403, 404, 429.

List shipments whose demurrage free time is nearly or already used up

GET /free_time/at_risk (operation list_free_time_at_risk)

Use this for a daily “what do I need to collect today” view. Returns one free-time summary per shipment that has a demurrage clock running with 2 days or fewer left (or already overdue), most urgent first. Only ocean shipments that are not archived, not yet received into the warehouse, and were discharged in the last 45 days are considered. Not paged. Shipments with unknown free-time terms never appear here; terms_unknown on get_shipment_free_time says when terms are missing.

No parameters.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "free_time_summary",
      "shipment_id": "shp_790",
      "shipment_reference": "SHIP-20260901-B2MD",
      "transport_reference": "MAEU123456789",
      "at_risk": true,
      "terms_unknown": false,
      "demurrage": [
        {
          "object": "free_time_clock",
          "kind": "demurrage",
          "container_number": "TGHU7654321",
          "state": "running",
          "free_days": 5,
          "free_days_source": "carrier",
          "free_days_basis": "calendar",
          "started_on": "2026-09-25",
          "ended_on": null,
          "last_free_day": "2026-09-29",
          "days_left": 1,
          "elapsed_days": null,
          "used_days": null,
          "overdue_days": null,
          "carrier": "Maersk"
        }
      ],
      "detention": [
        {
          "object": "free_time_clock",
          "kind": "detention",
          "container_number": "TGHU7654321",
          "state": "not_started",
          "free_days": 10,
          "free_days_source": "carrier",
          "free_days_basis": "calendar",
          "started_on": null,
          "ended_on": null,
          "last_free_day": null,
          "days_left": null,
          "elapsed_days": null,
          "used_days": null,
          "overdue_days": null,
          "carrier": "Maersk"
        }
      ],
      "active_clock": {
        "object": "free_time_clock",
        "kind": "demurrage",
        "container_number": "TGHU7654321",
        "state": "running",
        "free_days": 5,
        "free_days_source": "carrier",
        "free_days_basis": "calendar",
        "started_on": "2026-09-25",
        "ended_on": null,
        "last_free_day": "2026-09-29",
        "days_left": 1,
        "elapsed_days": null,
        "used_days": null,
        "overdue_days": null,
        "carrier": "Maersk"
      },
      "collect_by": "2026-09-29",
      "collect_by_calendars": [
        "DE-BY",
        "DE-HH"
      ]
    }
  ]
}

Errors: 400, 401, 429.

List companies

GET /companies (operation list_companies)

Use this to find a supplier, forwarder or customer and its id, for “who is our supplier Progum” or to filter list_shipments by supplier, forwarder or customer. Newest first, keyset paged. q matches the name or any other spelling of it (a company is known by every spelling seen on documents). role limits the list to one role and, like the Companies page, leaves out the organization’s own companies (own is true for those); without it every company is listed. A company that was merged into another no longer exists: its spellings are aliases of the company it was merged into.

Parameter In Type Description
role query string Only suppliers, forwarders or customers. Anything else is a 400. One of supplier, forwarder, customer. Example: supplier.
q query string Part of a company name or of one of its aliases, case-insensitive. At most 200 characters; longer is a 400. Example: progum.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last company of the previous page. Must start with cmp_; anything else is a 400. Example: cmp_41.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "company",
      "id": "cmp_41",
      "name": "Agro Andes SAC",
      "roles": [
        "supplier"
      ],
      "own": false,
      "country": "PE",
      "erp_code": "S-1042",
      "aliases": [
        "AGRO ANDES S.A.C.",
        "Agro Andes Peru"
      ],
      "open_shipments": {
        "supplier": 3,
        "forwarder": 0,
        "customer": 0
      },
      "created_at": "2026-03-02T10:15:00Z",
      "updated_at": "2026-09-14T08:30:00Z"
    }
  ]
}

Errors: 400, 401, 429.

Get one company

GET /companies/{id} (operation get_company)

Use this to read a company’s roles, other spellings, country, ERP code and how many live shipments it is on. An id from another organization, or of a company that was merged into another, is a 404.

Parameter In Type Description
id path string, required The company id (cmp_ prefix). An id from another organization, or with another prefix, is a 404. Example: cmp_41.

Example response, 200:

json
{
  "object": "company",
  "id": "cmp_41",
  "name": "Agro Andes SAC",
  "roles": [
    "supplier"
  ],
  "own": false,
  "country": "PE",
  "erp_code": "S-1042",
  "aliases": [
    "AGRO ANDES S.A.C.",
    "Agro Andes Peru"
  ],
  "open_shipments": {
    "supplier": 3,
    "forwarder": 0,
    "customer": 0
  },
  "created_at": "2026-03-02T10:15:00Z",
  "updated_at": "2026-09-14T08:30:00Z"
}

Errors: 400, 401, 403, 404, 429.

List open monitoring alerts

GET /alerts (operation list_alerts)

Use this to find shipments that Trackberry’s monitoring says have a problem right now: tracking gone quiet, ETA overdue or slipped, cargo sitting at the terminal, and similar. Only open alerts of the kinds customers can see are listed, across all shipments (archived ones included), newest first, keyset paged. Pass shipment to look at one shipment. An alert a member snoozed or dismissed on the issues page is still open and is listed with its state (snoozed_until, dismissed_at); pass hidden to leave those out, as the issues page does, or to list only them.

Parameter In Type Description
shipment query string Only alerts of this shipment. Must start with shp_; anything else is a 400. A well-formed id that is not in this organization simply matches nothing. Example: shp_812.
hidden query string Whether to list alerts a member snoozed or dismissed. include (the default) lists them with their state, exclude leaves them out, only lists just those. Anything else is a 400. One of include, exclude, only. Default include. Example: exclude.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last alert of the previous page. Must start with alr_; anything else is a 400. Example: alr_2210.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "monitoring_alert",
      "id": "alr_2210",
      "shipment_id": "shp_812",
      "shipment_reference": "SHIP-20260915-K7QX",
      "key": "eta_drift",
      "group": "schedule",
      "severity": "warning",
      "title": "ETA has slipped",
      "summary": "ETA has moved 3 days later than first quoted (2026-10-02 → 2026-10-05).",
      "since": "2026-10-02T06:00:00Z",
      "first_detected_at": "2026-09-25T03:00:00Z",
      "last_detected_at": "2026-09-29T03:00:00Z",
      "resolved_at": null,
      "dismissed_at": null,
      "snoozed_until": null
    }
  ]
}

Errors: 400, 401, 429.

List document checks across shipments

GET /checks (operation list_checks)

Use this to find paperwork and data problems: missing documents, packing list totals that disagree with the declared ones, invalid container numbers, and similar. By default only checks that failed or warned are listed; pass status to see others. Across all shipments (archived ones included), newest first, keyset paged. Pass shipment to look at one shipment.

Parameter In Type Description
status query comma-separated list Only checks in one of these statuses. One comma-separated value. Defaults to failed,warning when omitted or empty. An unknown status is a 400. One of pending, passed, failed, skipped, warning. Default failed,warning. Example: failed,warning.
shipment query string Only checks of this shipment. Must start with shp_; anything else is a 400. A well-formed id that is not in this organization simply matches nothing. Example: shp_812.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last check of the previous page. Must start with chk_; anything else is a 400. Example: chk_9001.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "shipment_check",
      "id": "chk_9001",
      "shipment_id": "shp_812",
      "shipment_reference": "SHIP-20260915-K7QX",
      "key": "has_commercial_invoice",
      "category": "documents",
      "status": "warning",
      "title": "Commercial invoice",
      "message": "No commercial invoice has been received for this shipment yet.",
      "ran_at": "2026-09-29T03:00:00Z"
    }
  ]
}

Errors: 400, 401, 429.

List the organization’s warehouses

GET /warehouses (operation list_warehouses)

Use this to learn where the organization receives containers and which weekdays and public-holiday calendar that site works to. A warehouse exists so delivery and collect-by dates skip the days nobody is there. Today there is one per organization, but this is a list. Archived (retired) warehouses are left out unless include_archived=true. Newest first, keyset paged. Opening hours are not recorded, only the weekdays in open_days.

Parameter In Type Description
include_archived query string true to list archived warehouses too. Defaults to false. Anything but true or false is a 400. One of true, false. Default false. Example: true.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last warehouse of the previous page. Must start with whs_; anything else is a 400. Example: whs_12.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "warehouse",
      "id": "whs_12",
      "name": "Main warehouse",
      "street": "Hafenstrasse 1",
      "postal_code": "80331",
      "city": "Munich",
      "country_code": "DE",
      "open_days": [
        "mon",
        "tue",
        "wed",
        "thu",
        "fri"
      ],
      "holiday_region": "DE-BY",
      "effective_holiday_region": "DE-BY",
      "located": true,
      "default": true,
      "archived": false
    }
  ]
}

Errors: 400, 401, 429.

List a warehouse’s closures

GET /warehouses/{id}/closures (operation list_warehouse_closures)

Use this to see the days the warehouse has been marked shut (stock-taking, the week between Christmas and New Year) or marked open against its calendar (a public holiday it works through). A closure’s word beats the weekly schedule and the holidays alike. By default only closures ending today or later are listed; pass from for earlier ones. Listed in date order, the closure that ends first leading, keyset paged. For a day-by-day answer use the delivery days of the warehouse instead.

Parameter In Type Description
id path string, required The warehouse id (whs_ prefix). An id from another organization, or with another prefix, is a 404. Example: whs_12.
from query date string Only closures ending on or after this date, as YYYY-MM-DD. Defaults to today. Anything else is a 400. Example: 2026-12-01.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last closure of the previous page. Must start with wcl_; anything else is a 400. Example: wcl_40.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "warehouse_closure",
      "id": "wcl_41",
      "warehouse_id": "whs_12",
      "starts_on": "2026-12-24",
      "ends_on": "2026-12-24",
      "open": false,
      "note": "Christmas Eve"
    }
  ]
}

Errors: 400, 401, 404, 429.

Get which days a warehouse can receive containers, and why not

GET /warehouses/{id}/delivery_days (operation get_warehouse_delivery_days)

Use this to answer “is the warehouse open on the 26th” or “why is the collect-by date Tuesday and not Monday”. Each day in the range is usable or not, with the reason: open (an ordinary open day), closure_open (a closure opens it), closure (a closure shuts it), weekday (not one of open_days), warehouse_holiday (a public holiday where the warehouse is) or port_holiday (a public holiday at the port). The first reason that applies wins, in the order closure, weekday, warehouse holiday, port holiday. Port holidays need a shipment, because the port is the one its free-time clock runs at (the same calendar collect_by uses): without shipment they are not counted. The range defaults to 14 days from today and is at most 62 days. Not paged.

Parameter In Type Description
id path string, required The warehouse id (whs_ prefix). An id from another organization, or with another prefix, is a 404. Example: whs_12.
from query date string First day of the range, as YYYY-MM-DD. Defaults to today. Anything else is a 400. Example: 2026-12-23.
to query date string Last day of the range (included), as YYYY-MM-DD. Defaults to 13 days after from. A date before from, or a range of more than 62 days, is a 400. Example: 2026-12-28.
shipment query string Count the public holidays of this shipment’s discharge port too. Must start with shp_; a malformed id or one that is not in this organization is a 404. Example: shp_812.

Example response, 200:

json
{
  "object": "warehouse_delivery_days",
  "warehouse_id": "whs_12",
  "shipment_id": null,
  "from": "2026-12-23",
  "to": "2026-12-28",
  "calendars": [
    "DE-BY"
  ],
  "days": [
    {
      "date": "2026-12-23",
      "weekday": "wed",
      "usable": true,
      "reason": "open"
    },
    {
      "date": "2026-12-24",
      "weekday": "thu",
      "usable": false,
      "reason": "closure"
    },
    {
      "date": "2026-12-25",
      "weekday": "fri",
      "usable": false,
      "reason": "warehouse_holiday"
    },
    {
      "date": "2026-12-26",
      "weekday": "sat",
      "usable": false,
      "reason": "weekday"
    },
    {
      "date": "2026-12-27",
      "weekday": "sun",
      "usable": false,
      "reason": "weekday"
    },
    {
      "date": "2026-12-28",
      "weekday": "mon",
      "usable": true,
      "reason": "open"
    }
  ]
}

Errors: 400, 401, 404, 429.

List the product catalogue

GET /products (operation list_products)

Use this to look up the organization’s own products (the item master loaded from its ERP) and what each supplier calls them: the supplier’s reference and description, and the factor that converts the supplier’s quantity into the organization’s unit. Answers “what is our SKU for the code printed on this supplier’s document” and “which products does this supplier ship us”. Newest first, keyset paged. q searches the SKU, the description and any supplier’s reference (ignoring case, spaces and punctuation in a reference).

Parameter In Type Description
q query string Only products whose SKU, description or any supplier reference contains this text, for example the code printed on a supplier’s packing list. Example: OR-2-369.
status query string active for products the latest ERP export still carries, discontinued for those it no longer does. Without it both are listed. Anything else is a 400. One of active, discontinued. Example: active.
supplier query string Only products this supplier has a reference or a description for. A company id (cmp_ prefix) from list_companies; anything else is a 400. A well-formed id that is not in this organization simply matches nothing. Example: cmp_41.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last product of the previous page. Must start with prd_; anything else is a 400. Example: prd_310.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "product",
      "id": "prd_310",
      "sku": "AVO-HASS-4KG",
      "description": "Hass avocado, 4 kg box",
      "unit": "box",
      "properties": {
        "family": "Avocado"
      },
      "discontinued_at": null,
      "supplier_references": [
        {
          "supplier": {
            "id": "cmp_41",
            "name": "Agrofresh Peru"
          },
          "reference": "OR-2-369",
          "description": "Palta Hass 4 kg",
          "conversion_factor": 1,
          "status": "confirmed",
          "confirmed_at": "2026-10-02T09:15:00Z"
        }
      ],
      "supplier_descriptions": [
        {
          "supplier": {
            "id": "cmp_41",
            "name": "Agrofresh Peru"
          },
          "description": "Hass avocados 12 x 4 kg",
          "trusted": true,
          "confirmations": 3,
          "last_confirmed_at": "2026-10-20T11:00:00Z"
        }
      ],
      "created_at": "2026-09-01T08:00:00Z",
      "updated_at": "2026-10-20T11:00:00Z"
    }
  ]
}

Errors: 400, 401, 403, 429.

Get one product

GET /products/{id} (operation get_product)

Use this to read one product with every supplier reference and description for it. The id comes from list_products, or from a purchase order line’s product_id.

Parameter In Type Description
id path string, required The product id, starting with prd_. Example: prd_310.

Example response, 200:

json
{
  "object": "product",
  "id": "prd_310",
  "sku": "AVO-HASS-4KG",
  "description": "Hass avocado, 4 kg box",
  "unit": "box",
  "properties": {
    "family": "Avocado"
  },
  "discontinued_at": null,
  "supplier_references": [
    {
      "supplier": {
        "id": "cmp_41",
        "name": "Agrofresh Peru"
      },
      "reference": "OR-2-369",
      "description": "Palta Hass 4 kg",
      "conversion_factor": 1,
      "status": "confirmed",
      "confirmed_at": "2026-10-02T09:15:00Z"
    }
  ],
  "supplier_descriptions": [
    {
      "supplier": {
        "id": "cmp_41",
        "name": "Agrofresh Peru"
      },
      "description": "Hass avocados 12 x 4 kg",
      "trusted": true,
      "confirmations": 3,
      "last_confirmed_at": "2026-10-20T11:00:00Z"
    }
  ],
  "created_at": "2026-09-01T08:00:00Z",
  "updated_at": "2026-10-20T11:00:00Z"
}

Errors: 400, 401, 403, 404, 429.

List purchase orders with their lines

GET /purchase_orders (operation list_purchase_orders)

Use this to see what the organization has ordered from its suppliers and how much of it has arrived or been matched to paperwork. Answers “what is still to come from Supplier X” and “has PO 4512 shipped”. Lines are grouped by supplier and order number, newest order first, keyset paged by order. Only orders with an open line are listed by default (lines the latest ERP export still carries), each with all its lines; pass status for closed ones or all. Each line has the ERP’s ordered and received quantities, the quantity still remaining, and what has since been matched to supplier invoices and packing lists on shipments, so a line with nothing invoiced or packed has not been seen on a shipment yet.

Parameter In Type Description
status query string Which lines to list: open (the default), closed (no longer in the latest ERP export, usually fully received) or all. An order is listed when any of its lines matches, and then with all its lines. Anything else is a 400. One of open, closed, all. Default open. Example: open.
q query string Only lines whose order number, article code, supplier or description contains this text. An order number matches however it is punctuated (AA/35.264, 35264). Example: 4512.
supplier query string Only this supplier’s lines. A company id (cmp_ prefix) from list_companies; anything else is a 400. A well-formed id that is not in this organization simply matches nothing. Lines whose supplier Trackberry does not know yet (only a name from the ERP export) have no id and are never matched. Example: cmp_41.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last order of the previous page. Must start with por_; anything else is a 400. Example: por_5100.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "purchase_order",
      "id": "por_5100",
      "order_number": "AA/4512",
      "supplier": {
        "id": "cmp_41",
        "name": "Agrofresh Peru"
      },
      "status": "open",
      "lines": [
        {
          "id": "pol_5100",
          "line_number": "10",
          "product_id": "prd_310",
          "article_code": "AVO-HASS-4KG",
          "supplier_reference": "OR-2-369",
          "description": "Hass avocado, 4 kg box",
          "quantity_ordered": 1000,
          "quantity_received": 200,
          "quantity_remaining": 800,
          "quantity_invoiced": 800,
          "quantity_packed": 800,
          "unit_price": 1.5,
          "currency": "EUR",
          "expected_on": "2026-12-01",
          "status": "open",
          "closed_at": null
        }
      ],
      "shipment_ids": [
        "shp_812"
      ]
    }
  ]
}

Errors: 400, 401, 403, 429.

List expected containers

GET /expected_shipments (operation list_expected_shipments)

Use this to see the containers suppliers have agreed to send, including ones that have no shipping document and are not tracked yet. Answers “what is expected from Supplier X in the coming weeks” and “which expected containers are overdue”. Each has the supplier, order number, produce, boxes, the expected week, the documents received for it (proformas and others) and, once Trackberry matched it to a tracked shipment, that shipment’s id. Planned containers by default; pass status for matched or cancelled ones. Newest first, keyset paged.

Parameter In Type Description
status query string planned (the default: still to come), matched (now a tracked shipment), cancelled or all. Anything else is a 400. One of planned, matched, cancelled, all. Default planned. Example: planned.
q query string Only containers whose order number, produce, variety or supplier contains this text. Example: PO-77.
supplier query string Only this supplier’s containers. A company id (cmp_ prefix) from list_companies; anything else is a 400. A well-formed id that is not in this organization simply matches nothing. Example: cmp_41.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last expected container of the previous page. Must start with exs_; anything else is a 400. Example: exs_90.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "expected_shipment",
      "id": "exs_90",
      "status": "planned",
      "supplier": {
        "id": "cmp_41",
        "name": "Agrofresh Peru"
      },
      "order_number": "PO-77",
      "produce_name": "Hass avocado",
      "variety": null,
      "calibre": null,
      "boxes": 1000,
      "pallets": 20,
      "expected_week_start": "2026-12-07",
      "expected_week_end": "2026-12-13",
      "overdue": false,
      "origin_location": "Callao",
      "destination_location": "Rotterdam",
      "unit_price": 9.5,
      "price_basis": "box",
      "currency": "USD",
      "notes": null,
      "shipment_id": null,
      "matched_at": null,
      "match_source": null,
      "cancelled_at": null,
      "documents": [
        {
          "kind": "proforma",
          "filename": "proforma-PO-77.pdf",
          "subject": "Proforma PO-77",
          "received_at": "2026-11-02T09:00:00Z"
        }
      ],
      "created_at": "2026-11-01T08:00:00Z",
      "updated_at": "2026-11-02T09:00:00Z"
    }
  ]
}

Errors: 400, 401, 403, 429.

List the organization’s labels

GET /labels (operation list_labels)

Use this to see which labels the organization has, with their ids, names and colors: the catalogue that the labels of a shipment are drawn from. Newest first, keyset paged. q narrows it to the labels whose name holds every word given, in any case and ignoring emoji and punctuation.

Parameter In Type Description
q query string Words of a label’s name, such as urgent for “🔥 Urgent”. Every word must be in the name; case, emoji and punctuation are ignored. Example: urgent.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last label of the previous page. Must start with lbl_; anything else is a 400. Example: lbl_3.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "label",
      "id": "lbl_4",
      "name": "Retail",
      "color": "blue",
      "color_hex": "#3b82f6"
    },
    {
      "object": "label",
      "id": "lbl_3",
      "name": "Priority",
      "color": "red",
      "color_hex": "#ef4444"
    }
  ]
}

Errors: 400, 401, 429.

List the inspection reports of a shipment with their per-pallet results

GET /shipments/{shipment_id}/inspections (operation list_shipment_inspections)

Use this to read what quality inspectors found: for each inspection report read from an inspection document, who inspected, when and where, the overall score and impression, and one result per pallet (score, recommendation, defects, remarks). Oldest first, not paged. Photos are not served here: each report and result only says how many photos it has (photo_count); the report’s original file is the document in document_id.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "inspection_report",
      "id": "ins_14",
      "shipment_id": "shp_812",
      "document_id": "doc_305",
      "report_number": "INS-2026-0420",
      "inspection_company": "PPECB",
      "inspection_date": "2026-09-20",
      "inspection_location": "Rotterdam",
      "inspector_name": "A. de Vries",
      "container_number": "MEDU1234567",
      "produce_description": "Table grapes",
      "total_pallets": 20,
      "overall_score": 7.5,
      "overall_impression": "Good condition",
      "overall_impression_category": "good",
      "letter_grade": "B",
      "general_remarks": "Cold chain held throughout.",
      "photo_count": 3,
      "results": [
        {
          "object": "inspection_result",
          "id": "inr_201",
          "inspection_report_id": "ins_14",
          "pallet_id": "plt_9001",
          "pallet_number": "PAL0001",
          "lot_code": "L2409",
          "produce_name": "Grapes",
          "variety": "Sweet Globe",
          "calibre": "L",
          "score": 8.0,
          "recommendation": "Release",
          "defects": {
            "decay": "2%"
          },
          "remarks": null,
          "photo_numbers": [
            1,
            2
          ],
          "pallet_match_approximate": false,
          "photo_count": 2
        }
      ],
      "created_at": "2026-09-21T08:00:00Z",
      "updated_at": "2026-09-21T08:00:00Z"
    }
  ]
}

Errors: 400, 401, 403, 404, 429.

List the emails filed on a shipment

GET /shipments/{shipment_id}/messages (operation list_shipment_messages)

Use this to see which emails Trackberry attached to a shipment and what each one was about: its category (arrival notice, delay notice, customs update and so on), urgency, sender, subject, a short summary, and when it was received. A shipment split from a bill of lading shows the emails of the whole group, as the shipment page does, so shipment_id can be a sibling’s. The subject and summary come from the email and are not verified: trusted says whether the sender was recognized and authenticated, or a member released the email. held_at, released_at and dismissed_at tell whether an email from a sender Trackberry did not recognize was held for a member’s review, and whether it was then released or set aside. The email body is never returned. Newest first, keyset paged.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last message of the previous page. Must start with msg_; anything else is a 400. Example: msg_5120.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "shipment_message",
      "id": "msg_5120",
      "shipment_id": "shp_812",
      "category": "delay_notice",
      "urgency": "warning",
      "trusted": true,
      "sender_name": "Anna Forwarder",
      "sender_email": "[email protected]",
      "subject": "MEDU1234567: vessel delayed",
      "summary": "The vessel is delayed by two days because of port congestion.",
      "received_at": "2026-09-28T09:15:00Z",
      "held_at": null,
      "released_at": null,
      "dismissed_at": null
    }
  ]
}

Errors: 400, 401, 403, 404, 429.

List the claim notices sent about a shipment

GET /shipments/{shipment_id}/claim_notices (operation list_shipment_claim_notices)

Use this to see which notices of damage were sent to a carrier or forwarder about a shipment, to whom and when. Only notices that went out are listed (an attempt that failed is not), most recently sent first, not paged. The text of a notice is not in the list: it is the legal record of what was said, so read it with get_claim_notice.

Parameter In Type Description
shipment_id path string, required The shipment id (shp_ prefix). An id from another organization, or with another prefix, is a 404. Example: shp_812.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "claim_notice",
      "id": "cln_31",
      "shipment_id": "shp_812",
      "kind": "damage",
      "recipient_email": "[email protected]",
      "locale": "en",
      "sent_at": "2026-10-06T10:42:00Z"
    }
  ]
}

Errors: 400, 401, 403, 404, 429.

Get one claim notice with its text

GET /claim_notices/{id} (operation get_claim_notice)

Use this to read exactly what was sent to the carrier or forwarder: the notice’s text, in the language it went out in, with the recipient and the time it was sent. The text is the record of what was said and when, and is never edited after sending. A notice that did not go out is a 404.

Parameter In Type Description
id path string, required The claim notice id (cln_ prefix). An id from another organization, with another prefix, or of a notice that did not go out, is a 404. Example: cln_31.

Example response, 200:

json
{
  "object": "claim_notice_detail",
  "id": "cln_31",
  "shipment_id": "shp_812",
  "kind": "damage",
  "recipient_email": "[email protected]",
  "locale": "en",
  "sent_at": "2026-10-06T10:42:00Z",
  "body": "Dear Sir or Madam,\n\nOn 2026-10-05 the inspection of container MEDU1234567 found damaged cartons on 4 pallets. We hold you responsible and ask you to acknowledge this notice."
}

Errors: 400, 401, 403, 404, 429.

List the organization’s carrier free-time terms

GET /carrier_free_times (operation list_carrier_free_times)

Use this to see the free-time terms the organization has negotiated with each carrier: demurrage days, detention days and whether they count calendar or working days. These are the terms behind the free-time numbers of each shipment (free_days_source says when a shipment used them). Newest first, keyset paged.

Parameter In Type Description
limit query integer Maximum number of items in the page, 1 to 100. Decimal digits only; anything else (0, 101, 1e1, 0x10, a negative number) is a 400. Default 25. Example: 50.
starting_after query string Cursor for the next page: the id of the last terms entry of the previous page. Must start with cft_; anything else is a 400. Example: cft_7.

Example response, 200:

json
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "carrier_free_time",
      "id": "cft_7",
      "carrier_name": "Maersk",
      "demurrage_days": 10,
      "detention_days": 7,
      "day_basis": "calendar",
      "updated_at": "2026-08-12T09:30:00Z"
    }
  ]
}

Errors: 400, 401, 403, 429.

Download every shipment as one flat table (CSV or JSON)

GET /feed/shipments (operation list_feed_shipments)

One row per shipment with identifiers, mode, carrier, supplier, origin and destination, ports, ETD/ATD/ETA/ATA, transit and delay days, free time end, container and cargo totals, invoice value and created/archived dates. Not paged: the whole table is returned in one streamed response. Append .csv for CSV; .json or no extension returns JSON.

Parameter In Type Description
from query ISO date or date-time Only shipments created at or after this time. No default.
to query ISO date or date-time Only shipments created at or before this time; a bare date includes that whole day.
status query comma-separated list One or more of draft, validated, in_transit, arrived, in_warehouse. An unknown status is a 400.
archived query string any (default), false or true.

Example response, 200:

json
{
  "object": "feed",
  "name": "shipments",
  "columns": [
    "id",
    "reference",
    "erp_reference",
    "display_name",
    "transport_type",
    "load_type",
    "status",
    "archived",
    "transport_reference",
    "house_bl",
    "container_count",
    "produce",
    "organic",
    "carrier",
    "carrier_scac",
    "supplier",
    "customer",
    "forwarder",
    "consignor",
    "consignee",
    "origin_location",
    "origin_country",
    "destination_location",
    "destination_country",
    "pol",
    "pol_locode",
    "pod",
    "pod_locode",
    "etd",
    "atd",
    "eta",
    "original_eta",
    "ata",
    "availability_date",
    "transit_days",
    "delay_days",
    "free_time_end",
    "demurrage_state",
    "demurrage_free_days",
    "demurrage_overdue_days",
    "detention_last_free_day",
    "detention_overdue_days",
    "pallets",
    "boxes",
    "net_weight_kg",
    "gross_weight_kg",
    "co2_tonnes",
    "invoice_value",
    "invoice_currency",
    "created_at",
    "approved_at",
    "validated_at",
    "archived_at",
    "updated_at",
    "net_weight_lb",
    "gross_weight_lb",
    "origin_code",
    "destination_code"
  ],
  "data": [
    {
      "id": "shp_812",
      "reference": "SHIP-20260915-K7QX",
      "erp_reference": "PO-88213",
      "display_name": "MSCU1234567",
      "transport_type": "ocean",
      "load_type": "fcl",
      "status": "in_transit",
      "archived": false,
      "transport_reference": "MEDURU156671",
      "house_bl": "HBL20260917",
      "container_count": 2,
      "produce": "Avocado; Lime",
      "organic": false,
      "carrier": "MSC",
      "carrier_scac": "MSCU",
      "supplier": "Fruta del Sol SA",
      "customer": "Fresh Imports Ltd",
      "forwarder": "Kuehne+Nagel",
      "consignor": "Fruta del Sol SA",
      "consignee": "Fresh Imports Ltd",
      "origin_location": "Valencia",
      "origin_country": "Spain",
      "destination_location": "Rotterdam",
      "destination_country": "Netherlands",
      "pol": "Valencia",
      "pol_locode": "ESVLC",
      "pod": "Rotterdam",
      "pod_locode": "NLRTM",
      "etd": "2026-09-10T18:00:00Z",
      "atd": "2026-09-10T18:00:00Z",
      "eta": "2026-10-05T06:00:00Z",
      "original_eta": "2026-10-02T06:00:00Z",
      "ata": "2026-10-05T08:30:00Z",
      "availability_date": "2026-10-07",
      "transit_days": 25.6,
      "delay_days": 3.1,
      "free_time_end": "2026-10-12",
      "demurrage_state": "running",
      "demurrage_free_days": 7,
      "demurrage_overdue_days": 0,
      "detention_last_free_day": "2026-10-19",
      "detention_overdue_days": 0,
      "pallets": 22,
      "boxes": 2860,
      "net_weight_kg": 12870.0,
      "gross_weight_kg": 14100.0,
      "co2_tonnes": 4.25,
      "invoice_value": 48250.5,
      "invoice_currency": "USD",
      "created_at": "2026-09-15T08:00:00Z",
      "approved_at": "2026-09-15T08:05:00Z",
      "validated_at": "2026-09-15T09:00:00Z",
      "archived_at": null,
      "updated_at": "2026-10-05T09:00:00Z",
      "net_weight_lb": 28373.49,
      "gross_weight_lb": 31085.18,
      "origin_code": "ESVLC",
      "destination_code": "NLRTM"
    }
  ]
}

Errors: 400, 401, 429.

Download tracking events (milestones) as one flat table

GET /feed/events (operation list_feed_events)

One row per tracking event, with its shipment id and reference so it joins to the shipments feed. Only the last 90 days by default. Append .csv for CSV; .json or no extension returns JSON.

Parameter In Type Description
from query ISO date or date-time Only events at or after this time. Defaults to 90 days ago, unless you pass only to.
to query ISO date or date-time Only events at or before this time; a bare date includes that whole day.

Example response, 200:

json
{
  "object": "feed",
  "name": "events",
  "columns": [
    "id",
    "shipment_id",
    "shipment_reference",
    "container_number",
    "milestone",
    "actual",
    "occurred_at",
    "location_name",
    "location_code",
    "location_country_code",
    "vessel_name",
    "vessel_imo",
    "voyage",
    "flight_number",
    "latitude",
    "longitude"
  ],
  "data": [
    {
      "id": "evt_90211",
      "shipment_id": "shp_812",
      "shipment_reference": "SHIP-20260915-K7QX",
      "container_number": "MSCU1234567",
      "milestone": "discharged",
      "actual": true,
      "occurred_at": "2026-10-05T08:30:00Z",
      "location_name": "Rotterdam",
      "location_code": "NLRTM",
      "location_country_code": "NL",
      "vessel_name": "MSC AURORA",
      "vessel_imo": "9876543",
      "voyage": "FA640W",
      "flight_number": null,
      "latitude": 51.95,
      "longitude": 4.14
    }
  ]
}

Errors: 400, 401, 429.

Download the statistics page’s KPIs as rows of metric, period, dimension and value

GET /feed/kpis (operation list_feed_kpis)

The KPIs of the Statistics page as rows, computed by the same code. Metrics, with the dimension each one uses: shipments_created (monthly, transport_type: ocean or air); shipments_by_carrier (carrier), shipments_by_lane (lane), shipments_by_origin_country and shipments_by_destination_country (the country): shipments in the window; arrivals_on_time, arrivals_late_up_to_5_days and arrivals_late_over_5_days (by carrier and by lane): arrivals against the original ETA; port_dwell_median_days, port_dwell_p10_days, port_dwell_p90_days, port_dwell_q1_days, port_dwell_q3_days and port_dwell_containers (destination_port): days containers sit in the destination port; on_time_arrival_pct and arrivals_measured (monthly, no dimension); co2_tonnes (monthly, no dimension); shipments_by_produce (monthly, produce); shipments_by_supplier (monthly, supplier: the 8 suppliers with most shipments); incidents (monthly, incident_type: delay, rollover, free_time_breach, document_error or customs_hold, unit incidents); and for each of carrier, forwarder and supplier (the 10 with most incidents) incidents_by_<dimension> (unit incidents), shipments_with_incidents_by_<dimension> (unit shipments) and incident_rate_by_<dimension> (unit per_100_shipments), all over the window. Incidents are counted by the month their shipment was created in; the rules are in the Statistics guide. Append .csv for CSV; .json or no extension returns JSON.

Parameter In Type Description
from query ISO date The first month to report, moved to the first day of its month. Defaults to twelve calendar months including the current one. At most 24 months back; an earlier date is a 400.

Example response, 200:

json
{
  "object": "feed",
  "name": "kpis",
  "columns": [
    "metric",
    "period_start",
    "period_end",
    "dimension",
    "dimension_value",
    "value",
    "unit"
  ],
  "data": [
    {
      "metric": "shipments_created",
      "period_start": "2026-09-01",
      "period_end": "2026-09-30",
      "dimension": "transport_type",
      "dimension_value": "ocean",
      "value": 14,
      "unit": "shipments"
    },
    {
      "metric": "arrivals_late_up_to_5_days",
      "period_start": "2026-04-01",
      "period_end": "2026-10-09",
      "dimension": "carrier",
      "dimension_value": "MSC",
      "value": 4,
      "unit": "shipments"
    }
  ]
}

Errors: 400, 401, 429.

Upload a document for extraction

POST /documents (operation upload_document)

Use this to have Trackberry read a loading sheet, packing list, invoice or bill of lading and turn it into structured data, whether or not the shipment is tracked with Trackberry. Give shipment_id to file it on a shipment you already have, or container_number to file it on the live shipment carrying that container; with neither, or with a container no live shipment carries, a new draft shipment is made for it and is not tracked. The response is the document with parse_status pending: the file is virus-scanned, then classified and read within a few minutes. Poll get_document until data_available is true and then call get_document_data, or subscribe to the document.processed webhook. The data goes to your ERP only after the same review as any other document. Needs the write scope. A new shipment is refused with billing_blocked (403) when the organization’s billing does not allow one. Recorded in the audit log as made through the API. Limited to 120 uploads an hour per token.

Parameter In Type Description
Idempotency-Key header string A value you generate per upload, such as a UUID or your own line id, 1 to 255 printable ASCII characters. Repeating it within 24 hours with the same file and target returns the first document with a 200; with a different file or target it is a 400 with code idempotency_key_reused. Example: 6f1c2a9e-1b7d-4c55-9a43-3f0e8d2b7c10.

Send the body as multipart/form-data:

Field Type Description
file file, required The document: PDF (digital or scanned), JPEG, PNG or TIFF image, Excel (.xlsx, .xls) or CSV, at most 50 MB. The type is read from the file’s contents, not from its name. An empty file is a 400 with file_empty, a larger one file_too_large, another type unsupported_file_type.
shipment_id string A shipment of your organization to file the document on (shp_ prefix). An id that finds no shipment is a 400 naming shipment_id. Not with container_number. Example: shp_903.
container_number string An ISO 6346 container number. The document goes on the live, unarchived shipment carrying it, or on a new untracked shipment with that reference when none does. Two live shipments carrying it is a 400 with code ambiguous_container. Not with shipment_id. Example: MSCU1234566.
bash
curl https://trackberry.com/api/v1/documents \
  -H "Authorization: Bearer tb_your_write_token" \
  -H "Idempotency-Key: 6f1c2a9e-1b7d-4c55-9a43-3f0e8d2b7c10" \
  -F [email protected] \
  -F container_number=MSCU1234566

Example response, 201 (a 200 with the same body for a replay: the Idempotency-Key was already used for this request, or this file is already on this shipment):

json
{
  "object": "document",
  "id": "doc_514",
  "shipment_id": "shp_903",
  "type": "unknown",
  "filename": "loading-sheet-0412.pdf",
  "content_type": "application/pdf",
  "byte_size": 182344,
  "source": "api",
  "parse_status": "pending",
  "downloadable": false,
  "page_range": null,
  "data_available": false,
  "created_at": "2026-10-15T08:12:00Z",
  "updated_at": "2026-10-15T08:12:00Z"
}

Errors: 400, 401, 403, 429.

Get one document

GET /documents/{id} (operation get_document)

Use this to describe a document you found through list_shipment_documents: its type, file name, size, source, processing status, and whether extracted data is available. download_document_file returns the file itself. Only current documents are found; a replaced or reference-only document is a 404.

Parameter In Type Description
id path string, required The document id (doc_ prefix). An id from another organization, with another prefix, or of a document that is not current, is a 404. Example: doc_301.

Example response, 200:

json
{
  "object": "document",
  "id": "doc_301",
  "shipment_id": "shp_812",
  "type": "packing_list",
  "filename": "PL_MEDURU156671.xlsx",
  "content_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  "byte_size": 48211,
  "source": "email_upload",
  "parse_status": "parsed",
  "downloadable": true,
  "page_range": null,
  "data_available": true,
  "created_at": "2026-09-15T12:01:00Z",
  "updated_at": "2026-09-15T12:03:00Z"
}

Errors: 400, 401, 404, 429.

Download a document’s file

GET /documents/{id}/file (operation download_document_file)

Use this to fetch the original file of a document (the PDF, scan, spreadsheet or picture that was uploaded or emailed), for archiving it or reading what extraction did not cover. The body is the file, sent as an attachment with its own Content-Type and file name in Content-Disposition. Only a document whose downloadable is true has one: a document without a file, or whose file has not passed the security scan (still being scanned, or blocked), is a 404.

Parameter In Type Description
id path string, required The document id (doc_ prefix). An id from another organization, with another prefix, or of a document that is not current, is a 404. Example: doc_301.
bash
curl -H "Authorization: Bearer tb_..." -OJ https://trackberry.com/api/v1/documents/doc_301/file

Errors: 400, 401, 404, 429.

Get the data Trackberry extracted from a document

GET /documents/{id}/data (operation get_document_data)

Use this to read the structured content Trackberry parsed out of a document (a packing list’s lines, an invoice’s totals, a bill of lading’s parties and departure and arrival days, a certificate’s numbers). Check data_available on the document first, or expect an empty result. When nothing was extracted, or the document type has no structured schema, the response is still a 200 with schema null and fields an empty object.

Parameter In Type Description
id path string, required The document id (doc_ prefix). An id from another organization, with another prefix, or of a document that is not current, is a 404. Example: doc_301.

Example response, 200:

json
{
  "object": "document_data",
  "document_id": "doc_301",
  "type": "packing_list",
  "schema": "packing_list",
  "fields": {
    "packing_list_number": "PL-2026-0915",
    "exporter_name": "Agro Andes SAC",
    "exporter_port": "Callao",
    "exporter_country": "Peru",
    "importer_name": "Fresh Imports Ltd",
    "importer_country": "Netherlands",
    "total_net_weight": 960.0,
    "total_boxes": 240,
    "diagram_pallet_numbers": [],
    "container_number": "MSCU1234567",
    "line_items": [
      {
        "pallet_number": "PAL0001",
        "produce_name": "Grapes",
        "variety": "Sweet Globe",
        "size_calibre": "L",
        "quality_category": "Class I",
        "format": "4.0 kg carton",
        "label": "Andes Gold",
        "produce_type": "Organic",
        "ggn": "4049929123456",
        "comment": null,
        "number_of_boxes": 120,
        "net_weight_kg": 480.0,
        "box_weight_kg": 4.0,
        "gross_weight_kg": 522.0
      }
    ]
  }
}

Errors: 400, 401, 404, 429.

Get this OpenAPI description

GET /openapi.json (operation get_openapi_document)

Use this to load the machine-readable description of the API into an agent, a code generator or a documentation tool. Public: no token needed. It describes the latest API version and does not depend on the organization or on Trackberry-Version. It counts against the per-IP limit for requests without a token. Cacheable for an hour.

No parameters.

Returns 200 with an OpenAPI 3.1 document as JSON (it is the file this reference is built from).

Errors: 429.

Objects

Objects the API returns carry an object field naming their type, and most have an id. Nested objects are shown with dotted field names. The type column says or null where a field can be null. Place is a building block used inside other objects; List and Error are the envelopes for lists and errors.

Error object

The single error body used by every failure.

Field Type Description
error object The details of what went wrong.
error.type string The broad class of the error. One of authentication_error, permission_error, not_found_error, invalid_request_error, rate_limit_error.
error.code string A stable machine-readable reason. Branch on this. One of missing_token, invalid_token, insufficient_scope, read_only_member, revoke_not_allowed, resource_missing, invalid_parameter, not_shareable, invalid_version, rate_limited, feed_in_progress, ambiguous_label, admin_required, not_trackable, nothing_to_acknowledge, cannot_mark_in_warehouse, refresh_too_soon.
error.message string An English sentence for people. Do not parse it.
error.param string or null The query parameter or header at fault, or null when the error is not about one.

List object

The envelope every list endpoint returns.

Field Type Description
object string Always list.
data array of objects The items of this page, in the order the endpoint documents. Each item is an object of the kind the endpoint returns.
has_more boolean True when more items exist after this page. Pass the last item’s id as starting_after to fetch them. Always false for unpaged lists.

Organization object

The organization a token reads, with the token that made the request.

Field Type Description
object string Always organization.
id string The organization id.
name string The organization’s display name.
slug string The organization’s URL slug in the Trackberry app.
api_version string or null The API version the organization is pinned to. Null only if the organization has not made a request without a Trackberry-Version header yet.
token object The API token that authenticated this request.
token.id string The token id (not the secret).
token.name string The name given to the token when it was created.
token.scopes array of strings What the token may do. Only read exists. One of read.
token.expires_at date-time string or null When the token stops working, or null if it never expires.
token.user_email string The email of the user the token belongs to.

Shipment object

A consignment of goods: one bill of lading or air waybill, its containers, and everything Trackberry knows about where it is and what is in it.

Field Type Description
object string Always shipment.
id string The shipment id.
reference string Trackberry’s reference for the shipment, unique within the organization. Generated (like SHIP-20260915-K7QX) unless a person set one.
erp_reference string or null The organization’s own reference for the shipment (for example a purchase order number), when one was recorded.
transport_reference string or null The number the cargo is tracked by, taken from the transport document. An ocean bill of lading number, an air waybill number or a container number. Ocean and road references are upper-cased with spaces and dashes removed; air waybills use the canonical 3-digit-prefix format.
transport_reference_type string or null What kind of number transport_reference is (a container number, an air waybill or a bill of lading), or null when it is blank or matches none of them. One of container, awb, bill_of_lading.
transport_type string or null How the cargo travels. Only ocean and air shipments are tracked with a carrier feed. Null when not yet known. One of ocean, air, road.
load_type string or null Whether an ocean shipment fills its own container (fcl) or shares one with other cargo (lcl). An LCL shipment travels in the forwarder’s consolidation container, so it has no free time of its own and its house_bl is never used for carrier tracking. Null when not set, and for air and road. One of fcl, lcl.
house_bl string or null The forwarder’s house bill of lading for an LCL shipment, as the forwarder wrote it. Carriers cannot resolve it, so it is never the transport_reference.
forwarder_reference string or null The forwarder’s own job or file reference for the shipment, when one was recorded.
forwarder_eta date string or null The date the forwarder says the cargo is available, which for LCL is later than eta because the container is unloaded at a container freight station first. Does not change eta or effective_eta.
cargo_type string or null The temperature regime of the cargo. Null when not yet known. One of ambient, reefer, frozen.
temperature_celsius number or null The temperature set point in degrees Celsius for refrigerated cargo, when known.
status string Where the shipment is in its life. draft is data read from documents that nobody has confirmed; validated means a person or the automatic checks confirmed the key facts; in_transit means the cargo is moving; arrived means it reached the port or airport; in_warehouse means it was received at the warehouse; error means processing failed (rarely used). Shipments waiting for approval are not exposed. One of draft, validated, in_transit, arrived, error, in_warehouse.
archived boolean True when the shipment was archived. Archived shipments are hidden from list_shipments unless archived asks for them.
archived_at date-time string or null When the shipment was archived, or null when it is not archived.
validated_at date-time string or null When the key facts were first confirmed. Stays set after the status moves on to in_transit, arrived or in_warehouse. Null for a shipment never validated.
approved_at date-time string or null When the shipment was approved, either by a person or automatically because it arrived from a trusted sender. Null when no approval was recorded.
origin Place object An origin or a destination.
destination Place object An origin or a destination.
etd date-time string or null Estimated (later actual) time of departure, from the documents or the carrier.
eta date-time string or null The estimated time of arrival at the destination as last stated by the documents or the carrier. This is the carrier’s own figure and moves whenever the carrier changes it. Null when unknown.
effective_eta date-time string or null The arrival time to plan around. It is eta when set, otherwise the earliest eta among the shipment’s containers, otherwise null. The eta_after and eta_before filters of list_shipments compare against this.
original_eta date-time string or null The first arrival estimate Trackberry recorded for the documented destination. Later estimates do not overwrite it, so eta minus original_eta is the total slip. Null when no estimate was ever recorded.
predicted_eta date-time string or null A separate arrival prediction for the port of discharge from the tracking data source, built from vessel movements, port congestion and weather. Only some sources publish one, and only when the shipment is within about three days of arrival. It is independent of eta (the carrier’s figure) and never overwrites it. Null when there is none.
availability_date date string or null The date the cargo can be picked up and sold: the ETA plus the organization’s working days, skipping weekends and the destination port’s public holidays. Null unless the organization uses availability dates, and for shipments by air or road, to ports the rule does not cover, or with no ETA.
carrier object The shipping line or airline.
carrier.name string or null The carrier’s name in its canonical spelling, from tracking data. Null before tracking has identified one.
carrier.scac string or null The carrier’s SCAC code (Standard Carrier Alpha Code), when known.
tracking object Health of carrier tracking for this shipment.
tracking.state string What Trackberry knows about tracking. available means tracking data exists; unavailable means Trackberry asked and cannot get data (see unavailable_reason); pending means tracking was requested and nothing has come back yet; not_started means there is a reference but tracking has not been requested; awaiting_reference means it could be tracked once a bill of lading, container or air waybill number is known; none means tracking does not apply (for example road freight). One of available, unavailable, pending, not_started, awaiting_reference, none.
tracking.status string or null The carrier’s latest reported status in the tracking data source’s own words (for example in_transit, arrived, not_found). Not a closed list. Null when there is none.
tracking.unavailable_reason string or null Why tracking could not produce data, when it could not. unsupported_carrier means the carrier or reference type is not tracked; invalid_reference means the number is not usable; not_found means the carrier has no record of it yet; provider_error means the lookup returned nothing usable; past_voyage means the voyage ended long before the documents arrived so tracking was not started. Null otherwise. One of unsupported_carrier, invalid_reference, not_found, provider_error, past_voyage.
tracking.halted_reason string or null Set when the tracking source reported that it stopped producing data. errored means its carrier feed failed on this reference; dropped means it removed the shipment from tracking. Cleared automatically when data flows again. Null otherwise. One of errored, dropped.
tracking.last_tracked_at date-time string or null When Trackberry last refreshed tracking data for this shipment. Null if never.
tracking.carrier_updated_at date-time string or null When the carrier last published new data for this shipment, as opposed to when Trackberry last asked. Null when the source does not say.
parties object The companies named on the transport document.
parties.consignor string or null The sender of the goods (shipper or supplier).
parties.consignee string or null The receiver of the goods named on the transport document.
parties.notify_party string or null The party the carrier notifies on arrival, when different from the consignee.
supplier object or null The company the goods come from, as Trackberry matched it. Null when none is linked. Read it with get_company (the REST operation and the MCP tool of the same name). See CompanyReference below.
forwarder object or null The freight forwarder, as Trackberry matched it. Null when none is linked.
customer object or null The customer the shipment is for, as Trackberry matched it. Null when none is linked.
produce array of strings The distinct produce names in the shipment, from its packing lines, or from the draft entry when no packing list has been read yet.
organic boolean True when at least one visible packing line is marked organic.
cargo object Totals over all pallets of the shipment. Zero when no packing list has been read.
cargo.pallets integer Number of pallets recorded for the shipment.
cargo.boxes integer Total number of boxes over the visible packing lines.
cargo.net_weight_kg number Total net weight of the produce in kilograms.
cargo.gross_weight_kg number Total gross weight, produce plus packaging, in kilograms.
containers array of Container objects The containers of the shipment, oldest first.
labels array of Label objects The labels the organization attached to the shipment, sorted by name.
checks object How many document checks the shipment has in each state. Use list_checks for the checks themselves.
checks.total integer All checks of the shipment.
checks.passed integer Checks that passed.
checks.failed integer Checks that failed, meaning something is wrong.
checks.warnings integer Checks that passed with a warning.
checks.skipped integer Checks skipped because their preconditions were not met.
checks.pending integer Checks that have not run yet.
checks.acknowledged integer Failed or warning checks an admin acknowledged (looked at and accepted). They are counted here instead of under failed or warnings.
notes string or null Free-text notes on the shipment.
public_tracking_url string or null The shipment’s public tracking page, which anyone with the link can open without logging in, for sending to a customer or partner. The English page; put /es before /track for the Spanish one. Null when the organization has public tracking pages turned off, or the shipment is archived or not yet validated. The link is unguessable and is replaced when the shipment’s link is regenerated, so read it fresh rather than storing it.
created_at date-time string When the shipment was created in Trackberry.
updated_at date-time string When the shipment record last changed.

Place object

An origin or a destination.

Field Type Description
location string or null The city or port, normalized (for example Rotterdam), without the country.
country string or null The country’s English name (for example Netherlands).
timezone string or null The UTC offset of the place as +HH:MM or -HH:MM (for example +02:00), learned from carrier data. Not an IANA time zone name.
code string or null The canonical code of the place: a 5-character UN/LOCODE for a port (for example NLRTM) or a 3-letter IATA code for an airport (for example LHR). Null when the place is only known by name.

Container object

One container of a shipment.

Field Type Description
object string Always container.
id string The container id.
number string or null The ISO 6346 container number (4 letters and 7 digits, like MSCU1234567).
seal_numbers array of strings The seals on the container door (carrier, customs, inspection), as its bill of lading lists them. Empty when none is known.
vessel string or null The vessel name the documents give for this container.
voyage string or null The voyage number the documents give for this container.
port_of_loading string or null Where the container is loaded, as written in the documents.
port_of_discharge string or null Where the container is discharged, as written in the documents.
etd date-time string or null Estimated time of departure of this container.
eta date-time string or null Estimated time of arrival of this container. When the shipment has no eta of its own, the earliest container eta becomes its effective_eta.
cargo_type string or null The temperature regime of this container. One of ambient, reefer, frozen.
temperature_celsius number or null The container’s temperature set point in degrees Celsius.

Label object

A colored tag the organization uses to group shipments.

Field Type Description
object string Always label.
id string The label id. Use it in the labels filter of list_shipments.
name string The label’s name, unique within the organization.
color string or null The name of the palette color. One of gray, red, orange, amber, green, teal, blue, indigo, purple, pink.
color_hex string The color as a hex code such as #ef4444.

InspectionReport object

A quality inspection report read from an inspection document, with one result per pallet. Photos are not served; only their counts are given.

Field Type Description
object string Always inspection_report.
id string The inspection report id.
shipment_id string The shipment the report belongs to.
document_id string or null The document the report was read from. Null when that document is not one list_shipment_documents serves (for example a superseded one), so it never points at a 404.
report_number string or null The inspection company’s own report number.
inspection_company string or null The company that carried out the inspection.
inspection_date string or null The day the inspection took place.
inspection_location string or null Where the inspection took place.
inspector_name string or null The inspector named on the report.
container_number string or null The container the report names, as written on it.
produce_description string or null The produce the report describes, as written on it.
total_pallets integer or null How many pallets the report says were inspected.
overall_score number or null The overall score on the usual 1 (discard) to 9 (excellent) scale. Null when the report gives none.
overall_impression string or null The report’s own wording of its overall impression.
overall_impression_category string or null The overall impression classified as excellent, good, fair, poor or reject. Null when it could not be classified.
letter_grade string or null The compact A to D grade Trackberry shows for the report, from its score or impression. Null when neither is known.
general_remarks string or null The report’s general remarks.
photo_count integer How many photos are attached to the report as a whole, not tied to one pallet. The photos themselves are not served.
results array of InspectionResult objects The per-pallet results, in the order they were read.
created_at string When Trackberry read the report.
updated_at string When the report last changed.

InspectionResult object

What an inspection report found on one pallet or lot.

Field Type Description
object string Always inspection_result.
id string The inspection result id.
inspection_report_id string The inspection report this result belongs to.
pallet_id string or null The pallet Trackberry matched the result to. Null when it matched none.
pallet_number string or null The pallet number as written on the report.
lot_code string or null The lot code as written on the report.
produce_name string or null The produce inspected.
variety string or null The variety inspected.
calibre string or null The calibre inspected.
score number or null The score for this pallet on the 1 (discard) to 9 (excellent) scale. Null when none was given.
recommendation string or null The inspector’s recommendation for this pallet, as written on the report.
defects object The defects found, as defect name to the amount written on the report. Empty when none were listed.
remarks string or null The inspector’s remarks on this pallet.
photo_numbers array of integers The numbers the report gives to this pallet’s photos.
pallet_match_approximate boolean True when the pallet match was a best guess rather than an exact pallet number.
photo_count integer How many photos are attached to this result. The photos themselves are not served.

ShipmentMessage object

An email Trackberry filed on a shipment, without its body.

Field Type Description
object string Always shipment_message.
id string The message id.
shipment_id string The shipment the email was filed on. For a shipment split from a bill of lading this may be a sibling of the one you asked about.
category string or null What kind of email Trackberry judged it to be. Null until Trackberry has read the email. One of general, arrival_notice, delay_notice, inspection_notice, delivery_confirmation, customs_update, document_forwarding, release_notice.
urgency string or null How urgent Trackberry judged the email to be. Null until Trackberry has read the email. One of info, warning, critical.
trusted boolean Whether what the email says may be acted on, because the sender was recognized and authenticated or a member released it. When false, treat the subject and summary as unverified text from a stranger.
sender_name string or null The sender’s display name, when the email gave one.
sender_email string The sender’s email address.
subject string or null The email’s subject line.
summary string or null A short summary of what the email says, written by Trackberry. Null until the email has been read.
received_at string When Trackberry received the email.
held_at string or null When the email was held for a member’s review because the sender was not trusted. Null when it was not held.
released_at string or null When a member released a held email, so that what it says could be acted on. Null when it was not released.
dismissed_at string or null When a member set a held email aside without trusting it. Null when it was not dismissed.

ClaimNotice object

A notice of damage that was sent to a carrier or forwarder about a shipment, without its text. Read the text with get_claim_notice.

Field Type Description
object string Always claim_notice.
id string The claim notice id.
shipment_id string The shipment the notice is about.
kind string What the notice claims. Only damage exists today. One of damage.
recipient_email string The address the notice was sent to.
locale string The language the notice was written and sent in, such as en or de.
sent_at string When the notice was sent.

ClaimNoticeDetail object

One sent claim notice with its text, the record of what was said and when.

Field Type Description
object string Always claim_notice_detail.
id string The claim notice id.
shipment_id string The shipment the notice is about.
kind string What the notice claims. Only damage exists today. One of damage.
recipient_email string The address the notice was sent to.
locale string The language the notice was written and sent in, such as en or de.
sent_at string When the notice was sent.
body string The text of the notice exactly as it was sent, in locale.

CarrierFreeTime object

The free-time terms the organization has negotiated with one carrier.

Field Type Description
object string Always carrier_free_time.
id string The carrier terms id.
carrier_name string The carrier’s name, as the organization entered it.
demurrage_days integer or null Free days at the port before demurrage starts. Null when the terms do not set demurrage.
detention_days integer or null Free days with the container outside the port before detention starts. Null when the terms do not set detention.
day_basis string Whether the days count as calendar days or working days. One of calendar, working.
updated_at string When the terms last changed.

Timeline object

The route, tracking events and ETA history of one shipment.

Field Type Description
object string Always timeline.
shipment_id string The shipment this timeline belongs to.
legs array of ShipmentLeg objects The legs of the route in travel order.
events array of TrackingEvent objects Tracking events, oldest first. Events without a time are placed by the usual order of milestones.
eta_revisions array of EtaRevision objects Every recorded change of the estimated arrival, oldest first.

ShipmentLeg object

One leg of a shipment’s planned route, for example a sea leg followed by a road leg.

Field Type Description
object string Always shipment_leg.
id string The leg id.
position integer The zero-based order of the leg in the route. Not the same as leg_index on tracking events.
transport_type string or null How the cargo travels on this leg. One of ocean, air, road.
carrier string or null The carrier of this leg, as written in the transport document.
transport_reference string or null The bill of lading, air waybill or consignment number of this leg.
origin Place object An origin or a destination.
destination Place object An origin or a destination.
etd date-time string or null Departure time of this leg, from the transport document.
eta date-time string or null Arrival time of this leg, from the transport document.

TrackingEvent object

One milestone of the cargo’s journey, actual or estimated.

Field Type Description
object string Always tracking_event.
id string The event id.
milestone string What happened, from Trackberry’s own milestone vocabulary (never a carrier’s raw code). Cargo milestones in usual order: booked, received_from_shipper (air), empty_pickup, stuffed, gate_in, manifested (air), loaded, departed, transshipment_arrival, transshipment_discharge, transferred (air), transshipment_load, transshipment_departure, arrived, discharged, held and hold_released (a hold on the box at the destination terminal, reported only by a terminal feed and timed when first seen), customs_cleared, notified (air), available_for_pickup, gate_out, cfs_released (LCL, when the forwarder releases the cargo at its freight station; known to the day only, so occurred_at is 00:00Z of that day), delivered, stripped, empty_return. Lifecycle milestones: eta_revised, exception, untracked. discharged (off the vessel) and gate_out (left the terminal) start and stop the demurrage clock. One of booked, received_from_shipper, empty_pickup, stuffed, gate_in, manifested, loaded, departed, transshipment_arrival, transshipment_discharge, transferred, transshipment_load, transshipment_departure, arrived, discharged, held, hold_released, customs_cleared, notified, available_for_pickup, gate_out, cfs_released, delivered, stripped, empty_return, eta_revised, exception, untracked.
actual boolean True when the event has happened; false when it is an estimate of a future or unconfirmed milestone.
occurred_at date-time string or null When the event happened (or is expected to), in UTC. Null when the source gave no time.
occurred_at_local date-time string or null The same instant written with the UTC offset of the place it happened (for example 2026-09-10T09:20:00-05:00), when the source reported the offset; otherwise the UTC time. Null when occurred_at is null.
container_number string or null The container the event is about. Null for events about the whole shipment.
leg_index integer or null The one-based number of the vessel or flight leg of the journey the event belongs to, as counted from the carrier’s event sequence (1 is the first leg, 2 comes after a transshipment). Not the position of a shipment leg. Null when the source does not say.
location object Where the event happened.
location.name string or null The place name, such as a port or an airport.
location.code string or null The location code as reported, a UN/LOCODE for ports (for example NLRTM) where available.
location.country_code string or null The ISO 3166-1 alpha-2 country code.
vessel object The vessel involved, for ocean events.
vessel.name string or null The vessel name.
vessel.imo string or null The vessel’s IMO number.
vessel.voyage string or null The voyage number.
flight_number string or null The flight, for air events.
position object Coordinates of the event, when the source gave them.
position.latitude number or null Latitude in decimal degrees.
position.longitude number or null Longitude in decimal degrees.

EtaRevision object

One observed change of a shipment’s estimated arrival. Revisions are recorded only when the ETA moves by 5 minutes or more.

Field Type Description
object string Always eta_revision.
id string The revision id.
observed_at date-time string When Trackberry saw the new estimate. For backfilled revisions this is only the time of the last refresh, not when the carrier revised the estimate.
previous_eta date-time string or null The estimate before this revision. Null for the first estimate ever learned.
new_eta date-time string The estimate after this revision.
slip_seconds number or null How much later the arrival got, in seconds (new_eta minus previous_eta). Negative when the carrier moved the arrival earlier. Null for the first estimate, because there is nothing to compare with.
first_estimate boolean True for the opening quote, when there was no previous estimate.
backfilled boolean True when the revision was reconstructed from older data, so observed_at is not the moment the change happened. Leave these out when measuring how fast schedules slip.

ShipmentMap object

The data to draw one shipment’s voyage on a map.

Field Type Description
object string Always shipment_map.
shipment_id string The shipment this map belongs to.
map ShipmentMapData object or null The route, ports, vessel and track. When the carrier’s data has nothing to draw, the shipment’s legs as straight lines between the places its own located tracking events put their ends, or the places those events were or are expected, in order, when no leg can be placed. Null when nothing can be placed.

ShipmentMapData object

What a map draws for one shipment. The keys are camelCase because they are the names the shipment page’s own map reads. All longitudes share one continuous scale: they can run past 180 or below -180 when a route crosses the antimeridian, which map libraries draw correctly.

Field Type Description
routeSegments array of objects The route as lines, one per leg, in travel order.
routeSegments[].path array of MapPoint objects The points of the line, in travel order.
routeSegments[].routeType string or null What the line crosses, for example SEA, AIR or LAND; RAIL marks an overland leg (rail or road) drawn between its two ends. Null when unknown.
locations array of objects The carrier’s ports on the route. Each item has name, type (pol for the port of loading, pod for the port of discharge, transshipment where the cargo changes vessel, port_call where the ship calls and the cargo stays aboard), locode, country and coordinates (a point with lat and lng). A transshipment whose two ships are both named also has vesselChange, with the from and to vessel names. A key the carrier did not publish is left out.
vesselCalls array of objects Upcoming calls of the vessel at ports the carrier’s route does not name. Each item has name, coordinates and, when known, locode and date (for example Due 12 Oct). The vessel’s own schedule, not the carrier’s.
routeSplit object Where the line stops being travelled and starts being remaining: segmentIndex and pointIndex name the point in routeSegments, position is its coordinates. An empty object when nothing says how far the cargo has come, in which case the whole route is remaining.
positionTrail array of objects The vessel’s recorded positions, oldest first.
positionTrail[].lat number Latitude in degrees.
positionTrail[].lng number Longitude in degrees.
positionTrail[].label string How long ago it was recorded, in words such as about 3 hours ago.
vesselMarker object Where to put the vessel (or aircraft) marker: lat, lng, source (fix for a recorded position, reported for the carrier’s estimate along its route, port for the last port seen when the cargo is on land), seenAt (how long ago, for a recorded position) and heading in compass degrees (null when unknown). An empty object when there is no position.
vesselName string or null The vessel or flight the carrier names last. Null when it names none.
airRoute boolean True when every line of the route is an air leg, so the marker is an aircraft.

MapPoint object

A point on a map.

Field Type Description
lat number Latitude in degrees.
lng number Longitude in degrees. Not confined to -180 to 180; see ShipmentMapData.

FreeTimeSummary object

The demurrage and detention position of one shipment. Demurrage is the charge for leaving a container at the terminal past its free days; detention is the charge for keeping the empty container past its free days. Only ocean shipments have clocks.

Field Type Description
object string Always free_time_summary.
shipment_id string The shipment id.
shipment_reference string The shipment’s Trackberry reference.
transport_reference string or null The shipment’s bill of lading, air waybill or container number.
at_risk boolean True when the demurrage clock is running with known free days and 2 days or fewer are left (or it is already overdue), or when collect_by is 2 days away or less. Shipments with unknown terms are never at risk.
terms_unknown boolean True when the free days for demurrage or detention are not known, meaning neither the shipment, an arrival notice nor the organization’s carrier terms supply them. Set the terms in Trackberry to get countdowns.
demurrage array of FreeTimeClock objects One demurrage clock per container. Empty for shipments that are not ocean or have no tracking events for it.
detention array of FreeTimeClock objects One detention clock per container, in the same order as demurrage. Empty for shipments that are not ocean.
active_clock FreeTimeClock object or null The clock to look at first. The most urgent demurrage clock while demurrage has not finished (this includes a not_started one); once demurrage has stopped or given up, the most urgent detention clock if it is running. Null when there are no clocks or nothing is left to watch.
collect_by date or null The last day, on or before the last free day of the most urgent demurrage clock, when the port and the organization’s warehouse are both working. Can be in the past when no usable day is left. Null when the organization has no warehouse, demurrage is not running or is over, or no day since discharge is usable.
collect_by_calendars array of strings or null The public holiday calendars collect_by was counted with, as ISO codes, the warehouse’s first. Null when collect_by is null.

FreeTimeClock object

One demurrage or detention clock for one container. Demurrage starts at the container’s discharge and stops at gate out (or, without one, at the return of the empty container). Detention starts at gate out and stops at the return of the empty container. Days are counted in the local calendar of the port. This object has no id.

Field Type Description
object string Always free_time_clock.
kind string Which charge this clock measures. One of demurrage, detention.
container_number string or null The container the clock is for. Null when tracking events carry no container number.
state string not_started means the clock has nothing to count from yet; running means it is counting against known free days; running_unknown_terms means it is counting but the free days are unknown (only elapsed_days is filled); stopped means it has ended (see ended_on, used_days, overdue_days); end_not_reported (demurrage) and return_not_reported (detention) mean the clock gave up waiting for the ending event because the container was archived or received in the warehouse, or 30 days passed without it. One of not_started, running, running_unknown_terms, stopped, end_not_reported, return_not_reported.
free_days integer or null The number of free days that apply. Null when unknown.
free_days_source string or null Where free_days comes from, in order of authority. shipment means set on the shipment itself; notice means read from the latest arrival notice; carrier means the organization’s negotiated terms for this carrier. Null when free_days is unknown. One of shipment, notice, carrier.
free_days_basis string or null How days are counted. calendar counts every day; working skips weekends and the country’s public holidays. Null when there are no known terms. One of calendar, working.
started_on date string or null The port-local day the clock started (the discharge day for demurrage, the gate-out day for detention). Null while not_started.
ended_on date string or null The port-local day the clock ended. Null unless stopped.
last_free_day date string or null The last day that is still free. Null unless running.
days_left integer or null Free days remaining after today, counted on free_days_basis. 0 means today is the last free day. Negative once overdue (at least -1). Null unless running.
elapsed_days integer or null Calendar days since the start, counting the start day. Only set while running_unknown_terms.
used_days integer or null How many days were used between start and end, counting both. Only set when stopped.
overdue_days integer or null How many days beyond the free days were used. 0 when the clock stopped in time. Only set when stopped and the free days are known.
carrier string or null The carrier the terms belong to, as a label.

MonitoringAlert object

A problem Trackberry’s monitoring found on a shipment and that is still open. An alert opens when a problem starts, can grow from warning to critical, and disappears from the API once resolved.

Field Type Description
object string Always monitoring_alert.
id string The alert id.
shipment_id string The shipment the alert is about.
shipment_reference string That shipment’s Trackberry reference.
key string Which monitor raised it. tracking_halted: the tracking source said it stopped producing data. tracking_blind: the tracking source stopped reaching the carrier. tracking_stale: the carrier has published nothing new for longer than usual. tracking_silent: registered for tracking but the carrier never said anything. tracking_not_found: the tracking source does not recognize the reference. overdue_eta: the ETA passed and arrival is not confirmed. missing_eta: nothing says when it will arrive. eta_drift: the ETA moved 5 days or more later than first quoted. rollover: the container is not on the ship it was booked on. port_dwell: discharged more than 5 days ago and not yet gated out. stalled_draft: approved but never validated. unresolved_checks: failed checks left unresolved for more than 3 days. free_time_at_risk: demurrage free time is running out or has run out. correction_needs_attention: a document correction stalled and needs a decision. missing_phytosanitary_certificate: produce is on its way and no phytosanitary certificate has been uploaded. quality_below_threshold: the latest inspection report grades the shipment C or D overall, or scores a pallet D. New keys may be added. One of tracking_halted, tracking_blind, tracking_stale, tracking_silent, tracking_not_found, overdue_eta, missing_eta, eta_drift, rollover, port_dwell, stalled_draft, unresolved_checks, free_time_at_risk, correction_needs_attention, missing_phytosanitary_certificate, quality_below_threshold.
group string or null The theme of the alert. Null if the monitor that raised it no longer exists. One of tracking, schedule, workflow, documents, quality.
severity string How urgent it is. Severity can rise from warning to critical as the problem ages. One of warning, critical.
title string A short English title for the kind of problem.
summary string or null An English sentence saying what is wrong on this shipment.
since date-time string or null When the problem began, as the monitor measures it (for example the moment the ETA passed). Null when unknown.
first_detected_at date-time string or null When a monitoring sweep first saw the problem.
last_detected_at date-time string or null When the latest sweep still saw it.
resolved_at date-time string or null When the problem went away. Always null here, because only open alerts are returned.
dismissed_at date-time string or null When a member dismissed the alert on the issues page, which hides it there for as long as the problem lasts. Null when it was not dismissed.
snoozed_until date-time string or null When a member’s snooze ends, while it is still running. Null when the alert is not snoozed or the snooze has ended.

ShipmentCheck object

The result of one document check run against one shipment, for example whether a packing list is present or whether its box count matches the declared total.

Field Type Description
object string Always shipment_check.
id string The check result id.
shipment_id string The shipment the check ran against.
shipment_reference string That shipment’s Trackberry reference.
key string The stable identifier of the check, for example has_packing_list, packing_list_box_count or invoice_total. New keys may be added.
category string or null The kind of problem the check looks for. documents means a required document is missing; data_integrity means figures that should agree do not; data_completeness means a needed value is missing from a document. Null if the check no longer exists. One of documents, data_integrity, data_completeness.
status string The outcome. pending has not run yet; passed is fine; failed means something is wrong; skipped means its preconditions were not met; warning means it passed with a caveat. One of pending, passed, failed, skipped, warning.
title string A short English name for this result.
message string or null An English sentence explaining the outcome. Null when the check has not produced one.
ran_at date-time string or null When the check last ran. Null if it never ran.

Document object

A file attached to a shipment, such as a bill of lading, packing list, invoice or certificate, with its processing state. The file itself is not part of this object: GET /documents/{id}/file serves it when downloadable is true.

Field Type Description
object string Always document.
id string The document id.
shipment_id string The shipment the document belongs to.
type string What kind of document Trackberry decided it is. transport_document covers bills of lading, air waybills and road consignment notes; merged_document is a single file holding several kinds; unknown means it could not be classified. One of unknown, packing_list, transport_document, invoice, phytosanitary_cert, merged_document, certificate_of_origin, warehouse_receipt, inspection_report, courier_document, other_certificate, arrival_notice, booking, pre_alert.
filename string or null The file’s name. Null when no file is attached.
content_type string or null The file’s MIME type. Null when no file is attached.
byte_size integer or null The file size in bytes. Null when no file is attached.
source string How the document reached Trackberry. manual_upload was uploaded in the app; email_upload arrived by email; api came in through an integration; correction_link was sent in answer to a correction request; shared_link was copied from another organization’s public tracking page when the shipment was saved from it. One of manual_upload, email_upload, api, correction_link, shared_link.
parse_status string Whether Trackberry has read the document. pending and processing are in progress; parsed means data was extracted; failed means reading failed. One of pending, processing, parsed, failed.
downloadable boolean True when a file is attached and passed the security scan, so GET /documents/{id}/file serves it.
page_range string or null For a document split out of a larger multi-document PDF, the pages of the original file it covers, like 3-5 or 7. Null for documents that are whole files.
data_available boolean True when get_document_data will return extracted fields for this document.
created_at date-time string When the document was added to Trackberry.
updated_at date-time string When the document record last changed.

DocumentData object

The structured data Trackberry extracted from one document. The set of fields depends on schema.

Field Type Description
object string Always document_data.
document_id string The document the data was read from.
type string The document’s class name when it has one (finer than Document.type, for example exporter_invoice, transport_invoice, sanitary_document), otherwise its type.
schema string or null The shape of fields. Null when nothing was extracted or the document type has no structured schema, in which case fields is empty. One of packing_list, transport_document, invoice, certificate, inspection_report, arrival_notice, booking, pre_alert, warehouse_receipt.
fields object The extracted values, keys in snake_case, calendar days as YYYY-MM-DD strings, amounts and weights as numbers, missing values null, repeated groups as arrays of objects. Fields by schema. packing_list: packing_list_number, exporter_name, exporter_port, exporter_country, importer_name, importer_country, total_net_weight, total_boxes, diagram_pallet_numbers, container_number, line_items (each with pallet_number, produce_name, variety, size_calibre, quality_category, format, label, produce_type, ggn, comment, number_of_boxes, net_weight_kg, box_weight_kg, gross_weight_kg). transport_document: transport_type, shipment_reference, equipment_numbers, container_lengths, package_count, package_unit, gross_weight_kg, consignor, consignee, notify_party, carrier, departure_location and arrival_location (each with location_name and country), etd, eta, temperature_setpoint_celsius, cargo_type, load_type, issuer. invoice: seller_name, seller_location, seller_country, buyer_name, buyer_location, buyer_country, invoice_number, invoice_date, total_amount, currency, line_items (each with produce_description, produce_name, variety, calibre, pack_format, box_weight_kg, quantity, unit_price, price_unit, total_amount). certificate: exporter_name, exporter_location, exporter_country, importer_name, importer_location, importer_country, certificate_number, certificate_date, produce_description. inspection_report: inspection_company, inspector_name, report_number, inspection_date, inspection_location, container_number, produce_description, total_pallets, overall_impression, overall_score, overall_impression_category, general_remarks, results (each with pallet_number, lot_code, produce_name, variety, calibre, score, recommendation, remarks, defects, photo_numbers). arrival_notice: carrier_name, bill_of_lading_number, container_numbers, vessel_arrival_date, free_time (each with applies_to, cargo_class, days, hours, basis, from_date, until_date, from_event, estimated, quote). booking: load_type, move_type, shipper, consignee, cargo_ready_date, departure_location and arrival_location (each with location_name and country), place_of_delivery, incoterm, po_number, package_count, package_unit, gross_weight_kg, volume_cbm, booking_reference, transport_type. pre_alert: forwarder_name, forwarder_reference, house_bill_of_lading, master_bill_of_lading, load_type, vessel, voyage, departure_location and arrival_location (each with location_name and country), etd, forwarder_arrival_date, shipper, consignee, incoterm, container_numbers, package_count, gross_weight_kg, volume_cbm. warehouse_receipt: warehouse_name, receipt_number, received_on, container_number, storage_location, supplier_name, total_boxes, total_pallets, lines (each with warehouse_pallet_number, pallet_number, batch_number, description, produce_name, variety, calibre, quality_category, pack_format, number_of_boxes, gross_weight_kg), allocations (each with pallet_number, batch_number, boxes, allocated_on, order_reference, customer). Fields may be added over time.

PackingList object

A packing list read from a document, saying what the exporter states is in the container, by pallet and produce line.

Field Type Description
object string Always packing_list.
id string The packing list id.
shipment_id string The shipment it belongs to.
document_id string or null The document it was read from. Null when it was created without one.
container_id string or null The container it covers. Null when the document did not say.
reference string or null The packing list’s own number.
declared_box_count integer or null The total number of boxes the document states, before Trackberry sums the lines. Compare with totals.boxes.
declared_net_weight_kg number or null The total net weight in kilograms the document states. Compare with totals.net_weight_kg.
totals object Totals Trackberry computed from this packing list’s own visible lines.
totals.pallets integer Number of pallets on this packing list.
totals.boxes integer Sum of the box counts of its lines.
totals.net_weight_kg number Sum of the net weights of its lines, in kilograms.
pallets array of Pallet objects The pallets of this packing list, oldest first.

Pallet object

One pallet of a packing list.

Field Type Description
object string Always pallet.
id string The pallet id.
pallet_number string or null The pallet’s number or SSCC as printed on the packing list. Unique within a shipment when set.
container_id string or null The container the pallet is loaded in. Null when unknown.
lines array of PackingLine objects The pallet’s produce lines in reading order. Lines merged into another line are left out.

PackingLine object

One produce line on a pallet, a quantity of one variety, calibre and pack format.

Field Type Description
object string Always packing_line.
id string The line id.
line_index integer or null The line’s position in the packing list, used to order lines.
produce_name string or null The produce, normalized (for example Grapes).
produce_type string or null How the produce was grown, as written on the packing list. Lines marked organic (any letter case) make the shipment organic.
variety string or null The variety or cultivar.
calibre string or null The size grade of the produce.
quality_category string or null The quality class, such as Class I.
pack_format string or null How the produce is packed, for example a carton size.
label string or null The brand or label printed on the packaging.
ggn string or null The GLOBALG.A.P. Number (GGN) of the producer, when stated.
comment string or null Remarks the packing list gives for this line, as written, often about how it is packed or labelled.
box_count integer or null Number of boxes on this line.
preallocated_boxes integer Boxes of this line already set aside for customers, the sum of its pre-allocations. box_count minus this is what is still free. 0 when there are none.
box_weight_kg number or null Net weight of one box in kilograms.
net_weight_kg number or null Net weight of the whole line in kilograms.
gross_weight_kg number or null Gross weight of the whole line in kilograms, packaging included.

A tracking link made for one of your customers. It opens the ordinary public tracking page, led by the customer’s own reference, and can be switched off without touching any other link.

Field Type Description
object string Always share_link.
id string The customer link id.
shipment_id string The shipment the link opens.
customer_reference string The customer’s own reference for the order, as shown to the customer.
label string or null Your own note to tell links apart. Never shown to the customer. Null when none was given.
url string or null The link to give the customer. The secret part of the link is only ever inside this URL. Null once the link is revoked.
active boolean False once the link has been revoked.
revoked_at string or null When the link was revoked. Null while it is active.
created_at string When the link was created.

Preallocation object

Boxes of one packing line set aside for a customer, with the tentative price they were given.

Field Type Description
object string Always preallocation.
id string The pre-allocation id.
packing_line_id string The packing line the boxes come from.
pallet_id string The pallet that packing line is on.
allocatee string or null The customer the boxes are set aside for. Null when none was given.
boxes integer How many boxes are set aside.
unit_price number or null The tentative price per box. Null when the pre-allocation has no price.
currency string or null The three-letter currency code of the price. Null when there is no price.
value number or null The tentative value of these boxes, boxes times unit_price. Null when there is no price.
created_at string When the pre-allocation was made.
updated_at string When the pre-allocation last changed.

CompanyReference object

A company a shipment, product, purchase order or expected container is linked to, enough to name it and to look it up with get_company (the REST operation and the MCP tool of the same name).

Field Type Description
id string The company id.
name string The company’s name.

Company object

A supplier, forwarder or customer of the organization. There is no contact email; Trackberry does not store one.

Field Type Description
object string Always company.
id string The company id.
name string The company’s name.
roles array of strings What the company is to the organization, learned from the documents it appears on. Empty for an organization’s own company. Each one of supplier, forwarder, customer.
own boolean True when the company is one of the organization’s own legal entities, which are neither suppliers, forwarders nor customers.
country string or null The ISO 3166-1 alpha-2 country code. Null when unknown.
erp_code string or null The company’s code in the organization’s ERP. Null when none was set.
aliases array of strings The other spellings of the name seen on documents, sorted alphabetically. The company’s own name is name, not repeated here.
open_shipments object How many live shipments (not archived, not waiting for approval) the company is linked to, by role. These are the counts list_shipments returns when filtered by that company.
open_shipments.supplier integer Live shipments with this company as supplier.
open_shipments.forwarder integer Live shipments with this company as forwarder.
open_shipments.customer integer Live shipments with this company as customer.
created_at string When the company was first seen or added.
updated_at string When the company last changed.

ShipmentNotes object

A shipment’s notes as they stand after a write.

Field Type Description
object string Always shipment_notes.
shipment_id string The shipment the notes belong to.
notes string or null The whole notes text, as Markdown. Null when the notes are empty.

ShipmentLabels object

The labels a shipment carries after a label write.

Field Type Description
object string Always shipment_labels.
shipment_id string The shipment the labels are on.
labels array of Label Every label the shipment carries now, by name.

CheckRun object

A request to run a shipment’s checks again.

Field Type Description
object string Always check_run.
shipment_id string The shipment whose checks were queued.
status string Always queued. The checks run in the background; read them with GET /checks shortly after.

TrackingRefresh object

A request for fresh tracking on a shipment.

Field Type Description
object string Always tracking_refresh.
shipment_id string The shipment whose tracking was queued for a refresh.
status string Always queued. The new data arrives in the background; read the shipment again shortly after.

CheckAcknowledgement object

A failed or warning check somebody accepted, with the reason they gave. The check keeps its status.

Field Type Description
object string Always check_acknowledgement.
check_id string The check that was acknowledged.
shipment_id string The shipment the check ran against.
acknowledged_at string (date-time) or null When it was acknowledged. Null once the acknowledgement was withdrawn.
reason string or null The reason given. Null once the acknowledgement was withdrawn.

Warehouse object

The importer’s own site, where containers are delivered. It exists so the dates Trackberry promises skip the days nobody is there to receive the goods. Opening hours are not recorded, only the weekdays it opens.

Field Type Description
object string Always warehouse.
id string The warehouse id.
name string The warehouse’s name.
street string or null Street and number. Null when not entered.
postal_code string or null Postal code. Null when not entered.
city string or null City. Null when not entered.
country_code string The two-letter ISO country code of the warehouse.
open_days array of strings The weekdays it receives containers, in week order. Closures can still shut or open single days. One of mon, tue, wed, thu, fri, sat, sun.
holiday_region string or null The public-holiday region someone chose for this warehouse, such as DE-BY. Null when none was chosen.
effective_holiday_region string Whose public holidays count at this warehouse: the chosen holiday_region, else the region found from the address, else the country code.
located boolean Whether the address was found on the map. The coordinates themselves are not exposed.
default boolean Whether this is the organization’s default warehouse, the one dates are counted for.
archived boolean Whether the warehouse has been retired. Archived warehouses are listed only on request.

WarehouseClosure object

A run of dates a warehouse is shut or, with open, open although its calendar says otherwise. A closure’s word beats the weekly schedule and the public holidays alike.

Field Type Description
object string Always warehouse_closure.
id string The closure id.
warehouse_id string The warehouse it belongs to.
starts_on date string The first day of the run.
ends_on date string The last day of the run, included. Equal to starts_on for a single day.
open boolean True when the warehouse is open on these days although the calendar says shut, false when it is shut.
note string or null A free-text reason entered with the closure. Null when none.

WarehouseDeliveryDays object

Each day of a range with whether a container can be received at the warehouse and why not, counted the way the free-time collect_by date is.

Field Type Description
object string Always warehouse_delivery_days.
warehouse_id string The warehouse the days are for.
shipment_id string or null The shipment whose port holidays were counted. Null when none was given, so port holidays are not counted.
from date string The first day of the range.
to date string The last day of the range, included.
calendars array of strings The public-holiday calendars counted, the warehouse’s first, as region codes such as DE-BY.
days array of WarehouseDeliveryDay objects One entry per day from from to to, in date order.

WarehouseDeliveryDay object

One day of a warehouse’s delivery calendar.

Field Type Description
date date string The calendar day this entry describes.
weekday string The day of the week. One of mon, tue, wed, thu, fri, sat, sun.
usable boolean Whether a container can be received that day. True for open and closure_open.
reason string What decides the day. open: an ordinary open day. closure_open: a closure opens it. closure: a closure shuts it. weekday: not one of the warehouse’s open weekdays. warehouse_holiday: a public holiday where the warehouse is. port_holiday: a public holiday at the port, only when a shipment was given. The first that applies wins, in the order listed from closure. New reasons may be added. One of open, closure_open, closure, weekday, warehouse_holiday, port_holiday.

Product object

One product of the organization’s own catalogue (its item master, as loaded from its ERP) with what each supplier calls it. Trackberry has no separate ERP id for a product: the sku is the ERP’s item code.

Field Type Description
object string Always product.
id string The product id.
sku string The organization’s own item code for the product, as its ERP prints it.
description string or null The organization’s own description of the product. Null when the ERP gave none.
unit string or null The unit the organization counts the product in, such as box or kg. Null when not set.
properties object Whatever else the ERP export carried for the product (family, material, size and so on), keyed by the export’s column names. Empty when there is nothing.
discontinued_at date-time string or null When the latest ERP export stopped carrying the product. Null for an active product.
supplier_references array of objects What suppliers call this product: the code printed on their documents, which Trackberry uses to match document lines to the product.
supplier_references[].supplier object or null The supplier, with its id for get_company. Null when the reference applies whichever supplier prints it. See CompanyReference.
supplier_references[].reference string The supplier’s own code for the product.
supplier_references[].description string or null How the supplier describes the product. Null when unknown.
supplier_references[].conversion_factor number How many of the organization’s units one of the supplier’s units is. Invoice quantities are multiplied by it.
supplier_references[].status string confirmed when the reference came from the ERP export or a person confirmed it, suggested when Trackberry guessed it and nobody has confirmed it yet. One of confirmed, suggested.
supplier_references[].confirmed_at date-time string or null When a person confirmed the reference. Null when nobody did.
supplier_descriptions array of objects The wordings a supplier has used on documents for this product, learned from corrections and purchase orders.
supplier_descriptions[].supplier object The supplier, with its id for get_company. See CompanyReference.
supplier_descriptions[].description string The wording the supplier used for the product.
supplier_descriptions[].trusted boolean Whether Trackberry has seen the wording often enough to match on it without asking. Untrusted wordings are only offered as suggestions.
supplier_descriptions[].confirmations integer How many times the wording was confirmed.
supplier_descriptions[].last_confirmed_at date-time string When the wording was last confirmed.
created_at date-time string When the product was added to Trackberry.
updated_at date-time string When the product last changed.

PurchaseOrder object

One purchase order: the lines of one order number from one supplier, as the organization’s ERP lists them, with how much of each has been matched to supplier invoices and packing lists. Every line of the order is included, whatever the request’s filters were; the filters only choose which orders are listed.

Field Type Description
object string Always purchase_order.
id string The order’s id, taken from its first line. Use it as the starting_after cursor; it is not accepted anywhere else.
order_number string The order number as the ERP prints it, for example AA/35.264.
supplier object or null The supplier, with its id for get_company. When Trackberry does not know the supplier yet, id is null and name is the name the ERP export gave. Null when the export gave none.
status string open when any of the order’s lines is open, otherwise closed. One of open, closed.
lines array of objects The order’s lines, sorted by line id, the order they were first loaded.
lines[].id string The order line id.
lines[].line_number string or null The line’s number within the order, as the ERP prints it.
lines[].product_id string or null The product ordered. Null while the ERP’s article code is not one in the catalogue.
lines[].article_code string or null The article code the ERP export gave for the line.
lines[].supplier_reference string or null The supplier’s own code for the article, when the export carried one.
lines[].description string or null The line’s description from the ERP.
lines[].quantity_ordered number or null How much was ordered, in the ERP’s unit. Null when the export did not say.
lines[].quantity_received number or null How much the ERP says has been received so far. Null when the export did not say.
lines[].quantity_remaining number or null How much is still to arrive according to the ERP: ordered minus received, never below zero. Null when the order quantity is unknown.
lines[].quantity_invoiced number How much supplier invoices on shipments have billed against this line so far, in the ERP’s unit (the invoice quantity times the matched supplier reference’s conversion factor). Zero when no invoice has been matched to the line.
lines[].quantity_packed number How many pieces the current packing lists of shipments list against this line. Zero when none has.
lines[].unit_price number or null The ordered unit price. Null when the export gave none.
lines[].currency string or null The three-letter currency code of the price. Null when none was given.
lines[].expected_on date string or null The date the ERP expects the goods. Null when it gave none.
lines[].status string open while the latest ERP export still carries the line, closed once it no longer does. One of open, closed.
lines[].closed_at date-time string or null When the line stopped being in the ERP export. Null for an open line.
shipment_ids array of strings The shipments whose supplier invoices or packing lists were matched to a line of this order. Empty when the goods have not been seen on a shipment yet.

ExpectedShipment object

A container a supplier has agreed to send, planned before any shipping document exists, with the documents received for it and, once matched, the tracked shipment it became.

Field Type Description
object string Always expected_shipment.
id string The expected container id.
status string planned while the container is still to come, matched once it was matched to a tracked shipment, cancelled when it will not come. One of planned, matched, cancelled.
supplier object or null The supplier, with its id for get_company. Null when none was set. See CompanyReference.
order_number string or null The organization’s purchase order number for the container. Null when none was set.
produce_name string or null The produce expected, such as Hass avocado.
variety string or null The produce’s variety. Null when none was set.
calibre string or null The produce’s size grade. Null when none was set.
boxes integer or null How many boxes are expected. Null when unknown.
pallets integer or null How many pallets are expected. Null when unknown.
expected_week_start date string The Monday of the week the container is expected to leave the origin.
expected_week_end date string The Sunday of that week.
overdue boolean True when the container is still planned and its expected week has passed.
origin_location string or null Where the container is expected to leave from. Null when none was set.
destination_location string or null Where the container is expected to arrive. Null when none was set.
unit_price number or null The agreed price, in the unit price_basis names. Null when there is none.
price_basis string What unit_price is the price of: one box, the total of the order, or the whole container. One of box, total, container.
currency string or null The three-letter currency code of the price. Null when there is no price.
notes string or null Free-text notes kept on the expected container. Null when there are none.
shipment_id string or null The tracked shipment this container was matched to. Null while it is not matched, or when the matched shipment is not available through the API.
matched_at date-time string or null When the container was matched to a shipment. Null when not matched.
match_source string or null How the match was made: by manual choice, from a shipping document or from an email. Null when not matched. One of manual, document, email.
cancelled_at date-time string or null When the expected container was cancelled. Null when it was not.
documents array of objects The proformas and other documents received for this container, oldest first.
documents[].kind string proforma for a proforma invoice, other for any other document. One of proforma, other.
documents[].filename string or null The file’s name. Null when the file is not available.
documents[].subject string or null The subject of the email the document arrived in. Null when it was uploaded by hand.
documents[].received_at date-time string When the document was received.
created_at date-time string When the expected container was added.
updated_at date-time string When the expected container last changed.

ShipmentFeedRow object

One row of the shipments feed: a shipment flattened for a BI tool. Every column is always present; a column with no value is empty in CSV and null in JSON.

Field Type Description
id string The shipment id. Use it to join with the events feed and to call the per-shipment endpoints.
reference string Trackberry’s own reference for the shipment.
erp_reference string or null Your ERP or purchase order reference, when one was set.
display_name string What people call the shipment: the container numbers for ocean (comma separated), the air waybill for air, otherwise the transport reference or Trackberry’s reference.
transport_type string or null The mode of transport. One of ocean, air, road.
load_type string or null Full container load or less than container load. Null for air, road or when unknown. One of fcl, lcl.
status string Where the shipment stands in its lifecycle. One of draft, validated, in_transit, arrived, in_warehouse.
archived boolean Whether the shipment has been archived.
transport_reference string or null The bill of lading number for ocean or the air waybill number for air.
house_bl string or null The forwarder’s house bill of lading, for consolidated cargo.
container_count integer Number of containers on the shipment.
produce string or null The produce names found on the packing lists, separated by semicolons.
organic boolean Whether any packing line is organic.
carrier string or null The shipping line or airline under one canonical name, so the same carrier is never spelled two ways.
carrier_scac string or null The carrier’s SCAC or airline code.
supplier string or null The supplier the goods were bought from.
customer string or null The customer the goods are sold to (exports).
forwarder string or null The freight forwarder that moved the shipment.
consignor string or null The consignor as written on the transport document.
consignee string or null The consignee as written on the transport document.
origin_location string or null Place of origin.
origin_country string or null Country of origin.
destination_location string or null Place of destination.
destination_country string or null Country of destination.
pol string or null Port of loading as the carrier names it.
pol_locode string or null UN/LOCODE of the port of loading, when known.
pod string or null Port of discharge as the carrier names it.
pod_locode string or null UN/LOCODE of the port of discharge, when known.
etd date-time string or null Estimated (later actual) time of departure.
atd date-time string or null Actual time of departure from the port of loading. Null until the carrier confirms it.
eta date-time string or null Current estimated arrival: the shipment’s ETA, else the earliest container ETA.
original_eta date-time string or null The first ETA Trackberry recorded, the baseline for delays.
ata date-time string or null Actual time of arrival at the port of discharge. Null until the carrier confirms it.
availability_date date string or null The ETA plus the organization’s working days. Null unless the organization uses availability dates.
transit_days number or null Days from actual departure to actual arrival, one decimal. Null until both are known.
delay_days number or null Days between the original ETA and the actual arrival, one decimal. Positive is late, negative is early. Null until the shipment has arrived.
free_time_end date string or null The last free day of the demurrage clock (the day free time ends). Null when there is no clock or no terms.
demurrage_state string or null State of the most urgent demurrage clock, for example running, stopped or not_started.
demurrage_free_days integer or null Free days granted before demurrage starts, when known.
demurrage_overdue_days integer or null Days beyond the free days that were used. Only set when the clock has stopped.
detention_last_free_day date string or null The last free day of the detention clock.
detention_overdue_days integer or null Days beyond the detention free days that were used. Only set when the clock has stopped.
pallets integer Number of pallets on the packing lists.
boxes integer Number of boxes on the packing lists.
net_weight_kg number Net weight from the packing lists, in kilograms.
gross_weight_kg number Gross weight from the packing lists, in kilograms.
co2_tonnes number or null Estimated CO2 emissions in tonnes, when computed.
invoice_value number or null Sum of the invoice line totals. Null when there are no invoices, or when they mix currencies.
invoice_currency string or null The currency of invoice_value.
created_at date-time string When the shipment was created in Trackberry.
approved_at date-time string or null When the shipment was approved.
validated_at date-time string or null When the shipment was validated.
archived_at date-time string or null When the shipment was archived.
updated_at date-time string When the shipment last changed.
net_weight_lb number The same net weight as net_weight_kg, in pounds.
gross_weight_lb number The same gross weight as gross_weight_kg, in pounds.
origin_code string or null Canonical code of the place of origin: a UN/LOCODE for a port or an IATA code for an airport. Null when the place is only known by name.
destination_code string or null Canonical code of the place of destination: a UN/LOCODE for a port or an IATA code for an airport. Null when the place is only known by name.

EventFeedRow object

One row of the events feed: a tracking event flattened for a BI tool, with its shipment’s id and reference.

Field Type Description
id string The event id.
shipment_id string The shipment the event belongs to. Join to the shipments feed on id.
shipment_reference string That shipment’s Trackberry reference.
container_number string or null The container the event is about. Null for events on the whole shipment, and for air.
milestone string What happened, for example loaded, departed, arrived, discharged, gate_out, empty_return. New milestones may be added.
actual boolean True when it happened, false when it is an estimate.
occurred_at date-time string or null When it happened or is expected, in UTC.
location_name string or null Where it happened, as the carrier names the place.
location_code string or null The UN/LOCODE or airport code of the place, when known.
location_country_code string or null The two-letter country code of the place.
vessel_name string or null The vessel involved, for ocean events.
vessel_imo string or null The vessel’s IMO number.
voyage string or null The voyage number.
flight_number string or null The flight number, for air events.
latitude number or null Latitude of the event, when the carrier gave a position.
longitude number or null Longitude of the event, when the carrier gave a position.

KpiFeedRow object

One row of the KPI feed: a single number for a metric, a period and, for breakdowns, one carrier, lane, country, port or produce.

Field Type Description
metric string The measure. See the list of metrics in the endpoint description.
period_start date string First day of the period. For monthly metrics the first day of the month; for ranked metrics the first day of the first month in the window.
period_end date string Last day of the period. For monthly metrics the last day of the month; for ranked metrics today.
dimension string or null What dimension_value names: transport_type, carrier, lane, origin_country, destination_country, destination_port, produce, supplier, forwarder or incident_type. Null for totals.
dimension_value string or null The carrier, lane (Valencia > Rotterdam), country, port, produce, supplier, forwarder or incident type (delay, rollover, free_time_breach, document_error, customs_hold) this row is about. Null for totals.
value number or null The number. Null when it cannot be computed, such as an on-time percentage for a month with no arrivals.
unit string What value counts. One of shipments, containers, days, percent, tonnes, incidents, per_100_shipments.

What the API doesn’t do yet

  • Writes are limited. You can make and revoke the tracking links you give your customers, upload documents for Trackberry to read, pre-allocate boxes write shipment notes, and label, archive and re-check shipments, but you can’t create tracked shipments, approve them, or correct extracted data through the API.
  • Webhooks are a separate feature. Trackberry can call your system when a shipment changes status or ETA, its checks finish, or an alert opens; see Webhooks. Other changes need polling /shipments or /alerts.
  • No browser calls. The API is for servers and scripts, so it doesn’t send CORS headers.

If one of these would unblock you, email [email protected] with what you’re building.

Tags: api integration automation tokens