Compatible with Swagger and Postman import
Overview
The FreightUtils API is the neutral freight reference layer for AI agents — authoritative dangerous-goods, customs, location and freight-calculation data an agent can call and cite, from primary sources (ADR 2025 / UNECE, HS 2022 / WCO, IATA-regulated airline prefixes). Neutral by design: no freight to sell and no carrier to push, so an agent can trust it as ground truth. It is a stateless REST API; every calculator on this site has a corresponding endpoint. No authentication is required. Responses are JSON. CORS is enabled for all origins.
Reliability & Support
FreightUtils APIs are hosted on Vercel's global edge network with automatic SSL and CDN caching.
MCP Server — AI Agent Integration
The full MCP server reference — all 24 tools, the response envelope, rate limits and directory listings — lives on its own page.
MCP server docs →FreightUtils is the neutral freight reference layer for AI agents, available as a Model Context Protocol (MCP) server — direct, citable access to all 24 MCP tools (23 REST-backed + get_subscribe_link) from authoritative sources, with no freight to sell and no carrier to push.
claude_desktop_config.json:After saving the config, fully quit and relaunch your MCP client (Claude Desktop, Cursor, Cline). MCP servers are only loaded at client startup — editing the config in a running session does nothing until restart.
Confirm the FreightUtils MCP surface is reachable before asking your agent any freight question:
A 200 response with "status":"ok" and "tools_registered":24 means the remote MCP surface is live. The endpoint is callable by your agent too — Claude/Cursor/Cline can hit it for a self-diagnostic without you having to open a terminal.
mcp.json file (Settings → MCP). Same shape as Claude Desktop:| Symptom | Likely cause | Fix |
|---|---|---|
| Tools not appearing in the client | MCP client wasn’t restarted after the config edit | Fully quit (Cmd+Q on macOS / right-click → Quit on Windows tray) and relaunch. Don’t just close the window. |
| "Server failed to start" / spawn error in client logs | npx not on PATH, or node version older than 18 | Install Node.js 18+ from nodejs.org. On macOS, an absolute path in the config (e.g. "/opt/homebrew/bin/npx") avoids PATH issues for GUI-launched clients. |
| Tool calls return HTTP 429 / "rate_limited" | Anonymous IP cap of 25 requests/day exceeded | Get a free API key from the signup form below (100/day) or upgrade to Pro (50,000/month). The freightutils-mcp npm package passes the key through on every call (since v2.3.0) — set the FREIGHTUTILS_API_KEY env var in your MCP client config. On the remote URL (https://www.freightutils.com/api/mcp), send it as an X-API-Key header. |
| Specific tool returns "isError": true | Bad input shape (snake_case vs camelCase, missing required field) or unknown lookup key (UN number / HS code / AWB prefix not in the dataset) | The error message in the tool response names the field. Verify against the schema at /api-docs or call the corresponding playground endpoint directly to confirm the input shape. |
| Want to verify the surface from inside an agent | No CLI access during a conversation | Ask the agent to fetch /api/mcp/health. The endpoint is public, returns the server version + registered tool count + transport URLs in a single JSON, and is rate-limit exempt so the diagnostic always works. |
Get Started in 2 Minutes
// FreightUtils API — JavaScript example // Calculate loading metres for 10 Euro pallets const response = await fetch( 'https://www.freightutils.com/api/ldm?pallet=euro&qty=10' ); const data = await response.json(); console.log(`LDM: ${data.ldm}`); console.log(`Utilisation: ${data.utilisation_percent}%`); console.log(`Fits: ${data.fits}`);
All endpoints work the same way. No auth, no signup. Full reference below ↓
Composite endpoint that chains CBM, chargeable weight, LDM, ADR compliance, and UK duty/VAT estimation into a single call. Accepts a unified Shipment object and returns comprehensive results based on transport mode.
Mode Parameter
| Mode | Calculations Included |
|---|---|
road | CBM, LDM, pallet spaces, trailer utilisation, road chargeable weight (1 LDM = 1,750 kg), vehicle suggestion |
air | CBM, volumetric weight (1 CBM = 167 kg), air chargeable weight |
sea | CBM, revenue tonnes (W/M at 1 CBM = 1,000 kg), container suggestion |
multimodal | All of the above — road, air, and sea calculations combined |
Example Request
Mixed 3-item road shipment with a DG item and HS code:
Example Response
Pro-tier endpoint. Free access: 25 requests/day anonymous, 100/day with a free API key. Subscribe for higher limits.
Calculate the cubic metre (CBM) volume of a shipment. Returns total CBM plus equivalents in cubic feet, litres, and cubic inches.
Parameters
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
l | number | Yes | Length of one piece in centimetres | — |
w | number | Yes | Width of one piece in centimetres | — |
h | number | Yes | Height of one piece in centimetres | — |
pcs | integer | No | Number of identical pieces | 1 |
Example Request
5 boxes, 120×80×100 cm each:
Estimate freight transport CO2e using the ISO 14083 / GLEC distance-based method: emissions = mass × distance × an open emission-intensity factor (kgCO2e/tonne-km). Provide actual gross mass, not chargeable/volumetric weight (a common air-freight mistake — see mass_basis). Returns well-to-wheel and tank-to-wheel emissions, the exact factor used, and a _source citing both the method and the specific open factor (DEFRA / EPA / ADEME). Each result also carries empty_running (the fleet-average factor already includes average empty running — don't double-count an empty return), representativeness (sea/air = low, high real-world variance), a human-readable summary, and _source.factor.last_verified. You provide the distance — this endpoint does not route. Best-effort estimate, not a verified carbon report; an unknown mode/sub_mode/region returns available:false with the covered options.
Parameters
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
mass | number | Yes | Shipment mass (in mass_unit) | — |
mass_unit | kg | tonnes | No | Unit for mass | kg |
distance_km | number | Yes | Transport distance in km (caller-provided; not routed) | — |
mode | enum | Yes | road | rail | sea | air | inland_waterway | — |
sub_mode | string | No | Vehicle class (e.g. articulated, container ship) | representative |
region | uk | us | fr | No | Factor source: uk=DEFRA, us=EPA, fr=ADEME | per-mode |
basis | wtw | ttw | No | Well-to-wheel or tank-to-wheel | wtw |
Example Request
10 tonnes by road, 500 km, UK (DEFRA), well-to-wheel:
Parse an arbitrary string (e.g. a booking line or email) to find and validate every freight identifier in it — shipping container (ISO 6346), air waybill (IATA modulus-7) and IMO ship number — or validate a single identifier by type. Returns per identifier: type, normalised form, valid (pass/fail), expected vs actual check digit, details (container owner/category; AWB airline; IMO number) and a _source. Structural only — a valid check digit means well-formed, not that the entity exists.
Parameters
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
text | string | No* | Arbitrary string to scan for container / AWB / IMO identifiers (parse mode) | — |
value | string | No* | A single identifier to validate (typed mode); requires type | — |
type | container | awb | imo | No* | Identifier type for value | — |
*Provide text (parse mode) OR value+type (typed mode).
Example Request
Parse a mixed string:
Check a goods description against the official EU ICS2 stop-words list (unacceptable/vague terms for entry summary declarations). Returns the flagged terms — each with a note on whether it is the standalone description (automatic ENS rejection) or embedded (make the description more specific) — a clean boolean, a caveat, and a _source citing the EU list + legal basis. Reference only: not an ENS filing, not a compliance determination; the list is non-exhaustive and clean does not guarantee acceptance. No accepted/rejected verdict. The submitted description is not persisted or logged (response is no-store).
Parameters
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
description | string | Yes | The goods description to check against the EU ICS2 stop-words list | — |
Example Request
A vague standalone description:
Look up an airport by IATA code (3 letters), ICAO code (4 chars), or free-text name / city search. Provide one of iata, icao or q. Returns the full record (both codes, name, type, municipality, region, country, coordinates, elevation); ambiguous name searches return ranked candidates. Optional type filter. Data: OurAirports (public domain), cross-checked vs OpenFlights + Wikidata. Reference only — not for navigation; verify current codes with IATA/ICAO.
Parameters
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
iata | string | One of | Exact 3-letter IATA code (e.g. LHR) | — |
icao | string | One of | Exact 4-character ICAO code (e.g. EGLL) | — |
q | string | One of | Name / city / municipality search (min 2 chars) | — |
type | string | No | Filter: large_airport, medium_airport, small_airport, heliport, closed, seaplane_base | — |
Example Request
Find the airports nearest to a caller-provided latitude/longitude, sorted by great-circle (haversine) distance with distance_km on each result. Coordinates are input only — never stored or logged. Optional radius_km, max_results (1–50, default 10) and type filter. Does NOT geocode place names or compute routes — pass coordinates you already hold.
Parameters
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
lat | number | Yes | Latitude in decimal degrees (-90 to 90) | — |
lon | number | Yes | Longitude in decimal degrees (-180 to 180) | — |
radius_km | number | No | Maximum distance in kilometres | — |
max_results | integer | No | Results to return (1–50) | 10 |
type | string | No | Filter by airport type (e.g. large_airport) | — |
Example Request
Calculate air freight chargeable weight — whichever is higher between actual gross weight and volumetric (dimensional) weight. Supports custom volumetric factors for all carriers.
Parameters
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
l | number | Yes | Length of one piece in centimetres | — |
w | number | Yes | Width of one piece in centimetres | — |
h | number | Yes | Height of one piece in centimetres | — |
gw | number | Yes | Total gross weight of all pieces in kg | — |
pcs | integer | No | Number of identical pieces | 1 |
factor | integer | No | Volumetric divisor: 6000 (IATA standard), 5000 (express carriers) | 6000 |
Example Request
2 pieces, 120×80×100 cm, 500 kg total, IATA factor:
Calculate how many boxes fit on a pallet using a layer-based algorithm. Returns boxes per layer, number of layers, total boxes, orientation used, and volume/weight analysis. Optional weight constraint caps the result at the pallet's maximum payload.
Parameters
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
pl | number | Yes | Pallet length in centimetres | — |
pw | number | Yes | Pallet width in centimetres | — |
pmh | number | Yes | Maximum total stack height in centimetres (floor to top of cargo) | — |
bl | number | Yes | Box length in centimetres | — |
bw | number | Yes | Box width in centimetres | — |
bh | number | Yes | Box height in centimetres | — |
ph | number | No | Pallet board/deck height in cm — deducted from usable height | 15 |
bwt | number | No | Weight per box in kg — enables weight constraint calculation | — |
mpw | number | No | Maximum pallet payload weight in kg — caps result if weight exceeded | — |
rotate | boolean | No | Allow 90° rotation of boxes for best fit. Pass false to disable. | true |
Example Request
Look up ADR 2025 dangerous goods by UN number, search by substance name, or filter by hazard class. The dataset contains 2,939 entries from the ADR 2025 Dangerous Goods List (Table A). Responses are cached for 1 hour (s-maxage=3600).
Query Modes
| Parameter | Type | Description | Max results |
|---|---|---|---|
un | string | Exact UN number lookup. Accepts 1203, UN1203, or 01203. | 1 |
search | string | Case-insensitive partial match on the proper shipping name. Min 2 characters. Also accepts q as an alias. | 50 |
class | string | Filter by ADR hazard class (e.g. 3, 6.1, 1.1). | 100 |
Provide exactly one parameter per request. Omitting all parameters returns a 400 with usage hints.
Example Requests
Exact UN number lookup:
Search by substance name:
Filter by hazard class:
Calculate whether the ADR 1.1.3.6 small load exemption applies to a dangerous goods consignment. Supports single-substance GET queries and multi-substance POST requests. Checks both total points threshold (1,000) and per-substance quantity limits per ADR 1.1.3.6.3.
GET — Single Substance
| Parameter | Type | Required | Description |
|---|---|---|---|
un | string | Yes | UN number (e.g. 1203) |
qty | number | Yes | Quantity in kg or litres |
Example — 200 litres of petrol:
POST — Multi-Substance Load
Request body:
Response structure is identical to the GET endpoint, with multiple items in the array.
Multi-variant UN numbers: some UN numbers have more than one ADR Table A row (different packing groups / concentration bands with different transport categories — e.g. UN 1789 PG II vs PG III). Pass an optional packing_group(I/II/III, GET query or per item) or variant_index(from /api/adr) to pin one row. Without one, the response is HTTP 200 with human_review_required: true and a candidates[] list (no verdict) rather than a silently-guessed row.
Response Fields
| Field | Type | Description |
|---|---|---|
packing_group | string | null | Resolved ADR packing group for the row (echoed for traceability) |
variant_index | number | Resolved ADR Table A variant index for the row |
transport_category | string | ADR transport category (0–4) |
multiplier | number | null | Points multiplier for the category (null for cat 0) |
points | number | null | quantity × multiplier |
total_points | number | Sum of all substance points |
exempt | boolean | true if total ≤ 1,000 AND no cat 0 AND no quantity exceedance |
has_category_zero | boolean | true if any substance is transport category 0 |
has_quantity_exceedance | boolean | true if any substance exceeds its per-category max quantity |
warnings | string[] | Human-readable warning messages for limit violations |
Check whether dangerous goods qualify for ADR Limited Quantity (Chapter 3.4) or Excepted Quantity (Chapter 3.5) concessions. Accepts up to 20 items per request and returns per-item pass/fail status against ADR Table A limits.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | No | lq (default) or eq |
items | array | Yes | 1–20 items to check |
items[].un_number | string | Yes | UN number (e.g. 1203) |
items[].quantity | number | Yes | Quantity per inner packaging |
items[].unit | string | No | ml, L (default), g, or kg |
items[].inner_packaging_qty | number | No | Number of inner packagings per outer (EQ mode only) |
items[].packing_group | string | No | I/II/III — disambiguates a UN number with more than one ADR Table A row (e.g. UN 1789). Ignored for single-row UN numbers. |
items[].variant_index | number | No | ADR Table A variant index (from /api/adr) — pins one row when variants share a packing group (concentration bands). |
A UN number that resolves to more than one ADR Table A row without a packing_group/variant_index returns HTTP 200 with human_review_required: true and a candidates[] list (no verdict) rather than checking a silently-guessed packing group.
Example — check LQ for 0.5 L of petrol:
Response Fields
| Field | Type | Description |
|---|---|---|
mode | string | lq or eq |
overall_status | string | qualifies, does_not_qualify, or partial |
items[] | array | Per-item results with substance info, limits, and pass/fail |
items[].status | string | within_limit, exceeds_limit, or not_permitted |
summary | object | Counts of qualifying, exceeding, and not-permitted items |
references | object | ADR chapter and table references |
Search airlines by name, IATA code, ICAO code, AWB prefix, or country. The dataset contains6,357 airlines including 391 cargo airlines with AWB prefixes.
Query Modes
| Parameter | Type | Description | Match |
|---|---|---|---|
q | string | General search — matches name, codes, prefix, country. Smart: 2–3 digits match prefix only, 2–3 letters match IATA/ICAO only, 4+ chars search all fields. | Smart |
iata | string | IATA 2-letter code (e.g. EK) | Exact |
icao | string | ICAO 3-letter code (e.g. UAE) | Exact |
prefix | string | AWB 3-digit prefix (e.g. 176) | Exact |
country | string | Country name (e.g. Germany) | Partial |
Example Requests
AWB prefix lookup:
IATA code lookup:
Name search:
Response Fields
| Field | Type | Description |
|---|---|---|
slug | string | URL-friendly identifier |
airline_name | string | Official airline name |
iata_code | string | null | 2-character IATA designator |
icao_code | string | null | 3-character ICAO designator |
awb_prefix | string[] | null | 3-digit AWB prefix(es) — array, some airlines have multiple |
callsign | string | null | Radio callsign for ATC communication |
country | string | null | Country of registration |
has_cargo | boolean | true if airline has AWB prefix(es) |
aliases | string[] | null | Alternative names (e.g. cargo division name) |
verified | boolean | true if prefix confirmed from multiple independent sources |
sources | object[] | Audited records only — the independent source URLs (with access dates) behind the record |
audited_at | string | Audited records only — date of the multi-source audit |
decision_rationale | string | Audited records only — why the published values were accepted |
Responses also carry a top-level _source citability envelope and a meta block whose airlines count is derived from the dataset at build time — never hand-typed.
Look up INCOTERMS 2020 trade terms. Returns all 11 terms by default, or filter by code or transport category. Each term includes seller/buyer responsibilities, risk and cost transfer points, insurance obligations, and practical guidance.
Parameters
| Parameter | Type | Description |
|---|---|---|
code | string | INCOTERM code (e.g. FOB, CIF, DDP) |
category | string | Filter by transport mode: any_mode or sea_only |
Omit all parameters to return all 11 INCOTERMS 2020 terms.
Example Requests
Single term lookup:
Filter by transport category:
All terms:
Shipping container specifications — internal/external dimensions, weights, door openings, and pallet capacity for all 10 standard ISO container types. Optionally calculate how many items fit in a specific container.
Query Modes
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | No | Container slug (e.g. 20ft-standard, 40ft-high-cube). Omit to list all. |
l | number | No | Item length in cm (requires type + w + h) |
w | number | No | Item width in cm |
h | number | No | Item height in cm |
wt | number | No | Item weight in kg |
qty | integer | No | Number of items |
Example Requests
List all containers:
Single container specs:
Loading calculation — how many 60×40×40cm boxes fit in a 40ft HC:
Convert between freight-relevant units — weights, volumes, lengths, and freight-specific conversions (CBM to chargeable weight, CBM to freight tonnes).
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
value | number | Yes | The number to convert |
from | string | Yes | Source unit code |
to | string | Yes | Target unit code |
Supported Unit Codes
| Group | Codes |
|---|---|
| Weight | kg, lbs, oz, tonnes, short_tons, long_tons |
| Volume | cbm, cuft, cuin, litres, gal_us, gal_uk |
| Length | cm, inches, m, feet, mm |
| Freight | chargeable_kg (target only, from=cbm), freight_tonnes (target only, from=cbm) |
Example Requests
Standard conversion:
CBM to chargeable weight (IATA 6000 divisor):
CBM to freight tonnes (W/M rule):
Search and browse Harmonized System (HS 2022) commodity codes. Supports text search by product description, exact code lookup with ancestor chain, and section browsing. Covers all 6,937 codes across 21 sections and 97 chapters.
Query Modes
| Parameter | Type | Description | Max results |
|---|---|---|---|
q | string | Case-insensitive search on descriptions and codes. Min 2 characters. | 50 |
code | string | Exact HS code lookup (2, 4, or 6 digit). Returns full details with ancestor chain and children. | 1 |
section | string | Browse by section (Roman numeral, e.g. II). Returns all chapters in that section. | All |
Provide exactly one parameter per request. Omitting all parameters returns a 400 with usage hints.
Example Requests
Search by description:
Code lookup with ancestors:
Browse section:
Calculate total CBM, loading metres (LDM), volumetric and mode-specific chargeable weight across a multi-item mixed consignment — per-line and grand totals, plus objective advisory flags (implausible density, mode/option mismatch, dangerous-goods presence by UN number against the ADR 2025 reference, and ISO 6346 container / IATA AWB check-digit validity). Supports sea, air, and road modes. Canonical request/response schema: consignment.v1.json.
Best-effort deterministic calculation and reference data only. Verify all inputs. Not regulatory, customs, or dangerous-goods compliance advice — you remain responsible for classification, documentation and carrier acceptance.
Request Body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | No | road (default), air, or sea |
lines | array | Yes* | 1–50 canonical line objects (see below). Preferred. |
items | array | Yes* | Legacy flat alias (dimensions in cm, weight in kg). *Provide lines or items. |
options | object | No | air_volumetric_divisor (default 6000), container_number, awb_number |
Canonical Line Object (lines[])
| Field | Type | Required | Description |
|---|---|---|---|
quantity | integer | Yes | Number of identical pieces |
dims | object | Yes | { l, w, h, unit } — unit one of mm, cm, m, in |
weight | object | Yes | { value, unit } — unit one of kg, g, t, lb |
stackable | boolean | No | Stack two-high (halves loading-metre footprint) |
hs_code | string | No | HS commodity code (6–10 digits) |
un_number | string | No | UN number — triggers the dangerous-goods reference flag |
description | string | No | Item label |
Example Request
Estimate UK import duty and VAT for a commodity code using live GOV.UK Trade Tariff data. Accepts customs value, origin country, freight/insurance costs, and INCOTERM for CIF adjustment.
Request Body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
commodity_code | string | Yes | HS/tariff code (min 6 digits) |
origin_country | string | Yes | ISO 2-letter country code (e.g. CN, DE) |
customs_value | number | Yes | Goods value in GBP |
freight_cost | number | No | Freight cost in GBP (added to CIF value) |
insurance_cost | number | No | Insurance cost in GBP (added to CIF value) |
incoterm | string | No | INCOTERM (e.g. FOB, CIF, EXW) |
Example Request
Search and look up UN/LOCODE transport locations — 116,129+ seaports, airports, rail terminals, inland depots, and border crossings worldwide. Responses are cached for 24 hours.
Query Modes
| Parameter | Type | Description |
|---|---|---|
code | string | Exact UN/LOCODE lookup (e.g. GBLHR, NLRTM) |
q | string | Search by name (e.g. rotterdam, heathrow) |
country | string | Filter by country code (e.g. GB, NL) |
function | string | Filter by function: port, airport, rail, road, icd, border |
limit | integer | Max results (1–100, default: 20) |
Example Requests
Search by name:
Exact code lookup:
Filter by country and function:
Look up air freight Unit Load Device (ULD) specifications. 16 types including LD3 (AKE), PMC main deck pallet, temperature-controlled containers, and more. Returns dimensions, weights, volume, and aircraft compatibility.
Parameters
| Parameter | Type | Description |
|---|---|---|
type | string | ULD code or slug (e.g. AKE, PMC). Omit to list all. |
category | string | Filter: container, pallet, or special |
deck | string | Filter by deck: lower or main |
Example Requests
Single ULD lookup:
Filter by category:
All ULD types:
Look up road freight vehicle and trailer specifications. 17 types covering articulated trailers, rigid trucks, and vans. Returns internal dimensions, payload limits, pallet capacity, and features.
Parameters
| Parameter | Type | Description |
|---|---|---|
slug | string | Vehicle slug (e.g. standard-curtainsider). Omit to list all. |
category | string | Filter: articulated, rigid, or van |
region | string | Filter: EU or US |
Example Requests
Single vehicle lookup:
Filter by category:
Filter by region:
HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Success — calculation result returned as JSON |
| 400 | Bad Request — missing or invalid parameters. Check the error message in the response. |
| 404 | Not Found — no results for the given query (airlines and ADR endpoints) |
| 405 | Method Not Allowed — only GET (or POST for /api/adr-calculator, /api/adr/lq-check, /api/shipment/summary) is supported |
| 500 | Internal Server Error — unexpected error, please report via GitHub |
Field Naming
All endpoints use snake_case field names in responses (e.g. internal_length_cm, max_gross_kg). POST request bodies on /api/duty and /api/consignment accept either casing for backwards compatibility — snake_case is the documented form.
Rate Limiting
The API is free to use. Anonymous rate limit: 25 requests per day per IP. Free API key: 100 requests per day. Pro: 50,000 requests per month.
Error Responses
All endpoints return standard HTTP error codes with a descriptive JSON error message:
Response Envelope (agent-facing, opt-in)
Every tool can also return a v1 response envelope — a thin, agent-facing wrapper that keeps the answer under result and adds the four things an autonomous agent needs to use and cite it safely: how much to trust it (confidence), where it came from(_source), a ready-to-quote line (citation), and — when relevant —what was corrected (normalized_input), advisories (warnings),blocking errors with a recovery hint (blocking_errors), and time-boxed validity(validity). It is fully described by the JSON Schema at /schemas/response-envelope.v1.json.
The envelope is opt-in. The flat legacy body (the answer at the top level) stays the default and is byte-unchanged, so existing REST consumers and the freightutils-mcp npm package are unaffected. Request the envelope explicitly with either ?envelope=1 or an Accept header:
On the hosted MCP server (/api/mcp) the envelope is returned as structuredContent (validating against each tool’s output schema), while content[0].text keeps the flat legacy JSON so text-parsing clients are unaffected. envelope_version ("1") lets any consumer detect the shape.
Confidence model
confidence.level is high / medium / low, and confidence.basissays why. A numeric score (0–1) is present only when the basis ismatch_quality.
| basis | Meaning | Typical level |
|---|---|---|
deterministic | Pure computation (CBM, chargeable weight, LDM, conversions). | high |
provenance | Reference-data lookup with an audit status. | high (verified) / medium (provenance pending) |
match_quality | Fuzzy / ranked search — carries a score. | from the score |
freshness | Computed over live, time-sensitive data (e.g. UK duty rates). | high |
Warnings & blocking errors
warnings are non-blocking advisories; blocking_errors mean no answer was produced (ok: false) and each carries a recovery hint (an action, and often atool + params to retry with). Both use a stable UPPER_SNAKE code taxonomy; the keys are omitted entirely when empty (never []).
| code | Meaning |
|---|---|
RATE_LIMITED | Quota exceeded (maps to the 429 + Retry-After). |
MISSING_INPUT | A required parameter was absent. |
INVALID_INPUT | A parameter was present but malformed. |
NOT_FOUND | An exact lookup (code / id) matched nothing. |
NO_MATCH | A search / ranked query returned nothing. |
FUZZY_BEST_MATCH | Advisory: the top result is a best-effort fuzzy match, not an exact hit. |
PROVENANCE_PENDING | Advisory: this dataset’s provenance is pending independent verification. |
METHOD_NOT_ALLOWED | Wrong HTTP method for the endpoint (e.g. GET on a POST-only tool). |
Provenance, citation & validity
_source is the canonical provenance (name, checked date orrequest-time, and provenance_status: verified / pending-verification /computed / live). citation.text is a ready-to-quote line, with an optionalqualifier hedge for fuzzy or not-legal-advice answers. validity appears only on time-boxed tools (regulatory editions, live rates) and carries effective_from / effective_to /as_of.
Fuzzy best-match (GET /api/airports?q=heathrow&envelope=1):
Blocking error with a recovery hint (GET /api/adr?un=9999&envelope=1 → 404):
Platform Commitments
Five pages that spell out what you can rely on:
Source Code & Issue Reporting
The FreightUtils MCP server is open source. Report bugs, request features, or contribute on GitHub: github.com/SoapyRED/freightutils-mcp. For data corrections or API support, email contact@freightutils.com.