Demurrage risk
Free-time clocks across every box we can assess. Read unassessable_containers before you read the list: free days are a term of your carrier contract, so a short list is often missing terms rather than free of risk.
Response schema
26 fields
Derived from the example response, nested as the JSON is.
The response contract this build answers, as a date. Pin it in your client and nothing in the shape below moves under you.
Whether the request succeeded.
data
The payload. Everything an endpoint returns sits under this key.
Projected demurrage across the assessable boxes, in USD.
How many boxes the projection covers.
The list of results.
items[]
The container number this row is about.
Port UN/LOCODE.
Days before free time runs out. Negative once charges are accruing, null when we hold no last free day.
Daily demurrage rate in USD.
Demurrage accrued so far on this box, in USD.
Current normalised status of the shipment. Ocean lifecycle order: discharged, available, delivered, returned_empty. Two values end a shipment, delivered and returned_empty, and returned_empty outranks delivered.
When the box was discharged, which is when free time starts counting. Null when no discharge is on file yet.
Free days the terms allow at this port. Null when no terms and no published tariff apply.
The last day free of charge, computed from the discharge and the free days. Null when either is missing.
Days past the last free day. Zero while still inside free time.
Which terms priced this box: your_contract_terms when you filed terms, carrier_published_tariff when we used the published tariff for that carrier, port and equipment size.
The tariff lane the published rate was read from: us_import, eu_import or asia_import. Absent when your own terms were used.
On a card, whether the slot partners agree with each other. On a prediction, how much to trust the shifted arrival.
True when the row carries a real money figure. False means the timing is known but no rate applied, so treat the amount as unknown rather than zero.
Discharged boxes we cannot assess because no free-time terms are on file. An empty risk list with a number here is not a clean bill of health.
Plain-English account of what the report could not measure. Null when nothing was missing.
How many boxes in your book we could actually assess.
Boxes we could time but not price, because no rate applied.
How many boxes were examined before filtering. Read it with truncated below.
True when the book was larger than one report can carry and the list was cut. An untruncated empty list means nothing was at risk; a truncated one does not.
Errors
A failure carries { "ok": false, "error": { "code", "message", "severity" } }. Branch on the code, and log the message.
The key is missing, malformed or revoked.
We could not read your book. Retry.
curl 'https://api.trackingmcp.com/v1/containers/demurrage' \
-H "Authorization: Bearer tmcp_YOUR_API_KEY"const res = await fetch("https://api.trackingmcp.com/v1/containers/demurrage", {
headers: {
"Authorization": "Bearer tmcp_YOUR_API_KEY"
}
});
const data = await res.json();import requests
res = requests.get(
"https://api.trackingmcp.com/v1/containers/demurrage",
headers={"Authorization": "Bearer tmcp_YOUR_API_KEY"},
)
data = res.json() {
"api_version": "2026-08-04",
"ok": true,
"data": {
"total_at_risk_usd": 0,
"containers_at_risk": 1,
"items": [
{
"container_id": "ONEU1234567",
"port": "BDCGP",
"free_days_left": 0,
"daily_rate_usd": 80,
"projected_usd": 0,
"status": "discharged",
"discharge_datetime": "2026-08-15T01:20:00+00:00",
"free_days": 5,
"last_free_day": "2026-08-20T01:20:00.000Z",
"days_overdue": 0,
"terms_source": "carrier_published_tariff",
"terms_lane": "asia_import",
"confidence": "estimated",
"costed": true
}
],
"unassessable_containers": 3,
"coverage_note": "3 container(s) could not be assessed: no contract terms on file and no published tariff for that carrier and port. An empty or short list is NOT a clean bill of health — supply terms via POST /v1/demurrage-terms.",
"assessed_containers": 1,
"uncosted_containers": 0,
"candidates_considered": 4,
"truncated": false
}
}