API endpoints
Base URL: https://api.myairliftusa.com/api/tariff. Requests and responses are JSON, and CORS is open, so browser code can call the API without a proxy.
Optional: send X-Airlift-Client: your-app/1.0 to identify your integration. It is logged, never required, and does not change your rate limit.
POST/api/tariff/calculate
Estimates duty, customs fees (MPF and HMF) and landed cost for one HTS code, country of origin and customs value.
Request
{
"hts_code": "6802.23.00.00",
"origin_country": "IN",
"value": 25000,
"quantity": 1,
"entry_date": "2026-09-01",
"transport_mode": "ocean"
}
Response
{
"hts_code": "6802.23.00.00",
"origin_country": "IN",
"value": 25000,
"quantity": 1,
"unit": "",
"general_rate": "3.7%",
"special_rate": "Free (A+,AU,BH,...)",
"other_rate": "40%",
"applicable_rate": "3.7%",
"duty_amount": 925,
"breakdown": {
"ad_valorem_duty": 925,
"additional_duties": 0,
"total_duty": 925,
"tariff_components": [
{
"hts_code": "6802.23.00.00",
"description": "General (MFN) duty",
"rate": "3.7%",
"duty_amount": 925
}
]
},
"hmf": 31.25,
"mpf": 86.6,
"landed_cost": 26042.85,
"entry_date": "2026-09-01",
"transport_mode": "ocean",
"assumptions": [
"Antidumping/countervailing duties, excise taxes and quota provisions are not included"
],
"measures_version": "2026-09-03"
}
GET/api/tariff/search?q={query}&limit={limit}
Searches the tariff schedule by code or description. limit defaults to 50; the maximum is 100.
Response
[
{
"id": 41233,
"htsno": "6802.23.00.00",
"indent": "2",
"description": "Granite: Other",
"superior": null,
"units": ["kg"],
"general": "3.7%",
"special": "Free (A+,AU,BH,...)",
"other": "40%",
"quotaQuantity": null,
"additionalDuties": null,
"createdAt": "2026-01-04T00:00:00Z",
"updatedAt": "2026-09-01T00:00:00Z"
}
]
GET/api/tariff/hts/{hts_code}
Returns the schedule entry for one exact code, with children[] and footnotes[] when present. Returns 404 if the code is not in the schedule.
Response
{
"id": 41233,
"htsno": "6802.23.00.00",
"description": "Granite: Other",
"units": ["kg"],
"general": "3.7%",
"special": "Free (A+,AU,BH,...)",
"other": "40%",
"footnotes": [
{ "id": 912, "htsEntryId": 41233, "columns": ["general"], "value": "See 9903.88.15.", "type": "endnote" }
]
}
GET/api/tariff/countries
Lists the origins the engine recognizes. Use code as the origin_country value on /calculate.
Response
[
{ "id": 6, "code": "IN", "name": "India", "isoCode": "IN" },
{ "id": 2, "code": "CN", "name": "China", "isoCode": "CN" }
]
GET/api/tariff/version
Reports which rule set and schedule edition answered your request. If measures_version differs from the value inside a cached calculation, recompute.
Response
{
"measures_version": "2026-10-05",
"schedule_revision": "2026 rev 20",
"build": "a1b2c3d"
}
Request fields for /calculate
Reading the /calculate response
breakdown.tariff_components[] is the duty stack, one row per measure applied: first the base rate (Column 1 General, Special or Column 2), then any Chapter 99 additional-duty lines. Each row has its own hts_code, description, rate and duty_amount. - The top-level
duty_amount is the sum of those rows. mpf and hmf are the two statutory customs fees.landed_cost is value plus duty plus those two fees.assumptions[] lists everything the engine had to assume. Show it to your users next to the number.
Rate limits
Limits apply per client IP address, enforced with a token bucket. Your address is the first hop of X-Forwarded-For when present, otherwise the socket address.
Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. When the bucket empties you get 429 with a Retry-After header in whole seconds and {"error":"rate limit exceeded"}. Wait at least that long before retrying. CORS preflight requests don't count against the limit.
Cache aggressively. /countries and /version change a handful of times a year. A calculation for the same hts_code, origin_country and entry_date stays the same until the schedule changes, and measures_version tells you when that happens. Need more headroom? Talk to us rather than working around the limit.