# Mati Logistics — Track and Trace API > GENERATED BY API EVANGELIST, NOT PUBLISHED BY THE PROVIDER. > Mati Logistics serves no llms.txt (https://www.matilogistics.com/llms.txt -> 404, > /.well-known/llms.txt -> 404 on every host, probed 2026-08-27). This file was > written from the provider's own public API Reference and pricing pages plus the > artifacts in this repository, so an agent has something machine-readable to read. > Generated 2026-08-27. Mati Logistics runs a network for global trade with two products: an AI sourcing agent over customs-derived supplier data, and Track and Trace. Only Track and Trace has an API. The Track and Trace API is a REST/JSON API for ocean container, bill-of-lading and booking visibility across 24 ocean carriers and NVOCCs. Submit a reference, get normalized milestone events back by polling or by signed webhook. - Base URL: https://api.matilogistics.com (all endpoints under /v2) - API Reference: https://www.matilogistics.com/api - Auth: `Authorization: Bearer tnt_...` — one key per organization, issued once - Pricing: https://www.matilogistics.com/track-trace#pricing ## What does NOT exist An agent should not go looking for these. All were probed on 2026-08-27 and all are absent: - No OpenAPI / Swagger. The service is FastAPI/uvicorn but /openapi.json, /docs and /redoc are switched off; GET https://api.matilogistics.com/ answers `{"service":"tnt_api","docs":null}`. - No GraphQL, no gRPC/protobuf, no SOAP/WSDL. - No AsyncAPI, though a real signed webhook surface exists. - No MCP server. No A2A agent card. No /.well-known/ document of any kind. - No SDKs or client libraries in any registry. No public GitHub organization. - No status page, no changelog, no deprecation policy, no terms of service and no privacy policy. - The apis.json advertised at https://www.matilogistics.com/apis.json returns 404. ## Endpoints Tracking requests - POST /v2/tracking_requests — submit a reference for tracking - GET /v2/tracking_requests — list; cursor-paginated - GET /v2/tracking_requests/{id} — one request, with its resolved shipment - POST /v2/tracking_requests/batch — retrieve many by id: {"ids": [...]} - DELETE /v2/tracking_requests/{id} — stop tracking (other subscribers unaffected) Shipments and containers - GET /v2/shipments — list shipments - GET /v2/shipments/{id} — one shipment with full event history - GET /v2/shipments/{id}/containers — containers on a shipment - GET /v2/containers/{id} — one container - GET /v2/containers/{id}/events — milestone events for one container Reference data - GET /v2/carriers — carrier coverage and SCACs - GET /v2/carriers/detect — classify a reference and resolve its carrier before submission Webhooks - POST /v2/webhooks — register an endpoint; the signing secret is returned once - POST /v2/webhooks/{id}/rotate_secret — rotate the signing secret ## Core behaviour an agent must know - Asynchronous resolution. A new reference returns 201 with status "pending" and no tracked_object. An already-tracked reference returns "succeeded" immediately with the payload inline. Evaluate `status` synchronously; then use the tracking_request.succeeded webhook rather than polling. - Upsert, not duplicate. Resubmitting the same reference with a carrier updates the existing request and keeps its id. There is NO Idempotency-Key header — this convergence applies to tracking references only, not to webhook writes. - Cursor pagination. Pass the previous `meta.next_cursor` as `?cursor=`; stop when `meta.has_more` is false. - Rate limits, per organization, fixed hourly window: 1,000 writes/hour, 10,000 reads/hour, 429 on exhaustion. NO RateLimit-* or Retry-After headers are emitted — an agent cannot read its remaining budget off the wire. Every response does carry `x-request-id`. - Errors: `{"error":{"code","message","request_id","fields"?}}`. Not RFC 9457. 400 malformed / 401 unauthenticated / 403 wrong subscriber / 404 missing or out-of-org / 422 validation or unsupported carrier / 429 rate limited. - Reversibility: a tracking request can be stopped with DELETE, with no stated time window and no documented restore. A registered webhook has no documented delete or deactivate operation — only secret rotation. ## Data semantics that will cause bugs if ignored - Local times are NOT UTC. Carrier wall-clock times are returned verbatim with a trailing Z as a storage convention, flagged by `eventTimeIsLocal`, `times_are_local` and labelled by `eventTimeZone` where the carrier states one. Converting them shifts the value by hours and can shift `last_free_day` by a calendar day, which carries direct demurrage exposure. - Track per container, not per bill of lading. A bill may cover several containers that discharge and return on different dates. Every event carries `containerNo`; any de-duplication key omitting it will collapse distinct milestones. `containerNo: null` means the event is bill-level. - `milestoneCode` is a normalized vocabulary; `milestoneDescription` keeps the carrier's own words. The vocabulary is Mati's own — it is NOT DCSA. - `route[].role` is deliberately free text ("POL", "pol", "receipt", "Place of Receipt"). Treat it as opaque; do not enumerate it. - null means the carrier published nothing. A null `last_free_day` is not unlimited free time. A null `arrival_is_actual` is not an estimate. Route data is never synthesized. - `summary.transshipments[].dwell_hours` is computed from actuals only and is null if either side is an estimate. `atd_is_load: true` means the departure was inferred from the onward load; `evidence[]` carries the verbatim carrier wording. ## Webhook events tracking_request.succeeded, tracking_request.failed, tracking_request.not_found, shipment.updated, container.transport_event. Signed with HMAC-SHA256 over the RAW request body, hex-encoded, in `X-TNT-Signature`; the event name is in `X-TNT-Event`. Compute the signature before parsing or re-serializing the body. Up to 3 retries; a slow handler counts as a failure, so return 2xx promptly and process asynchronously. Handlers must be idempotent. No delivery payload schema is published. ## Standards - ISO 6346 container identification, including check-digit validation — a bad check digit is rejected with 422 before any carrier is queried. - SCAC (NMFTA) carrier codes throughout; `GET /v2/carriers` is the live list. - NOT DCSA. Mati normalizes carrier events into its own milestone vocabulary and publishes no DCSA mapping, so a DCSA-native system needs a bilateral crosswalk. ## Access API access is not on the free tier. It is included with subscriptions of 250+ shipments/month, or $1,800/year as an add-on on lower-volume subscriptions. A 7-day free trial is available. Keys are issued from the API keys page in the app and shown exactly once. ## Artifacts in this repository - authentication/matilogistics-authentication.yml - conventions/matilogistics-conventions.yml - conformance/matilogistics-conformance.yml - data-model/matilogistics-data-model.yml - errors/matilogistics-problem-types.yml - asyncapi/matilogistics-webhooks.yml - lifecycle/matilogistics-lifecycle.yml - rate-limits/matilogistics-rate-limits.yml - plans/matilogistics-plans-pricing.yml - packages/matilogistics-packages.yml - mcp/matilogistics-mcp.yml - security/matilogistics-domain-security.yml - well-known/matilogistics-well-known.yml