Landed Cost Route Contract
Status: Active
Version: v1
Last updated: 2026-03-20
This document is the normative contract for POST /api/trade/landed-cost.
It is intentionally documented separately outside the versioned public API contract pack described in docs/api/public-api-contract-v1.md. The public pack remains scoped to signup, billing, jobs, SIMA, and upload routes. POST /api/trade/landed-cost is an authenticated tenant trade route documented separately here.
Route and auth
- Route:
POST /api/trade/landed-cost - Auth: Clerk bearer token or integration auth (
Authorization: Bearer ...or compatibilityx-api-key+x-org-id) - Customer-facing authority source is destination-aware:
OPENCLAWfor US/default,OPENCLAW_CBSAfor Canada,OPENCLAW_HMRCfor UK,OPENCLAW_TARICfor EU member states. - Catalog refresh uses the same destination-aware source selector as the public landed-cost route.
Request contract
Required fields:
productValuehsCodeoriginCountrydestinationCountry
Optional fields:
shippingCostinsurancecurrencyquantityquantityUnitproviderdescription
Quantity-aware rules:
quantityis a positive decimal representing the total customs quantity for the shipment line matched to the HS code.quantityUnitmust be one of:KGM,LTR,DZN,TNE.quantity and quantityUnit must be provided together- Quantity is preserved as provided in the first slice; no rounding or unit conversion occurs.
Currency rules:
currencyis an optional 3-letter ISO 4217 code (e.g.EUR,USD,GBP).- When provided, the engine evaluates de minimis thresholds for the destination country. Without
currency, de minimis evaluation is skipped. - If
currencydoes not match the threshold currency for the destination, the response includesdeMinimis.skipped: 'currency_mismatch'(no exemption applied, threshold still reported). - For EU destinations,
currencyalso drives the low-value trust gate: EUR values at or below the €150 IOSS boundary returntrust.level: 'indicative'; non-EUR currencies returntrust.level: 'undetermined'.
Provider comparison rules:
providerenables tenant-scoped external comparison for legacy value-only requests.provider comparison does not support quantity-aware landed-cost requests yet- Quantity-aware requests with
providerreturn400 INVALID_REQUEST. - Provider comparison only runs when
currencyis explicitly supplied and equals'USD'. Omittingcurrencyor supplying any non-USD value skips provider comparison (the response includes the internal result withproviderSkipReason: 'non_usd_corridor').
Example requests
Value-only request:
{
"productValue": 100.0,
"hsCode": "6109.10.00",
"originCountry": "CN",
"destinationCountry": "US",
"shippingCost": 50.0,
"insurance": 10.0
}Quantity-aware request:
{
"productValue": 100.0,
"hsCode": "2207.20.00",
"originCountry": "CN",
"destinationCountry": "CA",
"shippingCost": 50.0,
"insurance": 10.0,
"quantity": 2.0,
"quantityUnit": "KGM"
}Provider comparison request:
{
"productValue": 100.0,
"hsCode": "6109.10.00",
"originCountry": "CN",
"destinationCountry": "US",
"provider": "zonos",
"description": "Cotton knit t-shirt"
}Response notes
- Authoritative and
rate_not_availableresponses report the customer-facing source selected for the request destination. - Canada requests (
destinationCountry=CA) reportmetadata.sourceCode = "OPENCLAW_CBSA"when the authoritative engine resolves through the CBSA source. - Quantity-aware duty-expression evaluation is supported for the first landed-cost CBSA formula slice only; unsupported expressions remain
status: "rate_not_available"withmetadata.unsupportedExpression = true.
Contract boundaries
CLAUDE.mdis a route index, not the full normative contract.docs/postman/RGL8R-API.postman_collection.jsonis a first-party request example surface and must stay aligned with this document.packages/mcp-server/src/tools/landed-cost.tsis a first-party tool surface and must stay aligned with this document.apps/docs/content/public/...is generated fromdocs/and must not be edited directly.