Cargoplot API
API docs
OpenAPI spec

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_SHIPPER and 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 externalDocs points 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}/tracking returns 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: sea holds one entry per container, each with its own events; air holds one overall status and one list of events, because air cargo has no container to hang milestones on. etd and eta sit 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, and cargo says 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 return 400.

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/invoice lists your organization's invoices, and GET /v1/shipment/{shipment}/invoice narrows 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}/download returns 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}/document returns a shipment's document checklist: every slot, with the uploaded file where there is one. A slot with no document member 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}/download returns an uploaded file, with the content type it was stored as. The id is the document.id from the checklist, not the slot id.
  • The checklist covers the document types this API serves.
  • Fixed: GET /v1/inquiry sorted by reference or cargo_ready_date dropped 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 by status or create_time was never affected, and no other endpoint was.
  • The money schema is now named apiV1Money in the spec, where it was v1Money. 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 inquiry insured_goods_value fields point at the new name too.
  • Fixed: the documented media types for MEDIA_TYPE_DOCX and MEDIA_TYPE_XLSX were each other's — DOCX was documented as Excel's application/vnd.openxmlformats-officedocument.spreadsheetml.sheet and 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 DocumentMediaType on 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-Key header.
  • 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.com in production, and whatever /api-info.json reports as base_url in any other environment.
  • /openapi.json now 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 carried basePath: /api and no host, which left the host to be guessed.
  • Every rate-limited response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset, so you can pace yourself instead of discovering the ceiling by hitting it. RateLimit-Reset counts seconds from now, not a timestamp. A 429 still carries Retry-After as well, which answers the narrower question of when to retry this request.
  • Every description in /openapi.json documents 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.