API Reference

Programmatic access to US tariff rates and HS-code data. Base URL: https://exportsonar.com/api/v1/. Endpoints are live in production; every example value below is derived from the current HTS dataset.

Data vintage: 2026-10-09 · 23,193 tariff lines across 96 chapters · interactive OpenAPI spec at /api/docs

Authentication & quotas

ModeHeaderQuota
Anonymous (free)—Unlimited, no signup
Metered (paid)X-API-Key: <key>Prepaid credits, $0.06 per successful call

A metered call debits exactly one credit; the response carries credits_remaining. Errors: 401 INVALID_API_KEY, 402 INSUFFICIENT_CREDITS.

GET /api/v1/health

Liveness probe with dataset dimensions. No parameters.

curl https://exportsonar.com/api/v1/health
# => {"ok": true, "rows": 23193, "chapters": 96}

GET /api/v1/tariff

Duty estimate for one HTS line. Query parameters:

ParamRequiredNotes
hsyesdotted or bare; 8-digit base lines auto-fall-back to the 10-digit suffix
originyesISO country of origin (upper-cased server-side)
valueyescustoms value in USD, > 0
qtynoquantity for specific duties
unitnounit qualifier for qty (lower-cased server-side)
curl "https://exportsonar.com/api/v1/tariff?hs=0101.30.00.00&origin=CN&value=1000"
# => {"query": {"hs": "0101.30.00.00", "hs_normalized": "0101.30.00.00", "origin": "CN", ...},
#     "match": {"hts": "0101.30.00.00", "description": "Asses", "unit": "No."},
#     "rate":  {"basis": "ad_valorem", "general": "6.8%",
#               "ad_valorem_pct": 6.8, "specific": null,
#               "duty_usd": 68.0, "note": "..."},
#     "trade_remedy": [...]}   # present when Chapter 99 provisions apply

Errors: 400 MISSING_PARAM, 400 INVALID_VALUE, 404 HTS_NOT_FOUND, plus the auth errors above. When the requested line carries an active Chapter 99 trade-remedy provision, the response embeds a trade_remedy array with the surcharge detail.

GET /api/v1/lookup

Prefix-first HS-code and description search. Parameters: q (required, non-blank), limit (optional, clamped to 1–100, default 10).

curl "https://exportsonar.com/api/v1/lookup?q=asses&limit=3"
# => {"q": "asses", "count": 3, "results": [{"hts": "...", "description": "..."}, ...]}

Error: 400 MISSING_PARAM when q is blank.

GET /api/v1/usage

Balance and recent metered calls for one key. Requires X-API-Key; anonymous callers get 401 INVALID_API_KEY.

curl -H "X-API-Key: $EXPORTSONAR_KEY" https://exportsonar.com/api/v1/usage
# => {"ok": true, "credits_remaining": 87, "recent_calls": [...]}

Code examples — curl, Python & Node

The same duty estimate in three languages. Every example uses the live production base URL and works with an anonymous (free) request; add your X-API-Key header to receive metered responses with credits_remaining.

Python (stdlib only)

import json
from urllib.parse import urlencode
from urllib.request import urlopen

BASE = "https://exportsonar.com"
params = urlencode({"hs": "0101.30.00.00", "origin": "CN", "value": "1000"})
with urlopen(f"{BASE}/api/v1/tariff?{params}") as resp:
    data = json.load(resp)

rate = data["rate"]
print(rate["basis"], rate["duty_usd"])
# => percent 68.0

Node.js (18+, fetch built in)

const BASE = "https://exportsonar.com";
const params = new URLSearchParams({
  hs: "0101.30.00.00", origin: "CN", value: "1000",
});
const resp = await fetch(`${BASE}/api/v1/tariff?${params}`, {
  headers: { "X-API-Key": process.env.EXPORTSONAR_KEY },
});
if (!resp.ok) throw new Error(`API ${resp.status}`);
const data = await resp.json();
console.log(data.rate.basis, data.rate.duty_usd);
// => percent 68.0

curl

curl "https://exportsonar.com/api/v1/tariff?hs=0101.30.00.00&origin=CN&value=1000"
# => {"query": {"hs": "0101.30.00.00", ...}, "rate": {"duty_usd": 68.0, ...}}
# metered variant: add -H "X-API-Key: $EXPORTSONAR_KEY"

Error codes

HTTPCodeMeaning
400MISSING_PARAMa required query parameter is absent or blank
400INVALID_VALUEvalue/qty is not a finite positive number
401INVALID_API_KEYunknown or malformed X-API-Key
402INSUFFICIENT_CREDITSmetered balance exhausted
404HTS_NOT_FOUNDno HTS line matches after suffix fallback

API FAQ

Do I need an account?

No — anonymous access is unlimited and signup-free; a key only adds metering.

What does it cost?

$0.06 per successful call against prepaid credits; anonymous calls are free.

Unknown HS code?

404 HTS_NOT_FOUND, after automatic 8→10 digit suffix fallback.

Data provenance?

Official USITC Harmonized Tariff Schedule export plus Chapter 99 remedy provisions.