For developers

How AI agents classify products and compute landed cost

A developer's guide to PortRobin's customs API and MCP server: turn a product description into a sourced HTS code and landed cost an AI agent can trust.

March 19, 2026 · 11 min read

Server racks in a data centre, representing the infrastructure behind a customs API used by AI agents

Photo by panumas nikhomkhai on Pexels

Ask a general-purpose language model for an HS code and it will give you one — confidently, instantly, and quite often wrong. Ask it for a duty rate and it does the same thing, because that's what language models do by default: produce the most statistically plausible answer, not the verified one. For a chatbot, that's a minor annoyance. For an AI agent about to file a customs entry or price a product for a buyer, a fabricated HTS code or a stale Section 301 rate is the kind of error that shows up as a CBP penalty notice three months later.

This is a guide for developers building AI agents, and for the agents themselves reading it: how to turn a plain-English product description into a sourced HS/HTS code and a full landed-cost breakdown, using PortRobin's public JSON API and its MCP server, without letting the model invent a single number it shouldn't.

The two-part problem: classification vs rating

Getting from "product" to "landed cost" is really two separate jobs with different trust models. Classification — turning "men's cotton hoodie" into 6110.20.2079 — is a judgment task. It benefits from AI, provided the model is grounded in the actual heading text and the General Rules of Interpretation rather than pattern-matching on vibes. Rating — turning that code plus a country of origin into a duty percentage — is a lookup task, and there is exactly one acceptable source for a duty figure: the current published schedule, not a model's training data.

PortRobin's engine keeps that split explicit at the architecture level. The classification endpoint calls an AI provider, when one is configured, to reason about candidate codes and explain its match. Once a code is chosen, every dollar figure attached to it — the general rate, Section 301/232/IEEPA measures, MPF, HMF — comes from a maintained dataset of record, never the model's output. The two paths never cross.

The rule that makes this safe for automated use: the model may propose a code and explain its reasoning, but the rate always comes from the dataset. A code with no verified rate returns null and a "verify on the HTS" flag, not a plausible-looking number.

Start free

Why build a customs API for AI agents?

Import compliance is an unusually good fit for agentic automation, and a bad fit for an LLM working alone. It's a good fit because the task is repetitive, structured and high-volume — a checkout app estimating landed cost might need a classification for every new SKU a merchant lists. It's a bad fit for an unaided model because the underlying data changes constantly. Section 301 lists get amended, IEEPA measures get added or suspended, and the $800 de minimis exemption has moved more than once in the past two years. A model trained months ago simply doesn't know that.

A dedicated customs API solves that by putting a live, sourced dataset behind a stable interface the agent calls at run time, instead of relying on frozen training data. Picture a three-person team building a Shopify app that shows shoppers an estimated landed cost before checkout. They don't want to hand-maintain a tariff table for forty thousand SKUs across a dozen origin countries — they want to call one endpoint with a description and an origin, and get back a number refreshed every time a merchant adds a new listing.

See every endpoint, the MCP tool list, and how llms.txt fits together on one page.

PortRobin for developers

Classifying a product with the HS code classification API

The classification endpoint takes a product description — and, optionally, a country of origin — and returns ranked HTS candidates rather than a single answer. Each candidate carries the heading text, a plain-English gloss of what it covers, and the reasoning behind the match, so your agent can present the top result, ask a clarifying follow-up question ('is this knit or woven?'), or fall back to a broader heading when confidence is low. That's the same workflow a human classifier follows; the API just runs it in under a second.

  • Request: a description string ("women's knit cotton t-shirt") and an optional two-letter origin code.
  • Response: an array of candidates, each with a code, a confidence score, and the reasoning behind the match.
  • Each candidate also carries its sourced general rate, so you don't need a second call just to see the headline duty.
  • No AI provider configured on your account? The endpoint degrades to deterministic keyword matching and says so explicitly via a needsProvider flag — it never silently guesses.

Request/response schema, rate limits and a live curl example for the classify endpoint.

Classification API docs

Computing landed cost with the API

Once you have a resolved HTS code, pass it — with the customs value, origin, freight, insurance and transport mode — to the landed-cost endpoint. It looks up the base rate, layers on the Section 301, 232 and IEEPA measures that currently apply to that origin, adds the Merchandise Processing Fee and, for ocean freight, the Harbor Maintenance Fee, and returns an itemised breakdown. Every line is tagged with a source and a verification date, and any rate the dataset can't confirm comes back null rather than estimated.

That itemisation matters more to an agent than a headline total does. An agent that only gets "landed cost: $8,255" can't explain where the number came from if a user pushes back. An agent that gets product cost, freight, base duty, Section 301 duty, MPF and HMF as separate sourced lines can answer the follow-up question — usually "why is duty so high" — without another round trip.

Inputs, the itemised breakdown schema, and the honesty flags for the landed-cost endpoint.

Landed-cost API docs

What's the difference between the REST API and the MCP server?

PortRobin exposes the same underlying engine two ways, and most teams will end up using both. The REST API is a set of plain JSON endpoints you call from your own backend or app — the natural choice if you're building a checkout widget, a spreadsheet plugin, or a cron job that revalidates SKUs overnight. The MCP server exposes the identical capabilities as tools an agent framework can call natively — the natural choice when the caller is a conversational agent (Claude, or any client that speaks the Model Context Protocol) rather than your own code.

REST API vs MCP tools for calling PortRobin's customs engine
AspectREST APIMCP tools
TransportPlain HTTPS, JSON request and response bodiesJSON-RPC 2.0 over Streamable HTTP at /api/mcp
Best forYour own backend, app or scheduled jobAn agent framework calling tools natively mid-conversation
DiscoveryRead the endpoint docs or llms.txtCall tools/list once and get every tool's schema back
AuthNone required; sign in for higher rate limitsSame — none required, same rate limits apply
Example callPOST /api/classify with a descriptiontools/call with name: "classify_product"
OutputJSON body with candidates, sourced rate, disclaimerThe same JSON, wrapped as MCP text content

Either way, the response carries the identical sourced-or-null contract, so an agent reasoning about whether it has a trustworthy number behaves the same regardless of which transport it used to get there. PortRobin's MCP server currently exposes five tools:

  • classify_product — a plain-English description in, ranked HTS candidates with reasoning and sourced rates out.
  • lookup_duty — an HTS code and origin in, the base rate plus stacking Section 301/232/IEEPA measures out.
  • compute_landed_cost — customs value, code and origin in, an itemised sourced breakdown (duty, MPF, HMF, freight, insurance) out.
  • get_hts_code — one HTS code in, its official description, general rate and applicable measures out, all cited.
  • search_hts — a keyword or partial code in, matching HTS lines with their general rates out.

Client config, the initialize handshake and the full tool schemas for the MCP server.

Connect the MCP server

How does llms.txt help AI agents discover PortRobin?

llms.txt is an emerging convention — a plaintext file at the root of a site, written for language models rather than search crawlers, that summarises what the site does and where its machine-readable surfaces live. PortRobin's llms.txt lists every REST endpoint, every MCP tool, the honesty contract, and the free tools that need no login, in a format an agent can parse in a single pass rather than scraping rendered HTML. It's the difference between an agent guessing at your API shape from a marketing page and an agent reading a spec.

This matters more than it sounds. As more traffic arrives via an AI agent acting on a user's behalf rather than a person clicking a search result, agent-readable output stops being a nice-to-have and starts being the primary interface. A customs API only a human can discover, by reading prose on a docs page, is invisible to an agent scanning llms.txt files across candidate providers to decide which one to call.

The machine-readable index of every endpoint, MCP tool and free tool an agent can use.

Read llms.txt

More on the llms.txt convention and why it matters for agent-facing sites.

What is llms.txt and MCP for customs data?

Why the honesty contract matters for agents

As one licensed customs broker put it during a recent CBP trade compliance webinar, the classifications that cause real problems are rarely the obviously wrong ones — they're the confident-sounding wrong ones nobody double-checked before filing.

An agent is only as trustworthy as the worst number it will confidently repeat. If your agent calls a source that fills gaps with plausible guesses, every downstream decision it makes — a quoted landed cost, a sourcing recommendation, an entry it helps prepare — inherits that risk silently. Returning null instead of a fabricated rate lets the agent do the right thing instead: flag the uncertainty to the user, suggest a binding ruling request, or route the case to a licensed customs broker. That's the difference between an agent that helps an importer and one that gets them fined.

Section 301, 232 and IEEPA measures change often enough that any rate you hard-code today can be wrong within weeks. Build your agent to read the verifiedOn date on every response and treat anything older than your own tolerance as due for a refresh — don't cache a duty figure indefinitely.

Start free

None of this is legal, customs or tax advice, and nothing an agent generates from these endpoints substitutes for a CBP ruling or a licensed customs broker's review before you actually file an entry. Treat every response as an informational estimate to be verified, not a filing-ready determination.

The schedule of record every duty figure traces back to — confirm your line before you file.

Open the USITC HTS

CBP's guidance on binding rulings, entry filing and the penalties for misclassification.

CBP.gov

USTR's current Section 301 actions and exclusion lists by origin.

USTR Section 301 actions

Evaluating options? A comparison of the classification and duty APIs available to developers right now.

Best HS code classification APIs, compared

What is a customs API?

A customs API is a programmatic interface that returns HS/HTS classification, duty rates and landed-cost figures as structured JSON instead of a web page, so an app or AI agent can call it directly. A well-built one sources every rate to an official schedule and marks anything unverified, rather than letting a model guess.

Can an AI agent safely rely on tariff data from an API instead of a language model's own knowledge?

Yes, provided the API separates classification (a judgment task suited to AI reasoning) from rating (a lookup task that must come from a maintained dataset, not the model). An agent that calls a sourced API and treats null as "unverified" rather than filling the gap itself avoids the main failure mode — a confidently fabricated duty rate.

Should I use the REST API or the MCP server for my AI agent?

Use the MCP server if your agent framework already speaks the Model Context Protocol and you want it to call tools natively mid-conversation; use the REST API if you're calling from your own backend, a script, or an app that isn't itself an LLM agent. Both return the identical sourced JSON, so you can start with one and add the other later without changing your data model.

Is there a free HS code classification API?

PortRobin's classification, search, HTS lookup, duty and landed-cost endpoints are public, unauthenticated and CORS-enabled with no API key required, so you can call them directly from a browser or a server for free; signing in raises the daily rate limits on top of the same open surface.

What is llms.txt and why does a customs API need one?

llms.txt is a plaintext file, conventionally served at a site's root, that summarises what a site or API does in a format language models and agents can parse directly rather than scraping rendered pages. For a customs API it matters because it lets an agent discover every endpoint, MCP tool and free tool in one read, which is how agents increasingly decide which provider to call on a user's behalf.

Get an API key, connect the MCP server, and classify your first product programmatically today.

Start building free

Classify a product and see its real duty

Describe any product to get its HS/HTS code with the reasoning, the sourced duty rate including Section 301 and 232, and the full landed cost.