Skip to content

Documentation/Integrations and API·4 min read·Updated Nov 7, 2026

API overview

The Shipment Insight API will let your systems create shipments, read tracking and predictions, and manage webhooks over REST and JSON. This page is a preview of how it will work; details may change before launch.

Preview

The public API is not available yet. Everything here describes the planned design so you can prepare your integration. Endpoints and fields may still change before launch.

Basics

StyleREST, with JSON request and response bodies.
Base URLhttps://api.example.com/v1 (a placeholder: the real address will be announced at launch).
FormatUTF-8 JSON. Times are ISO 8601 in UTC, for example 2026-11-07T18:40:00Z.
IDsOpaque strings. Store them as text and don't parse them.
SpecificationAn OpenAPI 3.1 file will be published with the API.

Authentication with API keys

Every request needs an API key in the Authorization header. Admins will create keys in Settings. Each key has scopes that limit what it can do, for example reading shipments but not changing them.

PrefixUse
si_live_Your real data.
si_test_A sandbox with test data. Test keys never touch live data.
curl https://api.example.com/v1/shipments/shp_0123456789 \
  -H "Authorization: Bearer $SI_API_KEY"
Read one shipment.

Keep keys secret

A key is shown only once, when it's created. Store it in a secrets manager, never in code or in a browser app. If a key leaks, revoke it in Settings and create a new one.

  • Give each integration its own key with only the scopes it needs.
  • Rotate keys with an overlap period, so your integration has no downtime.
  • Each key shows when it was last used, which helps you find and remove unused keys.

Safe retries with idempotency keys

Networks fail. To retry a POST without creating a duplicate, send an Idempotency-Key header with a unique value (a UUID works well). If the same key arrives again, you get the original response back instead of a second shipment.

curl https://api.example.com/v1/shipments \
  -X POST \
  -H "Authorization: Bearer $SI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2a9e-3b7d-4e1a-9c55-0d2f8e4b7a10" \
  -d '{
    "reference": "LD-880142",
    "mode": "FTL",
    "stops": [
      { "type": "pickup", "facility_id": "fac_montreal_01", "appointment": "2026-11-08T13:00:00Z" },
      { "type": "delivery", "facility_id": "fac_chicago_02", "appointment": "2026-11-09T19:00:00Z" }
    ]
  }'
Create a shipment. Retrying with the same Idempotency-Key is safe.

Pagination

Lists are returned in pages. Use limit to choose the page size. Each response includes a next_cursor; pass it as cursor to get the next page. When next_cursor is null, you've reached the end.

curl "https://api.example.com/v1/shipments?status=in_transit&limit=50&cursor=eyJpZCI6..." \
  -H "Authorization: Bearer $SI_API_KEY"
{
  "data": [
    { "id": "shp_0123456789", "reference": "LD-880142", "status": "in_transit" }
  ],
  "next_cursor": "eyJpZCI6InNocF8wMTIzNDU2Nzg5In0"
}

Rate limits

Each key can make a limited number of requests per minute. If you go over, you get 429 Too Many Requests with a Retry-After header that says how many seconds to wait. Wait at least that long, then retry, ideally with exponential backoff.

HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json

Tip

Instead of polling for changes, subscribe to webhooks. You get updates as they happen and stay well within your limits.

Errors

Errors use standard HTTP status codes and always return the same JSON shape, with a stable code you can handle in your program and a message for people. Include the request_id when you contact support.

{
  "error": {
    "code": "validation_failed",
    "message": "stops[1].appointment must be after stops[0].appointment",
    "request_id": "req_01HZX4N8Q2"
  }
}
StatusMeaning
400The request is invalid. Fix it before retrying.
401The API key is missing, wrong, expired or revoked.
403You can see this resource, but your key's scopes don't allow this action.
404Not found, or not available to you. See below.
409Conflict, for example the same Idempotency-Key reused with a different body.
429Too many requests. Wait for Retry-After.
5xxA problem on our side. Retry with backoff.

Why you get 404 instead of 403

If you ask for something that belongs to another organization, or that your key isn't allowed to see, the API answers 404, exactly as if it didn't exist. This way the API never confirms that someone else's shipment exists. You get 403 only when you can already see the resource but can't perform one specific action on it. The same rule applies in the console: see Roles and access.

Versioning

  • The version is in the path: /v1.
  • Within a version we only add things: new endpoints, new optional fields, new event types. Your code should ignore fields it doesn't know.
  • Breaking changes go into a new version. The old one keeps working for a deprecation period announced in the Changelog.