Cargoplot API changelog
Changes to the public v1 API, newest first. Written for someone integrating against it: what moved, and what they have to do about it.
The spec at /openapi.json is served from the running API, so a change reaches
consumers the moment it deploys. The spec says what the contract is now; this
file is the only place that says what changed.
A regeneration that a consumer cannot observe still gets a line saying so, so the next reader can tell "nothing to see here" from "nobody wrote it down".
Changes land under an ## Unreleased heading while they are only on dev. That
heading is renamed to the release date in the very commit that gets built and
deployed: this file ships inside the image, so a heading corrected after the
deploy corrects nothing anyone is reading. The api's AGENTS.md carries the three
steps, under "Rolling the changelog over at release".
It lives beside the spec it describes rather than with the protos that generate
it, because go:embed cannot reach outside its own package directory and this
file is served, not just read.
2026-09-14
Every status and milestone the API returns now says what it means, and the spec points at a glossary for the codes it does not define itself.
- Statuses and milestones carry their meaning. Each value of a shipment,
inquiry and invoice status, and of the sea and air tracking vocabularies, is
now described in the spec beside the value itself.
STATUS_IN_COLLECTION,CONTAINER_TRACKING_STATUS_EMPTY_TO_SHIPPERand the rest read as sentences in the reference and in any client generated from/openapi.json. No value was added, removed or renamed, and no response changed. - The spec links a glossary. Its
externalDocspoints at https://developers.cargoplot.com/glossary, which explains the code systems the API returns as plain strings -- UN/LOCODE, IATA, ISO 6346 container numbers, Incoterms -- and the vocabularies that reach the spec from the shared domain model with no description of their own: cargo and container types, transport modes, document types, VAT categories.
2026-09-07
Shipment tracking reached production, for sea and air freight.
- Shipment tracking.
GET /v1/shipment/{shipment}/trackingreturns a shipment's movement timeline, addressed by Cargoplot reference or numeric id, unpaginated. The timeline sits under a key naming the transport mode and a response carries exactly one of them:seaholds one entry per container, each with its own events;airholds one overall status and one list of events, because air cargo has no container to hang milestones on.etdandetasit beside the mode key. Events run oldest to newest and say whether they are expected or actual; an empty list is a valid answer, not an error. Air events name their airport by IATA code and carry the flight they happened on, andcargosays how much of the consignment each leg carried — omitted where more than one shipment shares the waybill, since the figures would then cover more than yours. Road, rail and express return400.
2026-08-24
Invoices and shipment documents reached production, so the API answers what a shipment cost and what paperwork it still needs, not only where it is.
GET /v1/invoicelists your organization's invoices, andGET /v1/shipment/{shipment}/invoicenarrows that to one shipment. Both page, sort and filter exactly like the shipment and inquiry lists, so the cursor you already handle works unchanged.GET /v1/invoice/{invoice}reads one, addressed by reference (F2401-C2AE-XEE1) or numeric id, and renders it identically to one element of the list.GET /v1/invoice/{invoice}/downloadreturns the invoice PDF.- The API serves invoices that have been issued to your organization.
- Amounts arrive as an object carrying the currency alongside the number, so no field has to be read in combination with another to be meaningful.
GET /v1/shipment/{shipment}/documentreturns a shipment's document checklist: every slot, with the uploaded file where there is one. A slot with nodocumentmember is still outstanding — that is how the two are told apart. The list is not paginated; a checklist is small and bounded.GET /v1/document/{document}/downloadreturns an uploaded file, with the content type it was stored as. The id is thedocument.idfrom the checklist, not the slot id.- The checklist covers the document types this API serves.
- Fixed:
GET /v1/inquirysorted byreferenceorcargo_ready_datedropped inquiries whose value for that field is empty, from the second page onwards — silently, with no error and no short page. If you paged that endpoint sorted either way, the set you collected is incomplete and worth re-fetching. Sorting bystatusorcreate_timewas never affected, and no other endpoint was. - The money schema is now named
apiV1Moneyin the spec, where it wasv1Money. No response changed shape, and nothing needs doing if you read the JSON directly — but a generated client will see the type renamed, and the shipment and inquiryinsured_goods_valuefields point at the new name too. - Fixed: the documented media types for
MEDIA_TYPE_DOCXandMEDIA_TYPE_XLSXwere each other's — DOCX was documented as Excel'sapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetand XLSX as Word's…wordprocessingml.document. The enum values themselves never changed and no response moved, so nothing breaks; but if you mapped either to a content type from these docs, you have the two the wrong way round. - The media type schema is named
DocumentMediaTypeon the reference page, where it previously showed its list of values in place of a name.
2026-08-21
First public release. The documentation site at https://developers.cargoplot.com is live, and the profile tab that mints the Personal Access Tokens the API needs is available in production.
- Read-only — every documented operation is a GET, which a test over the generated spec enforces rather than trusting.
- Authenticate with a Personal Access Token in the
X-Cargoplot-Keyheader. - Shipments, inquiries, organizations and users, with one cursor-pagination contract shared by every list endpoint.
- Request limits and the conventions the spec cannot express are published at
/api-info.json, along with the base URL to call. - The API has a base URL of its own --
https://api.cargoplot.comin production, and whatever/api-info.jsonreports asbase_urlin any other environment. /openapi.jsonnow states the host and scheme it is served from, so a generated client or an agent handed only that file has somewhere to send requests. It previously carriedbasePath: /apiand no host, which left the host to be guessed.- Every rate-limited response carries
RateLimit-Limit,RateLimit-RemainingandRateLimit-Reset, so you can pace yourself instead of discovering the ceiling by hitting it.RateLimit-Resetcounts seconds from now, not a timestamp. A 429 still carriesRetry-Afteras well, which answers the narrower question of when to retry this request. - Every description in
/openapi.jsondocuments the contract: what an endpoint returns and what you have to handle. Notes aimed at Cargoplot's own engineers are kept out of it, so the reference stays about integrating rather than about how the service is built.