{"openapi":"3.1.0","info":{"title":"Trackberry API","version":"2026-10-01","summary":"Read-only JSON API for Trackberry shipments, tracking, free time, alerts, checks, documents and packing lists.","description":"The Trackberry API gives a customer's own scripts, BI tools and coding agents read access to the\nshipments of one organization: shipment details, containers, tracking events, ETA history,\ndemurrage and detention clocks, open monitoring alerts, quality checks, documents, the data\nextracted from documents, and packing lists with pallets and lines.\n\nIt is **read-only**: every endpoint is a `GET`. Nothing can be created, changed, approved or\nuploaded through it, and there are no webhooks, no file downloads and no CORS headers (it is for\nservers and scripts, not browsers).\n\n## When to use which endpoint\n\n- Find shipments: `list_shipments` (filter by text, status, label, archived flag, creation time or ETA).\n- Everything about one shipment: `get_shipment`, then `get_shipment_timeline` for tracking events and ETA\n  revisions, `get_shipment_free_time` for demurrage and detention, `list_shipment_documents` and\n  `list_shipment_packing_lists` for paperwork.\n- What needs attention now: `list_alerts` (open monitoring alerts), `list_checks` (failed and warning\n  quality checks) and `list_free_time_at_risk` (containers close to or past their free time).\n- Which organization and API version a token is bound to: `get_organization`.\n\n## Authentication\n\nSend a token in the `Authorization` header: `Authorization: Bearer tb_...`. A token is `tb_` followed by\n40 letters and digits. A member of the organization creates it under Settings, API tokens, and it is shown\nonce. A token belongs to one user and one organization and can read what that user can read in that\norganization. It expires after 30 days, 90 days, 1 year or never (chosen at creation), stops working when\nrevoked, and stops working when the user leaves the organization. The organization is implied by the token:\nthere is no organization slug in any URL. The only endpoint that needs no token is `get_openapi_document`.\n\n## Versioning\n\nThe API is versioned. A version is named after its release day, for example `2026-10-01`, and this\ndocument describes the latest one (`info.version`). An organization is pinned to the latest version on its\nfirst request that has no `Trackberry-Version` header, and every later response has that shape until an\norganization admin moves the pin forward in settings. To try another published version, send\n`Trackberry-Version: <version>` on a request: it applies to that request only and does not change the pin.\nAn unknown version is a 400 with code `invalid_version`. Responses carry a `Trackberry-Version` header with\nthe version they were built for.\n\nAdditive changes never create a new version: new endpoints, new fields, new optional parameters and new\nvalues in a documented enum are added to every version. **Clients must ignore unknown fields** (every\nobject here sets `additionalProperties: true`) and should not fail on an enum value they do not know.\nRemoving or renaming a field, changing a type, unit or meaning, or changing a default filter is a breaking\nchange and only ever ships as a new version.\n\n## IDs\n\nObject ids are strings shaped `<prefix>_<integer>`, for example `shp_812`. The prefix names the kind of\nobject: `org` organization, `tok` API token, `shp` shipment, `ctr` container, `lbl` label, `leg` shipment\nleg, `evt` tracking event, `eta` ETA revision, `alr` monitoring alert, `chk` shipment check, `doc` document,\n`pkl` packing list, `plt` pallet, `pln` packing line. Treat ids as opaque and pass them back exactly as\nreceived. An id with the wrong prefix or from another organization in a path is a 404; a malformed id given\nas a query parameter is a 400.\n\n## Lists and paging\n\nList endpoints return `{ \"object\": \"list\", \"data\": [...], \"has_more\": boolean }`. Lists that can grow\n(`list_shipments`, `list_alerts`, `list_checks`) are ordered by id, newest first, and use keyset paging:\n`limit` (1 to 100, default 25) and `starting_after`, the `id` of the last item of the previous page. Keep\npaging while `has_more` is true. Items that arrive while you page cause no gaps and no repeats. Lists\nbounded by one shipment or one population (documents, packing lists, free time at risk) are not paged and\nalways have `has_more: false`. Filters that take several values take them as one comma-separated value,\nfor example `status=in_transit,arrived`.\n\n## Formats\n\nTimestamps are UTC ISO 8601 with a `Z` suffix (`2026-09-29T14:03:00Z`); the only exception is\n`occurred_at_local`, which keeps the local offset of the place the event happened. Calendar days are\n`YYYY-MM-DD`. Query parameters that take a time accept either a full date-time or a bare date (midnight\nUTC). Weights are kilograms, temperatures are degrees Celsius, statuses are lowercase snake_case strings.\nA field with no value is always present and `null`, never omitted; empty lists are `[]`. A path may end in\n`.json`; any other extension is a 404. Unknown query parameters are ignored.\n\n## Errors\n\nEvery error has the same body, `{ \"error\": { \"type\", \"code\", \"message\", \"param\" } }`, with `param` naming\nthe offending parameter or header when there is one and `null` otherwise. Branch on `code`, show `message`\nto people.\n\n## Rate limits\n\n600 requests per 5 minutes per token, 1,200 per 5 minutes per IP address across all tokens, and 30 per\n5 minutes per IP address for requests that carry no token (this includes `get_openapi_document`). Past a\nlimit the response is a 429 with a `Retry-After` header giving the seconds to wait.\n\n## Support\n\nEmail support@trackberry.com with what you are building if a missing capability blocks you.\n","contact":{"name":"Trackberry support","email":"support@trackberry.com","url":"https://trackberry.com/learn/docs/guides/api"}},"servers":[{"url":"https://trackberry.com/api/v1","description":"Production"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Organization","description":"The organization and token a request is bound to."},{"name":"Shipments","description":"Shipments and everything hanging off one shipment."},{"name":"Free time","description":"Demurrage and detention clocks."},{"name":"Alerts and checks","description":"What Trackberry has flagged as needing attention."},{"name":"Documents","description":"Documents attached to shipments and the data extracted from them."},{"name":"Specification","description":"This description."}],"paths":{"/organization":{"get":{"operationId":"get_organization","tags":["Organization"],"summary":"Get the organization and token behind the request","description":"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.","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"}],"responses":{"200":{"description":"The organization and the token used.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"},"example":{"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":"you@freshimports.com"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/shipments":{"get":{"operationId":"list_shipments","tags":["Shipments"],"summary":"List and search shipments","description":"Use this to find shipments, to sync the whole book, 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.","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"},{"name":"q","in":"query","required":false,"description":"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.","schema":{"type":"string"},"example":"MSCU1234567"},{"name":"status","in":"query","required":false,"description":"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.","style":"form","explode":false,"schema":{"type":"array","items":{"type":"string","enum":["draft","validated","in_transit","arrived","in_warehouse"]}},"example":"in_transit,arrived"},{"name":"labels","in":"query","required":false,"description":"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.","style":"form","explode":false,"schema":{"type":"array","items":{"type":"string","pattern":"^lbl_[1-9][0-9]{0,17}$"}},"example":"lbl_3,lbl_9"},{"name":"archived","in":"query","required":false,"description":"Whether to include archived shipments. `false` (the default) lists only active ones, `true` only archived ones, `any` both.","schema":{"type":"string","enum":["false","true","any"],"default":"false"},"example":"any"},{"name":"created_after","in":"query","required":false,"description":"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.","schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"}]},"example":"2026-09-01"},{"name":"created_before","in":"query","required":false,"description":"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.","schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"}]},"example":"2026-09-30T23:59:59Z"},{"name":"eta_after","in":"query","required":false,"description":"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).","schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"}]},"example":"2026-10-01T00:00:00Z"},{"name":"eta_before","in":"query","required":false,"description":"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.","schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date"}]},"example":"2026-10-07"},{"$ref":"#/components/parameters/Limit"},{"name":"starting_after","in":"query","required":false,"description":"Cursor for the next page: the `id` of the last shipment of the previous page. Must start with `shp_`; anything else is a 400.","schema":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$"},"example":"shp_812"}],"responses":{"200":{"description":"A page of shipments, newest first.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/List"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Shipment"}}}}]},"example":{"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","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"},"destination":{"location":"Rotterdam","country":"Netherlands","timezone":"+02:00"},"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,"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},"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_number":"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},"notes":null,"created_at":"2026-09-15T12:00:00Z","updated_at":"2026-09-29T09:41:00Z"}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/shipments/{id}":{"get":{"operationId":"get_shipment","tags":["Shipments"],"summary":"Get one shipment","description":"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`.","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"},{"$ref":"#/components/parameters/ShipmentId"}],"responses":{"200":{"description":"The shipment.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Shipment"},"example":{"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","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"},"destination":{"location":"Rotterdam","country":"Netherlands","timezone":"+02:00"},"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,"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},"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_number":"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},"notes":null,"created_at":"2026-09-15T12:00:00Z","updated_at":"2026-09-29T09:41:00Z"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/shipments/{shipment_id}/timeline":{"get":{"operationId":"get_shipment_timeline","tags":["Shipments"],"summary":"Get the route, tracking events and ETA revisions of a shipment","description":"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.","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"},{"$ref":"#/components/parameters/ParentShipmentId"}],"responses":{"200":{"description":"The timeline of the shipment.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Timeline"},"example":{"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"},"destination":{"location":"Rotterdam","country":"Netherlands","timezone":"+02:00"},"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}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/shipments/{shipment_id}/free_time":{"get":{"operationId":"get_shipment_free_time","tags":["Free time"],"summary":"Get the demurrage and detention clocks of a shipment","description":"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`).","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"},{"$ref":"#/components/parameters/ParentShipmentId"}],"responses":{"200":{"description":"The free-time summary of the shipment.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreeTimeSummary"},"example":{"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"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/shipments/{shipment_id}/documents":{"get":{"operationId":"list_shipment_documents","tags":["Documents"],"summary":"List the documents of a shipment","description":"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. The API describes documents but does not serve the files.","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"},{"$ref":"#/components/parameters/ParentShipmentId"}],"responses":{"200":{"description":"The documents of the shipment.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/List"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Document"}}}}]},"example":{"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"}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/shipments/{shipment_id}/packing_lists":{"get":{"operationId":"list_shipment_packing_lists","tags":["Shipments"],"summary":"List the packing lists of a shipment with pallets and lines","description":"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).","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"},{"$ref":"#/components/parameters/ParentShipmentId"}],"responses":{"200":{"description":"The current packing lists of the shipment.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/List"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PackingList"}}}}]},"example":{"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","box_count":120,"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","box_count":120,"box_weight_kg":4.0,"net_weight_kg":480.0,"gross_weight_kg":522.0}]}]}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/free_time/at_risk":{"get":{"operationId":"list_free_time_at_risk","tags":["Free time"],"summary":"List shipments whose demurrage free time is nearly or already used up","description":"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.","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"}],"responses":{"200":{"description":"The at-risk shipments, most urgent first.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/List"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FreeTimeSummary"}}}}]},"example":{"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"}}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/alerts":{"get":{"operationId":"list_alerts","tags":["Alerts and checks"],"summary":"List open monitoring alerts","description":"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.","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"},{"name":"shipment","in":"query","required":false,"description":"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.","schema":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$"},"example":"shp_812"},{"$ref":"#/components/parameters/Limit"},{"name":"starting_after","in":"query","required":false,"description":"Cursor for the next page: the `id` of the last alert of the previous page. Must start with `alr_`; anything else is a 400.","schema":{"type":"string","pattern":"^alr_[1-9][0-9]{0,17}$"},"example":"alr_2210"}],"responses":{"200":{"description":"A page of open alerts, newest first.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/List"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MonitoringAlert"}}}}]},"example":{"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}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/checks":{"get":{"operationId":"list_checks","tags":["Alerts and checks"],"summary":"List quality checks across shipments","description":"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.","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"},{"name":"status","in":"query","required":false,"description":"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.","style":"form","explode":false,"schema":{"type":"array","items":{"type":"string","enum":["pending","passed","failed","skipped","warning"]},"default":["failed","warning"]},"example":"failed,warning"},{"name":"shipment","in":"query","required":false,"description":"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.","schema":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$"},"example":"shp_812"},{"$ref":"#/components/parameters/Limit"},{"name":"starting_after","in":"query","required":false,"description":"Cursor for the next page: the `id` of the last check of the previous page. Must start with `chk_`; anything else is a 400.","schema":{"type":"string","pattern":"^chk_[1-9][0-9]{0,17}$"},"example":"chk_9001"}],"responses":{"200":{"description":"A page of checks, newest first.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/List"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentCheck"}}}}]},"example":{"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"}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/documents/{id}":{"get":{"operationId":"get_document","tags":["Documents"],"summary":"Get one document","description":"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. It does not return the file itself. Only current documents are found; a replaced or reference-only document is a 404.","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"},{"$ref":"#/components/parameters/DocumentId"}],"responses":{"200":{"description":"The document.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"},"example":{"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"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/documents/{id}/data":{"get":{"operationId":"get_document_data","tags":["Documents"],"summary":"Get the data Trackberry extracted from a document","description":"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 accept 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.","parameters":[{"$ref":"#/components/parameters/TrackberryVersion"},{"$ref":"#/components/parameters/DocumentId"}],"responses":{"200":{"description":"The extracted data.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentData"},"example":{"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","number_of_boxes":120,"net_weight_kg":480.0,"box_weight_kg":4.0,"gross_weight_kg":522.0}]}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/openapi.json":{"get":{"operationId":"get_openapi_document","tags":["Specification"],"summary":"Get this OpenAPI description","description":"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.","security":[],"responses":{"200":{"description":"This OpenAPI 3.1 description, as JSON.","headers":{"Cache-Control":{"description":"Publicly cacheable for one hour.","schema":{"type":"string","example":"max-age=3600, public"}}},"content":{"application/json":{"schema":{"type":"object","description":"An OpenAPI 3.1 document.","additionalProperties":true}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"tb_ token","description":"An API token created under Settings, API tokens: `tb_` followed by 40 letters and digits. Send it as `Authorization: Bearer tb_...`."}},"parameters":{"TrackberryVersion":{"name":"Trackberry-Version","in":"header","required":false,"description":"The API version to build this response for, for example `2026-10-01`. Optional: without it the organization's pinned version is used (and the organization is pinned to the latest version on its first request without the header). Applies to this request only. An unpublished version is a 400 with code `invalid_version`.","schema":{"type":"string","pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}$"},"example":"2026-10-01"},"Limit":{"name":"limit","in":"query","required":false,"description":"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.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"example":50},"ShipmentId":{"name":"id","in":"path","required":true,"description":"The shipment id (`shp_` prefix). An id from another organization, or with another prefix, is a 404.","schema":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$"},"example":"shp_812"},"ParentShipmentId":{"name":"shipment_id","in":"path","required":true,"description":"The shipment id (`shp_` prefix). An id from another organization, or with another prefix, is a 404.","schema":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$"},"example":"shp_812"},"DocumentId":{"name":"id","in":"path","required":true,"description":"The document id (`doc_` prefix). An id from another organization, with another prefix, or of a document that is not current, is a 404.","schema":{"type":"string","pattern":"^doc_[1-9][0-9]{0,17}$"},"example":"doc_301"}},"headers":{"TrackberryVersion":{"description":"The API version this response was built for. Sent on every response produced after the token was accepted and the version resolved; not sent on 401, on an `invalid_version` 400, on unknown routes or on 429s.","schema":{"type":"string","example":"2026-10-01"}},"RetryAfter":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":1,"example":120}},"WWWAuthenticate":{"description":"Always `Bearer realm=\"Trackberry API\"`.","schema":{"type":"string","example":"Bearer realm=\"Trackberry API\""}}},"responses":{"BadRequest":{"description":"A parameter or header is invalid (`invalid_parameter`, with `param` naming it) or `Trackberry-Version` names an unpublished version (`invalid_version`, with `param` set to `Trackberry-Version`). A parameter that must be a single value but was sent as an array or hash (`status[]=x`, `q[a]=1`) is also a 400.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_parameter":{"value":{"error":{"type":"invalid_request_error","code":"invalid_parameter","message":"limit must be an integer between 1 and 100","param":"limit"}}},"invalid_version":{"value":{"error":{"type":"invalid_request_error","code":"invalid_version","message":"Unknown Trackberry-Version '2020-01-01'. Published versions: 2026-10-01.","param":"Trackberry-Version"}}}}}}},"Unauthorized":{"description":"No token was sent (`missing_token`) or the token is wrong, expired, revoked, or its user left the organization (`invalid_token`). The response has a `WWW-Authenticate` header.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/WWWAuthenticate"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_token":{"value":{"error":{"type":"authentication_error","code":"missing_token","message":"No API token supplied. Send Authorization: Bearer tb_...","param":null}}},"invalid_token":{"value":{"error":{"type":"authentication_error","code":"invalid_token","message":"Invalid API token.","param":null}}}}}}},"Forbidden":{"description":"Reserved for a token that lacks the scope an endpoint needs (`insufficient_scope`). Every endpoint needs the `read` scope and every token is issued with it, so this is not returned today.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"permission_error","code":"insufficient_scope","message":"This token does not have the scope this endpoint needs.","param":null}}}}},"NotFound":{"description":"No such object in this organization (`resource_missing`). This is also the answer for an id of another organization, an id with the wrong prefix, or a malformed id, so the API never confirms that an object exists elsewhere.","headers":{"Trackberry-Version":{"$ref":"#/components/headers/TrackberryVersion"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"not_found_error","code":"resource_missing","message":"No such shipment: 'shp_999999'","param":null}}}}},"TooManyRequests":{"description":"A rate limit was hit (`rate_limited`). Wait the number of seconds in `Retry-After`.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"rate_limit_error","code":"rate_limited","message":"Rate limit exceeded. Retry in 120 seconds.","param":null}}}}}},"schemas":{"Error":{"type":"object","description":"The single error body used by every failure.","additionalProperties":true,"required":["error"],"properties":{"error":{"type":"object","description":"The details of what went wrong.","additionalProperties":true,"required":["type","code","message","param"],"properties":{"type":{"type":"string","enum":["authentication_error","permission_error","not_found_error","invalid_request_error","rate_limit_error"],"description":"The broad class of the error."},"code":{"type":"string","enum":["missing_token","invalid_token","insufficient_scope","resource_missing","invalid_parameter","invalid_version","rate_limited"],"description":"A stable machine-readable reason. Branch on this."},"message":{"type":"string","description":"An English sentence for people. Do not parse it."},"param":{"type":["string","null"],"description":"The query parameter or header at fault, or null when the error is not about one."}}}}},"List":{"type":"object","description":"The envelope every list endpoint returns.","additionalProperties":true,"required":["object","data","has_more"],"properties":{"object":{"const":"list","description":"Always `list`."},"data":{"type":"array","description":"The items of this page, in the order the endpoint documents. Each item is an object of the kind the endpoint returns.","items":{"type":"object"}},"has_more":{"type":"boolean","description":"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":{"type":"object","description":"The organization a token reads, with the token that made the request.","additionalProperties":true,"required":["object","id","name","slug","api_version","token"],"properties":{"object":{"const":"organization","description":"Always `organization`."},"id":{"type":"string","pattern":"^org_[1-9][0-9]{0,17}$","description":"The organization id."},"name":{"type":"string","description":"The organization's display name."},"slug":{"type":"string","description":"The organization's URL slug in the Trackberry app."},"api_version":{"type":["string","null"],"description":"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":{"type":"object","description":"The API token that authenticated this request.","additionalProperties":true,"required":["id","name","scopes","expires_at","user_email"],"properties":{"id":{"type":"string","pattern":"^tok_[1-9][0-9]{0,17}$","description":"The token id (not the secret)."},"name":{"type":"string","description":"The name given to the token when it was created."},"scopes":{"type":"array","description":"What the token may do. Only `read` exists.","items":{"type":"string","enum":["read"]}},"expires_at":{"type":["string","null"],"format":"date-time","description":"When the token stops working, or null if it never expires."},"user_email":{"type":"string","description":"The email of the user the token belongs to."}}}}},"Shipment":{"type":"object","description":"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.","additionalProperties":true,"required":["object","id","reference","erp_reference","transport_reference","transport_reference_type","transport_type","cargo_type","temperature_celsius","status","archived","archived_at","validated_at","approved_at","origin","destination","etd","eta","effective_eta","original_eta","predicted_eta","carrier","tracking","parties","produce","organic","cargo","containers","labels","checks","notes","created_at","updated_at"],"properties":{"object":{"const":"shipment","description":"Always `shipment`."},"id":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$","description":"The shipment id."},"reference":{"type":"string","description":"Trackberry's reference for the shipment, unique within the organization. Generated (like SHIP-20260915-K7QX) unless a person set one."},"erp_reference":{"type":["string","null"],"description":"The organization's own reference for the shipment (for example a purchase order number), when one was recorded."},"transport_reference":{"type":["string","null"],"description":"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":{"type":["string","null"],"enum":["container","awb","bill_of_lading",null],"description":"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."},"transport_type":{"type":["string","null"],"enum":["ocean","air","road",null],"description":"How the cargo travels. Only ocean and air shipments are tracked with a carrier feed. Null when not yet known."},"cargo_type":{"type":["string","null"],"enum":["ambient","reefer","frozen",null],"description":"The temperature regime of the cargo. Null when not yet known."},"temperature_celsius":{"type":["number","null"],"description":"The temperature set point in degrees Celsius for refrigerated cargo, when known."},"status":{"type":"string","enum":["draft","validated","in_transit","arrived","error","in_warehouse"],"description":"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."},"archived":{"type":"boolean","description":"True when the shipment was archived. Archived shipments are hidden from `list_shipments` unless `archived` asks for them."},"archived_at":{"type":["string","null"],"format":"date-time","description":"When the shipment was archived, or null when it is not archived."},"validated_at":{"type":["string","null"],"format":"date-time","description":"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":{"type":["string","null"],"format":"date-time","description":"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":{"$ref":"#/components/schemas/Place"},"destination":{"$ref":"#/components/schemas/Place"},"etd":{"type":["string","null"],"format":"date-time","description":"Estimated (later actual) time of departure, from the documents or the carrier."},"eta":{"type":["string","null"],"format":"date-time","description":"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":{"type":["string","null"],"format":"date-time","description":"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":{"type":["string","null"],"format":"date-time","description":"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":{"type":["string","null"],"format":"date-time","description":"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."},"carrier":{"type":"object","description":"The shipping line or airline.","additionalProperties":true,"required":["name","scac"],"properties":{"name":{"type":["string","null"],"description":"The carrier's name in its canonical spelling, from tracking data. Null before tracking has identified one."},"scac":{"type":["string","null"],"description":"The carrier's SCAC code (Standard Carrier Alpha Code), when known."}}},"tracking":{"type":"object","description":"Health of carrier tracking for this shipment.","additionalProperties":true,"required":["state","status","unavailable_reason","halted_reason","last_tracked_at","carrier_updated_at"],"properties":{"state":{"type":"string","enum":["available","unavailable","pending","not_started","awaiting_reference","none"],"description":"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)."},"status":{"type":["string","null"],"description":"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."},"unavailable_reason":{"type":["string","null"],"enum":["unsupported_carrier","invalid_reference","not_found","provider_error","past_voyage",null],"description":"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."},"halted_reason":{"type":["string","null"],"enum":["errored","dropped",null],"description":"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."},"last_tracked_at":{"type":["string","null"],"format":"date-time","description":"When Trackberry last refreshed tracking data for this shipment. Null if never."},"carrier_updated_at":{"type":["string","null"],"format":"date-time","description":"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":{"type":"object","description":"The companies named on the transport document.","additionalProperties":true,"required":["consignor","consignee","notify_party"],"properties":{"consignor":{"type":["string","null"],"description":"The sender of the goods (shipper or supplier)."},"consignee":{"type":["string","null"],"description":"The receiver of the goods named on the transport document."},"notify_party":{"type":["string","null"],"description":"The party the carrier notifies on arrival, when different from the consignee."}}},"produce":{"type":"array","description":"The distinct produce names in the shipment, from its packing lines, or from the draft entry when no packing list has been read yet.","items":{"type":"string"}},"organic":{"type":"boolean","description":"True when at least one visible packing line is marked organic."},"cargo":{"type":"object","description":"Totals over all pallets of the shipment. Zero when no packing list has been read.","additionalProperties":true,"required":["pallets","boxes","net_weight_kg","gross_weight_kg"],"properties":{"pallets":{"type":"integer","description":"Number of pallets recorded for the shipment."},"boxes":{"type":"integer","description":"Total number of boxes over the visible packing lines."},"net_weight_kg":{"type":"number","description":"Total net weight of the produce in kilograms."},"gross_weight_kg":{"type":"number","description":"Total gross weight, produce plus packaging, in kilograms."}}},"containers":{"type":"array","description":"The containers of the shipment, oldest first.","items":{"$ref":"#/components/schemas/Container"}},"labels":{"type":"array","description":"The labels the organization attached to the shipment, sorted by name.","items":{"$ref":"#/components/schemas/Label"}},"checks":{"type":"object","description":"How many quality checks the shipment has in each state. Use `list_checks` for the checks themselves.","additionalProperties":true,"required":["total","passed","failed","warnings","skipped","pending"],"properties":{"total":{"type":"integer","description":"All checks of the shipment."},"passed":{"type":"integer","description":"Checks that passed."},"failed":{"type":"integer","description":"Checks that failed, meaning something is wrong."},"warnings":{"type":"integer","description":"Checks that passed with a warning."},"skipped":{"type":"integer","description":"Checks skipped because their preconditions were not met."},"pending":{"type":"integer","description":"Checks that have not run yet."}}},"notes":{"type":["string","null"],"description":"Free-text notes on the shipment."},"created_at":{"type":"string","format":"date-time","description":"When the shipment was created in Trackberry."},"updated_at":{"type":"string","format":"date-time","description":"When the shipment record last changed."}}},"Place":{"type":"object","description":"An origin or a destination.","additionalProperties":true,"required":["location","country","timezone"],"properties":{"location":{"type":["string","null"],"description":"The city or port, normalized (for example `Rotterdam`), without the country."},"country":{"type":["string","null"],"description":"The country's English name (for example `Netherlands`)."},"timezone":{"type":["string","null"],"description":"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."}}},"Container":{"type":"object","description":"One container of a shipment.","additionalProperties":true,"required":["object","id","number","seal_number","vessel","voyage","port_of_loading","port_of_discharge","etd","eta","cargo_type","temperature_celsius"],"properties":{"object":{"const":"container","description":"Always `container`."},"id":{"type":"string","pattern":"^ctr_[1-9][0-9]{0,17}$","description":"The container id."},"number":{"type":["string","null"],"description":"The ISO 6346 container number (4 letters and 7 digits, like `MSCU1234567`)."},"seal_number":{"type":["string","null"],"description":"The seal number on the container door."},"vessel":{"type":["string","null"],"description":"The vessel name the documents give for this container."},"voyage":{"type":["string","null"],"description":"The voyage number the documents give for this container."},"port_of_loading":{"type":["string","null"],"description":"Where the container is loaded, as written in the documents."},"port_of_discharge":{"type":["string","null"],"description":"Where the container is discharged, as written in the documents."},"etd":{"type":["string","null"],"format":"date-time","description":"Estimated time of departure of this container."},"eta":{"type":["string","null"],"format":"date-time","description":"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":{"type":["string","null"],"enum":["ambient","reefer","frozen",null],"description":"The temperature regime of this container."},"temperature_celsius":{"type":["number","null"],"description":"The container's temperature set point in degrees Celsius."}}},"Label":{"type":"object","description":"A colored tag the organization uses to group shipments.","additionalProperties":true,"required":["object","id","name","color","color_hex"],"properties":{"object":{"const":"label","description":"Always `label`."},"id":{"type":"string","pattern":"^lbl_[1-9][0-9]{0,17}$","description":"The label id. Use it in the `labels` filter of `list_shipments`."},"name":{"type":"string","description":"The label's name, unique within the organization."},"color":{"type":["string","null"],"enum":["gray","red","orange","amber","green","teal","blue","indigo","purple","pink",null],"description":"The name of the palette color."},"color_hex":{"type":"string","description":"The color as a hex code such as `#ef4444`."}}},"Timeline":{"type":"object","description":"The route, tracking events and ETA history of one shipment.","additionalProperties":true,"required":["object","shipment_id","legs","events","eta_revisions"],"properties":{"object":{"const":"timeline","description":"Always `timeline`."},"shipment_id":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$","description":"The shipment this timeline belongs to."},"legs":{"type":"array","description":"The legs of the route in travel order.","items":{"$ref":"#/components/schemas/ShipmentLeg"}},"events":{"type":"array","description":"Tracking events, oldest first. Events without a time are placed by the usual order of milestones.","items":{"$ref":"#/components/schemas/TrackingEvent"}},"eta_revisions":{"type":"array","description":"Every recorded change of the estimated arrival, oldest first.","items":{"$ref":"#/components/schemas/EtaRevision"}}}},"ShipmentLeg":{"type":"object","description":"One leg of a shipment's planned route, for example a sea leg followed by a road leg.","additionalProperties":true,"required":["object","id","position","transport_type","carrier","transport_reference","origin","destination","etd","eta"],"properties":{"object":{"const":"shipment_leg","description":"Always `shipment_leg`."},"id":{"type":"string","pattern":"^leg_[1-9][0-9]{0,17}$","description":"The leg id."},"position":{"type":"integer","description":"The zero-based order of the leg in the route. Not the same as `leg_index` on tracking events."},"transport_type":{"type":["string","null"],"enum":["ocean","air","road",null],"description":"How the cargo travels on this leg."},"carrier":{"type":["string","null"],"description":"The carrier of this leg, as written in the transport document."},"transport_reference":{"type":["string","null"],"description":"The bill of lading, air waybill or consignment number of this leg."},"origin":{"$ref":"#/components/schemas/Place"},"destination":{"$ref":"#/components/schemas/Place"},"etd":{"type":["string","null"],"format":"date-time","description":"Departure time of this leg, from the transport document."},"eta":{"type":["string","null"],"format":"date-time","description":"Arrival time of this leg, from the transport document."}}},"TrackingEvent":{"type":"object","description":"One milestone of the cargo's journey, actual or estimated.","additionalProperties":true,"required":["object","id","milestone","actual","occurred_at","occurred_at_local","container_number","leg_index","location","vessel","flight_number","position"],"properties":{"object":{"const":"tracking_event","description":"Always `tracking_event`."},"id":{"type":"string","pattern":"^evt_[1-9][0-9]{0,17}$","description":"The event id."},"milestone":{"type":"string","enum":["booked","received_from_shipper","empty_pickup","stuffed","gate_in","manifested","loaded","departed","transshipment_arrival","transshipment_discharge","transferred","transshipment_load","transshipment_departure","arrived","discharged","customs_cleared","notified","available_for_pickup","gate_out","delivered","stripped","empty_return","eta_revised","exception","untracked"],"description":"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`, `customs_cleared`, `notified` (air), `available_for_pickup`, `gate_out`, `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."},"actual":{"type":"boolean","description":"True when the event has happened; false when it is an estimate of a future or unconfirmed milestone."},"occurred_at":{"type":["string","null"],"format":"date-time","description":"When the event happened (or is expected to), in UTC. Null when the source gave no time."},"occurred_at_local":{"type":["string","null"],"format":"date-time","description":"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":{"type":["string","null"],"description":"The container the event is about. Null for events about the whole shipment."},"leg_index":{"type":["integer","null"],"description":"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":{"type":"object","description":"Where the event happened.","additionalProperties":true,"required":["name","code","country_code"],"properties":{"name":{"type":["string","null"],"description":"The place name, such as a port or an airport."},"code":{"type":["string","null"],"description":"The location code as reported, a UN/LOCODE for ports (for example `NLRTM`) where available."},"country_code":{"type":["string","null"],"description":"The ISO 3166-1 alpha-2 country code."}}},"vessel":{"type":"object","description":"The vessel involved, for ocean events.","additionalProperties":true,"required":["name","imo","voyage"],"properties":{"name":{"type":["string","null"],"description":"The vessel name."},"imo":{"type":["string","null"],"description":"The vessel's IMO number."},"voyage":{"type":["string","null"],"description":"The voyage number."}}},"flight_number":{"type":["string","null"],"description":"The flight, for air events."},"position":{"type":"object","description":"Coordinates of the event, when the source gave them.","additionalProperties":true,"required":["latitude","longitude"],"properties":{"latitude":{"type":["number","null"],"description":"Latitude in decimal degrees."},"longitude":{"type":["number","null"],"description":"Longitude in decimal degrees."}}}}},"EtaRevision":{"type":"object","description":"One observed change of a shipment's estimated arrival. Revisions are recorded only when the ETA moves by 5 minutes or more.","additionalProperties":true,"required":["object","id","observed_at","previous_eta","new_eta","slip_seconds","first_estimate","backfilled"],"properties":{"object":{"const":"eta_revision","description":"Always `eta_revision`."},"id":{"type":"string","pattern":"^eta_[1-9][0-9]{0,17}$","description":"The revision id."},"observed_at":{"type":"string","format":"date-time","description":"When Trackberry saw the new estimate. For `backfilled` revisions this is only the time of the last refresh, not when the carrier changed its mind."},"previous_eta":{"type":["string","null"],"format":"date-time","description":"The estimate before this revision. Null for the first estimate ever learned."},"new_eta":{"type":"string","format":"date-time","description":"The estimate after this revision."},"slip_seconds":{"type":["number","null"],"description":"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":{"type":"boolean","description":"True for the opening quote, when there was no previous estimate."},"backfilled":{"type":"boolean","description":"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."}}},"FreeTimeSummary":{"type":"object","description":"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.","additionalProperties":true,"required":["object","shipment_id","shipment_reference","transport_reference","at_risk","terms_unknown","demurrage","detention","active_clock"],"properties":{"object":{"const":"free_time_summary","description":"Always `free_time_summary`."},"shipment_id":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$","description":"The shipment id."},"shipment_reference":{"type":"string","description":"The shipment's Trackberry reference."},"transport_reference":{"type":["string","null"],"description":"The shipment's bill of lading, air waybill or container number."},"at_risk":{"type":"boolean","description":"True when the demurrage clock is running with known free days and 2 days or fewer are left (or it is already overdue). Shipments with unknown terms are never at risk."},"terms_unknown":{"type":"boolean","description":"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":{"type":"array","description":"One demurrage clock per container. Empty for shipments that are not ocean or have no tracking events for it.","items":{"$ref":"#/components/schemas/FreeTimeClock"}},"detention":{"type":"array","description":"One detention clock per container, in the same order as `demurrage`. Empty for shipments that are not ocean.","items":{"$ref":"#/components/schemas/FreeTimeClock"}},"active_clock":{"description":"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.","oneOf":[{"$ref":"#/components/schemas/FreeTimeClock"},{"type":"null"}]}}},"FreeTimeClock":{"type":"object","description":"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`.","additionalProperties":true,"required":["object","kind","container_number","state","free_days","free_days_source","free_days_basis","started_on","ended_on","last_free_day","days_left","elapsed_days","used_days","overdue_days","carrier"],"properties":{"object":{"const":"free_time_clock","description":"Always `free_time_clock`."},"kind":{"type":"string","enum":["demurrage","detention"],"description":"Which charge this clock measures."},"container_number":{"type":["string","null"],"description":"The container the clock is for. Null when tracking events carry no container number."},"state":{"type":"string","enum":["not_started","running","running_unknown_terms","stopped","end_not_reported","return_not_reported"],"description":"`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."},"free_days":{"type":["integer","null"],"description":"The number of free days that apply. Null when unknown."},"free_days_source":{"type":["string","null"],"enum":["shipment","notice","carrier",null],"description":"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."},"free_days_basis":{"type":["string","null"],"enum":["calendar","working",null],"description":"How days are counted. `calendar` counts every day; `working` skips weekends and the country's public holidays. Null when there are no known terms."},"started_on":{"type":["string","null"],"format":"date","description":"The port-local day the clock started (the discharge day for demurrage, the gate-out day for detention). Null while `not_started`."},"ended_on":{"type":["string","null"],"format":"date","description":"The port-local day the clock ended. Null unless `stopped`."},"last_free_day":{"type":["string","null"],"format":"date","description":"The last day that is still free. Null unless `running`."},"days_left":{"type":["integer","null"],"description":"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":{"type":["integer","null"],"description":"Calendar days since the start, counting the start day. Only set while `running_unknown_terms`."},"used_days":{"type":["integer","null"],"description":"How many days were used between start and end, counting both. Only set when `stopped`."},"overdue_days":{"type":["integer","null"],"description":"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":{"type":["string","null"],"description":"The carrier the terms belong to, as a label."}}},"MonitoringAlert":{"type":"object","description":"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.","additionalProperties":true,"required":["object","id","shipment_id","shipment_reference","key","group","severity","title","summary","since","first_detected_at","last_detected_at","resolved_at"],"properties":{"object":{"const":"monitoring_alert","description":"Always `monitoring_alert`."},"id":{"type":"string","pattern":"^alr_[1-9][0-9]{0,17}$","description":"The alert id."},"shipment_id":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$","description":"The shipment the alert is about."},"shipment_reference":{"type":"string","description":"That shipment's Trackberry reference."},"key":{"type":"string","enum":["tracking_halted","tracking_blind","tracking_stale","tracking_silent","tracking_not_found","overdue_eta","missing_eta","eta_drift","rollover","port_dwell","stalled_draft","unresolved_checks"],"description":"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. New keys may be added."},"group":{"type":["string","null"],"enum":["tracking","schedule","workflow",null],"description":"The theme of the alert. Null if the monitor that raised it no longer exists."},"severity":{"type":"string","enum":["warning","critical"],"description":"How urgent it is. Severity can rise from `warning` to `critical` as the problem ages."},"title":{"type":"string","description":"A short English title for the kind of problem."},"summary":{"type":["string","null"],"description":"An English sentence saying what is wrong on this shipment."},"since":{"type":["string","null"],"format":"date-time","description":"When the problem began, as the monitor measures it (for example the moment the ETA passed). Null when unknown."},"first_detected_at":{"type":["string","null"],"format":"date-time","description":"When a monitoring sweep first saw the problem."},"last_detected_at":{"type":["string","null"],"format":"date-time","description":"When the latest sweep still saw it."},"resolved_at":{"type":["string","null"],"format":"date-time","description":"When the problem went away. Always null here, because only open alerts are returned."}}},"ShipmentCheck":{"type":"object","description":"The result of one quality check run against one shipment, for example whether a packing list is present or whether its box count matches the declared total.","additionalProperties":true,"required":["object","id","shipment_id","shipment_reference","key","category","status","title","message","ran_at"],"properties":{"object":{"const":"shipment_check","description":"Always `shipment_check`."},"id":{"type":"string","pattern":"^chk_[1-9][0-9]{0,17}$","description":"The check result id."},"shipment_id":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$","description":"The shipment the check ran against."},"shipment_reference":{"type":"string","description":"That shipment's Trackberry reference."},"key":{"type":"string","description":"The stable identifier of the check, for example `has_packing_list`, `packing_list_box_count` or `invoice_total`. New keys may be added."},"category":{"type":["string","null"],"enum":["documents","data_integrity","data_completeness",null],"description":"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."},"status":{"type":"string","enum":["pending","passed","failed","skipped","warning"],"description":"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."},"title":{"type":"string","description":"A short English name for this result."},"message":{"type":["string","null"],"description":"An English sentence explaining the outcome. Null when the check has not produced one."},"ran_at":{"type":["string","null"],"format":"date-time","description":"When the check last ran. Null if it never ran."}}},"Document":{"type":"object","description":"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 served by the API.","additionalProperties":true,"required":["object","id","shipment_id","type","filename","content_type","byte_size","source","parse_status","downloadable","page_range","data_available","created_at","updated_at"],"properties":{"object":{"const":"document","description":"Always `document`."},"id":{"type":"string","pattern":"^doc_[1-9][0-9]{0,17}$","description":"The document id."},"shipment_id":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$","description":"The shipment the document belongs to."},"type":{"type":"string","enum":["unknown","packing_list","transport_document","invoice","phytosanitary_cert","merged_document","certificate_of_origin","warehouse_receipt","inspection_report","courier_document","other_certificate","arrival_notice"],"description":"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."},"filename":{"type":["string","null"],"description":"The file's name. Null when no file is attached."},"content_type":{"type":["string","null"],"description":"The file's MIME type. Null when no file is attached."},"byte_size":{"type":["integer","null"],"description":"The file size in bytes. Null when no file is attached."},"source":{"type":"string","enum":["manual_upload","email_upload","api","correction_link"],"description":"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."},"parse_status":{"type":"string","enum":["pending","processing","parsed","failed"],"description":"Whether Trackberry has read the document. `pending` and `processing` are in progress; `parsed` means data was extracted; `failed` means reading failed."},"downloadable":{"type":"boolean","description":"True when a file is attached and passed the security scan. The API itself never serves the file; this tells you whether it can be downloaded in the app."},"page_range":{"type":["string","null"],"description":"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":{"type":"boolean","description":"True when `get_document_data` will return extracted fields for this document."},"created_at":{"type":"string","format":"date-time","description":"When the document was added to Trackberry."},"updated_at":{"type":"string","format":"date-time","description":"When the document record last changed."}}},"DocumentData":{"type":"object","description":"The structured data Trackberry extracted from one document. The set of fields depends on `schema`.","additionalProperties":true,"required":["object","document_id","type","schema","fields"],"properties":{"object":{"const":"document_data","description":"Always `document_data`."},"document_id":{"type":"string","pattern":"^doc_[1-9][0-9]{0,17}$","description":"The document the data was read from."},"type":{"type":"string","description":"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":{"type":["string","null"],"enum":["packing_list","transport_document","invoice","certificate","inspection_report","arrival_notice",null],"description":"The shape of `fields`. Null when nothing was extracted or the document type has no structured schema, in which case `fields` is empty."},"fields":{"type":"object","additionalProperties":true,"description":"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, number_of_boxes, net_weight_kg, box_weight_kg, gross_weight_kg). `transport_document`: transport_type, shipment_reference, equipment_numbers, package_count, package_unit, consignor, consignee, notify_party, carrier, departure_location and arrival_location (each with location_name and country), etd, eta, temperature_setpoint_celsius, cargo_type. `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). Fields may be added over time."}}},"PackingList":{"type":"object","description":"A packing list read from a document, saying what the exporter states is in the container, by pallet and produce line.","additionalProperties":true,"required":["object","id","shipment_id","document_id","container_id","reference","declared_box_count","declared_net_weight_kg","totals","pallets"],"properties":{"object":{"const":"packing_list","description":"Always `packing_list`."},"id":{"type":"string","pattern":"^pkl_[1-9][0-9]{0,17}$","description":"The packing list id."},"shipment_id":{"type":"string","pattern":"^shp_[1-9][0-9]{0,17}$","description":"The shipment it belongs to."},"document_id":{"type":["string","null"],"pattern":"^doc_[1-9][0-9]{0,17}$","description":"The document it was read from. Null when it was created without one."},"container_id":{"type":["string","null"],"pattern":"^ctr_[1-9][0-9]{0,17}$","description":"The container it covers. Null when the document did not say."},"reference":{"type":["string","null"],"description":"The packing list's own number."},"declared_box_count":{"type":["integer","null"],"description":"The total number of boxes the document states, before Trackberry sums the lines. Compare with `totals.boxes`."},"declared_net_weight_kg":{"type":["number","null"],"description":"The total net weight in kilograms the document states. Compare with `totals.net_weight_kg`."},"totals":{"type":"object","description":"Totals Trackberry computed from this packing list's own visible lines.","additionalProperties":true,"required":["pallets","boxes","net_weight_kg"],"properties":{"pallets":{"type":"integer","description":"Number of pallets on this packing list."},"boxes":{"type":"integer","description":"Sum of the box counts of its lines."},"net_weight_kg":{"type":"number","description":"Sum of the net weights of its lines, in kilograms."}}},"pallets":{"type":"array","description":"The pallets of this packing list, oldest first.","items":{"$ref":"#/components/schemas/Pallet"}}}},"Pallet":{"type":"object","description":"One pallet of a packing list.","additionalProperties":true,"required":["object","id","pallet_number","container_id","lines"],"properties":{"object":{"const":"pallet","description":"Always `pallet`."},"id":{"type":"string","pattern":"^plt_[1-9][0-9]{0,17}$","description":"The pallet id."},"pallet_number":{"type":["string","null"],"description":"The pallet's number or SSCC as printed on the packing list. Unique within a shipment when set."},"container_id":{"type":["string","null"],"pattern":"^ctr_[1-9][0-9]{0,17}$","description":"The container the pallet is loaded in. Null when unknown."},"lines":{"type":"array","description":"The pallet's produce lines in reading order. Lines merged into another line are left out.","items":{"$ref":"#/components/schemas/PackingLine"}}}},"PackingLine":{"type":"object","description":"One produce line on a pallet, a quantity of one variety, calibre and pack format.","additionalProperties":true,"required":["object","id","line_index","produce_name","produce_type","variety","calibre","quality_category","pack_format","label","ggn","box_count","box_weight_kg","net_weight_kg","gross_weight_kg"],"properties":{"object":{"const":"packing_line","description":"Always `packing_line`."},"id":{"type":"string","pattern":"^pln_[1-9][0-9]{0,17}$","description":"The line id."},"line_index":{"type":["integer","null"],"description":"The line's position in the packing list, used to order lines."},"produce_name":{"type":["string","null"],"description":"The produce, normalized (for example `Grapes`)."},"produce_type":{"type":["string","null"],"description":"How the produce was grown, as written on the packing list. Lines marked organic (any letter case) make the shipment `organic`."},"variety":{"type":["string","null"],"description":"The variety or cultivar."},"calibre":{"type":["string","null"],"description":"The size grade of the produce."},"quality_category":{"type":["string","null"],"description":"The quality class, such as `Class I`."},"pack_format":{"type":["string","null"],"description":"How the produce is packed, for example a carton size."},"label":{"type":["string","null"],"description":"The brand or label printed on the packaging."},"ggn":{"type":["string","null"],"description":"The GLOBALG.A.P. Number (GGN) of the producer, when stated."},"box_count":{"type":["integer","null"],"description":"Number of boxes on this line."},"box_weight_kg":{"type":["number","null"],"description":"Net weight of one box in kilograms."},"net_weight_kg":{"type":["number","null"],"description":"Net weight of the whole line in kilograms."},"gross_weight_kg":{"type":["number","null"],"description":"Gross weight of the whole line in kilograms, packaging included."}}}}}}