API Documentation

Integrate Codici HS code lookups into your systems using our REST API.

Base URL

https://api.codi.ci

Authentication

Include your API key in every request via the api-key header:

Authorization: api-key YOUR_API_KEY

Or as a query parameter: ?api_key=YOUR_API_KEY

Manage API keys in your account.

Endpoints

GET /v1/lookup

Look up an HS code for a single product description.

ParameterRequiredDescription
descriptionrequiredProduct description in any language
regionoptionalCustoms region (default: global). Options: global, usa, european_union, great_britain, canada, china, japan, australia, saudi_arabia, faroe_islands
languageoptionalResponse language (default: en). Options: en, nl, fr, et, fo
GET https://api.codi.ci/v1/lookup?description=MacBook+Pro+16&region=usa

POST /v1/lookup-batch

Classify up to 100 product descriptions in a single call. The response is an array of result objects in the same order as the descriptions you sent.

Billing counts lookups, not API calls. Each description in the batch is one lookup against your monthly allowance, so a call containing 100 descriptions uses 100 lookups — batching saves round trips and time, not cost.

curl -X POST https://api.codi.ci/v1/lookup-batch \ -H "api-key: YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"descriptions":["MacBook Pro","Organic champagne"],"region":"usa"}'

GET /v1/balance

Where you stand this month: your plan, how many lookups it includes, how many you have used, how many remain, and any extras accrued beyond the allowance.

GET https://api.codi.ci/v1/balance

GET /v1/history

Your recent API usage records. This is metadata only — when each lookup happened, from which key and which IP. We never store the descriptions you send or the results we return, so there is no query content to retrieve here.

GET https://api.codi.ci/v1/history

Response format

Every lookup comes back in a signed envelope. The data object holds the request echo, an anonymous requestor reference, the classification result and our platform details. hmac is an HMAC-SHA256 signature over data, so a saved result can be proven to have come from us, unaltered — paste it into the verification page to check.

result_not_used sits deliberately outside data and is therefore not covered by the signature. It carries fields we have not yet curated into result and will shrink over time, so treat it as transitional.

Field shapes do not change with the region you request. confidence and each alternative's likelihood are fractions between 0 and 1 (so 0.9 means 90% confident).

Codes and notation

hs_code is the six-digit WCO Harmonized System code, written xxxx.xx everywhere. hts_code is the full national code, written the way that authority writes it:

RegionCodeNotationExample
European UnionCombined Nomenclature (8) / TARIC (10)digits only88040000
Great BritainUK commodity code (up to 10)digits only8804000000
United StatesHTSUS (10)xxxx.xx.xx.xx8211.92.90.30
Other regionsnational scheduledotted pairs3901.20.00.99.999

Compare codes on their digits, not their punctuation — strip everything that isn't a digit and the values are directly comparable across regions.

Verifying the signature yourself

You do not need to keep our exact JSON. To reproduce the signature: take the data object, sort every key alphabetically at every level, trim leading and trailing whitespace from every string value, serialise it compactly, and compute HMAC-SHA256 over that with your shared secret. Key order, indentation and stray whitespace therefore make no difference — only the field values do. result_not_used sits outside data and is deliberately not signed.

{ "data": { "request": { "description": "MacBook Pro 16", "region": "usa", "language": "en", "requested_at": "2026-07-27T09:14:02+00:00" }, "requestor": { "reference": "9BJ9FDRT" }, "result": { "hts_code": "8471.30.01.00", "hs_code": "8471.30", "confidence": 0.9, "characteristics": { "essential_character": "Portable automatic data processing machine", "material": "Mixed materials", "is_physical_item": true }, "classification_breakdown": [ { "depth": 0, "code": "84", "label": "Chapter", "text": "Nuclear reactors, boilers, machinery..." }, { "depth": 1, "code": "8471", "label": "Heading", "text": "Automatic data processing machines..." }, { "depth": 4, "code": "8471.30.01.00", "label": "Full classification (10-digit)", "text": "Portable automatic data processing machines..." } ], "reasoning": "The item is an automatic data processing machine...", "reasoning_detailed": "Main category: ...\n\nKey factors:\n• ...\n\nAssumptions:\n• ...", "alternatives": [ { "hts_code": "8471.41.0150", "hs_code": "8471.41", "likelihood": 0.05, "reasoning": "..." } ] }, "platform": { "name": "Codici B.V.", "url": "https://portal.codi.ci", "version": "1.0", "verify_url": "https://portal.codi.ci/?page=verify" } }, "result_not_used": { "initial_classification": "8471.30", "hs_description": "Laptop computer, Apple MacBook Pro", "hs_description_localized": null, "chapter": "Nuclear reactors, boilers, machinery...", "additional_flags": ["FD1"], "description_improvement_suggestion": null, "suggested_description": null, "enhancement_attempted": false, "algorithm_version": 75, "processed_at": "2026-07-27T09:14:01.695Z", "cost": 0 }, "hmac": "3b64eeba3ff1e1b485a015bc1ba510a482c47d8da8bae34958cdad1fcd697583" }

cost is what this one lookup added on top of your fixed monthly fee: 0 while you are inside your allowance, your plan's per-extra-lookup price once past it. /v1/lookup-batch returns an array of these objects, one per description.

Error responses

HTTP statusCodeMeaning
400missing_param / invalid_param / invalid_json / too_manyMissing or invalid parameters (too_many = more than 100 descriptions in one batch)
401missing_key / invalid_key / key_revokedMissing, unknown or revoked API key
402no_planNo plan is active on the account, so lookups are unavailable — contact us to get set up
429rate_limitRate limit exceeded
500upstream_errorInternal error (upstream provider or system)

Going over your included lookups is never an error — extra lookups are simply charged at your plan's per-lookup rate and appear on that month's invoice.

Not set up yet? Talk to us and we'll put you on the right plan and get your API keys issued.