API Reference · v1
The CargoMode API
Pull your bookings, containers and RFQ quotes out of CargoMode and into your own TMS, CRM or warehouse. REST over HTTPS, JSON in and out, built for incremental sync.
curl https://www.cargomo.de/api/v1/bookings \ -H "Authorization: Bearer cm_live_YOUR_API_KEY"
Endpoints
Bookings
Shipments with their containers, shipment groups and document metadata — the same shape the CargoMode UI renders.
RFQs
Rate requests with the structured AI extraction, per-component cost sources, and the quote that was sent back.
Public tools
Container tracking and AI HS-code classification. No API key — rate limited per IP, free to try.
Authentication
Every /api/v1 request is authenticated with a bearer token. Keys look like cm_live_ followed by 40 hex characters, and are scoped to a single organization — a key only ever returns your own data.
curl https://www.cargomo.de/api/v1/bookings \ -H "Authorization: Bearer cm_live_YOUR_API_KEY"
Getting a key
Keys are issued by the CargoMode team. Email us with your organization name and what you're building, and we'll provision one and send it over securely.
api@cargomo.de →Keep keys server-side. A key carries full read access to your organization's bookings and quotes, so it belongs in an environment variable on your backend — never in browser JavaScript or a mobile app. Only a SHA-256 hash of each key is stored, so a lost key can't be recovered; ask us to revoke it and we'll issue a replacement.
Pagination & sync
List endpoints return rows ordered by updatedAt ascending — oldest change first. Pass the meta.nextSince value from one response back as the since parameter of the next request to walk forward through changes. When nextSince comes back null, you are caught up.
First run: call without
sinceto get the oldest page.Store
meta.nextSinceand pass it assinceon the next call.nextSince: nullmeans no more rows. Persist the last cursor and resume from it on your next scheduled run.
// Walk every page, then persist the cursor for the next run. let since = await loadCursor() // null on first run let url = new URL('https://www.cargomo.de/api/v1/bookings') url.searchParams.set('limit', '100') while (true) { if (since) url.searchParams.set('since', since) const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.CARGOMODE_API_KEY}` } }) const { data, meta } = await res.json() for (const booking of data) await upsertIntoYourTms(booking) if (!meta.nextSince) break // caught up since = meta.nextSince } await saveCursor(since)
Because the cursor tracks updatedAt, a record that changes after you've synced it reappears in a later page. Upsert on the record id rather than inserting blindly.
Errors
Errors use standard HTTP status codes and return a JSON body with a human-readable message.
400A parameter is malformed — e.g. `since` is not a valid ISO 8601 timestamp.401No `Authorization` header, a key that is not `cm_live_…`, or a revoked key.404The record does not exist, or belongs to another organization.500Unexpected server error. Safe to retry with backoff.
{
"statusCode": 401,
"message": "Missing API key. Send it as: Authorization: Bearer cm_live_..."
}What v1 covers
v1 is a read API. It exists so the data CargoMode assembles — bookings enriched from documents and carrier APIs, RFQs with their extracted fields and quotes — can flow into whatever system you already run your business on.
Writing bookings or RFQs back in over HTTP isn't part of v1 yet. Today that happens through the product itself: documents emailed to your ingestion address, and rate requests emailed to your RFQ address, both of which create records the API then returns. Tell us what you need to write — it shapes what ships next.
