Declarant API
Search and classify across 5,612 HS6 subheadings, resolve broad official tariff schedules across 12 priced destinations, and calculate duty, import VAT or GST, de minimis relief and border charges.
Overview
Classification results include the working. Each candidate code is returned with the General Rules of Interpretation that were applied, the product feature that decided the heading, a confidence figure, and the codes that ranked below it. Where a description is too vague to classify safely, the missing_information field lists the attributes that would settle it.
Landed-cost results are itemised. Duty rates, de minimis thresholds and import rules each carry the schedule they came from and the date that schedule was current. Valuation basis, tax base and every individual charge are returned separately, so a total can be checked against a broker invoice line by line.
422 with national choices.
valuation.duty_base_method.
Authentication
Send your RapidAPI key on every request. Subscribing to any plan, including the free tier, issues one.
X-RapidAPI-Key: your-key-here
X-RapidAPI-Host: declarant.p.rapidapi.com
GET /v1/health requires no key, so uptime monitors can reach it. Every other endpoint requires one.
Quickstart
Classify a product and price it into the United States.
cURL
curl -X POST 'https://declarant.p.rapidapi.com/v1/landed-cost' \
-H 'X-RapidAPI-Key: YOUR_KEY' \
-H 'X-RapidAPI-Host: declarant.p.rapidapi.com' \
-H 'Content-Type: application/json' \
-d '{
"hs_code": "6109.10",
"origin": "BD",
"destination": "US",
"goods_value": 4200,
"freight": 380,
"insurance": 45,
"currency": "USD",
"quantity": 600,
"transport_mode": "ocean",
"entry_type": "formal"
}'
JavaScript
const res = await fetch('https://declarant.p.rapidapi.com/v1/classify', {
method: 'POST',
headers: {
'X-RapidAPI-Key': process.env.RAPIDAPI_KEY,
'X-RapidAPI-Host': 'declarant.p.rapidapi.com',
'Content-Type': 'application/json',
},
body: JSON.stringify({
description: "Men's crew neck t-shirt, 100% combed cotton jersey",
destination: 'US',
origin: 'BD',
top_k: 3,
}),
});
const { candidates, missing_information } = await res.json();
console.log(candidates[0].hs_code_formatted); // 6109.10
console.log(candidates[0].confidence); // 0.91
console.log(candidates[0].gri_applied); // ["GRI 1", "GRI 6"]
Python
import os, requests
r = requests.post(
"https://declarant.p.rapidapi.com/v1/classify",
headers={
"X-RapidAPI-Key": os.environ["RAPIDAPI_KEY"],
"X-RapidAPI-Host": "declarant.p.rapidapi.com",
},
json={
"description": "Stainless steel vacuum insulated water bottle, 750ml",
"destination": "GB",
"top_k": 3,
},
timeout=30,
)
r.raise_for_status()
top = r.json()["candidates"][0]
print(top["hs_code_formatted"], top["confidence"], top["rationale"])
Errors
Every non-2xx response uses the same envelope. Branch on error.code, which is stable. The message text may be reworded between releases.
{
"error": {
"code": "plan_upgrade_required",
"message": "Batch classification is not available on the BASIC plan. Upgrade to PRO or above.",
"upgrade_url": "https://rapidapi.com/declarant/api/declarant/pricing",
"request_id": "0f3c1a2e-..."
}
}
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Validation failed. details lists the offending fields. |
| 401 | unauthorized | Missing or unrecognised key. |
| 403 | plan_upgrade_required | Valid request, but beyond the plan's entitlements. |
| 404 | not_found | The HS code, market or route is not in the dataset. |
| 422 | calculation_requires_input | A national code or schedule-specific quantity is required to avoid guessing. |
| 429 | rate_limit_exceeded | Burst limit hit. Honour Retry-After. |
| 502 | upstream_error | The reasoning layer was unavailable for an operation that cannot safely use lexical fallback. |
Include request_id when reporting a problem. It appears in every response body and in the X-Request-Id header.
Plans and limits
RapidAPI meters the monthly allowance. Each plan also carries a short-window burst limit, which caps how fast a single client can call the service.
| Plan | Requests / month | Burst / 10s | Batch size | Candidates |
|---|---|---|---|---|
| Basic — free | 100 | 5 | — | 3 |
| Pro | 2,500 | 30 | 25 | 5 |
| Ultra | 15,000 | 80 | 100 | 8 |
| Mega | 100,000 | 200 | 250 | 10 |
GET /v1/me returns the entitlements the gateway resolved for your key.
POST /v1/classify
Ranks candidates from the 5,612-subheading HS6 nomenclature against a product description and explains each result.
Request
| Field | Type | Notes |
|---|---|---|
description required | string | What the product is. Material, construction and function determine the heading. |
material | string | Fibre or material composition. For textiles and footwear this often decides the rate on its own. |
intended_use | string | What the article is for. Two physically similar goods can sit in different chapters on this basis. |
origin, destination | string | ISO 3166-1 alpha-2. |
top_k | integer | 1–10, capped by plan. Default 3. |
Response
{
"candidates": [
{
"hs_code": "610910",
"hs_code_formatted": "6109.10",
"description": "T-shirts, singlets and other vests, of cotton, knitted or crocheted",
"chapter": "61",
"heading": "6109",
"confidence": 0.91,
"rationale": "Knitted construction and cotton fibre content place the article in
heading 6109; the cotton subheading follows at GRI 6.",
"gri_applied": ["GRI 1", "GRI 6"],
"statistical_unit": "doz."
}
],
"method": "ai_assisted",
"missing_information": [],
"shortlist_size": 18,
"cached": false,
"data_as_of": "2026-07-21"
}
method before relying on a result.
ai_assisted means the reasoning layer ran. lexical means it was unavailable and results were ranked on text match alone. Confidence figures on that path are capped and should be read as weak signals rather than classifications.
POST /v1/batch/classify
Classifies up to 250 products in one call. Available on Pro and above. A failure on one item does not fail the batch: each result carries its own status of ok, no_match or error, and the response ends with a summary count.
{
"items": [
{ "id": "SKU-1001", "description": "Stainless steel vacuum insulated water bottle, 750ml" },
{ "id": "SKU-1002", "description": "Bluetooth over-ear headphones with active noise cancelling" }
],
"destination": "GB",
"top_k": 1
}
POST /v1/landed-cost
Calculates the cost of importing a consignment into a destination market. Supply hs_code if you know it. Supply description instead and the goods are classified first, in which case the response includes that classification and flags that the code was inferred rather than given. Description-only pricing requires AI-assisted classification; if the reasoning layer is unavailable, this route returns 502 instead of converting a weak lexical match into a duty estimate.
| Field | Type | Notes |
|---|---|---|
hs_code / description | string | One of the two is required. |
origin, destination required | string | ISO 3166-1 alpha-2. |
goods_value required | number | Commercial value excluding freight and insurance. |
currency | string | ISO 4217. Default USD. |
freight, insurance | number | Default 0. Affects the duty base in CIF markets. |
quantity | integer | Drives per_unit_landed_cost. |
weight_kg, volume_liters | number | Used for national formulas stated per kilogram or liter. |
customs_quantity, customs_quantity_unit | number, string | Supply together for a schedule-specific measure. The unit must exactly match /v1/national-lines. |
transport_mode | enum | air, ocean, road, rail, courier. Some fees are ocean-only. |
entry_type | enum | formal or informal. Formal entries attract processing fees. |
claim_preference | boolean | See below. Default false. |
claim_preference defaults to false.
A preferential rate under an agreement such as USMCA is only usable if the goods satisfy the product-specific rule of origin and the importer holds a valid certificate at the time of entry. Most shipments move without one, so defaulting to the preferential rate would understate their cost. Set it to true once you hold the certificate. Either way the response names the programme, the certificate requirement, and what claiming it would save.
Response shape
The response is grouped so each figure can be checked on its own:
valuation— goods, freight, insurance, CIF, and the duty and tax bases with the method used to derive each.duty— rate, amount, programme, whether de minimis relieved it, and any additional duties that stack on top.fees— each country-specific fee as its own line, with the rate, floor and ceiling that produced it.excluded_fees— fees that are charged on the entry but are denominated in another currency, and so are absent fromtotals. Normally empty; see the note below.tax— import VAT or GST, its base, and whether relief applied.de_minimis— the thresholds, the assessed value, and any FX rate used to compare across currencies.provenance— the source schedule and as-of date for every input.notes— conditions that materially affect the figures returned.
excluded_fees instead of estimating it, and totals excludes it. Quote US entries in USD and Australian entries in AUD for a complete total.
GET /v1/hs/search
Text search across official subheading wording and the vocabulary merchants actually use. Suitable for building a code picker. For a classification you can stand behind, use /v1/classify.
GET /v1/hs/search?q=insulated%20water%20bottle&limit=10
GET /v1/hs/{code}
Accepts 2, 4, 6, 8 or 10 digits, with or without separators. National 8/10-digit inputs resolve to their internationally harmonised HS6 parent. Returns the HS node, its hierarchy, children, and any safe standard rates loaded for that subheading.
GET /v1/hs/6109.10
GET /v1/hs/851762
GET /v1/hs/64
GET /v1/duty
Resolves the rate for an origin and destination pair. A rate specific to the origin country, which is how free-trade agreements and preference schemes are held, takes precedence over the standard rate. Additional duties charged on top are returned as separate figures rather than folded into one number.
GET /v1/duty?hs=64041190&origin=VN&destination=US
GET /v1/national-lines
Lists jurisdiction-specific legal tariff lines below HS6, their raw statutory formulas, and whether each formula is directly calculable. Use this endpoint when /v1/duty or /v1/landed-cost asks for a national code.
GET /v1/national-lines?hs=640411&destination=US&limit=25
GET /v1/countries
Returns 20 import-rule profiles. Each item includes landed_cost_supported and duty_rate_subheadings, so clients can distinguish the 12 destinations with loaded rates from reference-only profiles.
Data and provenance
Duty rates come from the published national schedules: the USITC Harmonized Tariff Schedule, EU TARIC, the UK Global Tariff, the Canada Customs Tariff and the Australian Customs Tariff. Import rules, meaning consumption tax rates and bases, de minimis thresholds and processing fees, come from the corresponding revenue and border authorities.
Every rate row and country record carries an as_of date and a source string. Both appear on any response that depends on them.
The classification index contains 5,612 HS6 subheadings and 1,228 headings from the official USITC 2026 Revision 12 export, released 21 July 2026. The US, UK, EU, Canadian and Australian source schedules contain 56,739 unique tariff lines, represented as 125,276 destination-specific records across all 12 priced markets. Of those records, 120,820 are directly calculable and 4,456 conditional or non-linear records remain reference-only. Import-rule profiles cover 20 destinations.
Caching
Classification results are cached for 30 days against a hash of the product facts, brand, origin, destination and requested candidate count. A cache hit returns X-Declarant-Cache: HIT and "cached": true.
Only ai_assisted results are cached. A lexical result is a degraded answer and is never held.
Scope and limitations
Declarant produces estimates for commercial planning: pricing, margin modelling, duty display at checkout, and catalogue pre-classification. It is not a customs broker, and its output is not customs, legal or tax advice. What is actually owed is determined by the customs authority of the importing country, on the goods presented and the schedule in force on the date of entry.
What the service does not cover:
- Compound and specific rates. A small number of subheadings, including certain watches and spirits, carry a per-unit component alongside the percentage rate. Where the stored figure approximates one, the subheading's
classification_notesays so. - Antidumping and countervailing duties. Not covered. These are specific to a case and an exporter, and can be many times the ordinary rate.
- Subnational tax. US state and local sales tax, Canadian PST, QST and HST, and equivalents elsewhere. These sit outside the customs entry.
- Temporary and trade-remedy tariffs. Section 232, Section 301, antidumping, countervailing and other country- or exporter-specific additional duties are not loaded. The response carries a
duty.surchargesfield for future data, but it is not a signal that those measures were checked. - Rules of origin. Declarant does not verify origin.
claim_preferenceis taken as an assertion by the caller.