# border.bot > border.bot classifies products to HS codes and calculates duties, taxes and landed cost for cross-border parcels, in a web dashboard, over a REST API and through an MCP server for Claude, ChatGPT, Codex, Cursor and other AI clients. --- # HS codes and landed cost for cross-border parcels > Classify products to HS and HTS codes and calculate duties, taxes and landed cost for cross-border parcels in a dashboard, over an API or in Claude via MCP. Source: https://border.bot Last updated: 2026-10-09 Paste a product page or describe the product. border.bot returns the tariff code for the destination country and the duty, import tax and fees due when the parcel arrives. [Create a free account](https://app.border.bot/signup) · [Try the free classifier](https://border.bot/tools/hs-code-classifier) ## How a shipment is handled The example below follows a Heavyweight crew-neck T-shirt made in Vietnam and shipped to Los Angeles, United States. ### Read the product page Paste a product URL or type a description. We read the title, brand, materials and price from the page and look for the country of origin in its product data or text. When the page doesn’t say where the item was made, we estimate it and show the evidence. - Product page: https://shop.example/products/heavyweight-tee - Title: Heavyweight crew-neck T-shirt - Material: 100% cotton jersey knit - Price: $24.00 - Made in: Vietnam, from “Made in Vietnam” on the product page ### Classify it for the destination The product is matched against the destination’s tariff: the 10-digit HTS for the US, 10-digit commodity codes for the UK and Canada, CN and TARIC codes for the EU, and the 6-digit HS code for other countries. Each level of the code comes with its official description and a confidence score. | Level | Code | Description | | --- | --- | --- | | Chapter | 61 | Articles of apparel and clothing accessories, knitted or crocheted | | Heading | 6109 | T-shirts, singlets, tank tops and similar garments, knitted or crocheted | | Subheading | 6109.10 | Of cotton | | Tariff line | 6109.10.00.12 | The 10-digit US statistical line the shipment is declared under | Confidence: High. ### Calculate duty, tax and fees Duty, import tax and customs fees are calculated for that code, origin and destination, one line per charge with the rate used. Added to the goods and shipping, they give the landed cost. | Line | Amount (USD) | Note | | --- | --- | --- | | Goods | 24.00 | From the product page | | Shipping | 6.50 | Your carrier rate | | Duty | 5.40 | For this code and origin | | Fees | 1.10 | Customs processing | | Taxes | 0.00 | No import tax on this item | | Landed cost | 37.00 | What the customer pays in total | _Illustrative figures. Rates change, so run the calculator for a current answer._ ### Charge it at checkout With the landed cost known, you can collect duty and tax at checkout so the customer pays nothing on delivery, and the customs declaration carries the right code and origin. Every result is saved in your account. Status: cleared and delivered to Los Angeles, United States. ## Classification Send a product description, a product page URL or both, with the destination country. You get the tariff code that country’s customs expects, the official description at each level of the code, a confidence score, the reasoning and the closest alternatives. Results with low confidence are flagged for review. For high-value or regulated goods, have a licensed customs broker confirm the code or ask customs for a binding ruling. | Destination | Tariff | Code | | --- | --- | --- | | United States | Harmonized Tariff Schedule (HTS) | 10 digits | | United Kingdom | UK Global Tariff | 10 digits | | European Union | Combined Nomenclature (CN) and TARIC | 8 or 10 digits | | Canada | Customs Tariff | 10 digits | | Other countries | Harmonized System (HS) | 6 digits | [Try the free classifier](https://border.bot/tools/hs-code-classifier) ## Landed cost Give an HS code, or a description to classify first, with the country of origin, the destination, the total goods value and the shipping cost. You get each duty, tax and fee line with the rate used, the de minimis check for the destination and the total in the destination’s currency. Measures that apply only under certain conditions are listed separately and not added to the total. Carrier brokerage and handling fees are not included. Destinations: United States, United Kingdom, Canada, European Union (all 27 member states). Other destinations are checked when you run a calculation, and you’re told if one isn’t covered yet. How a landed cost is built, with hypothetical rates of 10% duty and 20% VAT for a destination that charges duty on goods plus shipping: | Line | Calculation | Amount | | --- | --- | --- | | Goods | Invoice value | 100.00 | | Shipping | Carrier rate | 10.00 | | Customs value | Goods plus shipping | 110.00 | | Duty | 10% of the customs value | 11.00 | | Import VAT | 20% of customs value plus duty | 24.20 | | Landed cost | Goods, shipping, duty and VAT | 145.20 | [Try the free calculator](https://border.bot/tools/landed-cost-calculator) ## REST API Classify and calculate from your own systems: the checkout, the product catalogue, an ERP or shipping software. Requests and responses are JSON over HTTPS. ```bash curl https://api.border.bot/v1/classify \ -H "Authorization: Bearer $BORDERBOT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "description": "Heavyweight crew-neck T-shirt, 100% cotton jersey knit", "destinationCountry": "US", "originCountry": "VN" }' ``` Example response (trimmed): ```json { "result": { "hsCode": "6109100012", "hsCodeFormatted": "6109.10.00.12", "nomenclature": "us", "confidence": "high", "needsReview": false, "hierarchy": [ { "level": "chapter", "code": "61", "description": "Articles of apparel … knitted or crocheted" }, { "level": "heading", "code": "6109", "description": "T-shirts, singlets, tank tops …" }, { "level": "subheading", "code": "610910", "description": "Of cotton" } ], "alternatives": [ … ] }, "credits": { "charged": 1, "balance": 99 } } ``` - Authenticate with a workspace API key in the Authorization header. - Errors come back as JSON with a code such as insufficient_credits or rate_limited. - Repeating a request with the same idempotency key returns the first result without charging again. - Calls use the same credits as the dashboard and the MCP server. [Developer quickstart](https://border.bot/developers) · [API reference](https://border.bot/docs/api) ## Use border.bot from Claude, ChatGPT, Codex, Cursor and 30 other MCP clients Add the border.bot MCP server to your AI client and sign in with your border.bot account. The assistant can then classify products and calculate landed cost during a conversation. Each call uses credits from the workspace you pick when you connect. MCP server URL: `https://api.border.bot/mcp`. Setup guides: [Claude](https://border.bot/mcp#claude), [ChatGPT](https://border.bot/mcp#chatgpt), [Claude Code](https://border.bot/mcp#claude-code), [Codex](https://border.bot/mcp#codex), [Cursor](https://border.bot/mcp#cursor), [Visual Studio Code](https://border.bot/mcp#vscode), [Gemini CLI](https://border.bot/mcp#gemini-cli), [Gemini](https://border.bot/mcp#gemini), [GitHub Copilot CLI](https://border.bot/mcp#github-copilot-cli), [Perplexity](https://border.bot/mcp#perplexity), [Vibe Work](https://border.bot/mcp#mistral-vibe), [Cline](https://border.bot/mcp#cline). [Setup steps for all 34 clients](https://border.bot/mcp). ## Pricing Credits are prepaid and there is no subscription. A classification uses 1 credit and a landed-cost calculation 1 credit. New accounts get 10 credits free. Credits for a failed call are refunded automatically. ### Credit packs | Pack | Credits | Price | Per credit | Notes | | --- | --- | --- | --- | --- | | Starter | 100 | $19.00 | $0.19 | For trying border.bot on real shipments. | | Growth (most popular) | 500 | $79.00 | $0.16 | For growing stores shipping internationally every day. | | Scale | 2000 | $249.00 | $0.12 | For teams classifying whole catalogues. | | Volume | 10000 | $990.00 | $0.10 | For platforms and high-volume shippers. | ### What each action costs | Action | Cost | What it does | | --- | --- | --- | | Classification (Mini) | 1 credit | The fastest: search by meaning and words, then the reranker. No language model. | | Classification (Pro) | 1 credit | A model rewrites the listing in customs terms, the search stays in the chapters it names, and a model ranks the candidates by the rules of interpretation, with precedent rulings. Brand-only listings are identified on the web. | | Classification (Max) | 3 credits | The highest accuracy: an agent searches the tariff, walks its tree, reads rulings and identifies products on the web. | | Agency product code | 1 credit | Find the product code the destination’s import agency asks for. | | Landed cost calculation | 1 credit | Duties, taxes and fees for one HS code / origin / destination. | | Duty stacking | Free | Which duty lines apply to a code and origin, without a shipment. | | Product URL extraction | Free | Read a product page and extract title, brand, price and materials. | | Country of origin inference | Free | Infer where a product is made from page data and AI. | - New accounts get 10 credits free. - The free tools allow 3 free runs per visitor every 30 days, no account needed. Prices as of 2026-10-09. [See live pricing](https://border.bot/pricing). ## Free classifier, calculator and origin finder The free tools work without an account: 3 free runs per visitor every 30 days, shared between them. - [HS code classifier](https://border.bot/tools/hs-code-classifier) - [Landed cost calculator](https://border.bot/tools/landed-cost-calculator) - [Country of origin finder](https://border.bot/tools/country-of-origin-finder) ## Common questions ### What does border.bot do? It finds the HS code for a product and calculates the duty, import tax, fees and total landed cost of shipping it to another country. You can use it in the web dashboard, through the REST API, or from Claude, ChatGPT, Codex, Cursor and other AI clients through our MCP server. ### Which countries and tariff schedules do you cover? Classification returns 10-digit codes for the US (HTS), the UK and Canada, CN and TARIC codes for the EU, and the 6-digit HS code for every other destination. Landed cost calculation covers the US, the UK, Canada, all 27 EU member states and more destinations, checked when you run it. ### How accurate is the classification? Each result shows the official description at every level of the code, a confidence score, the reasoning and the closest alternatives, and low-confidence results are flagged for review. Treat it as a well-documented first answer. For high-value, regulated or disputed goods, have a licensed customs broker confirm it or ask the customs authority for a binding ruling. ### How does pricing work? You buy prepaid credit packs and there is no subscription. Each classification or landed-cost calculation uses credits, the cost of every action is listed on the pricing page, and credits for a failed call are refunded automatically. New accounts start with free credits. ### Can I use border.bot from Claude, ChatGPT, Codex or Cursor? Yes. Add our remote MCP server to your client, sign in with your border.bot account and choose which workspace pays. The assistant can then classify products and calculate landed cost in the conversation, using the same credits as the dashboard. The MCP page has setup steps for each supported client. ### Is the free classifier really free? Yes. The free HS code classifier, landed cost calculator and country of origin finder give each visitor a few runs without an account. Cloudflare Turnstile and a usage limit stop automated abuse. Create an account when you need more. ### What happens to the product data I send? We use it to produce the result and keep it in your workspace history so you can find it again. Payments are handled by Stripe and card details never reach our servers. The security page explains sign-in, API keys, MCP access and data handling in detail. ## Guides - [The EU’s €3 customs duty on parcels under €150](https://border.bot/blog/eu-3-euro-customs-duty): Since 1 July 2026 the EU charges a temporary €3 customs duty on low-value parcels, once per tariff classification. What it covers, who pays and how it adds up. - [US de minimis suspension: what changed for parcels](https://border.bot/blog/us-de-minimis-suspension): US de minimis has been suspended since 29 August 2025. The timeline, the June 2026 CBP rules, how parcels clear now and what ends on 1 July 2027. - [Classify products from Claude and ChatGPT](https://border.bot/blog/classify-products-with-mcp): Connect the border.bot MCP server to Claude, ChatGPT or Cursor, then classify products, check origin and estimate landed cost from a chat. Setup and tips. ## Create an account New accounts get 10 free credits. You get the dashboard, an API key and the MCP server, and you buy more credits when you need them. [Create a free account](https://app.border.bot/signup) --- # Free HS code, landed cost and origin tools > Free HS code classifier, landed cost calculator and country of origin finder for cross-border ecommerce. A few free runs per visitor, no account needed. Source: https://border.bot/tools Last updated: 2026-10-09 An HS code classifier, a landed cost calculator and a country of origin finder. They run on the same engine as the border.bot dashboard, API and MCP server, and they work without an account. ## HS code classifier Describe a product or paste a product URL and get the HS, HTS, CN/TARIC, UK or Canadian code for its destination, with official descriptions and confidence. [Classify a product](https://border.bot/tools/hs-code-classifier) ## Landed cost calculator Estimate duties, taxes and fees for parcels to the US, UK, Canada, the EU and more, from an HS code or a product description. [Calculate landed cost](https://border.bot/tools/landed-cost-calculator) ## Country of origin finder Paste a product URL or give a title, description or barcode, and get the likely country of manufacture with its probability, alternatives and evidence. [Find the country of origin](https://border.bot/tools/country-of-origin-finder) ## How free runs work Every visitor gets a small number of free runs, shared between the classifier, the calculator and the origin finder. Free runs are checked by Cloudflare Turnstile and counted per visitor, so they stay available for real people. Create an account for free credits and the full dashboard, API and MCP access. ## For AI agents Each tool exposes WebMCP tools to in-browser agents (`classify_product_free`, `calculate_landed_cost_free`, `find_country_of_origin`, `get_free_runs_remaining`). For automated or high-volume use, call the REST API or connect the MCP server instead. --- # Find the HS code for any product > Find the HS code for any product. Describe it or paste a product URL to get the US HTS, UK, EU CN or Canadian code with official descriptions and confidence. Source: https://border.bot/tools/hs-code-classifier Last updated: 2026-10-09 Describe a product or paste its product page URL and choose where it’s going. You get the code that destination’s customs expects, the official description at every level, a confidence score, the reasoning and the closest alternatives. ## Use the tool Open https://border.bot/tools/hs-code-classifier in a browser, describe the product or paste its URL, choose the destination (and origin if known) and submit. In-browser agents can call the WebMCP tool `classify_product_free` on that page. Supported outputs: US HTS (10-digit); Canadian Customs Tariff (10-digit); EU Combined Nomenclature / TARIC; UK Global Tariff (10-digit); Harmonized System (6-digit); National tariff. Every visitor gets a small number of free runs, shared between the classifier, the calculator and the origin finder. Free runs are checked by Cloudflare Turnstile and counted per visitor, so they stay available for real people. Create an account for free credits and the full dashboard, API and MCP access. ## How to find an HS code with border.bot 1. **Describe the product.** Write what the item is, what it’s made of and what it’s for. Or paste the URL of its product page and we’ll read the details from it. 2. **Choose the destination.** Pick the country the parcel is going to. The destination decides the tariff schedule: US HTS, the UK tariff, EU CN/TARIC, the Canadian tariff, or the 6-digit HS for everywhere else. 3. **Add the country of origin.** If you know where the product was made, add it. If you paste a product URL, we look for the origin on the page and show you what we found. 4. **Review the result.** Check the code against its official descriptions, the confidence score and the alternatives. Use “Calculate landed cost” to carry the code straight into the duty and tax calculator. ## What decides the code ### What it’s made of Material often decides the heading or subheading: a cotton T-shirt and a polyester one sit on different lines. For blends, the material that predominates by weight usually counts. ### What it does Function and intended use matter as much as appearance. A bag designed for a laptop and a bag designed for sport can classify differently even if they look alike. ### How it’s made Knitted versus woven apparel are separate chapters (61 and 62). Whether goods are finished, unfinished, assembled or in kit form also changes the answer. ### Who it’s for For clothing and footwear, men’s, women’s, children’s and babies’ goods often have their own lines at the 8- and 10-digit level. ### Sets, parts and accessories Goods put up in sets for retail sale, spare parts and accessories follow their own rules. A set is usually classified by the item that gives it its essential character, and parts often go with the machine they belong to. ### The destination The first six digits are shared worldwide. Digits seven to ten are set by each country, so the same product has a different full code in the US, the UK, the EU and Canada. ## Write a description customs can classify - Name the item plainly: “insulated stainless steel water bottle”, not a brand or a marketing name. - State the material and, for blends, the percentages. - Say what it’s for and who uses it (adult, child, professional). - Mention how it’s made when it matters: knitted or woven, moulded or machined. - For sets and kits, list every item in the set. ## Frequently asked questions ### What is an HS code? An HS code is the number customs uses to identify a product. The Harmonized System, maintained by the World Customs Organization, defines the first six digits; countries add more digits for their own tariffs and statistics. The code determines duty rates, import rules and trade statistics. ### What’s the difference between HS, HTS, CN and TARIC codes? HS is the shared 6-digit international system. The US extends it to the 10-digit Harmonized Tariff Schedule (HTS). The EU extends it to the 8-digit Combined Nomenclature (CN) and the 10-digit TARIC for import measures. The UK and Canada use 10-digit codes of their own. The first six digits match everywhere. ### Why does the code change with the destination? Because each country sets its own digits after the first six. The free classifier returns the code in the destination’s own format: US HTS, UK commodity code, EU CN/TARIC, Canadian classification number, or the 6-digit HS for other countries. ### Can I classify from a product URL? Yes. Paste the product page link and we read the title, description, materials, brand and price from the page, look for the country of origin, and classify from those details. Pages that block automated access may need a written description instead. ### What does the confidence score mean? It reflects how clearly the description points to one code. High confidence means the product fits one line well; medium or low means plausible alternatives exist, so review them or add detail such as material, use or construction. Results that need a human check are flagged. ### Is the result legally binding? No. It is guidance to help you declare goods correctly. The importer of record is responsible for the classification. For certainty on a specific product, ask a licensed customs broker or request a binding ruling from the destination’s customs authority. ### How many free classifications do I get? Each visitor gets a few free runs, shared between the free tools, and the page shows how many you have left. Create an account to keep going with free credits. --- # Calculate import duty, tax and landed cost > Estimate import duties, taxes, fees and total landed cost for parcels to the US, UK, EU, Canada and more. Enter an HS code or describe the product. Source: https://border.bot/tools/landed-cost-calculator Last updated: 2026-10-09 Enter an HS code, or describe the product and we’ll classify it first. Add the origin, destination, total goods value and shipping. You get every duty, fee and tax line with the rate used, and the total your customer pays to receive the parcel. ## Use the tool Open https://border.bot/tools/landed-cost-calculator in a browser, enter an HS code or describe the product, choose origin and destination (the US, UK, Canada, the EU-27 and more), add the total goods value, currency, shipping and quantity, and submit. In-browser agents can call the WebMCP tool `calculate_landed_cost_free` on that page. Every visitor gets a small number of free runs, shared between the classifier, the calculator and the origin finder. Free runs are checked by Cloudflare Turnstile and counted per visitor, so they stay available for real people. Create an account for free credits and the full dashboard, API and MCP access. ## How to calculate landed cost with border.bot 1. **Enter the HS code.** Type the product’s HS or HTS code. If you don’t know it, switch to “Describe the product” and we’ll classify it as part of the same run. 2. **Set origin and destination.** Choose where the goods were made and where they’re going. Origin decides preferential and additional duties; the destination decides the tariff, taxes and thresholds. 3. **Add value, shipping and quantity.** Enter the total goods value of the shipment and its currency, the shipping cost, the number of units and, if you have it, the weight. These decide the customs value that duties and taxes are charged on. 4. **Read the breakdown.** Review each duty, fee and tax line with its rate, the de minimis check, any conditional measures, and the total landed cost. ## What changes the total ### The HS code The code sets the base duty rate. A one-line difference in classification can change the duty from zero to double digits, so start from the right code. ### Country of origin Origin is where the goods were made, not where they ship from. It decides whether trade-agreement preferences apply and whether extra duties such as trade remedies are added. ### Customs value Some countries charge duty on the goods value alone; others include shipping and insurance to the border. The calculator applies the right basis for the destination. ### De minimis thresholds Low-value shipments may be exempt from duty, tax or both below a threshold that differs by country and changes over time. The result shows whether one applied. ### Import taxes VAT and GST are usually charged on the customs value plus duty, so duty raises the tax too. Some countries collect tax at checkout for low-value parcels instead of at the border. ### Fees and currency Customs processing fees and exchange rates move the total. Carrier brokerage or handling fees are set by each carrier and are not part of the government charges shown. ## Get a figure you can rely on - Use the code for the destination country, not a generic 6-digit HS code, when you have it. - Use the real transaction value of the goods, in the currency you invoice in. - Include shipping and insurance costs, because several destinations charge duty on them. - Re-check before large shipments: rates, thresholds and trade measures change. ## Frequently asked questions ### What is landed cost? Landed cost is the total cost of getting a product to the customer’s door: the goods, shipping and insurance, plus the duties, import taxes and customs fees charged on arrival. Knowing it lets you price correctly and avoid surprise bills on delivery. ### Which destinations does the calculator support? The United States, the United Kingdom, Canada, all 27 EU member states and more. The engine checks each destination live and tells you if one isn’t covered yet; you can always classify the product with the free classifier. ### What is de minimis? A de minimis threshold is the value below which a country waives duty, tax or both on an import. Thresholds differ by country, can apply to duty and tax separately, and change over time. The calculator checks the current rule for the destination. ### Why does the country of origin matter? Duty rates depend on where goods were made. Trade agreements can lower the rate for qualifying goods, while trade remedies and other measures can add duties for specific origins. Shipping from a warehouse in another country does not change the origin. ### Does the result include VAT, GST and sales tax? It includes import taxes charged at the border, such as VAT and GST, with the rate used. US state sales tax is not an import tax and is not included. ### Are carrier fees included? Government fees such as customs processing fees are included where they apply. Brokerage, disbursement or handling fees charged by carriers vary by carrier and contract, so they are not part of the result. ### Is the estimate guaranteed? No. It is an estimate based on the code, origin, values and the rules in force when you run it. Final charges are assessed by customs when the goods are declared, so check the result for high-value shipments. --- # Find where a product was made > Find where a product was made from its URL, title or barcode. Get the likely country of origin with its probability, alternatives and the evidence behind it. Source: https://border.bot/tools/country-of-origin-finder Last updated: 2026-10-09 Paste a product page URL, or give the title, description or barcode. You get the most likely country of origin with its probability, the other countries it could be, and every piece of evidence behind the answer. ## Use the tool Open https://border.bot/tools/country-of-origin-finder in a browser, paste a product page URL or enter a title, description or barcode (GTIN, UPC or EAN), optionally add the brand, materials and ship-from country, and submit. In-browser agents can call the WebMCP tool `find_country_of_origin` on that page. With an account, the REST API (`POST /v1/origin`, `/v1/origin/validate`, `/v1/origin/batch`) and the MCP server do the same. Every visitor gets a small number of free runs, shared between the classifier, the calculator and the origin finder. Free runs are checked by Cloudflare Turnstile and counted per visitor, so they stay available for real people. Create an account for free credits and the full dashboard, API and MCP access. ## How to find a product’s country of origin with border.bot 1. **Identify the product.** Paste the URL of its product page, or enter the title or a description. A barcode (GTIN, UPC or EAN) works on its own too. 2. **Add what you know.** Brand and materials help narrow the answer. If you know where the goods ship from, add it: it counts as weak evidence, because goods often ship from a different country than the one they were made in. 3. **Run the finder.** We read the product page for structured product data and “Made in” text, check the barcode prefix, and make an AI estimate only when the page doesn’t say. 4. **Check the evidence.** Read the likely country, its probability, the alternatives and what pointed where. When the result is flagged for review, confirm the origin with the supplier or the product label before you declare it. ## What points to a country ### Product page data Many shops publish a country of origin in the page’s structured product data, the same data search engines read. When it’s there, it is usually the strongest evidence. ### “Made in” text Product descriptions, specifications and care details often say “Made in Portugal” or “Imported”. We quote the text we found so you can check it. ### Where it ships from The ship-from country is weak evidence. Goods made in one country are often stocked and shipped from a warehouse in another, and shipping from there doesn’t change their origin. ### Barcode prefix The first digits of a GS1 barcode show which country’s GS1 office issued the brand’s company prefix. That is where the brand registered, not where the product was made, so it counts for little. ### AI estimate When nothing on the page names a country, an AI model estimates one from the product, brand and materials. An estimate alone is never given high confidence. ### What origin means for customs Country of origin is where the goods were made or, if more than one country was involved, where they were last substantially transformed into a new product. It is not where they ship from or where the brand is based. ## Get an answer you can rely on - Use the product page from the brand or manufacturer when you can; resellers often leave the origin out. - Add the barcode if you have it, but don’t treat its prefix as the country of manufacture. - Check the product label or packaging: a “Made in” mark there is better evidence than any estimate. - Ask the supplier for the origin on the commercial invoice or a certificate of origin before large shipments. - Preferential origin under a trade agreement has its own rules and needs supplier proof; this finder estimates where the goods were made. ## Frequently asked questions ### What is a country of origin? For customs, the country of origin is where goods were wholly obtained or made. When more than one country was involved, it is generally the country where the goods last underwent a substantial transformation, meaning processing that turned them into a new product. Customs uses it to set duty rates, apply trade measures and check marking rules. ### Is the country of origin where the parcel ships from? No. A product made in Vietnam and shipped from a warehouse in Germany still has Vietnam as its country of origin. That’s why the ship-from country only counts as weak evidence here. ### Does the barcode tell me where a product was made? No. A GS1 barcode prefix shows which national GS1 office issued the company’s prefix, which is usually where the brand registered. Products can be made anywhere, so the finder gives the prefix little weight. ### What does the probability mean? It is the finder’s estimate that the top country is right, given the evidence it found. The alternatives show the other countries it could be, each with its own probability. ### Why is my result flagged for review? A result is flagged when its probability is below the review threshold or when strong pieces of evidence point to different countries. The result says why in plain words. Confirm the origin with the supplier or the label before you declare it. ### Is the result legally binding? No. It is an estimate to help you declare goods correctly. The importer is responsible for the declared origin. For certainty, ask the supplier for documentation, consult a licensed customs broker, or request a binding origin ruling from the destination’s customs authority. ### Can I check many products at once? Yes, with an account. The REST API finds origins one product at a time or in batches of up to 50. The API and the MCP server can also check a declared origin against the evidence. ### How many free runs do I get? Each visitor gets a few free runs, shared between the free tools, and the page shows how many you have left. Create an account to keep going with free credits. --- # Pricing > Prepaid credit packs for HS classification and landed cost. Each action has a fixed credit cost, failed calls are refunded, and new accounts get free credits. Source: https://border.bot/pricing Last updated: 2026-10-09 Buy a credit pack, spend it on classifications and calculations, and top up when you need to. Credits are shared by everyone in your workspace and work the same in the dashboard, the API and the MCP server. ## Live pricing ### Credit packs | Pack | Credits | Price | Per credit | Notes | | --- | --- | --- | --- | --- | | Starter | 100 | $19.00 | $0.19 | For trying border.bot on real shipments. | | Growth (most popular) | 500 | $79.00 | $0.16 | For growing stores shipping internationally every day. | | Scale | 2000 | $249.00 | $0.12 | For teams classifying whole catalogues. | | Volume | 10000 | $990.00 | $0.10 | For platforms and high-volume shippers. | ### What each action costs | Action | Cost | What it does | | --- | --- | --- | | Classification (Mini) | 1 credit | The fastest: search by meaning and words, then the reranker. No language model. | | Classification (Pro) | 1 credit | A model rewrites the listing in customs terms, the search stays in the chapters it names, and a model ranks the candidates by the rules of interpretation, with precedent rulings. Brand-only listings are identified on the web. | | Classification (Max) | 3 credits | The highest accuracy: an agent searches the tariff, walks its tree, reads rulings and identifies products on the web. | | Agency product code | 1 credit | Find the product code the destination’s import agency asks for. | | Landed cost calculation | 1 credit | Duties, taxes and fees for one HS code / origin / destination. | | Duty stacking | Free | Which duty lines apply to a code and origin, without a shipment. | | Product URL extraction | Free | Read a product page and extract title, brand, price and materials. | | Country of origin inference | Free | Infer where a product is made from page data and AI. | - New accounts get 10 credits free. - The free tools allow 3 free runs per visitor every 30 days, no account needed. Prices as of 2026-10-09. [See live pricing](https://border.bot/pricing). ## Every pack includes - The dashboard, REST API and MCP server - Classification for the US, UK, EU, Canada and 6-digit HS worldwide - Landed cost for the US, UK, Canada, the EU-27 and more - Product URL reading and country-of-origin detection - Team members and API keys at no extra cost - Automatic refunds when a call fails ## Frequently asked questions ### What uses credits? Billable actions such as a classification or a landed-cost calculation. The table on this page lists every action and how many credits it uses; reading a product page and detecting its origin are listed separately. ### Is there a subscription or a minimum? No. You buy prepaid credit packs when you need them. There are no seats, no monthly fees and no minimum commitment. ### What happens if a call fails? Credits are taken in one atomic step just before the call runs. If it fails, they are refunded automatically and the refund shows up in your credit history. ### Do new accounts get free credits? Yes. Every new account starts with free credits, so you can try classification and landed cost in the dashboard, the API and the MCP server before you buy. ### Can my team share credits? Yes. Credits belong to the workspace. Everyone in it, and every API key and MCP connection tied to it, draws from the same balance. ### How do I pay? Securely through Stripe Checkout. Credits are added to your workspace as soon as Stripe confirms the payment. [Create a free account](https://app.border.bot/signup) --- # REST API for classification and landed cost > REST API for HS code classification and landed cost. Create an API key, send your first request with curl, and handle credits, errors and idempotent retries. Source: https://border.bot/developers Last updated: 2026-10-09 Call the classification and landed-cost engine behind the border.bot dashboard from your checkout, catalogue or shipping software. It is JSON over HTTPS with Bearer API keys and prepaid credits, and you don’t need an SDK. Base URL: `https://api.border.bot` · [API reference](https://border.bot/docs/api) ## Quickstart ### 1. Create an API key Sign in to the dashboard and create a key for your workspace. It starts with bb_live_ and is shown once, so store it in your secrets manager straight away. ### 2. Classify a product Send a description or a product URL with the destination country. Add the origin if you know it. ```bash curl https://api.border.bot/v1/classify \ -H "Authorization: Bearer $BORDERBOT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "description": "Heavyweight crew-neck T-shirt, 100% cotton jersey knit", "destinationCountry": "US", "originCountry": "VN" }' ``` ### 3. Read the result You get the code in the destination’s format, the official description at each level, a confidence score, the reasoning, alternatives, and the credits charged with your new balance. ```json { "result": { "hsCode": "6109100012", "hsCodeFormatted": "6109.10.00.12", "nomenclature": "us", "confidence": "high", "needsReview": false, "hierarchy": [ { "level": "chapter", "code": "61", "description": "Articles of apparel … knitted or crocheted" }, { "level": "heading", "code": "6109", "description": "T-shirts, singlets, tank tops …" }, { "level": "subheading", "code": "610910", "description": "Of cotton" } ], "alternatives": [ … ] }, "credits": { "charged": 1, "balance": 99 } } ``` ### 4. Calculate landed cost Pass the code, origin, destination, total goods value, currency and shipping cost to the landed-cost endpoint to get every duty, tax and fee line and the total. The API reference has the full request and response schemas. ## Concepts ### Authentication Send your key in the Authorization header as Bearer bb_live_…. Keys belong to a workspace and only a hash is stored, so a lost key can’t be shown again. Revoke it and create a new one. ### Credits Each billable call debits the workspace before it runs, in one atomic step, so a balance can never go negative. If the call fails, the credits are refunded automatically. Responses report what was charged and the balance left. ### Safe retries Send an idempotency key with a request and repeat it as often as you need: you get the original result back and are not charged twice. The API reference documents the header. ### Same engine as the dashboard The API, the dashboard, the MCP server and the free tools all run on the same classification and duty engine, with the same prices per action. ## Errors Errors return JSON with a stable machine-readable code and a human-readable message, and the HTTP status that matches the code. | Code | HTTP status | Meaning | | --- | --- | --- | | `invalid_input` | 400 | The request failed validation. The message names the field to fix. | | `unauthorized` | 401 | The API key is missing, malformed or revoked. | | `insufficient_credits` | 402 | The workspace balance is too low for this action. Top up in the dashboard. | | `forbidden` | 403 | The key is valid but not allowed to perform this action (a key without the scope the endpoint needs: details.reason is missing_scope). | | `not_found` | 404 | The resource or path doesn’t exist. | | `conflict` | 409 | A request with the same idempotency key is still running, or the change clashes with existing data. Wait and retry. | | `org_suspended` | 403 | The workspace is suspended. Contact support. | | `payload_too_large` | 413 | The request body is over 10 MB. Link to a photo instead of sending it inline, or split a bulk run. | | `version_retired` | 410 | The API version in the path has passed its sunset date. Move to the version the message names. | | `action_disabled` | 403 | This action is temporarily switched off. Try again later. | | `unsupported_country` | 422 | The destination isn’t covered for this action yet. The message says what is supported. | | `rate_limited` | 429 | Too many requests in a short period. Back off and retry. | | `upstream_error` | 502 | The engine couldn’t complete the request. Credits were refunded; retry. | | `upstream_timeout` | 504 | The engine took too long. Credits were refunded; retry. | | `internal` | 500 | Something went wrong on our side. Credits were refunded. | ## Coverage - US HTS (10-digit) - Canadian Customs Tariff (10-digit) - EU Combined Nomenclature / TARIC - UK Global Tariff (10-digit) - Harmonized System (6-digit) - National tariff Landed cost: United States, United Kingdom, Canada, European Union (all 27 member states). Other destinations are checked when you run a calculation, and you’re told if one isn’t covered yet. ## Prefer an AI assistant? Connect the [MCP server](https://border.bot/mcp) to use the same engine from Claude, ChatGPT, Codex, Cursor or another MCP client. --- # Connect border.bot to your AI tools > Connect border.bot to Claude, ChatGPT, Codex, Cursor, Visual Studio Code, Gemini and other MCP clients. Classify products and calculate landed cost from chat. Source: https://border.bot/mcp Last updated: 2026-10-09 Our remote MCP server lets AI assistants and coding agents classify products and calculate landed cost for you. Add one URL, sign in with your border.bot account, and choose which workspace pays. ## Server URL ```text https://api.border.bot/mcp ``` Streamable HTTP transport with OAuth 2.1. Your client finds the sign-in endpoints itself, so there is no API key to paste. ## Set up your client Steps for 34 clients, checked against each vendor’s own documentation on 7 October 2026. Menu names change between versions and plans; if one has moved, look for “connectors”, “integrations” or “MCP” in your client’s settings. - Assistants: [Claude](https://border.bot/mcp#claude), [ChatGPT](https://border.bot/mcp#chatgpt), [Gemini](https://border.bot/mcp#gemini), [Perplexity](https://border.bot/mcp#perplexity), [Vibe Work (formerly Le Chat)](https://border.bot/mcp#mistral-vibe), [Raycast](https://border.bot/mcp#raycast), [LM Studio](https://border.bot/mcp#lm-studio) - Editors and IDEs: [Cursor](https://border.bot/mcp#cursor), [Visual Studio Code](https://border.bot/mcp#vscode), [Devin Desktop (formerly Windsurf)](https://border.bot/mcp#devin-desktop), [Visual Studio](https://border.bot/mcp#visual-studio), [Cline](https://border.bot/mcp#cline), [Zed](https://border.bot/mcp#zed), [Kiro](https://border.bot/mcp#kiro), [Replit](https://border.bot/mcp#replit), [v0](https://border.bot/mcp#v0), [JetBrains Air](https://border.bot/mcp#jetbrains-air), [TraeCode](https://border.bot/mcp#trae) - Command line: [Claude Code](https://border.bot/mcp#claude-code), [Codex](https://border.bot/mcp#codex), [Gemini CLI](https://border.bot/mcp#gemini-cli), [GitHub Copilot CLI](https://border.bot/mcp#github-copilot-cli), [OpenCode](https://border.bot/mcp#opencode), [Warp](https://border.bot/mcp#warp), [Junie CLI](https://border.bot/mcp#junie), [Amp](https://border.bot/mcp#amp), [goose](https://border.bot/mcp#goose), [Qwen Code](https://border.bot/mcp#qwen-code), [Kimi Code CLI](https://border.bot/mcp#kimi-cli) - Automation: [Microsoft Copilot Studio](https://border.bot/mcp#copilot-studio), [n8n](https://border.bot/mcp#n8n), [Zapier](https://border.bot/mcp#zapier), [Make](https://border.bot/mcp#make), [Postman](https://border.bot/mcp#postman) Clients that aren’t listed can connect too, as long as they support remote MCP servers with OAuth. Point yours at the server URL; it finds the authorization server and opens the border.bot sign-in page, where you approve the connection and choose the workspace it may bill. ## Assistants Chat apps where you add border.bot once and then ask for a code or a landed cost in any conversation. ### Claude By Anthropic. Free, Pro, Max, Team and Enterprise (Free is limited to one custom connector). On Team and Enterprise an Owner adds it for the organization. 1. Open Customize › Connectors (claude.ai/customize/connectors), click “+ Add”, then “Add custom connector”. 2. Enter border.bot as the name and `https://api.border.bot/mcp` as the remote MCP server URL, then click “Continue”. 3. Review the authentication settings Claude detected and click “Continue”; under Authentication choose “Sign in now” and under OAuth client “Use Claude’s published identity (Recommended)”, then click “Add”. 4. Sign in to border.bot and approve access in the window that opens. 5. In a chat, open “+” › “Connectors” and switch border.bot on. Official setup guide: https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp Notes: One connector covers claude.ai, Claude Desktop, Cowork and the mobile apps. Claude connects from Anthropic’s cloud, so the URL must be publicly reachable. Team/Enterprise: an Owner adds it under Organization settings › Connectors (“Add” › “Custom” › “Web”), then each member clicks “Connect” in Customize › Connectors. ### ChatGPT By OpenAI. ChatGPT on the web. OpenAI’s help center lists full MCP (read and write tools) for Business, Enterprise and Edu (beta) and read/fetch-only custom MCP for Pro in developer mode; workspace admins control who may create plugins with MCP servers. 1. Go to ChatGPT Plugins (chatgpt.com/plugins), select the plus button, then “Add custom MCP server”. 2. Enter border.bot as the name and, under “Connection”, `https://api.border.bot/mcp` as the “Server URL”. 3. Choose “OAuth” for authentication, review the risk warning, select “I understand and want to continue”, then “Create as a plugin”. 4. Open the new plugin in your personal plugins, install it with the plus button and sign in to border.bot when asked. 5. In a new chat, type @ and select border.bot. Official setup guide: https://developers.openai.com/api/docs/guides/custom-mcp-server Notes: Not available in the mobile apps. ChatGPT supports Client ID Metadata Documents and Dynamic Client Registration. Write tools ask for confirmation unless marked read-only. Workspaces still on the older flow create it under Settings › Apps › Create with developer mode on. ### Gemini By Google. Personal Google Accounts only (not work or school), 18+ in the US, with Keep Activity on; English only. Added on the web, then usable in the web and mobile apps. 1. On a computer, go to gemini.google.com and click Settings › “Connected Apps” at the bottom. 2. Under “Custom apps”, click “Add a custom app” and enter `https://api.border.bot/mcp` as the MCP server URL. 3. Click “Next” and follow the on-screen instructions to sign in to border.bot. 4. In a chat, enter @ and select the app to make sure Gemini uses it. Official setup guide: https://support.google.com/gemini/answer/17209137?hl=en Notes: Gemini registers itself with Dynamic Client Registration, so no client credentials are needed. Write actions always need manual confirmation. ### Perplexity Pro, Max and Enterprise. Enterprise members can add their own only when an admin allows custom connectors. 1. Go to Account settings › Connectors, click “+ Custom connector” in the top-right corner and select “Remote”. 2. Name: border.bot; MCP Server URL: `https://api.border.bot/mcp`; Authentication: “OAuth”; Transport: “Streamable HTTP”. 3. Check the acknowledgement box and click “Add”. 4. Click the border.bot connector card to start the sign-in and enable it. Official setup guide: https://www.perplexity.ai/help-center/en/articles/13915507-adding-custom-remote-connectors Notes: Perplexity discovers border.bot’s OAuth endpoints and registers itself dynamically, so no client ID or secret is needed. Enterprise admins can add it for everyone under Enterprise settings › Permissions › Connectors permissions. ### Vibe Work (formerly Le Chat) By Mistral AI. Administrators only: on Free, Pro and Student plans the account owner is the administrator. 1. In Vibe Work (chat.mistral.ai), open the “Connectors” page from the sidebar. 2. Click “+ Add Connector” and switch to the “Custom MCP Connector” tab. 3. Connector name: `borderbot`; Server URL: `https://api.border.bot/mcp`; then click “Connect”. 4. Complete the OAuth consent flow when prompted. Official setup guide: https://docs.mistral.ai/vibe/work/connectors/mcp-connectors Notes: Formerly Le Chat. The authentication method (OAuth 2.1 with dynamic client registration) is detected automatically. Under “Connectors” › “My Connectors” › “Functions” you can mark read-only tools “Always allow”. ### Raycast Raycast Pro. 1. Open the “Install MCP Server” command in Raycast. 2. Name: border.bot; Transport: “HTTP”; URL: `https://api.border.bot/mcp`; OAuth Type: “Dynamic”. 3. Press “Install MCP Server” (⌘↵), then select “Sign In” to authorize border.bot. 4. In AI Chat or Quick AI, type @ and the server’s name to use it. Official setup guide: https://manual.raycast.com/ai/model-context-protocol Notes: Works on desktop and iOS (HTTP servers only on iOS). The “Logout Server” action in “Manage MCP Servers” clears saved tokens. ### LM Studio By Element Labs. 1. Click “Add to LM Studio”, or open the “Program” tab in the right-hand sidebar, click “Install” › “Edit mcp.json” and add the config snippet. 2. LM Studio opens border.bot’s authorization page in your browser; approve access. 3. border.bot’s tools are then available to your models in chat. Config file mcp.json (Program › Install › Edit mcp.json): ```json { "mcpServers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` One-click install: [Add to LM Studio](lmstudio://add_mcp?name=borderbot&config=eyJ1cmwiOiJodHRwczovL2FwaS5ib3JkZXIuYm90L21jcCJ9) Official setup guide: https://lmstudio.ai/docs/integrations/mcp-remote Notes: OAuth sign-in for MCP servers needs LM Studio 0.4.10 or later. Install-link format: lmstudio.ai/docs/app/mcp/deeplink. ## Editors and IDEs Code editors and app builders whose agents can call border.bot while they work on your catalogue or checkout code. ### Cursor By Anysphere. 1. Click “Add to Cursor” and confirm when Cursor prompts to install the server, or add the config snippet to `~/.cursor/mcp.json`. 2. Open “Customize” in the sidebar, find `borderbot` and complete the OAuth sign-in it asks for (Cursor CLI: `agent mcp login borderbot`). 3. Ask Agent to use border.bot; Cursor asks for approval before running MCP tools. Config file `~/.cursor/mcp.json`: ```json { "mcpServers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` One-click install: [Add to Cursor](cursor://anysphere.cursor-deeplink/mcp/install?name=borderbot&config=eyJ1cmwiOiJodHRwczovL2FwaS5ib3JkZXIuYm90L21jcCJ9) Official setup guide: https://cursor.com/docs/mcp Notes: The same `mcp.json` configures the Cursor CLI (`agent`). Install-link format: cursor.com/docs/mcp/install-links. ### Visual Studio Code By Microsoft. Uses GitHub Copilot. Copilot Business and Enterprise members need the “MCP servers in Copilot” policy enabled by their organization. 1. Click “Install in VS Code” and confirm in VS Code, or run “MCP: Add Server” from the Command Palette, choose the HTTP type, enter `https://api.border.bot/mcp` and the name `borderbot`, and pick “Copilot Global” to use it in every workspace. 2. Trust the server when prompted; on first connection VS Code opens a browser window to sign in to border.bot. 3. Open the Chat view and ask for border.bot; select “Configure Tools” in the chat input to see its tools. Command: ```bash code --add-mcp '{"name":"borderbot","type":"http","url":"https://api.border.bot/mcp"}' ``` Config file `~/.copilot/mcp-config.json`: ```json { "mcpServers": { "borderbot": { "type": "http", "url": "https://api.border.bot/mcp", "tools": [ "*" ] } } } ``` One-click install: [Install in VS Code](vscode:mcp/install?%7B%22name%22%3A%22borderbot%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fapi.border.bot%2Fmcp%22%7D) Official setup guide: https://code.visualstudio.com/docs/agent-customization/mcp-servers Notes: `~/.copilot/mcp-config.json` is the portable user format VS Code now prefers (shared with GitHub Copilot CLI). The older VS Code format (`.vscode/mcp.json`, or the user-profile file from “MCP: Open User Configuration”) uses a top-level "servers" object: `{"servers": {"borderbot": {"type": "http", "url": "https://api.border.bot/mcp"}}}`. For VS Code Insiders use the `vscode-insiders:` scheme. ### Devin Desktop (formerly Windsurf) By Cognition. Enterprise users must turn MCP on in settings. 1. Open the MCP config: in the Cascade panel click “..” (Actions) › “Open MCP config file” (`~/.config/devin/mcp_config.json`), or run `devin mcp add -s user borderbot https://api.border.bot/mcp` with Devin CLI. 2. Add border.bot under "mcpServers" using the config snippet and save. 3. Sign in to border.bot when prompted on first use; if the server shows “Needs auth”, click “Authenticate”. Command: ```bash devin mcp add -s user borderbot https://api.border.bot/mcp ``` Config file `~/.config/devin/mcp_config.json`: ```json { "mcpServers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://docs.devin.ai/desktop/cascade/mcp Notes: Formerly Windsurf (windsurf.com now redirects to Devin Desktop). The file is shared by the legacy Cascade agent, the default Devin Local agent and Devin CLI (Windows: `%APPDATA%\devin\mcp_config.json`). Devin Local asks before each MCP tool call; `devin mcp login borderbot` re-runs the sign-in. ### Visual Studio By Microsoft. Visual Studio 2026, or Visual Studio 2022 17.14 and later, with GitHub Copilot. Organization MCP allow-list policies apply. 1. Click “Install in Visual Studio”, or in the Copilot Chat pane switch to Agent mode, select “Tools”, then the plus (+) button › “Add custom MCP server”, and enter `borderbot` and `https://api.border.bot/mcp`. 2. In `.mcp.json`, select “Authentication Required” (or “Manage Authentication”) from the CodeLens above `borderbot` and sign in to border.bot in the browser pop-up. 3. Enable border.bot’s tools in the tool picker and choose “Allow” when Copilot asks to run one. Config file `%USERPROFILE%\.mcp.json`: ```json { "servers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` One-click install: [Install in Visual Studio](https://vs-open.link/mcp-install?%7B%22name%22%3A%22borderbot%22%2C%22url%22%3A%22https%3A%2F%2Fapi.border.bot%2Fmcp%22%7D) Official setup guide: https://learn.microsoft.com/en-us/visualstudio/ide/mcp-servers Notes: Visual Studio supports any MCP-spec OAuth provider. The install-link format is the one Microsoft’s own “Install” buttons on that page use. A solution-level `.mcp.json` works too. ### Cline 1. In the Cline panel, click the “MCP Servers” icon and open the “Remote Servers” tab. 2. Server Name: `borderbot`; Server URL: `https://api.border.bot/mcp`; Transport Type: “Streamable HTTP”; then click “Add Server”. 3. Complete the border.bot authorization in your browser (Cline CLI: run `cline mcp` and choose “Authorize OAuth”). Command: ```bash cline mcp add borderbot https://api.border.bot/mcp --transport http --yes ``` Config file `~/.cline/data/settings/cline_mcp_settings.json`: ```json { "mcpServers": { "borderbot": { "type": "streamableHttp", "url": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://docs.cline.bot/mcp/mcp-overview Notes: The path above is the Cline CLI’s; in the IDE extension use “MCP Servers” › “Configure” › “Configure MCP Servers” to edit the same JSON. Keep "type": "streamableHttp", without it Cline uses legacy SSE. ### Zed By Zed Industries. 1. Open Settings › AI › MCP Servers, click “Add Server” and choose “Add Remote Server”. 2. Enter `borderbot` and `https://api.border.bot/mcp` (no Authorization header) and save. 3. Zed prompts you to authenticate with the standard MCP OAuth flow, sign in to border.bot. 4. When the indicator next to `borderbot` is green (“Server is active”), use it from the Agent Panel. Config file `~/.config/zed/settings.json`: ```json { "context_servers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://zed.dev/docs/ai/mcp Notes: Zed also forwards configured MCP servers to external agents over ACP. ### Kiro By Amazon Web Services. 1. Run “Kiro: Open user MCP config (JSON)” from the Command Palette (or select the “Open MCP Config” icon in the Kiro panel). 2. Add border.bot under "mcpServers" using the config snippet and save, servers reconnect automatically. 3. Kiro opens border.bot’s authorization page; sign in and approve. 4. Check the MCP servers tab in the Kiro panel to confirm it is connected. Config file `~/.kiro/settings/mcp.json`: ```json { "mcpServers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://kiro.dev/docs/mcp/configuration/ Notes: If MCP is off, enable the MCP support setting (Settings, search “MCP”). Kiro CLI reads the same file. Kiro registers via Dynamic Client Registration and requires the issuer in border.bot’s protected-resource metadata to match the authorization server’s `issuer` exactly. ### Replit 1. Click “Add to Replit”, or go to replit.com/integrations, scroll to “MCP Servers for Replit Agent” and click “+ Add MCP server”. 2. Display name: border.bot; MCP Server URL: `https://api.border.bot/mcp`. 3. Click “Test & save” and complete the border.bot OAuth sign-in Replit walks you through. 4. Mention border.bot in an Agent chat to use its tools in any project. One-click install: [Add to Replit](https://replit.com/integrations?mcp=eyJkaXNwbGF5TmFtZSI6ImJvcmRlci5ib3QiLCJiYXNlVXJsIjoiaHR0cHM6Ly9hcGkuYm9yZGVyLmJvdC9tY3AifQ%3D%3D) Official setup guide: https://docs.replit.com/build/connect-via-mcp ### v0 By Vercel. 1. In v0, open the + menu in the prompt form and select “MCPs”. 2. Configure a custom MCP server with `https://api.border.bot/mcp` and choose “OAuth” as the authentication. 3. Sign in to border.bot when prompted; v0 then considers its tools in new and existing chats. Official setup guide: https://v0.app/docs/MCP Notes: MCP tools are available to v0 while it generates; the apps v0 builds can’t call them. Tool calls follow your global permission mode (Ask, Auto or Full). ### JetBrains Air By JetBrains. 1. Open Settings › AI › MCP Servers and make sure “Enable MCP support” is on. 2. Click “Add Global MCP Server”, paste the config snippet and save. 3. Click “Connect” next to `borderbot` and approve the connection on border.bot’s authorization page. Config file `.air/mcp.json`: ```json { "mcpServers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://www.jetbrains.com/help/air/mcp-servers.html Notes: `.air/mcp.json` is the project-local location (“Add Local MCP Server”); a global server is stored by the app. Air cloud tasks take MCP servers from the repository’s `mcp.json` or a JetBrains Air Teams connector instead. ### TraeCode By ByteDance. 1. Click “Add to TraeCode” and confirm the configuration with “Confirm”, or open Settings (top-right icon) › “MCP” › “Add” › “Add Manually”. 2. If adding manually, paste the config snippet and click “Confirm”. 3. Sign in to border.bot if TraeCode prompts you to. Config file TraeCode mcp.json (Settings › MCP › Add › Add Manually): ```json { "mcpServers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` One-click install: [Add to TraeCode](trae://trae.ai-ide/mcp-import?type=http&name=borderbot&config=eyJ1cmwiOiJodHRwczovL2FwaS5ib3JkZXIuYm90L21jcCJ9) Official setup guide: https://docs.trae.ai/ide/add-mcp-servers Notes: TraeCode (the TRAE IDE) documents remote HTTP servers with header authentication only; OAuth sign-in isn’t documented, so it may not connect to border.bot’s OAuth-only endpoint. Install-link format: docs.trae.ai/ide/mcp-server-install-links. ## Command line Coding agents that run in a terminal. Most add the server with one command. ### Claude Code By Anthropic. 1. Run `claude mcp add --transport http --scope user borderbot https://api.border.bot/mcp`. 2. Start Claude Code, run `/mcp`, select `borderbot` and follow the steps in your browser to log in (or run `claude mcp login borderbot` from your shell). 3. Run `/mcp` again to confirm `borderbot` is connected. Command: ```bash claude mcp add --transport http --scope user borderbot https://api.border.bot/mcp ``` Config file `.mcp.json`: ```json { "mcpServers": { "borderbot": { "type": "http", "url": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://code.claude.com/docs/en/mcp Notes: `--scope user` makes border.bot available in every project; the `.mcp.json` snippet is for sharing it with a team via a repository. Claude Code discovers OAuth and border.bot’s Client ID Metadata Document support automatically and refreshes tokens itself. If you added border.bot as a connector on claude.ai and log in to Claude Code with that account, it already appears in `/mcp`. ### Codex By OpenAI. 1. CLI: run `codex mcp add borderbot --url https://api.border.bot/mcp`, then `codex mcp login borderbot` and sign in to border.bot in your browser. 2. IDE extension: open the gear menu › “MCP servers” › “Add server”, enter `borderbot`, choose “Streamable HTTP”, paste `https://api.border.bot/mcp`, save and select “Restart extension”, then “Authenticate”. 3. ChatGPT desktop app: “Settings” › “MCP servers” › “Add server” with the same values, save and select “Restart”, then “Authenticate”. 4. Type `/mcp` to see the connected servers. Command: ```bash codex mcp add borderbot --url https://api.border.bot/mcp ``` Config file `~/.codex/config.toml`: ```toml [mcp_servers.borderbot] url = "https://api.border.bot/mcp" ``` Official setup guide: https://learn.chatgpt.com/docs/extend/mcp Notes: The Codex CLI, IDE extension and ChatGPT desktop app share `~/.codex/config.toml`, so adding border.bot once covers all three. Codex uses a Client ID Metadata Document when the authorization server advertises it and otherwise Dynamic Client Registration, with a loopback callback on 127.0.0.1. ### Gemini CLI By Google. 1. Run `gemini mcp add --transport http --scope user borderbot https://api.border.bot/mcp`. 2. Start `gemini` and run `/mcp auth borderbot`; sign in to border.bot in the browser window that opens. 3. Run `/mcp list` to check that `borderbot` is connected. Command: ```bash gemini mcp add --transport http --scope user borderbot https://api.border.bot/mcp ``` Config file `~/.gemini/settings.json`: ```json { "mcpServers": { "borderbot": { "httpUrl": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://geminicli.com/docs/tools/mcp-server/ Notes: Use `httpUrl` for Streamable HTTP. `url` means SSE in Gemini CLI. OAuth needs a local browser and a localhost callback, so it doesn’t work in headless or SSH sessions without forwarding. ### GitHub Copilot CLI By GitHub. All Copilot plans. With Copilot from an organization, the Copilot CLI policy must be enabled, and MCP allowlist policies apply. 1. Run `copilot mcp add --transport http borderbot https://api.border.bot/mcp`, or in interactive mode enter `/mcp add`, pick “HTTP or SSE”, paste the URL and press Ctrl+S. 2. If `borderbot` shows `needs-auth`, run `/mcp auth borderbot` and sign in to border.bot in your browser. 3. Run `/mcp show borderbot` to see its status and tools. Command: ```bash copilot mcp add --transport http borderbot https://api.border.bot/mcp ``` Config file `~/.copilot/mcp-config.json`: ```json { "mcpServers": { "borderbot": { "type": "http", "url": "https://api.border.bot/mcp", "tools": [ "*" ] } } } ``` Official setup guide: https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers Notes: Copilot CLI registers itself with Dynamic Client Registration. `~/.copilot/mcp-config.json` is also read by Visual Studio Code. ### OpenCode By Anomaly. 1. Add border.bot under "mcp" in `~/.config/opencode/opencode.json` using the config snippet (or run `opencode mcp add` and choose a remote server). 2. Run `opencode mcp auth borderbot` and authorize in your browser. OpenCode also prompts the first time you use it. 3. Run `opencode mcp list` to check its connection and auth status. Config file `~/.config/opencode/opencode.json`: ```json { "$schema": "https://opencode.ai/config.json", "mcp": { "borderbot": { "type": "remote", "url": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://opencode.ai/docs/mcp-servers/ Notes: OpenCode uses Dynamic Client Registration automatically; no client ID is needed. ### Warp 1. Open Settings › Agents › MCP servers (or run “Open MCP Servers” from the Command Palette) and click “+ Add”. 2. Paste the config snippet and save. 3. Start `borderbot`; Warp opens a browser to sign in to border.bot the first time. Config file `~/.warp/.mcp.json`: ```json { "mcpServers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://docs.warp.dev/agents/capabilities/mcp/ Notes: Servers in `~/.warp/.mcp.json` start automatically and show an authentication modal on first spawn. Credentials stay on the device, so sign in again on a new machine. ### Junie CLI By JetBrains. 1. Add the config snippet to `~/.junie/mcp/mcp.json`, or run `/mcp`, press Ctrl+A to add a server with the MCP Installation Assistant, and choose “User scope” and “Remote”. 2. border.bot shows the “Authorization required” status: select it, choose “Authorize” and log in on the border.bot page that opens. 3. Check that its status changes to “Active”. Config file `~/.junie/mcp/mcp.json`: ```json { "mcpServers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://junie.jetbrains.com/docs/junie-cli-mcp-configuration.html Notes: Junie in JetBrains IDEs reads the same `~/.junie/mcp/mcp.json`, but JetBrains documents OAuth sign-in only for Junie CLI. JetBrains AI Assistant chat can’t sign in to OAuth MCP servers yet. ### Amp 1. Run `amp mcp add borderbot https://api.border.bot/mcp` (saved to `amp.mcpServers` in `~/.config/amp/settings.json`). 2. Start the Amp TUI (`amp`); it opens your browser to sign in to border.bot automatically. 3. To use border.bot from every Amp client, including orbs, store it on ampcode.com instead: `amp mcp remote --personal add borderbot https://api.border.bot/mcp --auth oauth`, then `amp mcp remote --personal login borderbot`. Command: ```bash amp mcp add borderbot https://api.border.bot/mcp ``` Config file `~/.config/amp/settings.json`: ```json { "amp.mcpServers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://ampcode.com/docs/customize/mcp Notes: Local sign-in relies on Dynamic Client Registration. Browser OAuth isn’t available inside orbs, so use the remote definition there. ### goose By Agentic AI Foundation. 1. Click “Add to goose”, or run `goose configure` › “Add Extension” › “Remote Extension (Streamable HTTP)” and enter `borderbot` and `https://api.border.bot/mcp`. 2. In goose Desktop you can also use the sidebar › “Extensions” › “Add custom extension”. 3. Sign in to border.bot in your browser when goose asks; it registers itself automatically (Client ID Metadata Document or Dynamic Client Registration). Config file `~/.config/goose/config.yaml`: ```yaml extensions: borderbot: name: borderbot type: streamable_http uri: "https://api.border.bot/mcp" enabled: true timeout: 300 ``` One-click install: [Add to goose](goose://extension?url=https%3A%2F%2Fapi.border.bot%2Fmcp&type=streamable_http&id=borderbot&name=borderbot&description=HS%20codes%2C%20duties%20and%20landed%20cost&timeout=300) Official setup guide: https://goose-docs.ai/docs/getting-started/using-extensions ### Qwen Code By Alibaba Cloud. 1. Run `qwen mcp add --scope user --transport http borderbot https://api.border.bot/mcp`. 2. Start `qwen`, enter `/mcp` and authenticate `borderbot`; sign in to border.bot in your browser. 3. Ask the model to use border.bot (restart Qwen Code first if it was already running). Command: ```bash qwen mcp add --scope user --transport http borderbot https://api.border.bot/mcp ``` Config file `~/.qwen/settings.json`: ```json { "mcpServers": { "borderbot": { "httpUrl": "https://api.border.bot/mcp" } } } ``` Official setup guide: https://qwenlm.github.io/qwen-code-docs/en/users/features/mcp/ Notes: OAuth endpoints are discovered and the client registers dynamically. The callback is `http://localhost:7777/oauth/callback`, so sign-in needs a local browser. ### Kimi Code CLI By Moonshot AI. 1. Run `kimi mcp add --transport http --auth oauth borderbot https://api.border.bot/mcp`. 2. Run `kimi mcp auth borderbot` and complete the OAuth flow in your browser. 3. Run `kimi mcp test borderbot` (or `/mcp` inside Kimi Code CLI) to check the connection. Command: ```bash kimi mcp add --transport http --auth oauth borderbot https://api.border.bot/mcp ``` Official setup guide: https://moonshotai.github.io/kimi-cli/en/customization/mcp.html Notes: Servers are saved to `~/.kimi/mcp.json`; OAuth tokens are kept in `~/.kimi/mcp-oauth/`. ## Automation Agent and workflow builders that call border.bot from a step in a workflow, and an API client for trying its tools by hand. ### Microsoft Copilot Studio By Microsoft. 1. Open your agent’s “Tools” page and select “Add a tool” › “New tool” › “Model Context Protocol”. 2. Server name: border.bot; Server description: what border.bot does (e.g. “Classifies products to HS codes and calculates duties, taxes and landed cost”); Server URL: `https://api.border.bot/mcp`. 3. Authentication: “OAuth 2.0”, type “Dynamic discovery”; select “Create”, then “Next”. 4. In “Add tool”, select “Create a new connection”, sign in to border.bot, then “Add to agent”. Official setup guide: https://learn.microsoft.com/en-us/microsoft-copilot-studio/mcp-add-existing-server-to-agent Notes: Copilot Studio supports the Streamable HTTP transport only. The orchestrator uses the server description to decide when to call border.bot. ### n8n 1. Add an “MCP Client Tool” to your AI Agent (or an “MCP Client” node to run one tool as a workflow step). 2. Set “Endpoint” (“MCP Endpoint URL” on the MCP Client node) to `https://api.border.bot/mcp` and “Server Transport” to “HTTP Streamable”. 3. Set “Authentication” to “MCP OAuth2”, create a new “MCP OAuth2 API” credential with “Use Dynamic Client Registration” on, and click “Connect my account” to sign in to border.bot. 4. Choose which border.bot tools to expose under “Tools to Include”. Official setup guide: https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolmcp/ Notes: Labels match the current node versions; n8n’s MCP Client Tool page still shows the older “SSE Endpoint” field. ### Zapier MCP Client is in beta. 1. Go to the Apps page, click “+ Add connection”, search for and select “MCP Client”, then click “Add connection”. 2. Server URL: `https://api.border.bot/mcp`; Transport: “Streamable HTTP”; OAuth: “Yes”. 3. Click “Yes, Continue to MCP Client”, sign in to border.bot and grant Zapier access. 4. Rename the connection to border.bot, then use its tools in Zaps or Agents. Official setup guide: https://help.zapier.com/hc/en-us/articles/38777069364109-Connect-remote-MCP-servers-to-Zapier-using-MCP-Client Notes: MCP Client supports tool calls only. ### Make MCP Client is in open beta for all users. 1. Add the “MCP Client” module to your scenario and click “Create a connection”. 2. Connection name: border.bot; in “MCP Server” click “+ New MCP Server” and enter `https://api.border.bot/mcp` in the “URL” field (leave “API Key / Access token” empty). 3. Click “Save”, then sign in to border.bot and confirm access. Official setup guide: https://apps.make.com/mcp-client Notes: Make’s OAuth redirect URI is `https://www.make.com/oauth/cb/mcp`. ### Postman 1. In a workspace, click + › “MCP” in the left sidebar, choose “HTTP” and enter `https://api.border.bot/mcp`. 2. Click “Connect” / “Load Capabilities”; for an OAuth server Postman opens the “OAuth Debugger”, click “Continue” through each phase and sign in when the “Authorization request” step opens your browser. 3. Open the “Tools” tab, pick a tool, fill in its arguments and click “Run”. Official setup guide: https://learning.postman.com/docs/use/send-requests/protocols/mcp-requests/create/ Notes: Useful for testing border.bot’s tools outside an AI client; Postman runs the full MCP OAuth flow (protected-resource metadata, Dynamic Client Registration, PKCE). ## What your assistant can do ### Classify products From a description or a product URL, to the code for any destination, with descriptions, confidence and alternatives. ### Calculate landed cost Duties, taxes and fees for a code, origin and destination, with the total landed cost. ### Read product pages Extract the title, materials, price and country of origin from a product link before classifying. ## Things to ask - “What’s the HTS code for an insulated stainless steel water bottle made in China?” - “Classify this product for import into the UK: https://shop.example/products/linen-shirt” - “Calculate the landed cost of 20 units of 6109.10 from Vietnam to Germany at €12 each, with €40 shipping.” - “Which of these product descriptions need more detail before we can classify them?” ## Billing and security - You sign in on border.bot. The assistant never sees your password. - Each connection is tied to one workspace that you choose when you approve it. - Calls use the same credits and prices as the dashboard and the API, and failed calls are refunded. - Every result is saved to the workspace history, and you can revoke a connection at any time from the dashboard. ## Frequently asked questions ### What is MCP? The Model Context Protocol is an open standard for connecting AI assistants to tools and data. A remote MCP server, like border.bot’s, runs on the web, so you add it with a URL and sign in with OAuth instead of installing anything. ### Do I need an API key for MCP? No. MCP clients sign in with OAuth: you log in to border.bot in your browser and approve the connection. API keys are only for calling the REST API from your own code. ### Which workspace pays for MCP calls? The one you choose when you approve the connection. Each call uses credits from that workspace at the same prices as the dashboard and API, and the results appear in its history. ### How do I disconnect a client? Open the dashboard to see every client connected to your workspace and revoke any of them. Revoking takes effect immediately; the client has to ask you to sign in again. ### Does my AI client’s plan support custom connectors? Support for remote MCP servers depends on the client and sometimes on your plan or edition. Each guide on this page lists the plans its vendor documents. If the option is missing, check the vendor’s setup guide linked from that client’s steps. --- # Security and data handling > How border.bot handles sign-in, API keys, MCP authorization, credits, payments and your product data, and how to report a security issue to our team. Source: https://border.bot/security Last updated: 2026-10-09 border.bot runs on Cloudflare Workers, signs people in through WorkOS, takes payments through Stripe and records every credit movement in a ledger. This page explains each part and how to report a security issue. ## Signing in and workspaces - Dashboard sign-in is handled by WorkOS AuthKit. Your session lives in an encrypted, signed cookie. - Work happens inside workspaces (organizations). Each member has a role: admins manage billing, API keys, the team and settings; members classify, calculate and see history. - Admin tooling is protected by Cloudflare Access (Zero Trust) and every request to it is verified. ## Keeping workspaces apart - Each workspace’s data is separated by the database itself. Postgres row-level security only lets a request see and change the rows of the workspace it was authenticated for, even if application code asks for something else. - Each part of border.bot connects with its own database login that can do only what that part needs. The customer dashboard can’t read across workspaces at all, and the credit ledger can only be added to, never edited or deleted. - Automated tests run as those real database logins on every change and try to read and write across workspaces. ## API keys - Keys are created per workspace, start with bb_live_ and are shown once. - We store only a hash of each key, never the key itself, so a leaked database would not reveal usable keys. - Admins can revoke a key at any time; revoked keys stop working immediately. ## AI assistants (MCP) - The MCP server uses OAuth 2.1. You sign in on border.bot; the assistant receives a scoped token, not your password. - When you approve a client you choose which workspace it may bill. - Every connection is listed in the dashboard and can be revoked at any time. ## Credits and payments - Prices are stored on our servers. A client only says which action or credit pack it wants, never how much it costs. - Each billable call debits credits in a single atomic transaction before it runs; a database constraint makes a negative balance impossible, even under heavy concurrency. - If a call fails, its credits are refunded automatically, and every movement is recorded in the credit ledger. - Payments go through Stripe Checkout. Card details never touch our servers, and credits are added only after Stripe’s signed webhook confirms the payment. ## Free tools - The free classifier, calculator and origin finder are protected by Cloudflare Turnstile and rate limits. - Free runs are counted per visitor using keyed hashes of the IP address, its address range and a signed first-party cookie (bb_vid), and aren’t offered from VPN, hosting or Tor networks. We don’t store raw IP addresses for this. ## Your product data - Descriptions, product URLs and values you submit are used to produce your result and are kept in your workspace history so you can find them again. - When you classify from a URL, we fetch that public page to read the product details (see how our page fetcher works at border.bot/bot). - Classification and duty calculation are performed with a specialist trade-data provider that receives the product details needed to produce the result. - Data is stored in PlanetScale Postgres, reached through Cloudflare, and in Cloudflare R2. Our main processors are Cloudflare, PlanetScale, WorkOS, Stripe and our trade-data provider. ## Report a security issue If you think you’ve found a vulnerability, email us with the details and steps to reproduce. Please don’t access other people’s data or degrade the service while testing. We’ll acknowledge your report and keep you updated while we fix it. Email: support@border.bot (subject “Security”). --- # About border.bot > border.bot classifies products and calculates duty, tax and landed cost for merchants who ship parcels abroad, via a dashboard, a REST API and an MCP server. Source: https://border.bot/about Last updated: 2026-10-07 border.bot is a classification and duty-calculation service for merchants who ship parcels abroad. It gives you the HS code and the landed cost of a product, with the reasoning behind each answer, through a web dashboard, a REST API and an MCP server for AI assistants. ## Why it exists Every parcel that crosses a border needs a tariff code, a country of origin and, if you want to avoid surprise charges on delivery, an accurate estimate of the duty and tax. Getting any of them wrong delays parcels, triggers penalties or leaves the customer with a bill they refuse to pay. Most shops either pay a broker for each question or copy codes from a spreadsheet that drifts out of date. border.bot answers those questions directly and shows how it reached each answer. Operations teams use the dashboard, developers call the API from checkout and catalogue systems, and anyone using Claude, ChatGPT, Codex, Cursor or another MCP client can connect the MCP server. ## What you can expect ### Answers you can check Every classification shows the official description at each level of the code, the reasoning, a confidence score and the alternatives that were considered. ### Fixed prices per action You buy credits up front. Each action has a fixed credit cost shown on the pricing page and in the dashboard, and credits for a failed call are refunded automatically. ### The same answer everywhere The dashboard, the API, the MCP server and the free tools use the same engine and the same tariff data. ### Clear limits Results are guidance, not a binding ruling. Low-confidence results are flagged for review, and for high-value or regulated goods we recommend a licensed broker or a binding ruling from customs. Questions? [Contact us](https://border.bot/contact). --- # Contact > Get in touch with border.bot for support, billing questions, partnerships or security reports. Email our team or find answers in the docs and guides. Source: https://border.bot/contact Email is the quickest way to reach us. For product questions, say what you’re shipping, from which country and to where. ## Email us - ### Product support Questions about a classification, a landed-cost result, your account or the dashboard. [support@border.bot](mailto:support@border.bot?subject=Support) - ### Billing Credit packs, invoices, refunds and anything to do with payments. [support@border.bot](mailto:support@border.bot?subject=Billing) - ### Partnerships and volume Platforms, marketplaces, 3PLs and high-volume shippers who want to integrate border.bot. [support@border.bot](mailto:support@border.bot?subject=Partnerships) - ### Security reports Found a vulnerability? Send us the details and how to reproduce it. [support@border.bot](mailto:support@border.bot?subject=Security) ## Documentation and tools - [Free HS code classifier](https://border.bot/tools/hs-code-classifier) - [Free landed cost calculator](https://border.bot/tools/landed-cost-calculator) - [Free country of origin finder](https://border.bot/tools/country-of-origin-finder) - [Developer quickstart](https://border.bot/developers) - [API reference](https://border.bot/docs/api) - [MCP setup for Claude, ChatGPT, Codex, Cursor and other clients](https://border.bot/mcp) - [Security and data handling](https://border.bot/security) --- # border.bot blog > Plain-English guides to HS codes, tariff schedules, landed cost, DDP vs DAP and country of origin for merchants who ship parcels across borders. Source: https://border.bot/blog Last updated: 2026-10-07 Plain-English guides to HS codes, tariff schedules, landed cost, DDP vs DAP and country of origin for merchants who ship parcels across borders. ## [The EU’s €3 customs duty on parcels under €150](https://border.bot/blog/eu-3-euro-customs-duty) Since 1 July 2026 the EU charges a temporary €3 customs duty on low-value parcels, once per tariff classification. What it covers, who pays and how it adds up. Published 2026-10-08 · 2 min read · Markdown: https://border.bot/blog/eu-3-euro-customs-duty.md ## [US de minimis suspension: what changed for parcels](https://border.bot/blog/us-de-minimis-suspension) US de minimis has been suspended since 29 August 2025. The timeline, the June 2026 CBP rules, how parcels clear now and what ends on 1 July 2027. Published 2026-10-08 · 4 min read · Markdown: https://border.bot/blog/us-de-minimis-suspension.md ## [Classify products from Claude and ChatGPT](https://border.bot/blog/classify-products-with-mcp) Connect the border.bot MCP server to Claude, ChatGPT or Cursor, then classify products, check origin and estimate landed cost from a chat. Setup and tips. Published 2026-09-30 · 4 min read · Markdown: https://border.bot/blog/classify-products-with-mcp.md ## [Country of origin: shipped from isn’t made in](https://border.bot/blog/country-of-origin-vs-shipped-from) Why the country a parcel ships from often isn’t its country of origin, how origin is decided, and how it changes duties, marking rules and trade-deal savings. Published 2026-09-16 · 4 min read · Markdown: https://border.bot/blog/country-of-origin-vs-shipped-from.md ## [DDP vs DAP for ecommerce parcels](https://border.bot/blog/ddp-vs-dap-ecommerce) Should you collect duties and taxes at checkout (DDP) or let customers pay on delivery (DAP)? The costs, risks and setup of each, explained for parcel shippers. Published 2026-09-09 · 4 min read · Markdown: https://border.bot/blog/ddp-vs-dap-ecommerce.md ## [Landed cost explained: duties, taxes and fees](https://border.bot/blog/landed-cost-explained) What makes up the landed cost of an international parcel (goods, shipping, duty, import VAT or GST, and fees) and how each part is calculated. Published 2026-09-01 · 5 min read · Markdown: https://border.bot/blog/landed-cost-explained.md ## [HS vs HTS vs CN/TARIC: the digits explained](https://border.bot/blog/hs-hts-cn-taric-commodity-codes) Why one product has a 6-digit HS code, a 10-digit US HTS code, an 8-digit EU CN code and a 10-digit TARIC code, and which one goes on which document. Published 2026-08-25 · 4 min read · Markdown: https://border.bot/blog/hs-hts-cn-taric-commodity-codes.md ## [What is an HS code, and how do you find yours?](https://border.bot/blog/what-is-an-hs-code) A plain-English guide to HS codes: how the six digits are built, why countries add more, and a step-by-step method for finding the right code for your product. Published 2026-08-18 · 5 min read · Markdown: https://border.bot/blog/what-is-an-hs-code.md RSS: https://border.bot/blog/rss.xml --- # Customs and shipping glossary > Plain definitions of HS, HTS, CN and TARIC codes, de minimis, customs value, duty, import VAT, DDP, DAP, IOSS and landed cost, with links to the full guides. Source: https://border.bot/glossary Last updated: 2026-10-08 Short definitions of the terms that decide what a parcel pays at the border, with links to the full guides. ## Anti-dumping and countervailing duties Extra duties on specific products from specific countries, and sometimes from specific manufacturers, that offset dumping (selling below normal value) or foreign subsidies. They are charged on top of the normal rate, which is why the same HS code can cost more from one origin than from another. Read more: [Country of origin vs shipped from](https://border.bot/blog/country-of-origin-vs-shipped-from). ## Binding ruling A written decision by a customs authority on how a specific product is classified, which that authority then has to apply to it. Examples are CBP rulings in the US (searchable in CROSS), Binding Tariff Information (BTI) in the EU and Advance Tariff Rulings (ATaR) in the UK. Read more: [What is an HS code?](https://border.bot/blog/what-is-an-hs-code). ## CN code (Combined Nomenclature) The EU’s 8-digit product code. The first 6 digits are the HS code and the last 2 are EU subdivisions. The CN sets the EU’s customs duty rates. Read more: [HS vs HTS vs CN/TARIC](https://border.bot/blog/hs-hts-cn-taric-commodity-codes). ## Commodity code (UK) The UK’s product code in the UK Trade Tariff: 10 digits for imports and 8 for exports. The first 6 digits are the HS code. Read more: [HS vs HTS vs CN/TARIC](https://border.bot/blog/hs-hts-cn-taric-commodity-codes). ## Country of origin Where goods were made, or where they last went through a substantial change, under the importing country’s rules of origin. It decides the duty rate and any extra duties. It is not the country the parcel ships from. Read more: [Country of origin vs shipped from](https://border.bot/blog/country-of-origin-vs-shipped-from). ## Customs value The value duty is calculated on, usually the price paid for the goods (the transaction value). The EU and the UK add transport and insurance to the border (a CIF basis); the US and Canada leave international freight out. Read more: [Landed cost explained](https://border.bot/blog/landed-cost-explained). ## DAP (Delivered at Place) An Incoterms rule: the seller delivers to the named destination, and the buyer pays the import duty and taxes and handles import clearance. For parcels, that usually means the customer pays the carrier on delivery. Read more: [DDP vs DAP for parcels](https://border.bot/blog/ddp-vs-dap-ecommerce). ## DDP (Delivered Duty Paid) An Incoterms rule: the seller handles import clearance and pays the import duty and taxes, so the customer pays nothing on delivery. Ecommerce sellers usually collect the amount at checkout. Read more: [DDP vs DAP for parcels](https://border.bot/blog/ddp-vs-dap-ecommerce), [Free landed cost calculator](https://border.bot/tools/landed-cost-calculator). ## De minimis A value below which a country waives duty, tax or both on an import. Thresholds differ by country and change: the US suspended its $800 duty exemption on 29 August 2025, and since 1 July 2026 the EU charges €3 per tariff classification on parcels worth up to €150. Read more: [US de minimis suspension](https://border.bot/blog/us-de-minimis-suspension), [The EU’s €3 customs duty](https://border.bot/blog/eu-3-euro-customs-duty). ## Duty (customs duty) A tax on imported goods, set by the tariff line for the product’s code and country of origin. It can be a percentage of the customs value (ad valorem), an amount per unit or weight (specific), or both (compound). Read more: [Landed cost explained](https://border.bot/blog/landed-cost-explained), [Free landed cost calculator](https://border.bot/tools/landed-cost-calculator). ## Formal entry (US) The full US customs entry, generally required for shipments worth more than $2,500 and for some goods at any value. It needs a customs bond and is usually filed by a licensed customs broker. Read more: [US de minimis suspension](https://border.bot/blog/us-de-minimis-suspension). ## General Rules of Interpretation (GRI) The six rules, applied in order, that decide which heading and subheading of the Harmonized System a product belongs to. Most products are classified under Rule 1: the wording of the headings and the section and chapter notes. Read more: [What is an HS code?](https://border.bot/blog/what-is-an-hs-code). ## HS code (Harmonized System code) A 6-digit product code from the Harmonized System, maintained by the World Customs Organization and used by most countries as the basis of their tariffs. Countries add digits for their own tariff lines, such as the 10-digit US HTS code. Read more: [What is an HS code?](https://border.bot/blog/what-is-an-hs-code), [Free HS code classifier](https://border.bot/tools/hs-code-classifier). ## HTS code (Harmonized Tariff Schedule of the United States) The US 10-digit product code, published by the US International Trade Commission. The first 6 digits are the HS code, the first 8 set the duty rate, and the last 2 are for statistics. Read more: [HS vs HTS vs CN/TARIC](https://border.bot/blog/hs-hts-cn-taric-commodity-codes), [Free HS code classifier](https://border.bot/tools/hs-code-classifier). ## Import VAT and GST Consumption tax charged on imports at the destination’s rate, such as VAT in the EU and the UK or GST in Canada and Australia. It is usually calculated on the customs value plus duty, so duty raises the tax too. Read more: [Landed cost explained](https://border.bot/blog/landed-cost-explained). ## Incoterms Standard trade terms from the International Chamber of Commerce (the current set is Incoterms 2020) that say who pays for and handles transport, insurance and customs. DDP and DAP are the two that matter most for parcels. Read more: [DDP vs DAP for parcels](https://border.bot/blog/ddp-vs-dap-ecommerce). ## Informal entry (US) A simplified US customs entry for most shipments worth $2,500 or less. With de minimis suspended, low-value courier parcels use it, and since 24 July 2026 parcels sent by post use CBP’s postal informal entry process. Read more: [US de minimis suspension](https://border.bot/blog/us-de-minimis-suspension). ## IOSS (Import One-Stop Shop) An EU scheme for collecting VAT at checkout on goods sent to EU consumers in consignments worth up to €150. The registered seller declares and pays the VAT monthly in one EU country, and the parcel clears without VAT being charged again. Read more: [The EU’s €3 customs duty](https://border.bot/blog/eu-3-euro-customs-duty). ## Landed cost The full cost of getting goods to the buyer: the price, shipping and insurance, plus duty, import taxes and fees. It is what the customer pays in total, at checkout or on delivery. Read more: [Landed cost explained](https://border.bot/blog/landed-cost-explained), [Free landed cost calculator](https://border.bot/tools/landed-cost-calculator). ## Merchandise processing fee (MPF) A US CBP fee on imports. Formal entries pay a percentage of the value, with a minimum and a maximum; informal entries pay a smaller flat fee. Read more: [Landed cost explained](https://border.bot/blog/landed-cost-explained). ## Preferential origin Origin that qualifies goods for a lower or zero duty rate under a trade agreement, such as USMCA or the EU–UK Trade and Cooperation Agreement. The goods have to meet that agreement’s rules of origin, and the importer usually needs proof. Read more: [Country of origin vs shipped from](https://border.bot/blog/country-of-origin-vs-shipped-from). ## Section 321 The US de minimis provision (19 U.S.C. 1321), which let shipments worth $800 or less, imported by one person on one day, enter free of duty. It has been suspended for goods from every country since 29 August 2025, and a 2025 law ends it on 1 July 2027. Read more: [US de minimis suspension](https://border.bot/blog/us-de-minimis-suspension). ## TARIC code The EU’s integrated tariff code: 10 digits that add EU measures, such as anti-dumping duties, tariff suspensions and quotas, to the 8-digit CN code. Read more: [HS vs HTS vs CN/TARIC](https://border.bot/blog/hs-hts-cn-taric-commodity-codes). --- # border.bot API documentation > Classify products to HS codes and calculate duties, taxes and landed cost for cross-border parcels with the border.bot REST API or MCP server. Source: https://border.bot/docs Last updated: 2026-10-09 > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. border.bot classifies products to HS codes and works out the duties, taxes and fees a parcel pays on arrival. The same engine runs the dashboard, the REST API at `https://api.border.bot` and the remote MCP server at `https://api.border.bot/mcp`. ## When to use border.bot Use border.bot when software, or an agent working for someone, needs one of these answers for a cross-border shipment: | Job | REST endpoint | MCP | | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | --- | | The HS, HTS, CN or UK commodity code for a product, in the destination's format | `POST /v1/classify` (`/classify/batch` for up to 25) | yes | | Landed cost: every duty, tax and fee line and the total for a parcel | `POST /v1/calculate` (`/calculate/shipment` for up to 50 lines) | yes | | How additional duties stack on one line (US Section 232, 301, IEEPA and similar) | `POST /v1/calculate/stacking` | no | | Where a product was made, from a URL, title or barcode | `POST /v1/origin` | yes | | Whether goods are restricted or prohibited in the destination | `POST /v1/restrictions` | yes | | Denied-party screening of a buyer or seller | `POST /v1/screen` | yes | | Thousands of products at once | `POST /v1/bulk/runs` | no | border.bot gives estimates and classifications backed by cited sources. It does not issue binding rulings, file customs declarations or book freight. ## Two ways in - **REST API**: JSON over HTTPS with a workspace API key. Best for checkouts, catalogues and back-office jobs. Start with the [quickstart](https://border.bot/docs/quickstart). - **MCP server**: for Claude, ChatGPT, Codex, Cursor and other MCP clients. People sign in with OAuth, so no API key is needed. See [MCP](https://border.bot/docs/mcp). Both use the same prepaid credits. New workspaces get free credits, and three reference endpoints need no key at all (see [authentication](https://border.bot/docs/authentication#endpoints-without-a-key)). ## For agents Every docs page is available as Markdown: add `.md` to its URL or send `Accept: text/markdown`. The index of everything is at [/llms.txt](https://border.bot/llms.txt), and the machine-readable discovery files are listed in [Agent discovery](https://border.bot/docs/agents). --- # Quickstart > Create a border.bot API key, classify a product, then calculate its landed cost, with curl. Source: https://border.bot/docs/quickstart Last updated: 2026-10-09 > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. ## 1. Create an API key Sign in to the [dashboard](https://app.border.bot/developers?tab=keys) and open **Developers → API keys**. Create a key for your workspace. It starts with `bb_live_` and is shown once, so put it in your secrets manager straight away. ```bash export BORDERBOT_API_KEY=bb_live_... ``` Check the key works. `GET /v1/me` is free and returns the workspace, the key's scopes and the credit balance: ```bash curl https://api.border.bot/v1/me \ -H "Authorization: Bearer $BORDERBOT_API_KEY" ``` ## 2. Classify a product Send a description or a product URL with the destination country. Add the origin if you know it. ```bash curl -X POST https://api.border.bot/v1/classify \ -H "Authorization: Bearer $BORDERBOT_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{"description":"Men'\''s cotton crew-neck t-shirt, knitted","destinationCountry":"US","originCountry":"PT"}' ``` The response has the code in the destination's format, the official description at each level, a confidence score, the reasoning and alternatives. The `X-Credits-Charged` and `X-Credits-Remaining` headers say what the call cost. ## 3. Calculate landed cost Pass the code, the origin and destination, the goods value and the shipping cost: ```bash curl -X POST https://api.border.bot/v1/calculate \ -H "Authorization: Bearer $BORDERBOT_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{"hsCode":"6109.10.00.12","originCountry":"PT","destinationCountry":"US","value":120,"currency":"USD","shippingCost":15}' ``` You get every duty, tax and fee line with its legal basis and the total landed cost. The [reference for this endpoint](https://border.bot/docs/api/calculate-landed-cost) lists every field, including shipping terms, preferential rates and seller-collected taxes. ## Next - [Authentication](https://border.bot/docs/authentication): scopes and key handling. - [Credits and retries](https://border.bot/docs/credits): what each call costs and how to retry without paying twice. - [Errors](https://border.bot/docs/errors) and [rate limits](https://border.bot/docs/rate-limits). - [API reference](https://border.bot/docs/api): every endpoint. --- # Authentication > Authenticate border.bot REST calls with a workspace API key and scopes, and MCP clients with OAuth 2.1. Source: https://border.bot/docs/authentication Last updated: 2026-10-09 > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. ## API keys REST calls authenticate with a workspace API key in the `Authorization` header: ```http Authorization: Bearer bb_live_... ``` Create and revoke keys in the [dashboard](https://app.border.bot/developers?tab=keys) under **Developers → API keys**. A key is shown once and stored only as a hash, so a lost key can't be recovered: revoke it and create another. A key can also have an expiry date. A missing or invalid key gets `401 unauthorized` with a `WWW-Authenticate: Bearer` header. ## Scopes A key has full access, or only the scopes you pick when you create it. Each endpoint in the [reference](https://border.bot/docs/api) names the scope it needs. A key without that scope gets `403 forbidden` with `details.reason` set to `missing_scope`, and the message says which scope is missing. | Scope | Allows | | --- | --- | | `classify` | Classification: Classify products (single and batch), agency product codes, and feedback on answers. | | `calculate` | Landed cost: Landed cost for a line or a whole shipment, and duty stacking. | | `origin` | Products and origin: Read product pages and work out or check the country of origin. | | `compliance` | Compliance checks: Restricted goods checks and denied-party screening, with the screening history. | | `bulk` | Bulk runs: Start, follow and cancel bulk runs. A run also needs the scope of what it runs: Classification, or Landed cost. | | `settings` | Workspace rules: Read and change blocked codes and restriction rules. | | `account` | Account: Credit balance, ledger and usage history. | `GET /v1/me` works with any key and reports its `scopes` and `expiresAt`. ## Endpoints without a key These reference endpoints are public and rate limited per IP address: - `GET /v1/countries`: destinations and what each one supports. - `GET /v1/pricing`: what every action costs in credits. - `GET /v1/classify/modes`: the classification modes you can choose. ## MCP clients: OAuth 2.1 The MCP server at `https://api.border.bot/mcp` doesn't take API keys. MCP clients sign the user in with OAuth 2.1 (authorization code with PKCE `S256`): - Clients can register themselves with dynamic client registration (`POST https://api.border.bot/oauth/register`, RFC 7591) or use a client ID metadata document. - Scopes: `mcp:read` to read, `mcp:write` to run actions that spend credits. - Discovery: [protected resource metadata](https://api.border.bot/.well-known/oauth-protected-resource/mcp) (RFC 9728) and [authorization server metadata](https://api.border.bot/.well-known/oauth-authorization-server) (RFC 8414). Agents that register themselves should read [auth.md](https://border.bot/auth.md). ## Keeping keys safe - Call the API from your server, never from a browser or a mobile app. - Give each integration its own key with only the scopes it needs, so you can revoke one without breaking the others. - Every call is in the workspace's request log (`GET /v1/requests`, 30 days), with the key that made it. --- # Credits and retries > How border.bot charges prepaid credits per API call, refunds failed calls, and makes retries safe with Idempotency-Key. Source: https://border.bot/docs/credits Last updated: 2026-10-09 > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. ## Credits Billable calls spend prepaid credits from the workspace. Each action has a fixed price, set on the server; `GET /v1/pricing` (no key needed) lists them, and so does the [pricing page](https://border.bot/pricing). New workspaces get free credits to start with. The price is taken before the work runs, in one atomic step, so the balance can't go below zero. If the call then fails, the credits are refunded automatically. Every billable response carries: | Header | Meaning | | --------------------- | --------------------------------- | | `X-Credits-Charged` | Credits this call cost. | | `X-Credits-Remaining` | The workspace balance afterwards. | A workspace without enough credits gets `402 insufficient_credits`, with `details.required` and `details.balance`. Top up in the [dashboard](https://app.border.bot). `GET /v1/credits` returns the balance and ledger, and `GET /v1/usage` the usage history. ## Safe retries Send an `Idempotency-Key` header (any unique string, such as a UUID) on billable `POST` requests. Repeating a request with the same key returns the original result and doesn't charge again. While the first request is still running, a repeat gets `409 conflict`; wait and retry. ```bash curl -X POST https://api.border.bot/v1/classify \ -H "Authorization: Bearer $BORDERBOT_API_KEY" \ -H "Idempotency-Key: 4f9c1a52-0b8e-4c5e-9d0a-5d1f2b8a7e31" \ -H "Content-Type: application/json" \ -d '{"description":"Stainless steel water bottle, 750 ml","destinationCountry":"GB"}' ``` Retry on `429`, `502`, `504` and network errors, with the same idempotency key and backoff (honour `Retry-After`). Don't retry other `4xx` errors unchanged: fix the request first. --- # Rate limits > border.bot API rate limits per API key and per IP address, the RateLimit-Policy and Retry-After headers, and how to back off. Source: https://border.bot/docs/rate-limits Last updated: 2026-10-09 > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. ## Limits | Who | Limit | | ----------------------------------------------------------------- | ------------------------------------------- | | Calls with an API key | 120 requests per 60 seconds, per key | | Public endpoints (no key) | 120 requests per 60 seconds, per IP address | | OAuth endpoints (`/authorize`, `/oauth/token`, `/oauth/register`) | 30 requests per 60 seconds, per IP address | Batch endpoints count as one request, so use `/classify/batch`, `/origin/batch` or a [bulk run](https://border.bot/docs/api/start-bulk-run) for volume. ## Headers Responses follow the IETF HTTPAPI RateLimit header fields: ```http RateLimit-Policy: "key";q=120;w=60 ``` `q` is the number of requests allowed in a window of `w` seconds. When you go over it, the response is `429 rate_limited` with: ```http RateLimit: "key";r=0;t=60 Retry-After: 60 ``` `r` is what's left (zero) and `t` the seconds until you can send again. Wait at least `Retry-After` seconds before retrying, then send with the same `Idempotency-Key` so a retried billable call is never charged twice. Requests refused for rate limiting are never charged. --- # Errors > border.bot API error format, every error code with its HTTP status, and which errors to retry. Source: https://border.bot/docs/errors Last updated: 2026-10-09 > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. Errors return JSON with a stable, machine-readable `code`, a message written for people, and sometimes `details`: ```json { "error": { "code": "insufficient_credits", "message": "This workspace needs 5 credits and has 2.", "details": { "required": 5, "balance": 2 } } } ``` Every response carries an `X-Request-Id`. Quote it when you contact support, or find the request with `GET /v1/requests?requestId=…`. ## Codes | Code | HTTP | Meaning | | --- | --- | --- | | `invalid_input` | 400 | The request failed validation. The message names the field to fix. | | `unauthorized` | 401 | The API key is missing, malformed or revoked. | | `insufficient_credits` | 402 | The workspace balance is too low for this action. Top up in the dashboard. | | `forbidden` | 403 | The key is valid but not allowed to perform this action (a key without the scope the endpoint needs: details.reason is missing_scope). | | `not_found` | 404 | The resource or path doesn’t exist. | | `conflict` | 409 | A request with the same idempotency key is still running, or the change clashes with existing data. Wait and retry. | | `org_suspended` | 403 | The workspace is suspended. Contact support. | | `payload_too_large` | 413 | The request body is over 10 MB. Link to a photo instead of sending it inline, or split a bulk run. | | `version_retired` | 410 | The API version in the path has passed its sunset date. Move to the version the message names. | | `action_disabled` | 403 | This action is temporarily switched off. Try again later. | | `unsupported_country` | 422 | The destination isn’t covered for this action yet. The message says what is supported. | | `rate_limited` | 429 | Too many requests in a short period. Back off and retry. | | `upstream_error` | 502 | The engine couldn’t complete the request. Credits were refunded; retry. | | `upstream_timeout` | 504 | The engine took too long. Credits were refunded; retry. | | `internal` | 500 | Something went wrong on our side. Credits were refunded. | ## What to retry - `429`, `502` and `504`: retry with backoff and the same `Idempotency-Key`. Credits for a failed call are already refunded. - `409 conflict` on a repeated idempotency key: the first request is still running, so wait and retry. - Everything else: fix the request first. `invalid_input` names the field in its message and lists up to ten problems in `details.issues`. --- # Versioning > How the border.bot API is versioned by path, what counts as a breaking change, and the Deprecation and Sunset headers. Source: https://border.bot/docs/versioning Last updated: 2026-10-09 > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. The version is the first part of the path: `https://api.border.bot/v1/classify`. The current version is **v1**. URLs without a version (`/openapi.json`, `/docs`) always serve the current one. ## What can change within a version Only additions: new endpoints, new optional request fields, new response fields and new enum values. Write clients that ignore fields they don't know and handle enum values they haven't seen. Anything that would break a working client ships as a new version. ## Retiring a version When a version is deprecated, its responses carry: | Header | Meaning | | ------------------------------------ | ---------------------------------------------- | | `API-Version` | The version that answered (on every response). | | `Deprecation` | When it was deprecated (RFC 9745). | | `Sunset` | When it stops working (RFC 8594). | | `Link: <…>; rel="successor-version"` | The docs of the version to move to. | After the sunset date, the version answers `410 version_retired`. `GET https://api.border.bot/versions` lists every version with its status, dates and changes. Each version has its own OpenAPI 3.1 document at `https://api.border.bot/v1/openapi.json`. --- # MCP server > Connect Claude, ChatGPT, Codex, Cursor and other MCP clients to the border.bot remote MCP server, with OAuth sign-in. Source: https://border.bot/docs/mcp Last updated: 2026-10-09 > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. The border.bot MCP server classifies products, calculates landed cost, infers country of origin and checks restricted goods from inside an MCP client. | | | | --------- | -------------------------------------------------------------------------- | | URL | `https://api.border.bot/mcp` | | Transport | Streamable HTTP | | Auth | OAuth 2.1; the client opens a sign-in page, no API key | | Credits | Tools that run the engine spend the workspace's credits, like the REST API | ## Connect Add `https://api.border.bot/mcp` as a remote (HTTP) MCP server in your client. For example, in Claude Code: ```bash claude mcp add --transport http borderbot https://api.border.bot/mcp ``` Or in an `mcp.json` file (Cursor, VS Code and others): ```json { "mcpServers": { "borderbot": { "url": "https://api.border.bot/mcp" } } } ``` Step-by-step setup for every client, including Claude, ChatGPT, Codex, Cursor, VS Code and Gemini CLI, is on the [MCP server page](https://border.bot/mcp). The menu at the top of this page also connects Cursor and VS Code in one click. ## Tools Every tool with its input schema is public at [https://api.border.bot/mcp/tools.json](https://api.border.bot/mcp/tools.json), and the server card at [https://border.bot/.well-known/mcp/server-card.json](https://border.bot/.well-known/mcp/server-card.json). --- # Agent discovery > Machine-readable files that let AI agents find and use border.bot - llms.txt, Markdown pages, OpenAPI, MCP server card, AI catalog, agent skills and auth.md. Source: https://border.bot/docs/agents Last updated: 2026-10-09 > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. Everything here is public, needs no key and allows cross-origin requests. ## Read the docs | File | What it is | | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | | [/llms.txt](https://border.bot/llms.txt) | Index of the site and docs, with when to use border.bot | | [/llms-full.txt](https://border.bot/llms-full.txt) | Every page in one Markdown file | | Any page + `.md` | That page as Markdown, e.g. [/docs/quickstart.md](https://border.bot/docs/quickstart.md). `Accept: text/markdown` works too | | [https://api.border.bot/llms.txt](https://api.border.bot/llms.txt) | Index for the API host | ## Call the API | File | What it is | | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | | [OpenAPI 3.1](https://api.border.bot/openapi.json) | The REST API, machine-readable | | [API catalog](https://border.bot/.well-known/api-catalog) | RFC 9727 links to the OpenAPI documents and docs | | [Agent skill](https://border.bot/.well-known/agent-skills/landed-cost/SKILL.md) | How an agent should use border.bot for landed cost ([index](https://border.bot/.well-known/agent-skills/index.json)) | ## Connect over MCP | File | What it is | | ----------------------------------------------------------- | --------------------------------------------------------- | | [MCP server card](https://border.bot/.well-known/mcp/server-card.json) | Server name, version, transport endpoint and capabilities | | [MCP tools](https://api.border.bot/mcp/tools.json) | Every tool with its input schema | | [AI catalog](https://border.bot/.well-known/ai-catalog.json) | The MCP server, API and skill as catalog entries | ## Authenticate | File | What it is | | ------------------------------------------------------------------------------- | ----------------------------- | | [auth.md](https://border.bot/auth.md) | How an agent gets credentials | | [Protected resource metadata](https://border.bot/.well-known/oauth-protected-resource) | RFC 9728, for the MCP server | | [Authorization server metadata](https://api.border.bot/.well-known/oauth-authorization-server) | RFC 8414 | ## Behaviour agents can rely on - Errors are JSON with a stable `code` ([errors](https://border.bot/docs/errors)); a missing page returns `404` with a Markdown body when you ask for Markdown. - `RateLimit-Policy` and, on `429`, `RateLimit` and `Retry-After` ([rate limits](https://border.bot/docs/rate-limits)). - `Idempotency-Key` makes retries free ([credits and retries](https://border.bot/docs/credits)). --- # API reference > Every border.bot REST endpoint for HS code classification, landed cost, origin and compliance, with parameters, responses and curl examples. Source: https://border.bot/docs/api > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. Base URL `https://api.border.bot`, version 1.3.0. Machine-readable: [OpenAPI 3.1](https://api.border.bot/v1/openapi.json). Try requests in the [interactive reference](https://api.border.bot/v1/docs/interactive). Classify products to HS/HTS codes and calculate duties, taxes, fees and landed cost for cross-border parcels. **Versions**: This is **v1**, the current version. Within a version, changes are only additive (new endpoints, new optional fields, new enum values). Breaking changes ship as a new version; every version and its dates: https://api.border.bot/versions **Authentication**: send a workspace API key: `Authorization: Bearer bb_live_…`. Create keys in the dashboard. **Credits**: billable requests use prepaid credits (see `GET /v1/pricing`). Prices are set server-side; failed requests are refunded automatically. Every response includes `X-Request-Id` and `API-Version`; billable responses include `X-Credits-Charged` and `X-Credits-Remaining`. **Retries**: send an `Idempotency-Key` header on POST requests; repeating it returns the original result without charging again. **Rate limits**: 120 requests per 60 seconds per API key, and per IP address for public endpoints. Responses carry the IETF `RateLimit-Policy` header (`"key";q=120;w=60` with a key, `"ip";q=120;w=60` without). Over the limit you get 429 `rate_limited` with `RateLimit: "key";r=0;t=60` and `Retry-After` in seconds; wait that long before retrying. **Errors**: `{ "error": { "code", "message", "details"? } }` with a stable `code` (e.g. 402 `insufficient_credits`, 429 `rate_limited`). **MCP**: use border.bot from Claude, ChatGPT, Codex, Cursor, VS Code and other MCP clients at `https://api.border.bot/mcp` (OAuth, no API key). Setup guides: https://border.bot/mcp ## Classification HS/HTS codes. - [Classify a product](https://border.bot/docs/api/classify-product): `POST /v1/classify` - [Classify up to 25 products](https://border.bot/docs/api/classify-batch): `POST /v1/classify/batch` - [Find an agency product code](https://border.bot/docs/api/classify-regulator): `POST /v1/classify/regulator` - [Classification modes](https://border.bot/docs/api/classify-modes): `GET /v1/classify/modes` - [Blocked codes](https://border.bot/docs/api/list-blocked-codes): `GET /v1/classify/blocklist` - [Block a code](https://border.bot/docs/api/add-blocked-code): `POST /v1/classify/blocklist` - [Unblock a code](https://border.bot/docs/api/remove-blocked-code): `DELETE /v1/classify/blocklist` - [Block many codes](https://border.bot/docs/api/import-blocked-codes): `POST /v1/classify/blocklist/import` - [Say whether a classification was right](https://border.bot/docs/api/send-classify-feedback): `POST /v1/classify/feedback` ## Landed cost Duties, taxes and fees. - [Calculate duties, taxes and landed cost](https://border.bot/docs/api/calculate-landed-cost): `POST /v1/calculate` - [Calculate a whole shipment](https://border.bot/docs/api/calculate-shipment): `POST /v1/calculate/shipment` - [Duty stacking](https://border.bot/docs/api/duty-stacking): `POST /v1/calculate/stacking` ## Products Product pages and country of origin. - [Read a product page](https://border.bot/docs/api/extract-product): `POST /v1/products/extract` ## Compliance Restricted and prohibited goods (free). - [Check restricted goods](https://border.bot/docs/api/check-restricted-goods): `POST /v1/restrictions` - [Restricted-goods checks](https://border.bot/docs/api/list-restriction-checks): `GET /v1/restrictions/checks` - [Your restricted-goods rules](https://border.bot/docs/api/list-restriction-rules): `GET /v1/restrictions/rules` - [Add a restricted-goods rule](https://border.bot/docs/api/add-restriction-rule): `POST /v1/restrictions/rules` - [Remove a restricted-goods rule](https://border.bot/docs/api/remove-restriction-rule): `DELETE /v1/restrictions/rules` - [Screen a person or company](https://border.bot/docs/api/screen-party): `POST /v1/screen` - [Your screening checks](https://border.bot/docs/api/list-screening-checks): `GET /v1/screen/checks` ## Account Your workspace, credits and usage. - [Who am I](https://border.bot/docs/api/get-workspace): `GET /v1/me` - [Credit balance](https://border.bot/docs/api/get-credits): `GET /v1/credits` - [Usage history](https://border.bot/docs/api/list-usage): `GET /v1/usage` - [Request log](https://border.bot/docs/api/list-api-requests): `GET /v1/requests` ## Reference Public reference data (no key needed). - [Supported countries](https://border.bot/docs/api/list-countries): `GET /v1/countries` - [Pricing](https://border.bot/docs/api/get-pricing): `GET /v1/pricing` ## Origin - [Infer country of origin](https://border.bot/docs/api/infer-origin): `POST /v1/origin` - [Check a declared country of origin](https://border.bot/docs/api/validate-origin): `POST /v1/origin/validate` - [Infer or check the origin of up to 50 products](https://border.bot/docs/api/origin-batch): `POST /v1/origin/batch` ## Bulk - [Your bulk runs](https://border.bot/docs/api/list-bulk-runs): `GET /v1/bulk/runs` - [Start a bulk run](https://border.bot/docs/api/start-bulk-run): `POST /v1/bulk/runs` - [Cancel a bulk run](https://border.bot/docs/api/cancel-bulk-run): `DELETE /v1/bulk/runs` - [A bulk run’s progress](https://border.bot/docs/api/bulk-run-status): `GET /v1/bulk/status` - [A bulk run’s results](https://border.bot/docs/api/bulk-results): `GET /v1/bulk/results` --- # Classify a product (POST /v1/classify) > POST /v1/classify: Classify a product. border.bot API reference (Classification). Source: https://border.bot/docs/api/classify-product > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/classify` Requires an API key (`Authorization: Bearer bb_live_…`). Find the HS/HTS code for a product shipped to `destinationCountry`. Give a description, a product page URL, or both. Costs the mode’s credits (`GET /v1/classify/modes` lists the modes and their prices); a weak answer may escalate to another mode at no extra charge. Failed requests are refunded automatically. API key scope: `classify`. ## Headers | Name | Type | Required | Description | | --- | --- | --- | --- | | `idempotency-key` | string | no | Make retries safe: a repeat with the same key returns the original result without charging again (keys are scoped to your workspace). | ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `description` | string | no | What the product is: type, material/composition, intended use and user. Required unless `productUrl` or `imageUrl` is given. | | `productUrl` | string | no | Product page URL. border.bot reads the listing (title, brand, materials, price and any stated country of origin) and classifies from it, with your description when you give one. | | `imageUrl` | string | no | A product photo, classified with vision (in the modes that read photos: see `GET /v1/classify/modes`): a public URL, or the picture itself as a `data:image/jpeg;base64,…` URL (up to 6 MB). When given, the photo is classified instead of the listing URL. | | `destinationCountry` | string | yes | Where the parcel is going: selects the tariff (the national one where border.bot has it, else the 6-digit HS). ISO 3166-1 alpha-2, case-insensitive. | | `originCountry` | string | no | Where the product was made (context only). ISO 3166-1 alpha-2, case-insensitive. | | `mode` | string | no | The classification mode: one of the modes `GET /v1/classify/modes` lists (each with its price and what it reads). Omitted: the default mode. An unknown or unavailable mode is refused (`invalid_input`, with `details.availableModes`). | | `title` | string | no | Product title (optional extra context). | | `brand` | string | no | Brand (optional extra context). | | `sku` | string | no | Your SKU (stored with the usage record). | | `price` | number | no | Unit price (optional context). | | `currency` | string | no | ISO 4217 currency of `price`. | | `hsCodeHint` | string | no | An HS code you believe is close (2–10 digits) — used as a hint, not trusted blindly. | ## Responses - `200`: The classification and the credits charged. (`ClassifyResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `402`: Not enough credits (`insufficient_credits`). Nothing was charged. (`Error`) - `403`: Workspace suspended, action disabled, or the key lacks the scope (`org_suspended`, `action_disabled`, `forbidden`). (`Error`) - `409`: A request with this Idempotency-Key is still in progress (`conflict`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). The credits are refunded automatically. (`Error`) - `504`: The engine timed out (`upstream_timeout`). The credits are refunded automatically. (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/classify' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"description":"Men'\''s short-sleeve t-shirt, 100% cotton, knitted","destinationCountry":"US","originCountry":"PT"}' ``` --- # Classify up to 25 products (POST /v1/classify/batch) > POST /v1/classify/batch: Classify up to 25 products. border.bot API reference (Classification). Source: https://border.bot/docs/api/classify-batch > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/classify/batch` Requires an API key (`Authorization: Bearer bb_live_…`). Each item is a classify request, run four at a time and charged as one classification by its own mode; one failing (an unclassifiable description, insufficient credits) never stops the others and is refunded. With an `Idempotency-Key`, each item replays on its own. API key scope: `classify`. ## Headers | Name | Type | Required | Description | | --- | --- | --- | --- | | `idempotency-key` | string | no | Make retries safe: a repeat with the same key returns the original result without charging again (keys are scoped to your workspace). | ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `items` | ClassifyRequest[] | yes | | ## Responses - `200`: One result per item, in order. (`ClassifyBatchResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `402`: Not enough credits (`insufficient_credits`). Nothing was charged. (`Error`) - `403`: Workspace suspended, action disabled, or the key lacks the scope (`org_suspended`, `action_disabled`, `forbidden`). (`Error`) - `409`: A request with this Idempotency-Key is still in progress (`conflict`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). The credits are refunded automatically. (`Error`) - `504`: The engine timed out (`upstream_timeout`). The credits are refunded automatically. (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/classify/batch' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"items":[{"description":"Men'\''s short-sleeve t-shirt, 100% cotton, knitted","destinationCountry":"US"},{"description":"Stainless steel water bottle, 750 ml","destinationCountry":"GB"}]}' ``` --- # Find an agency product code (POST /v1/classify/regulator) > POST /v1/classify/regulator: Find an agency product code. border.bot API reference (Classification). Source: https://border.bot/docs/api/classify-regulator > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/classify/regulator` Requires an API key (`Authorization: Bearer bb_live_…`). The product code the destination’s import agency asks for, in that agency’s coding scheme: for the US, FDA’s import product code (e.g. `16AYN07`) for foods, drugs, devices, cosmetics and other goods FDA regulates. The answer names the `agency` and `scheme`, lists the code’s `parts` in order, and says whether the agency’s own check accepted it. Costs 1 credit; goods the agency doesn’t regulate are refused (`details.reason: "not_regulated"`, with `details.agency`) and refunded. API key scope: `classify`. ## Headers | Name | Type | Required | Description | | --- | --- | --- | --- | | `idempotency-key` | string | no | Make retries safe: a repeat with the same key returns the original result without charging again (keys are scoped to your workspace). | ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `description` | string | yes | What the product is, what it is made of, and how it is processed or packed (frozen, smoked, canned…). | | `destinationCountry` | string | yes | Where the goods are imported. Its import agency and coding scheme follow from it (for `US`, FDA’s import product codes). | | `hsCode` | string | no | The goods’ tariff code, when known: a hint for the product pick. | ## Responses - `200`: The agency product code and the credits charged. (`RegulatorClassifyResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `402`: Not enough credits (`insufficient_credits`). Nothing was charged. (`Error`) - `403`: Workspace suspended, action disabled, or the key lacks the scope (`org_suspended`, `action_disabled`, `forbidden`). (`Error`) - `409`: A request with this Idempotency-Key is still in progress (`conflict`). (`Error`) - `422`: No agency product codes for this destination yet (`unsupported_country`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). The credits are refunded automatically. (`Error`) - `504`: The engine timed out (`upstream_timeout`). The credits are refunded automatically. (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/classify/regulator' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"description":"","destinationCountry":""}' ``` --- # Classification modes (GET /v1/classify/modes) > GET /v1/classify/modes: Classification modes. border.bot API reference (Classification). Source: https://border.bot/docs/api/classify-modes > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/classify/modes` Public: no API key needed. The classification modes you can use (admin configures them: today `mini`, `pro` and `max`), with what each costs and reads, in general or for one destination: whether it reads a product photo, and a photo sent inline, and which mode runs when a request names none. A product page URL works in every mode. No API key needed. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `destination` | string | no | ISO-2 destination: what each mode offers there (photos sent inline need border.bot’s own classifier). | ## Responses - `200`: The modes. (`ClassifyModesResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/classify/modes' ``` --- # Blocked codes (GET /v1/classify/blocklist) > GET /v1/classify/blocklist: Blocked codes. border.bot API reference (Classification). Source: https://border.bot/docs/api/list-blocked-codes > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/classify/blocklist` Requires an API key (`Authorization: Bearer bb_live_…`). Codes your classifications never suggest: a blocked line, or every line under a blocked heading, is skipped and the next best answers. Free. API key scope: `settings`. ## Responses - `200`: Your blocked codes. (`BlockedCodesResponse`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `settings` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/classify/blocklist' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Block a code (POST /v1/classify/blocklist) > POST /v1/classify/blocklist: Block a code. border.bot API reference (Classification). Source: https://border.bot/docs/api/add-blocked-code > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/classify/blocklist` Requires an API key (`Authorization: Bearer bb_live_…`). Never suggest this code (or any line under it) again, for one destination or all. Adding a code that is already blocked updates its reason. Free; up to 5,000 codes. API key scope: `settings`. ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `code` | string | yes | | | `destination` | "*" \| string | no | | | `reason` | string | no | | ## Responses - `200`: The blocked code. (`BlockedCodeResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `settings` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/classify/blocklist' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"code":"6109.10","destination":"US","reason":"Our broker files these under 6109.90"}' ``` --- # Unblock a code (DELETE /v1/classify/blocklist) > DELETE /v1/classify/blocklist: Unblock a code. border.bot API reference (Classification). Source: https://border.bot/docs/api/remove-blocked-code > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `DELETE https://api.border.bot/v1/classify/blocklist` Requires an API key (`Authorization: Bearer bb_live_…`). Lets classifications suggest the code again. Free. API key scope: `settings`. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `code` | string | yes | | | `destination` | "*" \| string | no | | ## Responses - `200`: Whether a blocked code was removed. (`BlockedCodeRemoveResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `settings` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X DELETE 'https://api.border.bot/v1/classify/blocklist' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Block many codes (POST /v1/classify/blocklist/import) > POST /v1/classify/blocklist/import: Block many codes. border.bot API reference (Classification). Source: https://border.bot/docs/api/import-blocked-codes > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/classify/blocklist/import` Requires an API key (`Authorization: Bearer bb_live_…`). Block a list of codes at once, or with `replace: true` make the list exactly these. All or nothing: an import that would pass 5,000 codes changes nothing. Free. API key scope: `settings`. ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `codes` | object[] | yes | | | `replace` | boolean | no | | ## Responses - `200`: What the import added, updated and removed. (`BlockedCodesImportResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `settings` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/classify/blocklist/import' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"codes":[{"code":"6109.10","destination":"US","reason":"Our broker files these under 6109.90"},{"code":"9503"}],"replace":false}' ``` --- # Say whether a classification was right (POST /v1/classify/feedback) > POST /v1/classify/feedback: Say whether a classification was right. border.bot API reference (Classification). Source: https://border.bot/docs/api/send-classify-feedback > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/classify/feedback` Requires an API key (`Authorization: Bearer bb_live_…`). Tell border.bot a code was right, or what it should have been. Corrections are reviewed and become test cases the classifier must pass. With the classification’s `usageId`, sending again replaces your earlier verdict until it is reviewed. Free; up to 1,000 a day. API key scope: `classify`. ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `usageId` | string | no | | | `destinationCountry` | string | yes | | | `description` | string | yes | | | `predictedCode` | string | yes | | | `verdict` | "right" \| "wrong" | yes | | | `correctCode` | string | no | | | `reason` | string | no | | | `mode` | string | no | | | `productUrl` | string (uri) | no | | ## Responses - `200`: The feedback was recorded. (`ClassifyFeedbackResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `classify` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/classify/feedback' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"usageId":"use_01J9ZK8Q7X4N2M","destinationCountry":"US","description":"Yoga mat, 6 mm, TPE","predictedCode":"3926909985","verdict":"wrong","correctCode":"9506910030","reason":"Exercise equipment, not an article of plastics"}' ``` --- # Calculate duties, taxes and landed cost (POST /v1/calculate) > POST /v1/calculate: Calculate duties, taxes and landed cost. border.bot API reference (Landed cost). Source: https://border.bot/docs/api/calculate-landed-cost > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/calculate` Requires an API key (`Authorization: Bearer bb_live_…`). Duties, taxes, fees and the landed cost for one HS code / origin / destination (the destinations `GET /countries` marks `landedCost`). Costs 1 credit. Unsupported destinations return 422 `unsupported_country` without charging. API key scope: `calculate`. ## Headers | Name | Type | Required | Description | | --- | --- | --- | --- | | `idempotency-key` | string | no | Make retries safe: a repeat with the same key returns the original result without charging again (keys are scoped to your workspace). | ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `destinationCountry` | string | yes | Destination: one `GET /countries` marks `landedCost`. ISO 3166-1 alpha-2, case-insensitive. | | `currency` | string | no | ISO 4217 currency of `value`, `shippingCost` and `insuranceCost`. | | `shippingCost` | number | no | Shipping cost (affects CIF-based duty/VAT bases). | | `insuranceCost` | number | no | Insurance cost. | | `transportMode` | "air" \| "sea" \| "road" \| "rail" | no | Transport mode (fees such as HMF apply to sea freight). | | `shippingTerms` | "EXW" \| "FCA" \| "FAS" \| "FOB" \| "CFR" \| "CIF" \| "CPT" \| "CIP" \| "DAP" \| "DPU" \| "DDP" | no | Incoterm of the price (Incoterms 2020). Under C and D terms (CFR, CIF, CPT, CIP, DAP, DPU, DDP) the price already carries the goods to the destination, so `shippingCost` isn’t added to the customs value again. | | `shipmentChannel` | "courier" \| "postal" | no | How the parcel travels: `courier` (express carriers, default) or `postal` — affects de minimis and channel-specific regimes. | | `entryDate` | string | no | Calculate with the rates in force on this date (YYYY-MM-DD). Default: today. | | `tradeAgreement` | string | no | Ignored. Preferential rates are applied automatically from the origin and destination; the agreement used is returned as `tradeAgreement`. | | `region` | string | no | State, province or territory, where import taxes differ inside the country. Canada needs one (`ON`, `QC`, `BC`…). | | `purpose` | "sale" \| "gift" \| "sample" \| "return" | no | Why the goods are sent: some thresholds differ for gifts, samples and returns. Default: `sale`. | | `businessBuyer` | boolean | no | The buyer is a business: some taxes are reverse-charged or apply differently. | | `sellerRegistrations` | string[] | no | Tax schemes the seller is registered for (`EU_IOSS`, `GB_VAT`, `AU_GST`, `NZ_GST`, `NO_VOEC`…). Taxes the seller collects at checkout are returned with `collectedBy: "seller"`. | | `preference` | string | no | `best` (default): the lowest preferential rate the origin qualifies for. `none`: the general rate only. Or a programme code (`S` for USMCA into the US). Every option is returned in `options`. | | `claims` | string[] | no | Exemption, relief and quota codes being claimed (US Chapter 99 exclusions such as `9903.88.69`; an end-use authorisation such as TARIC document `N990`; a tariff quota order number such as `050331`). Codes you could claim are returned in `claims.available`. | | `enforceValidation` | boolean | no | Refuse a shipment that matches one of the destination’s `reject` validation rules (400 `invalid_input`, `details.reason: "validation_failed"`, refunded) instead of reporting it in `validation`. | | `hsCode` | string | yes | HS/HTS code (4–10 digits; dots and spaces are ignored). | | `originCountry` | string | yes | Country of origin — drives preferential rates and additional duties (e.g. Section 301). ISO 3166-1 alpha-2, case-insensitive. | | `value` | number | yes | Total customs value of the goods in the shipment (unit price × quantity), in `currency`, excluding shipping. | | `quantity` | integer | no | Number of units. | | `weight` | number | no | Shipment weight (needed for weight-based duties). Requires `weightUnit`. | | `weightUnit` | "kg" \| "lb" | no | Unit of `weight`. | | `volumeLiters` | number | no | Volume of the goods in litres, for duties charged per litre (wine, spirits, fuel). | | `alcoholPercent` | number | no | Alcohol by volume (%), for duties charged per litre of pure alcohol. | | `components` | object[] | no | Metal content by value (line totals in `currency`), for duties charged on it: US Section 232 steel, aluminum and copper derivatives. Without it, those duties come back as `regulatory` (conditional). | | `metalWeightPercent` | number | no | Share of the product’s weight that is metal (0–100), for content-based exemptions. | | `conditions` | string[] | no | Rate conditions the goods meet, when the destination reserves a rate for them: a harmonised kind (`pharmaceutical`, `end_use`, `certificate`, `company`, `quality`, `route`) or the publisher’s own code (EU TARIC additional code `2500`). Without it the default rate is charged (the unconditional one, or the highest when every rate has a condition); the rates you could claim are returned in `options` with their `condition`. The importer must hold what justifies a claimed condition. | ## Responses - `200`: The landed-cost breakdown and the credits charged. (`CalculateResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `402`: Not enough credits (`insufficient_credits`). Nothing was charged. (`Error`) - `403`: Workspace suspended, action disabled, or the key lacks the scope (`org_suspended`, `action_disabled`, `forbidden`). (`Error`) - `409`: A request with this Idempotency-Key is still in progress (`conflict`). (`Error`) - `422`: Destination not supported (`unsupported_country`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). The credits are refunded automatically. (`Error`) - `504`: The engine timed out (`upstream_timeout`). The credits are refunded automatically. (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/calculate' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"hsCode":"6109.10.00.12","originCountry":"CN","destinationCountry":"US","value":120,"currency":"USD","shippingCost":15}' ``` --- # Calculate a whole shipment (POST /v1/calculate/shipment) > POST /v1/calculate/shipment: Calculate a whole shipment. border.bot API reference (Landed cost). Source: https://border.bot/docs/api/calculate-shipment > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/calculate/shipment` Requires an API key (`Authorization: Bearer bb_live_…`). Duties, taxes, fees and the landed cost of a cart or order to one destination: up to 50 lines, freight and insurance shared out by value, one de minimis check, and per-entry fees charged once. Costs 1 credit per line. Priced on border.bot’s own data: a destination it doesn’t cover yet returns 422 `unsupported_country` without charging. API key scope: `calculate`. ## Headers | Name | Type | Required | Description | | --- | --- | --- | --- | | `idempotency-key` | string | no | Make retries safe: a repeat with the same key returns the original result without charging again (keys are scoped to your workspace). | ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `destinationCountry` | string | yes | Destination: one `GET /countries` marks `landedCost`. ISO 3166-1 alpha-2, case-insensitive. | | `currency` | string | no | ISO 4217 currency of `value`, `shippingCost` and `insuranceCost`. | | `shippingCost` | number | no | Shipping cost (affects CIF-based duty/VAT bases). | | `insuranceCost` | number | no | Insurance cost. | | `transportMode` | "air" \| "sea" \| "road" \| "rail" | no | Transport mode (fees such as HMF apply to sea freight). | | `shippingTerms` | "EXW" \| "FCA" \| "FAS" \| "FOB" \| "CFR" \| "CIF" \| "CPT" \| "CIP" \| "DAP" \| "DPU" \| "DDP" | no | Incoterm of the price (Incoterms 2020). Under C and D terms (CFR, CIF, CPT, CIP, DAP, DPU, DDP) the price already carries the goods to the destination, so `shippingCost` isn’t added to the customs value again. | | `shipmentChannel` | "courier" \| "postal" | no | How the parcel travels: `courier` (express carriers, default) or `postal` — affects de minimis and channel-specific regimes. | | `entryDate` | string | no | Calculate with the rates in force on this date (YYYY-MM-DD). Default: today. | | `tradeAgreement` | string | no | Ignored. Preferential rates are applied automatically from the origin and destination; the agreement used is returned as `tradeAgreement`. | | `region` | string | no | State, province or territory, where import taxes differ inside the country. Canada needs one (`ON`, `QC`, `BC`…). | | `purpose` | "sale" \| "gift" \| "sample" \| "return" | no | Why the goods are sent: some thresholds differ for gifts, samples and returns. Default: `sale`. | | `businessBuyer` | boolean | no | The buyer is a business: some taxes are reverse-charged or apply differently. | | `sellerRegistrations` | string[] | no | Tax schemes the seller is registered for (`EU_IOSS`, `GB_VAT`, `AU_GST`, `NZ_GST`, `NO_VOEC`…). Taxes the seller collects at checkout are returned with `collectedBy: "seller"`. | | `preference` | string | no | `best` (default): the lowest preferential rate the origin qualifies for. `none`: the general rate only. Or a programme code (`S` for USMCA into the US). Every option is returned in `options`. | | `claims` | string[] | no | Exemption, relief and quota codes being claimed (US Chapter 99 exclusions such as `9903.88.69`; an end-use authorisation such as TARIC document `N990`; a tariff quota order number such as `050331`). Codes you could claim are returned in `claims.available`. | | `enforceValidation` | boolean | no | Refuse a shipment that matches one of the destination’s `reject` validation rules (400 `invalid_input`, `details.reason: "validation_failed"`, refunded) instead of reporting it in `validation`. | | `items` | object[] | yes | The shipment’s lines (up to 50), each with its code, origin and line value. Freight and insurance are shared out by value. | ## Responses - `200`: The shipment’s landed cost, line by line, and the credits charged. (`CalculateShipmentResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `402`: Not enough credits (`insufficient_credits`). Nothing was charged. (`Error`) - `403`: Workspace suspended, action disabled, or the key lacks the scope (`org_suspended`, `action_disabled`, `forbidden`). (`Error`) - `409`: A request with this Idempotency-Key is still in progress (`conflict`). (`Error`) - `422`: Destination not covered by border.bot’s own data (`unsupported_country`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). The credits are refunded automatically. (`Error`) - `504`: The engine timed out (`upstream_timeout`). The credits are refunded automatically. (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/calculate/shipment' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"destinationCountry":"GB","currency":"USD","shippingCost":12,"items":[{"hsCode":"6109.10","originCountry":"CN","value":60,"quantity":3},{"hsCode":"6204.62","originCountry":"BD","value":45}]}' ``` --- # Duty stacking (POST /v1/calculate/stacking) > POST /v1/calculate/stacking: Duty stacking. border.bot API reference (Landed cost). Source: https://border.bot/docs/api/duty-stacking > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/calculate/stacking` Requires an API key (`Authorization: Bearer bb_live_…`). Which duty lines apply to a code from an origin on a date, without a shipment: the base duty, then every additional measure (Section 301, 232, reciprocal…), which exemption codes remove which, the measures that depend on metal content or a claim, and the claim codes you could file. Up to 100 lines; free unless your pricing says otherwise. Answers from border.bot’s own data: a destination it doesn’t cover returns 422 `unsupported_country`. API key scope: `calculate`. ## Headers | Name | Type | Required | Description | | --- | --- | --- | --- | | `idempotency-key` | string | no | Make retries safe: a repeat with the same key returns the original result without charging again (keys are scoped to your workspace). | ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `items` | object[] | yes | | ## Responses - `200`: Each line’s stack. (`StackingResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `402`: Not enough credits (`insufficient_credits`). Nothing was charged. (`Error`) - `403`: Workspace suspended, action disabled, or the key lacks the scope (`org_suspended`, `action_disabled`, `forbidden`). (`Error`) - `409`: A request with this Idempotency-Key is still in progress (`conflict`). (`Error`) - `422`: A destination border.bot’s own data doesn’t cover yet (`unsupported_country`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). The credits are refunded automatically. (`Error`) - `504`: The engine timed out (`upstream_timeout`). The credits are refunded automatically. (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/calculate/stacking' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"items":[{"hsCode":"8479.89.94","originCountry":"CN","destinationCountry":"US"}]}' ``` --- # Read a product page (POST /v1/products/extract) > POST /v1/products/extract: Read a product page. border.bot API reference (Products). Source: https://border.bot/docs/api/extract-product > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/products/extract` Requires an API key (`Authorization: Bearer bb_live_…`). Fetch a product page and extract its title, brand, price, materials, images and any stated country of origin. API key scope: `origin`. ## Headers | Name | Type | Required | Description | | --- | --- | --- | --- | | `idempotency-key` | string | no | Make retries safe: a repeat with the same key returns the original result without charging again (keys are scoped to your workspace). | ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `url` | string | yes | Product page URL (http/https). | ## Responses - `200`: The extracted product. (`ExtractProductResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `402`: Not enough credits (`insufficient_credits`). Nothing was charged. (`Error`) - `403`: Workspace suspended, action disabled, or the key lacks the scope (`org_suspended`, `action_disabled`, `forbidden`). (`Error`) - `409`: A request with this Idempotency-Key is still in progress (`conflict`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). The credits are refunded automatically. (`Error`) - `504`: The engine timed out (`upstream_timeout`). The credits are refunded automatically. (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/products/extract' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"url":""}' ``` --- # Check restricted goods (POST /v1/restrictions) > POST /v1/restrictions: Check restricted goods. border.bot API reference (Compliance). Source: https://border.bot/docs/api/check-restricted-goods > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/restrictions` Requires an API key (`Authorization: Bearer bb_live_…`). Check items against the destination’s import prohibitions and restrictions and, when `originCountry` is given, the origin’s export rules (sanctions, agency requirements such as FDA or APHIS), plus your own rules (`/restrictions/rules`). It uses no credits and is limited to 10 checks per minute per workspace (up to 100 items each). Destinations without coverage return 422 `unsupported_country`. API key scope: `compliance`. ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `destinationCountry` | string | yes | Ship-to country — its import rules are checked. ISO 3166-1 alpha-2, case-insensitive. | | `originCountry` | string | no | Ship-from country — its export rules are checked when given. ISO 3166-1 alpha-2, case-insensitive. | | `items` | RestrictionItem[] | yes | 1–100 items. | | `reference` | string | no | Your reference (an order or customer id), kept with the check as evidence. | ## Responses - `200`: Matches per item (an empty `restrictions` list means nothing matched). (`RestrictionsResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `compliance` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `422`: Restricted-goods checks are not available for this destination (`unsupported_country`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). (`Error`) - `504`: The engine timed out (`upstream_timeout`). (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/restrictions' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"destinationCountry":"US","originCountry":"CN","items":[{"sku":"LAMP-01","title":"Lithium battery desk lamp","hsCode":"9405.21"}]}' ``` --- # Restricted-goods checks (GET /v1/restrictions/checks) > GET /v1/restrictions/checks: Restricted-goods checks. border.bot API reference (Compliance). Source: https://border.bot/docs/api/list-restriction-checks > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/restrictions/checks` Requires an API key (`Authorization: Bearer bb_live_…`). Your restricted-goods checks, newest first (up to 200): the evidence of what was checked, for which lane, by which engine, and what matched. Free. API key scope: `compliance`. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `limit` | integer | no | | ## Responses - `200`: Your checks. (`RestrictionChecksResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `compliance` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/restrictions/checks' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Your restricted-goods rules (GET /v1/restrictions/rules) > GET /v1/restrictions/rules: Your restricted-goods rules. border.bot API reference (Compliance). Source: https://border.bot/docs/api/list-restriction-rules > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/restrictions/rules` Requires an API key (`Authorization: Bearer bb_live_…`). Rules your restricted-goods checks apply on top of border.bot’s (a compliance team’s own list). Free. API key scope: `settings`. ## Responses - `200`: Your rules. (`RestrictionRulesResponse`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `settings` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/restrictions/rules' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Add a restricted-goods rule (POST /v1/restrictions/rules) > POST /v1/restrictions/rules: Add a restricted-goods rule. border.bot API reference (Compliance). Source: https://border.bot/docs/api/add-restriction-rule > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/restrictions/rules` Requires an API key (`Authorization: Bearer bb_live_…`). A rule matched by HS code (and everything under it), by words in the item, or by origin, for one country or `*`. Free. API key scope: `settings`. ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `country` | "*" \| string | no | | | `direction` | "import" \| "export" | no | | | `ruleType` | "prohibition" \| "restriction" \| "observation" | yes | | | `code` | string | no | | | `keywords` | string[] | no | | | `origins` | string[] | no | | | `title` | string | yes | | | `summary` | string | no | | ## Responses - `200`: The rule. (`RestrictionRuleResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `settings` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/restrictions/rules' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"country":"US","ruleType":"prohibition","code":"9304","keywords":["airsoft"],"title":"No airsoft or air guns (company policy)"}' ``` --- # Remove a restricted-goods rule (DELETE /v1/restrictions/rules) > DELETE /v1/restrictions/rules: Remove a restricted-goods rule. border.bot API reference (Compliance). Source: https://border.bot/docs/api/remove-restriction-rule > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `DELETE https://api.border.bot/v1/restrictions/rules` Requires an API key (`Authorization: Bearer bb_live_…`). Removes one of your rules by its id. Free. API key scope: `settings`. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string (uuid) | yes | The rule’s id. | ## Responses - `200`: Whether a rule was removed. (`RestrictionRuleRemoveResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `settings` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X DELETE 'https://api.border.bot/v1/restrictions/rules' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Screen a person or company (POST /v1/screen) > POST /v1/screen: Screen a person or company. border.bot API reference (Compliance). Source: https://border.bot/docs/api/screen-party > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/screen` Requires an API key (`Authorization: Bearer bb_live_…`). Check a name (and a company) against denied-party lists: the US Consolidated Screening List (the SDN list, the Entity List, the Denied Persons List and the other export-screening lists of Commerce, State and the Treasury). Names and aliases match exactly or fuzzily (from 0.7); each check is kept as your evidence. Free, up to 60 a minute per workspace. A match is a lead to review, not a verdict. API key scope: `compliance`. ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `name` | string | yes | The person’s or company’s name, as you have it. | | `company` | string | no | A company to screen too (a buyer and their employer, say). | | `country` | string | no | The party’s country (ISO-2): matches with an address, nationality or flag there are flagged `countryMatch`. | | `type` | "individual" \| "entity" | no | Only parties of this type. Vessels, aircraft and parties of unknown type are always screened. | | `reference` | string | no | Your reference (an order or customer id), kept with the check as evidence. | ## Responses - `200`: The matches, best first, and the lists screened. (`ScreenResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `compliance` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/screen' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"name":""}' ``` --- # Your screening checks (GET /v1/screen/checks) > GET /v1/screen/checks: Your screening checks. border.bot API reference (Compliance). Source: https://border.bot/docs/api/list-screening-checks > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/screen/checks` Requires an API key (`Authorization: Bearer bb_live_…`). Every screening your workspace ran, newest first: the evidence that a name was screened, when, against which lists, and what matched. Free. API key scope: `compliance`. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `limit` | integer | no | | ## Responses - `200`: Your checks. (`ScreeningChecksResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `compliance` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/screen/checks' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Who am I (GET /v1/me) > GET /v1/me: Who am I. border.bot API reference (Account). Source: https://border.bot/docs/api/get-workspace > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/me` Requires an API key (`Authorization: Bearer bb_live_…`). The workspace and API key behind this request, with the current credit balance. Any API key may call this. ## Responses - `200`: The calling workspace. (`MeResponse`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/me' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Credit balance (GET /v1/credits) > GET /v1/credits: Credit balance. border.bot API reference (Account). Source: https://border.bot/docs/api/get-credits > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/credits` Requires an API key (`Authorization: Bearer bb_live_…`). Current balance, lifetime totals and the 20 most recent ledger entries (purchases, usage, refunds). API key scope: `account`. ## Responses - `200`: Balance and recent ledger. (`CreditsResponse`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `account` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/credits' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Usage history (GET /v1/usage) > GET /v1/usage: Usage history. border.bot API reference (Account). Source: https://border.bot/docs/api/list-usage > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/usage` Requires an API key (`Authorization: Bearer bb_live_…`). Every billable request made by the workspace (dashboard, API and MCP), newest first, with cursor pagination. API key scope: `account`. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `limit` | integer | no | Page size (1–100). | | `cursor` | string | no | Opaque cursor from a previous page. | | `action` | "classify" \| "classify_max" \| "classify_regulator" \| "calculate" \| "calculate_stacking" \| "extract_product" \| "infer_origin" | no | Only this action. | ## Responses - `200`: A page of usage events. (`UsageResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `account` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/usage' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Request log (GET /v1/requests) > GET /v1/requests: Request log. border.bot API reference (Account). Source: https://border.bot/docs/api/list-api-requests > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/requests` Requires an API key (`Authorization: Bearer bb_live_…`). Every request your API keys made in the last 30 days, newest first: what it called, how it ended (status and error code), how long it took, and, for requests that change something, the body. Quote a request's `requestId` (its `X-Request-Id`) to support. API key scope: `account`. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `limit` | integer | no | Page size (1–100). | | `cursor` | string | no | The `next` of the previous page. | | `failed` | "true" \| "false" | no | `true`: only requests that failed (status 400 and up). | | `requestId` | string | no | One request, by the `X-Request-Id` its response carried. | ## Responses - `200`: A page of requests. (`ApiRequestsResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `account` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/requests' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Supported countries (GET /v1/countries) > GET /v1/countries: Supported countries. border.bot API reference (Reference). Source: https://border.bot/docs/api/list-countries > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/countries` Public: no API key needed. All ISO countries with the nomenclature classification answers in (a 10-digit national tariff where border.bot has one, 6-digit HS elsewhere) and whether landed-cost calculation is supported. No API key needed. ## Responses - `200`: Country coverage. (`CountriesResponse`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/countries' ``` --- # Pricing (GET /v1/pricing) > GET /v1/pricing: Pricing. border.bot API reference (Reference). Source: https://border.bot/docs/api/get-pricing > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/pricing` Public: no API key needed. Credits per action, credit packs and free-tool limits. No API key needed. ## Responses - `200`: Current pricing. (`PricingResponse`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/pricing' ``` --- # Infer country of origin (POST /v1/origin) > POST /v1/origin: Infer country of origin. border.bot API reference (Origin). Source: https://border.bot/docs/api/infer-origin > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/origin` Requires an API key (`Authorization: Bearer bb_live_…`). Where a product is made, as a probability per country with the evidence behind each: the product page’s data, “Made in …” text, a label in the photo, an AI estimate from brand, materials and price, the ship-from country and the barcode’s GS1 prefix. An AI estimate alone is never reported as high confidence. `needsReview` (with `reviewReason`) says when a person should confirm, because origin drives duty rates: below `reviewThreshold` (the request’s, else the workspace’s setting, else the platform default of 0.8), or when strong evidence disagrees. API key scope: `origin`. ## Headers | Name | Type | Required | Description | | --- | --- | --- | --- | | `idempotency-key` | string | no | Make retries safe: a repeat with the same key returns the original result without charging again (keys are scoped to your workspace). | ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `productUrl` | string | no | Product page URL: its structured data and “Made in …” text are read first. | | `imageUrl` | string | no | Product photo (JPEG, PNG, WebP or GIF, up to 6 MB), as an http(s) URL or a base64 data URL: a visible “Made in …” label is strong evidence. | | `description` | string | no | Product description. | | `title` | string | no | Product name. | | `brand` | string | no | Brand. | | `sku` | string | no | Your SKU (kept with the result). | | `gtin` | string | no | Barcode (GTIN, UPC, EAN). Its GS1 prefix shows where the brand registered: a weak hint, never proof. | | `material` | string | no | Main materials. | | `categories` | string[] | no | Category path, broadest first. | | `price` | number | no | Selling price, in `currency`. | | `currency` | string | no | ISO 4217 currency of `price`. | | `shipFromCountry` | string | no | Country the goods ship from (often, not always, where they are made). ISO 3166-1 alpha-2, case-insensitive. | | `reviewThreshold` | number | no | When `needsReview` is set (0–1). Inferring: an answer below this probability. Validating: a declaration whose `probabilityOfMisrepresentation` is at or above it. Without it, the workspace’s setting (dashboard → Settings → Origin review) applies, then the platform default (0.8 to infer, 0.3 to validate). | ## Responses - `200`: The most likely origin, its probability, the alternates and the evidence. (`InferOriginResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `402`: Not enough credits (`insufficient_credits`). Nothing was charged. (`Error`) - `403`: Workspace suspended, action disabled, or the key lacks the scope (`org_suspended`, `action_disabled`, `forbidden`). (`Error`) - `409`: A request with this Idempotency-Key is still in progress (`conflict`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). The credits are refunded automatically. (`Error`) - `504`: The engine timed out (`upstream_timeout`). The credits are refunded automatically. (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/origin' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"title":"Organic cotton tee","brand":"Example","productUrl":"https://shop.example.com/products/organic-tee"}' ``` --- # Check a declared country of origin (POST /v1/origin/validate) > POST /v1/origin/validate: Check a declared country of origin. border.bot API reference (Origin). Source: https://border.bot/docs/api/validate-origin > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/origin/validate` Requires an API key (`Authorization: Bearer bb_live_…`). How believable a declared origin is, given everything else known about the product: the share of the evidence pointing elsewhere (`probabilityOfMisrepresentation`), a verdict, the likely origin, and the reasons in words. With no evidence either way the verdict is `unknown`, never a guess. `needsReview` flags it when the misrepresentation probability reaches `reviewThreshold` (the request’s, else the workspace’s setting, else the platform default of 0.3), or when there is no evidence. API key scope: `origin`. ## Headers | Name | Type | Required | Description | | --- | --- | --- | --- | | `idempotency-key` | string | no | Make retries safe: a repeat with the same key returns the original result without charging again (keys are scoped to your workspace). | ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `productUrl` | string | no | Product page URL: its structured data and “Made in …” text are read first. | | `imageUrl` | string | no | Product photo (JPEG, PNG, WebP or GIF, up to 6 MB), as an http(s) URL or a base64 data URL: a visible “Made in …” label is strong evidence. | | `description` | string | no | Product description. | | `title` | string | no | Product name. | | `brand` | string | no | Brand. | | `sku` | string | no | Your SKU (kept with the result). | | `gtin` | string | no | Barcode (GTIN, UPC, EAN). Its GS1 prefix shows where the brand registered: a weak hint, never proof. | | `material` | string | no | Main materials. | | `categories` | string[] | no | Category path, broadest first. | | `price` | number | no | Selling price, in `currency`. | | `currency` | string | no | ISO 4217 currency of `price`. | | `shipFromCountry` | string | no | Country the goods ship from (often, not always, where they are made). ISO 3166-1 alpha-2, case-insensitive. | | `reviewThreshold` | number | no | When `needsReview` is set (0–1). Inferring: an answer below this probability. Validating: a declaration whose `probabilityOfMisrepresentation` is at or above it. Without it, the workspace’s setting (dashboard → Settings → Origin review) applies, then the platform default (0.8 to infer, 0.3 to validate). | | `declaredOrigin` | string | yes | The country of origin declared (by a supplier, a listing, a customs entry). ISO 3166-1 alpha-2, case-insensitive. | ## Responses - `200`: The verdict on the declared origin, with reasons. (`ValidateOriginResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `402`: Not enough credits (`insufficient_credits`). Nothing was charged. (`Error`) - `403`: Workspace suspended, action disabled, or the key lacks the scope (`org_suspended`, `action_disabled`, `forbidden`). (`Error`) - `409`: A request with this Idempotency-Key is still in progress (`conflict`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). The credits are refunded automatically. (`Error`) - `504`: The engine timed out (`upstream_timeout`). The credits are refunded automatically. (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/origin/validate' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"declaredOrigin":"US","title":"Wireless earbuds","description":"Bluetooth 5.3. Made in China."}' ``` --- # Infer or check the origin of up to 50 products (POST /v1/origin/batch) > POST /v1/origin/batch: Infer or check the origin of up to 50 products. border.bot API reference (Origin). Source: https://border.bot/docs/api/origin-batch > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/origin/batch` Requires an API key (`Authorization: Bearer bb_live_…`). Each item is inferred, or validated when it has `declaredOrigin`. Items run four at a time, each charged as one origin call; one failing (bad photo, insufficient credits) never stops the others. With an `Idempotency-Key`, each item replays on its own. API key scope: `origin`. ## Headers | Name | Type | Required | Description | | --- | --- | --- | --- | | `idempotency-key` | string | no | Make retries safe: a repeat with the same key returns the original result without charging again (keys are scoped to your workspace). | ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | | `items` | object[] | yes | | | `reviewThreshold` | number | no | The review threshold for every item that doesn’t set its own `reviewThreshold` (see `POST /v1/origin`). | ## Responses - `200`: One result per item, in order. (`OriginBatchResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `402`: Not enough credits (`insufficient_credits`). Nothing was charged. (`Error`) - `403`: Workspace suspended, action disabled, or the key lacks the scope (`org_suspended`, `action_disabled`, `forbidden`). (`Error`) - `409`: A request with this Idempotency-Key is still in progress (`conflict`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) - `502`: The engine failed (`upstream_error`). The credits are refunded automatically. (`Error`) - `504`: The engine timed out (`upstream_timeout`). The credits are refunded automatically. (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/origin/batch' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"items":[{"title":"Organic cotton tee","brand":"Example"},{"title":"Wireless earbuds","declaredOrigin":"US","gtin":"6901234567892"}]}' ``` --- # Your bulk runs (GET /v1/bulk/runs) > GET /v1/bulk/runs: Your bulk runs. border.bot API reference (Bulk). Source: https://border.bot/docs/api/list-bulk-runs > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/bulk/runs` Requires an API key (`Authorization: Bearer bb_live_…`). Your workspace’s bulk runs, newest first. API key scope: `bulk`. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `limit` | integer | no | | ## Responses - `200`: The runs. (`BulkRunsResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `bulk` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/bulk/runs' \ -H 'Authorization: Bearer bb_live_...' ``` --- # Start a bulk run (POST /v1/bulk/runs) > POST /v1/bulk/runs: Start a bulk run. border.bot API reference (Bulk). Source: https://border.bot/docs/api/start-bulk-run > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `POST https://api.border.bot/v1/bulk/runs` Requires an API key (`Authorization: Bearer bb_live_…`). Classify, calculate, find agency product codes or find and check countries of origin for up to 10,000 items in the background. Each item is charged when it runs (as its single request would be) and refunded if it fails; a run stops when your credits run out. Follow it with `GET /bulk/status`, read its answers with `GET /bulk/results`. API key scope: `bulk`. ## Request body (JSON) | Name | Type | Required | Description | | --- | --- | --- | --- | ## Responses - `200`: The run, queued. (`BulkRunResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `bulk` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X POST 'https://api.border.bot/v1/bulk/runs' \ -H 'Authorization: Bearer bb_live_...' \ -H 'Content-Type: application/json' \ -d '{"kind":"classify","reference":"catalogue-2026-10","items":[{"description":"Men'\''s cotton t-shirt","destinationCountry":"US"},{"description":"Stainless steel water bottle, 750 ml","destinationCountry":"GB"}]}' ``` --- # Cancel a bulk run (DELETE /v1/bulk/runs) > DELETE /v1/bulk/runs: Cancel a bulk run. border.bot API reference (Bulk). Source: https://border.bot/docs/api/cancel-bulk-run > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `DELETE https://api.border.bot/v1/bulk/runs` Requires an API key (`Authorization: Bearer bb_live_…`). Stops a run after the chunk it is working on. Items already done stay done (and charged). API key scope: `bulk`. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | | ## Responses - `200`: The run, cancelled. (`BulkRunResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `bulk` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X DELETE 'https://api.border.bot/v1/bulk/runs' \ -H 'Authorization: Bearer bb_live_...' ``` --- # A bulk run’s progress (GET /v1/bulk/status) > GET /v1/bulk/status: A bulk run’s progress. border.bot API reference (Bulk). Source: https://border.bot/docs/api/bulk-run-status > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/bulk/status` Requires an API key (`Authorization: Bearer bb_live_…`). How far a run has got: items done, succeeded and failed, and the credits charged so far. API key scope: `bulk`. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | | ## Responses - `200`: The run. (`BulkRunResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `bulk` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/bulk/status' \ -H 'Authorization: Bearer bb_live_...' ``` --- # A bulk run’s results (GET /v1/bulk/results) > GET /v1/bulk/results: A bulk run’s results. border.bot API reference (Bulk). Source: https://border.bot/docs/api/bulk-results > Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`. `GET https://api.border.bot/v1/bulk/results` Requires an API key (`Authorization: Bearer bb_live_…`). The answers so far, in item order, up to 1,000 at a time (`next` is the following page’s `offset`). Each is exactly what its single endpoint returns, or the error it failed with. API key scope: `bulk`. ## Parameters | Name | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | yes | | | `offset` | integer \| null | no | | | `limit` | integer | no | | ## Responses - `200`: A page of results. (`BulkResultsResponse`) - `400`: Invalid input (`invalid_input`). (`Error`) - `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`) - `403`: The API key doesn’t have the `bulk` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`) - `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`) - `500`: Unexpected error (`internal`). (`Error`) ## Example ```bash curl -X GET 'https://api.border.bot/v1/bulk/results' \ -H 'Authorization: Bearer bb_live_...' ``` --- # The EU’s €3 customs duty on parcels under €150 > Since 1 July 2026 the EU charges a temporary €3 customs duty on low-value parcels, once per tariff classification. What it covers, who pays and how it adds up. Source: https://border.bot/blog/eu-3-euro-customs-duty Last updated: 2026-10-08 By border.bot team · Published 2026-10-08 · 2 min read · Tags: de minimis, European Union, duties, VAT Rules as of 8 October 2026. Customs rules change; check the source at the end before you rely on any detail. **Since 1 July 2026, the EU charges a temporary €3 customs duty on parcels worth up to €150 imported from outside the EU.** Before that date, these low-value parcels were exempt from customs duty. ## What the rule covers The duty applies to low-value parcels sent into the EU from outside it, most of them ecommerce orders. The European Commission lists clothing, toys, electronics and other consumer goods worth up to €150 as examples, and describes the duty as temporary. Import VAT is a separate charge. It has applied to ecommerce imports of any value since 1 July 2021, collected either at checkout through the Import One-Stop Shop (IOSS) or when the parcel is imported. ## €3 per tariff classification, not per item The Commission says the duty applies “per item, based on tariff classification and not quantity”. Its examples: - **5 T-shirts:** €3, because all T-shirts fall under the same tariff classification. - **3 T-shirts and a watch:** €6, because T-shirts and watches fall under two different tariff classifications. So an order pays €3 for each distinct tariff classification in it. To know what an order owes, you need the tariff code of every product in it. ## Who pays The seller or the importer declares and pays the duty as part of the customs process. If you ship DDP, it is part of what you collect at checkout. If you ship DAP, your customer pays it on arrival, usually with a carrier handling fee on top. ## A worked example A customer in Germany orders a €40 hoodie and a €12 cap from a store outside the EU. | Line | Amount | | ----------------------------------- | -------------------------------------- | | Goods | €52 | | Customs duty: hoodie classification | €3 | | Customs duty: cap classification | €3 | | Import VAT | Germany’s VAT rate, charged separately | Customs duty for the order is €6. Import VAT is added on top at the destination country’s rate. ## What to do as a seller - **Classify each product** to its EU tariff code. The [free HS code classifier](/tools/hs-code-classifier) returns the EU Combined Nomenclature code for EU destinations. - **Count tariff classifications per order,** not items, when you estimate the duty. - **Show the total at checkout** if you ship DDP. The [landed cost calculator](/tools/landed-cost-calculator) covers EU destinations. ## Source - European Commission, _Ensuring fairness and safety: €3 customs duty for low-value parcels_ (29 June 2026): [commission.europa.eu](https://commission.europa.eu/news-and-media/news/ensuring-fairness-and-safety-eur3-customs-duty-low-value-parcels-2026-06-29_en) --- # US de minimis suspension: what changed for parcels > US de minimis has been suspended since 29 August 2025. The timeline, the June 2026 CBP rules, how parcels clear now and what ends on 1 July 2027. Source: https://border.bot/blog/us-de-minimis-suspension Last updated: 2026-10-08 By border.bot team · Published 2026-10-08 · 4 min read · Tags: de minimis, United States, duties Rules as of 8 October 2026. Customs rules change; check the sources at the end before you rely on any detail. **Since 29 August 2025, a low value no longer exempts goods sold into the US from duty.** The exemption that let a shipment worth $800 or less enter without duty (the de minimis exemption in Section 321 of the Tariff Act) is suspended for goods from every country. CBP made the suspension indefinite in its own regulations in June 2026, and a 2025 law ends the exemption permanently on 1 July 2027. ## Timeline | Date | What happened | | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 30 July 2025 | Executive Order 14324 suspends duty-free de minimis treatment for all countries. | | 29 August 2025 | The suspension takes effect. CBP rejects Section 321 manifest filings and Type 86 entries. | | 20 February 2026 | The Supreme Court rules in _Learning Resources, Inc. v. Trump_ that IEEPA does not authorize the President to impose additional tariffs. The ruling does not address de minimis. The same day, Executive Order 14389 ends several IEEPA tariff actions and Executive Order 14388 continues the de minimis suspension. | | 24 June 2026 | A CBP rule suspends de minimis indefinitely for every mode except mail (91 FR 37789). | | 24 July 2026 | A second CBP rule, published with the first, takes effect: de minimis is suspended indefinitely for mail too, and a new postal informal entry process starts (91 FR 37801). | | 8 October 2026 | CBP proposes changes to informal entries of $2,500 or less, including a new electronic entry type for mail and bonds for some entries (91 FR 64532). Comments close on 7 December 2026. | | 1 July 2027 | The One Big Beautiful Bill Act ends the de minimis exemption by law. | ## What is still exempt CBP’s 2026 rules leave two other Section 321 exemptions in place: bona fide gifts, and personal or household articles that travellers bring with them. Neither covers goods sold online. For ecommerce, every parcel now needs a customs entry and payment of the duty owed. ## How a parcel clears now **By courier, express or freight** (every mode except mail), a shipment worth $800 or less needs a formal or informal entry, filed in CBP’s Automated Commercial Environment (ACE) by a party allowed to make entry, with duties, taxes and fees paid. Informal entry covers most shipments worth $2,500 or less. **By post**, since 24 July 2026 shipments worth $2,500 or less use CBP’s new postal informal entry process: - **Who files:** the owner or purchaser of the goods, or a licensed customs broker they designate. The filer needs a CBP import bond. - **What CBP needs:** a spreadsheet giving, for each package, the 10-digit HTS code, country of origin, value, duty rate and duty owed, plus the tracking number and arrival details. - **When:** the spreadsheet and the payment are due by the 7th of the month after the package arrives. - **No collection at the door:** CBP no longer collects duty from the person receiving the parcel. Goods under quotas or antidumping and countervailing duty orders need a formal entry. Goods with partner government agency requirements, duties under HTS chapters 98 or 99, or a free trade agreement claim can use the postal process only during a temporary transition window. After it, they need a formal entry or CBP’s voluntary Entry Type 13 test. ## What a parcel pays now For a commercial shipment, the charges are: 1. **Duty** at the rate for the product’s 10-digit HTS code and its country of origin, plus any additional duties for that product and origin, such as Section 232 or Section 301 duties. 2. **Customs fees**, such as the merchandise processing fee, where they apply to the entry type. 3. **Carrier or broker charges** for clearing the parcel. These vary by carrier and are not set by CBP. The duty depends on where the product was **made**, not where it was shipped from. A product made in China and shipped from a UK warehouse is still a Chinese-origin product for US duty. We explain the difference in [country of origin vs shipped from](/blog/country-of-origin-vs-shipped-from). ## What to do as a seller - **Classify every product to a 10-digit HTS code.** Both entry routes ask for it. The [free HS code classifier](/tools/hs-code-classifier) gives you the code with the official description at each level. - **Record the real country of origin** for each product, from the supplier or the label. - **Decide who pays.** Collect the duty at checkout and ship DDP, or have the customer pay on delivery (DAP) where the carrier offers it. Postal parcels are no longer charged at the door, so settle who files and pays before you ship by mail. The trade-offs are in [DDP vs DAP](/blog/ddp-vs-dap-ecommerce). - **Quote it before you ship.** The [landed cost calculator](/tools/landed-cost-calculator) returns every duty, fee and tax line for an HS code, origin and value. - **Follow the October 2026 proposal.** It would change filing requirements for informal entries and add bond requirements for some of them. ## Sources - CBP, CSMS #66065494, _Suspension of the De Minimis Exemption_ (28 August 2025): [content.govdelivery.com/accounts/USDHSCBP/bulletins/3f01456](https://content.govdelivery.com/accounts/USDHSCBP/bulletins/3f01456) - Federal Register, _Indefinite Suspension of the De Minimis Exemption for Merchandise Arriving Through All Modes Other Than the International Postal Network_, 91 FR 37789 (24 June 2026): [federalregister.gov/d/2026-12670](https://www.federalregister.gov/documents/2026/06/24/2026-12670/indefinite-suspension-of-the-de-minimis-exemption-for-merchandise-arriving-through-all-modes-other) - Federal Register, _Indefinite Suspension of the De Minimis Exemption for Mail Shipments and New Postal Informal Entry Process_, 91 FR 37801 (24 June 2026): [federalregister.gov/d/2026-12669](https://www.federalregister.gov/documents/2026/06/24/2026-12669/indefinite-suspension-of-the-de-minimis-exemption-for-mail-shipments-and-new-postal-informal-entry) - CBP, CSMS #69183472, _Updated Global Guidance for International Mail_ (8 July 2026): [content.govdelivery.com/accounts/USDHSCBP/bulletins/41fa7f0](https://content.govdelivery.com/accounts/USDHSCBP/bulletins/41fa7f0) - Federal Register, _Low-Value Shipments_ (proposed rule), 91 FR 64532 (8 October 2026): [federalregister.gov/d/2026-20650](https://www.federalregister.gov/documents/2026/10/08/2026-20650/low-value-shipments) - CBP, E-Commerce: [cbp.gov/trade/basic-import-export/e-commerce](https://www.cbp.gov/trade/basic-import-export/e-commerce) --- # Classify products from Claude and ChatGPT > Connect the border.bot MCP server to Claude, ChatGPT or Cursor, then classify products, check origin and estimate landed cost from a chat. Setup and tips. Source: https://border.bot/blog/classify-products-with-mcp Last updated: 2026-10-07 By border.bot team · Published 2026-09-30 · 4 min read · Tags: mcp, ai assistants, classification Questions that used to go to a spreadsheet or a broker now often go to an AI assistant first: “What’s the HS code for this?”, “Will my customer pay duty on that?” Assistants understand the question well. On their own, they are not a reliable source of tariff codes: they may recall outdated schedules, mix up countries or invent a plausible-looking number. The **border.bot MCP server** gives the assistant a tool to call for those answers, so the code comes from a classification engine instead of the model’s memory. ## What MCP is The [Model Context Protocol](https://modelcontextprotocol.io/) is an open standard for connecting AI assistants to external tools and data. An MCP server describes the tools it offers; the assistant decides when to call them, sends structured inputs and gets structured results back. A **remote** MCP server runs on the web. You add it to your client with a URL and sign in through your browser with OAuth. Nothing is installed locally and no API key goes into a config file. ## What the border.bot server can do Once connected, your assistant can: - **Classify products** from a description or a product URL, for any destination, returning the code in that country’s format with official descriptions, a confidence score and alternatives. - **Read product pages** to pull out the title, materials, price and country of origin before classifying. - **Calculate landed cost** for a code, origin and destination, with each duty, tax and fee and the total. Every call runs on the same engine as the border.bot dashboard and API, uses your workspace’s credits at the same prices, and is saved to your workspace history. ## Setting it up The server URL is `https://api.border.bot/mcp`. In short: - **Claude:** Customize › Connectors › “+ Add” › “Add custom connector”, enter the URL, then sign in to border.bot. - **ChatGPT:** on chatgpt.com/plugins, choose the plus button › “Add custom MCP server”, enter the URL with OAuth, then install the plugin and sign in. - **Codex:** run `codex mcp add borderbot --url https://api.border.bot/mcp`, then `codex mcp login borderbot`. - **Cursor:** add the URL to `~/.cursor/mcp.json` (or use “Add to Cursor” on the MCP setup page), then complete the sign-in Cursor asks for. When you sign in, you approve the connection and choose **which workspace pays** for the calls. Menu names change between client versions, so check the [MCP setup page](/mcp) for current step-by-step instructions, including Claude Code, Visual Studio Code, Gemini CLI and the other clients we have guides for. ## What to ask Some prompts that work well: > What’s the US HTS code for a men’s 100% cotton crew-neck T-shirt made in Vietnam? Show me the description at each level. > Classify this for import into Germany and tell me where it’s made: https://shop.example/products/merino-beanie > Calculate the landed cost of 50 units at $18 each, HS 4202.92, from China to the UK with $120 shipping. > Here are twelve product descriptions from our catalogue. Classify each one for Canada and list any that come back with low confidence. The last one shows where an assistant shines: it can loop over a list, call the tool for each item and summarise the results, while the codes themselves still come from the tool. ## What happens behind a single question Take the first prompt above. The assistant recognises that it needs a classification, so it calls the border.bot classify tool with structured inputs: the description, the destination (`US`) and the origin (`VN`). border.bot returns a structured result with the 10-digit HTS code, the official description for the chapter, heading, subheading and tariff line, a confidence level, the reasoning and the closest alternatives. Your workspace is charged for one classification. The assistant then writes its answer from that result. Because the code, the descriptions and the confidence come straight from the tool, you can check the assistant’s summary against them, and the same result is waiting in your workspace history if you want to share it with a colleague or re-run it later. ## Tips for reliable answers - **Ask it to use border.bot.** Say “use the border.bot tool” so the assistant doesn’t answer from memory. - **Give it the facts customs needs.** Material, function, construction and who the product is for matter more than the product name. - **Always name the destination.** Codes beyond six digits differ by country. - **Ask for alternatives on low confidence.** If the result is flagged for review, ask the assistant to show the alternatives and what would distinguish them, then add that detail and run it again. - **Keep origin honest.** If the assistant reports an origin detected from a product page, confirm it with your supplier before you rely on it. ## Billing and security - You sign in on border.bot; the assistant receives a scoped OAuth token, never your password. - Each connection is tied to the workspace you chose, and its calls draw on that workspace’s credits. If a call fails, its credits are refunded automatically. - You can see every connected client in the dashboard and revoke any of them at any time. ## Where this fits The MCP server suits ad-hoc questions, research and one-off batches inside the tools your team already uses. For checkout and catalogue automation, use the [REST API](/developers); for reviewing and sharing results, use the dashboard. All three use the same engine and the same credits. To see the results before connecting anything, try the [free HS code classifier](/tools/hs-code-classifier). It runs on the same engine. --- # Country of origin: shipped from isn’t made in > Why the country a parcel ships from often isn’t its country of origin, how origin is decided, and how it changes duties, marking rules and trade-deal savings. Source: https://border.bot/blog/country-of-origin-vs-shipped-from Last updated: 2026-09-16 By border.bot team · Published 2026-09-16 · 4 min read · Tags: country of origin, compliance, duties Your parcels leave a warehouse in the Netherlands. Your products were made in China, Vietnam and Portugal. On the customs declaration, which country is the **country of origin**? Not the Netherlands. Origin is where goods were **made**, not where they were **shipped from**. Mixing the two up is a common mistake in cross-border ecommerce, and it can mean paying the wrong duty or claiming a trade-agreement rate you aren’t entitled to. ## Why the two get mixed up Modern supply chains separate making and shipping. Goods are produced in one country, stored by a 3PL in a second, sold by a brand in a third and shipped to a customer in a fourth. Many shipping tools default the origin field to the warehouse address, and many product feeds don’t carry origin at all. The result: declarations that quietly state the wrong origin. ## What “origin” means to customs There are two different questions customs may ask: ### Non-preferential origin This is the “made in” country used for ordinary duty rates, trade remedies, import restrictions, quotas, marking requirements and statistics. Broadly, goods originate where they were: - **wholly obtained**: grown, mined, or born and raised in one country; or - **last substantially transformed**: where the last processing step that created a new and different article took place. What counts as substantial transformation varies by country and product. Assembling components into a finished product often qualifies; **repacking, relabelling, sorting or simple assembly usually does not**. Storing goods in a warehouse never does. ### Preferential origin This is the origin used to claim a **lower duty rate under a trade agreement**. Each agreement has its own product-specific rules, for example a change of tariff classification, a minimum regional value content or a required manufacturing process. Meeting them usually requires a proof of origin, such as an origin statement on the invoice or a certificate. The key point: shipping goods between two countries that have a trade agreement does **not** by itself make them eligible. The goods must meet the agreement’s origin rules, and you must be able to prove it. ## A few examples - **A phone case moulded in China, stocked in a Dutch warehouse and sold to a UK customer.** Origin: China. Storage and repacking in the Netherlands don’t change it. - **Leather shoes made in Portugal and shipped from a US distribution centre to Canada.** Origin: Portugal, even though the parcel leaves the US. US–Canada trade-agreement preferences don’t apply just because of the shipping route. - **A bicycle assembled in one country from a frame, wheels and components made in several others.** Origin depends on the rules that apply to that product: assembly may or may not be a substantial transformation. This is where rulings and expert advice earn their keep. ## Why origin changes the bill - **Duty rates.** The same product can face a different rate depending on where it was made: lower under a trade agreement, higher where additional duties or trade remedies target that origin. - **Restrictions and sanctions.** Some goods from some origins are restricted, need licences or can’t be imported at all. - **Marking.** Several countries require imported goods to be marked with their country of origin, and false or missing marks can lead to penalties or re-marking at your cost. - **Customer claims.** “Made in” statements on your product pages are consumer-protection claims too; they should match what you declare. ## How to establish origin properly 1. **Ask your supplier.** Get a written statement of where each product is manufactured, and for trade-agreement claims, the supporting origin evidence. 2. **Know the manufacturing steps.** For products assembled from imported components, record where each significant step happens. 3. **Store origin per product, not per warehouse.** Make it a required field in your catalogue and product feeds. 4. **Check the product page.** If you sell other brands, the “Made in” line on the manufacturer’s product page or label is a useful signal, but confirm it with the supplier. 5. **Keep evidence.** Customs can ask for proof long after a shipment clears. ## Common mistakes - Filling the origin field with the **ship-from** country. - Claiming a trade-agreement rate because both countries are **party to the agreement**, without checking the product-specific rule. - Treating **“assembled in”**, **“designed in”** or **“distributed by”** as statements of origin. - Assuming origin never changes. A new supplier, factory or component source can move it. ## How border.bot helps When you classify from a product URL, border.bot looks for the country of origin on the page. It checks structured product data first, then the page text, and falls back to an AI estimate when the page doesn’t say. The result shows **where the origin was found**, with a confidence level. Origin you enter yourself always wins. Try it with the [free HS code classifier](/tools/hs-code-classifier), then carry the code and origin into the [landed cost calculator](/tools/landed-cost-calculator) to see how origin changes the duty. You remain responsible for the origin you declare, so treat a detected origin as a lead to confirm with your supplier, not as proof. --- # DDP vs DAP for ecommerce parcels > Should you collect duties and taxes at checkout (DDP) or let customers pay on delivery (DAP)? The costs, risks and setup of each, explained for parcel shippers. Source: https://border.bot/blog/ddp-vs-dap-ecommerce Last updated: 2026-09-09 By border.bot team · Published 2026-09-09 · 4 min read · Tags: incoterms, landed cost, checkout When you ship a parcel abroad, someone has to pay the import duty and taxes. Under **DDP** you collect them at checkout and pay them at the border. Under **DAP** your customer pays them when the parcel arrives. The choice affects what your customer pays and when, your cash flow, and how many parcels are refused and sent back. ## The terms, briefly DDP and DAP are two of the eleven **Incoterms® rules** published by the International Chamber of Commerce; the current edition is Incoterms 2020. They define who is responsible for what between seller and buyer. - **DAP (Delivered at Place).** The seller delivers the goods to the named place, ready for unloading. The **buyer** handles import clearance and pays import duty and taxes. - **DDP (Delivered Duty Paid).** The seller delivers the goods cleared for import, with duty and taxes paid. The **buyer** pays nothing extra on arrival. You will still hear **DDU** (“delivered duty unpaid”). It was retired from the Incoterms rules in 2010 and replaced in practice by DAP, but many carriers still use the label for parcel services where the recipient pays. For parcels, carriers turn these into products: a “duties paid” or DDP service where they bill you for the duty and tax, and a standard service where they collect from the recipient. ## DAP: the customer pays on delivery **How it works.** You charge for the goods and shipping. The carrier clears the parcel, advances the duty and tax, and collects them from the customer before or at delivery, usually with a handling or disbursement fee on top. **Why merchants choose it** - Nothing to calculate or remit; the carrier deals with customs. - No tax registrations in the destination for you to manage. - Lower checkout price, at least on the surface. **What it costs you** - **Surprise bills.** Customers who didn’t expect to pay on delivery often feel misled, and some refuse the parcel. - **Refusals and returns.** A refused parcel can cost you the outbound shipping, the return shipping and sometimes the goods. - **Support load.** “Why do I have to pay to receive my order?” becomes a common ticket. - **Carrier fees on top.** Handling fees for advancing duty can be a large share of the charge on low-value parcels, and the customer blames you, not the carrier. ## DDP: you collect at checkout **How it works.** You calculate the landed cost at checkout, show it to the customer, and collect it with the order. The carrier clears the parcel and bills you for the duty and tax, or you pay through your own customs arrangements. **Why merchants choose it** - **A single, final price.** The customer pays once and receives the parcel without another bill. - **Fewer refusals.** Nobody refuses a parcel they’ve already fully paid for. - **A domestic-feeling experience** in your key markets. **What it takes** - **Accurate landed cost at checkout.** Undercharge and you pay the difference; overcharge and you lose sales. That means the right HS code, the right country of origin and current rates. See [Landed cost explained](/blog/landed-cost-explained) for the moving parts. - **Tax registration in some markets.** Several destinations collect tax on low-value goods from the seller rather than at the border, which can mean registering there. The EU’s Import One-Stop Shop (IOSS) and the UK’s rules for low-value consignments are well-known examples. Thresholds and rules differ and change, so check each market you sell into. - **A carrier or partner that supports DDP** for the lanes you ship. - **A plan for returns.** Recovering duty and tax on returned goods is possible in some countries and not others, and usually takes paperwork. ## Side by side | | DAP | DDP | | ----------------------- | ------------------------------ | -------------------------------------------- | | Who pays duty and tax | The customer, on delivery | You, collected at checkout | | Price shown at checkout | Goods and shipping only | The full landed cost | | Customer experience | Possible surprise bill and fee | No extra payment on delivery | | Risk of refused parcels | Higher | Lower | | Your admin | Low | Higher: rates, registrations, reconciliation | | Cash flow | No duty or tax to advance | You advance or remit duty and tax | ## Many merchants do both DDP and DAP aren’t an all-or-nothing choice. Common patterns: - **DDP in your top markets, DAP elsewhere.** Put the effort where most of your international revenue is. - **DDP below a value threshold.** Low-value orders, where a delivery charge would feel most unfair, get duties included; high-value orders, where customers expect formalities, ship DAP. - **Let the customer choose.** Offer “duties included” at checkout with DAP as the fallback. ## Making DDP work in practice 1. **Classify every product properly.** Store the 6-digit HS code and the full code for each destination you ship to. 2. **Record the real country of origin** for each product, not the country of the warehouse it ships from. 3. **Calculate landed cost live at checkout** from the code, origin, destination, value and shipping, so thresholds and rates stay current. 4. **Round and display carefully.** Show duties and taxes as a clear line, in the customer’s currency. 5. **Reconcile.** Compare what you collected with what the carrier billed you. Differences usually point to a wrong code or origin. 6. **Re-check after changes.** New tariffs, de minimis changes and new trade measures can make yesterday’s estimate wrong. ## Which to choose DAP is easy to start and expensive in ways that don’t show up on an invoice: refused parcels, support tickets and customers who don’t order again. DDP takes more setup but gives your customers the experience they get from domestic shops. It depends on a correct code and origin for every product and a landed cost calculated at checkout. [border.bot’s API](/developers) returns both, and you can try the numbers on a real product with the [free landed cost calculator](/tools/landed-cost-calculator). --- # Landed cost explained: duties, taxes and fees > What makes up the landed cost of an international parcel (goods, shipping, duty, import VAT or GST, and fees) and how each part is calculated. Source: https://border.bot/blog/landed-cost-explained Last updated: 2026-10-08 By border.bot team · Published 2026-09-01 · 5 min read · Tags: landed cost, duties, taxes Your customer in Toronto sees a $60 jacket at checkout. By the time it reaches their door, shipping, duty, sales tax and fees can add a lot to that price. **Landed cost** is the full amount: everything it takes to get a product from your shelf to your customer’s hands, including the charges collected at the border. It affects two things: whether you make money on international orders, and whether your customer gets a surprise bill on delivery and refuses the parcel. ## What goes into landed cost ### 1. The goods The **transaction value**: what the buyer paid, or will pay, for the goods. It is the starting point for almost every other number, so it should be the real price on the invoice, not a rounded or “gift” value. ### 2. Shipping and insurance What it costs to move the parcel. Shipping matters twice: as a cost in its own right, and because some countries include it in the value that duty is charged on (see _customs value_ below). ### 3. Customs duty The tax on importing goods, set by the destination’s tariff for the product’s code and often its **country of origin**. Duty comes in a few forms: - **Ad valorem**: a percentage of the customs value. This is the most common form. - **Specific**: a fixed amount per unit, kilogram, litre or pair. - **Compound or mixed**: a combination, sometimes with a minimum or maximum. Many products are duty-free under the general rate; others carry substantial duty. Trade agreements can reduce the rate for goods that qualify as originating in a partner country. ### 4. Additional duties On top of the ordinary rate, some goods attract **trade remedy** duties (anti-dumping, countervailing or safeguard duties) or other measures aimed at particular products or origins. They change more often than ordinary tariffs and depend heavily on origin, which is why origin has to be right. Read [Country of origin: shipped from isn’t made in](/blog/country-of-origin-vs-shipped-from) for how origin is decided. ### 5. Import taxes Most countries charge their consumption tax on imports: **VAT** in the EU and the UK, **GST** (and HST) in Canada, Australia and elsewhere. Some goods, such as alcohol, tobacco and certain fuels, also carry **excise** duties. Import VAT and GST are usually charged on the customs value **plus the duty**, so duty raises the tax too. The US has no federal import VAT; US state sales tax is collected domestically and is not a border charge. ### 6. Fees Two very different kinds: - **Government fees**, such as customs processing fees charged on imports in some countries. - **Carrier and broker fees** for clearing the parcel and advancing duty and tax on the customer’s behalf, often called brokerage, disbursement or handling fees. They vary by carrier and contract and can be a large share of the cost on low-value parcels. ### 7. Currency conversion Customs converts your invoice value into its own currency at an official rate, and the customer may pay in yet another currency. Small exchange differences add up on margins. ## Customs value: what duty is charged on Duty is a percentage of the **customs value**, and countries don’t agree on what that includes: - The **EU** and the **UK** generally use a value that includes the cost of transport and insurance up to the border, often described as a CIF basis. - The **United States** and **Canada** generally exclude international freight and insurance, which is closer to an FOB basis. So the same parcel with the same duty rate can pay different duty in different markets simply because the base is different. ## A worked example This hypothetical example uses a 10% duty and a 20% import VAT, with no fees, for a destination that charges duty on a CIF basis: | Line | Calculation | Amount | | --------------- | ----------------------------- | ---------- | | Goods | Invoice value | 100.00 | | Shipping | Carrier rate | 10.00 | | Customs value | Goods + shipping (CIF basis) | 110.00 | | Duty | 10% of 110.00 | 11.00 | | VAT base | Customs value + duty | 121.00 | | Import VAT | 20% of 121.00 | 24.20 | | **Landed cost** | Goods + shipping + duty + VAT | **145.20** | Notice two things: duty was charged on shipping as well as the goods, and VAT was charged on the duty. Ignoring either makes the estimate too low. Real rates, bases and thresholds differ by country and product and change over time, so use a calculator with current rules rather than fixed percentages. ## De minimis: when nothing is charged Many countries waive duty, tax or both on shipments below a **de minimis** value. The thresholds vary widely, can differ for duty and for tax, and change. Two of the largest markets have changed theirs recently: - **United States:** the $800 duty-free de minimis exemption has been suspended for goods from every country since 29 August 2025, and a 2025 law ends it on 1 July 2027. Low-value parcels now need a customs entry and pay the duty owed. See [US de minimis suspension: what changed for parcels](/blog/us-de-minimis-suspension). - **European Union:** import VAT has applied to ecommerce imports of any value since 1 July 2021, often collected at checkout through the Import One-Stop Shop (IOSS). Since 1 July 2026, parcels worth up to €150 also pay a temporary €3 customs duty for each tariff classification they contain. See [The EU's €3 customs duty on parcels under €150](/blog/eu-3-euro-customs-duty). Never hard-code a threshold you read once; check the current rule for each destination. ## Who pays: DDP or DAP Landed cost has to be paid by someone. Under **DDP** (delivered duty paid) you collect it at checkout and pay it at the border, so the customer pays nothing on delivery. Under **DAP** (delivered at place) the customer pays duty, taxes and carrier fees on arrival. We compare the two in [DDP vs DAP for ecommerce parcels](/blog/ddp-vs-dap-ecommerce). ## Putting landed cost to work - **Show it at checkout.** Customers abandon fewer international orders when the total is clear up front. - **Price by market.** If duty and tax are high in a market, decide whether to absorb, pass on or split them. - **Check margins by lane.** The same product can be profitable to one country and loss-making to another. - **Re-run it when things change.** New tariffs, thresholds and exchange rates all move the total. ## Calculate it for your product Our [free landed cost calculator](/tools/landed-cost-calculator) takes an HS code (or a product description), origin, destination, total goods value, shipping and quantity, and returns every duty, fee and tax line with the rate used, the de minimis check, any conditional measures and the total landed cost. It covers the US, UK, Canada, the EU-27 and more. --- # HS vs HTS vs CN/TARIC: the digits explained > Why one product has a 6-digit HS code, a 10-digit US HTS code, an 8-digit EU CN code and a 10-digit TARIC code, and which one goes on which document. Source: https://border.bot/blog/hs-hts-cn-taric-commodity-codes Last updated: 2026-08-25 By border.bot team · Published 2026-08-25 · 4 min read · Tags: hs codes, classification, tariffs Ask three people for the code of the same cotton T-shirt and you may get three different answers: `6109.10`, `6109.10.00.12` and `6109 10 00`. They can all be right. The difference is how many digits each country adds to the shared international code, and which document you are filling in. ## The shared six digits The first six digits come from the **Harmonized System (HS)**, maintained by the World Customs Organization. Chapter (2 digits), heading (4) and subheading (6) mean the same thing in every country that uses the HS. If you only remember one rule, remember this one: **the first six digits of a correct code match everywhere**. After six digits, each country or customs union extends the code for its own duty rates, quotas and statistics. Those extra digits are real subdivisions by gender, value, use, material or a specific trade measure, so you can’t simply add zeros. ## United States: HTS (10 digits) The US uses the **Harmonized Tariff Schedule of the United States (HTSUS)**, published by the US International Trade Commission and applied by US Customs and Border Protection. - Digits 1–6: the HS subheading. - Digits 7–8: the **tariff rate line**, which carries the duty rate. - Digits 9–10: the **statistical suffix**, used for trade statistics. A US code is usually written `6109.10.00.12`. Imports are declared at the full 10 digits. Exports use a separate but closely related 10-digit system, **Schedule B**, maintained by the Census Bureau. The schedule is revised several times a year, so a code that was right last year can need a second look. The official, searchable version is at [hts.usitc.gov](https://hts.usitc.gov/). ## European Union: CN (8 digits) and TARIC (10 digits) The EU has two layers: - The **Combined Nomenclature (CN)** adds two digits to the HS, giving an 8-digit code such as `6109 10 00`. It sets the common customs tariff and is republished every year, applying from 1 January. - **TARIC**, the integrated tariff of the EU, adds two more digits to reach 10. Those digits carry EU measures such as tariff suspensions, quotas, anti-dumping duties and import restrictions. Import declarations into the EU generally use the 10-digit TARIC code, sometimes with additional four-character codes for specific measures. Export declarations use the 8-digit CN code. You can look codes up in the European Commission’s [TARIC database](https://ec.europa.eu/taxation_customs/dds2/taric/taric_consultation.jsp). Import VAT is set by each member state, so the same TARIC code can carry the same duty but different VAT across the EU. ## United Kingdom: commodity codes (10 digits) Since leaving the EU, the UK applies its own tariff, the **UK Global Tariff**. Commodity codes are 10 digits for imports and 8 digits for exports, and they are published in the [UK Trade Tariff](https://www.trade-tariff.service.gov.uk/). Many UK codes still look like their EU equivalents because both grew from the same nomenclature, but the duty rates and measures are the UK’s own. Goods moving into Northern Ireland can follow different arrangements, so check the rules for that route separately. ## Canada: classification numbers (10 digits) Canada’s **Customs Tariff** extends the HS to an 8-digit **tariff item**, which carries the duty rate, plus a 2-digit **statistical suffix**, giving a 10-digit classification number declared to the Canada Border Services Agency. ## Everywhere else Most other countries follow the same pattern: six international digits plus national digits of their own, often reaching eight to ten or more. When no national schedule is available to you, use the 6-digit HS code. It is what most carriers ask for on commercial invoices and postal customs forms. ## Which code goes where | Document or system | Code to use | | ------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | Import declaration in the destination | The destination’s full national code (US HTS, EU TARIC, UK commodity code, Canadian classification number) | | Export declaration | The origin country’s export code (US Schedule B, EU CN, UK 8-digit code) | | Commercial invoice and carrier data | At least the 6-digit HS; many carriers prefer the destination’s full code | | Postal customs forms (CN22/CN23) | The HS code, ideally 6 digits or more | | Your product catalogue | The 6-digit HS for each product, plus the full code for each destination you ship to | ## Why the same product can differ after six digits National subdivisions reflect national policy. The US splits many apparel lines by gender and construction for quota and statistics history; the EU creates TARIC lines to apply measures to specific products and origins; the UK has diverged from the EU since 2021. That is why a product catalogue that stores one “HS code” per product eventually breaks: what you need is the shared six digits plus one full code per destination. ## Keeping codes current The WCO amends the HS itself periodically. The current edition is HS 2022, the next is planned for 2028, and every edition moves, merges and splits subheadings. National schedules change far more often. Build a habit of re-checking codes when a tariff edition changes and whenever duty on a product looks different from what you expected. ## How border.bot handles it When you [classify a product](/tools/hs-code-classifier), choose the destination and border.bot returns the code in that country’s own format: 10-digit US HTS, a UK commodity code, an EU CN or TARIC code, a Canadian classification number, or the 6-digit HS for other destinations. Each result includes the official description at every level, so you can see where the digits came from. New to the topic? Start with [What is an HS code, and how do you find yours?](/blog/what-is-an-hs-code) --- # What is an HS code, and how do you find yours? > A plain-English guide to HS codes: how the six digits are built, why countries add more, and a step-by-step method for finding the right code for your product. Source: https://border.bot/blog/what-is-an-hs-code Last updated: 2026-10-01 By border.bot team · Published 2026-08-18 · 5 min read · Tags: hs codes, classification, basics Every product that crosses a border is declared to customs with a number. That number, the HS code, decides how much duty is charged, whether the goods need a licence or inspection, and which line of the trade statistics they land in. Get it right and your parcel clears quietly. Get it wrong and you risk delays, penalties or a customer who refuses a surprise bill at the door. This guide explains what an HS code is, how its digits are built, and a practical method for finding the right one for your product. ## What an HS code is HS stands for the **Harmonized Commodity Description and Coding System**, usually shortened to the Harmonized System. It is maintained by the [World Customs Organization](https://www.wcoomd.org/en/topics/nomenclature/overview/what-is-the-harmonized-system.aspx) and used by customs authorities in almost every country as the common language for describing goods. The system covers everything that can be traded, from live animals to aircraft, and arranges it from raw materials to finished, manufactured products. Because the first six digits are shared internationally, a code assigned in one country means the same family of goods in another. ## How the digits are built An HS code is a hierarchy. Each pair of digits narrows the description: | Level | Digits | Example | Meaning | | ---------- | ------ | ------- | ------------------------------------------------------------------------ | | Chapter | 2 | 61 | Articles of apparel and clothing accessories, knitted or crocheted | | Heading | 4 | 6109 | T-shirts, singlets, tank tops and similar garments, knitted or crocheted | | Subheading | 6 | 6109.10 | Of cotton | Above the chapters sit 21 **sections**, which group related chapters. Section XI, for example, covers textiles and textile articles. There are 97 chapters, with chapter 77 reserved for future use. Six digits is where the international system stops. Countries then add their own digits for tariff rates and statistics, which is why the same T-shirt has a longer, country-specific code in the United States, the European Union, the United Kingdom and Canada. We explain those national codes in [HS vs HTS vs CN/TARIC: the digits explained](/blog/hs-hts-cn-taric-commodity-codes). ## The rules behind every classification Classification is not a keyword search. It follows the **General Rules for the Interpretation of the Harmonized System** (often called GRIs or GIRs), applied in order: 1. **Headings and notes come first.** Classification is decided by the wording of the headings and the section and chapter notes. Section and chapter titles are for reference only. 2. **Incomplete goods and mixtures.** An unfinished or unassembled article is classified as the finished article if it already has its essential character. Mixtures and combinations of materials are dealt with under the next rule. 3. **When more than one heading fits.** Prefer the most specific description; if that doesn’t settle it, classify by the material or component that gives the goods their essential character; if it is still a tie, take the heading that comes last in numerical order. 4. **Goods that fit nowhere** go under the heading for the goods they are most akin to. 5. **Cases and packing.** Fitted cases, such as a camera case sold with the camera, and normal packing materials usually follow the goods they hold. 6. **Subheadings** are compared with each other using the same rules, only at the same level. In practice, rule 1 decides the large majority of products. The trap is reading only the short heading text: the chapter and section notes often include or exclude goods explicitly, and they are legally binding. ## A step-by-step method for finding your code ### 1. Describe the product precisely Customs classifies what the product _is_, not what it is called. Write down: - what it is, in plain words (“insulated stainless steel drinking bottle”); - what it is made of, with percentages for blends; - what it does and who it is for; - how it is made, when that matters (knitted or woven, moulded or machined); - whether it is a set, a part or an accessory. ### 2. Find the section and chapter Start broad. Is it a textile article, a machine, a plastic article, a toy? Skim the section titles to find the right neighbourhood, then read the **notes** at the start of the section and chapter. They often redirect you: certain textile goods, for instance, are excluded from the apparel chapters. ### 3. Choose the heading Compare the four-digit headings within the chapter. Apply rule 1 strictly: the heading text plus the notes. If two headings seem to fit, work through rule 3. ### 4. Narrow to the subheading Within the heading, choose the six-digit subheading, comparing only subheadings at the same level (rule 6). Material and function are the usual deciders here. ### 5. Extend to the destination’s digits Look up the subheading in the tariff of the country you are shipping to and pick the national line. The destination’s official tariff, such as the [US Harmonized Tariff Schedule](https://hts.usitc.gov/) or the [UK Trade Tariff](https://www.trade-tariff.service.gov.uk/), is the authority for those extra digits. ### 6. Sanity-check against rulings Search published rulings for similar products. The US publishes its customs rulings in [CROSS](https://rulings.cbp.gov/), and the EU publishes binding tariff information decisions. A ruling on a near-identical product is strong evidence; a ruling that disagrees with you is a warning sign. ### 7. Write down your reasoning Record the description you classified, the heading and notes you relied on, and any rulings you checked. If customs ever questions the code, this is your defence, and it makes re-checking easy when the tariff changes. ## Common mistakes - **Classifying by product name.** “Yoga set” or “gift box” says nothing about material or function. - **Reusing your supplier’s code.** The exporter’s code may be for a different country, a different tariff version, or simply wrong. - **Padding a six-digit code with zeros.** National digits are real subdivisions, not filler. - **Ignoring materials.** For textiles, plastics and metals, the material often decides the heading. - **Mixing up parts and accessories.** Parts frequently classify with the machine they belong to, but there are many exceptions in the notes. - **Never revisiting codes.** The HS is amended periodically (the current edition is HS 2022, and the next is scheduled for 2028), and national tariffs change more often. ## When to get a binding ruling If a product is high-value, regulated, or genuinely ambiguous, ask the destination’s customs authority for an advance or binding ruling. It takes time, but it gives you legal certainty for that product. A licensed customs broker can also review your classification. ## How border.bot helps Our [free HS code classifier](/tools/hs-code-classifier) follows the same logic: describe the product or paste its page, choose the destination, and you get the code in that country’s format with the official description at every level, a confidence score, the reasoning and the closest alternatives. Uncertain results are flagged for review, so you know which products to check further. --- # Privacy policy > Template privacy policy for border.bot describing what data we collect and why, the processors we use, cookies, retention periods and your rights. Source: https://border.bot/legal/privacy What we collect when you use border.bot, why we collect it, who helps us process it and the choices you have. This is a template that a lawyer has not reviewed. It is a starting point drafted for border.bot and must be reviewed and completed by a qualified lawyer before anyone relies on it. Items in \[square brackets\] need your details. ## 1\. Who we are border.bot (“we”, “us”) is operated by \[legal entity name\], \[registered address\]. We are the controller of the personal data described in this policy. You can reach us at [support@border.bot](mailto:support@border.bot). ## 2\. What we collect - **Account data:** your name, email address and workspace (organization) details, provided when you sign up through our authentication provider. - **Workspace and usage data:** the product descriptions, product URLs, countries and values you submit, the results we return, and your credit history. - **Payment data:** payments are processed by Stripe. We receive confirmation of the payment and limited billing details; we never receive or store full card numbers. - **Free tool data:** when you use the free tools without an account, we keep a keyed hash of your IP address, of its surrounding address range and of a random visitor identifier stored in a signed cookie, the country and network (ASN) your request came from, and the inputs and results of your runs, to enforce the free-run limit and prevent abuse. Free runs aren’t offered from VPN, hosting or Tor networks. - **AI assistant connections:** when you connect an MCP client, we store the client’s name, the workspace you chose and the permissions you granted. - **Technical data:** request logs such as IP address, browser type and timestamps, kept for security and reliability. - **Crawler and referral statistics:** for requests from search and AI crawlers, visits that arrive from an AI assistant, Markdown requests and missing pages, we count the page, the response status, the referring site, the crawler’s name and the network (ASN) the request came from. We do not record your IP address in these statistics. ## 3\. How we use it - To provide classification, landed-cost and related features, and to keep your history. - To bill for credits and keep accurate financial records. - To secure the service, prevent fraud and abuse, and enforce usage limits. - To answer support requests and send service messages. - To improve the service, using aggregated or de-identified information where possible. ## 4\. Legal bases Where data-protection law such as the GDPR or UK GDPR applies, we process personal data to perform our contract with you, for our legitimate interests in running and securing the service, to meet legal obligations, and with your consent where it is required. \[Confirm the legal bases with counsel.\] ## 5\. Service providers We share personal data only with providers who help us run border.bot, under appropriate agreements: - Cloudflare: hosting, storage, network security, bot protection (Turnstile), usage statistics (Analytics Engine) and the AI models (Workers AI) that read product pages and estimate a product’s country of origin. - WorkOS: sign-in and organization management. - Stripe: payment processing. - Our trade-data provider: classification and duty calculation. It receives the product details needed for each result. - \[Email or support tooling providers, if any.\] We do not sell personal data. ## 6\. International transfers Our providers may process data outside your country. Where required, we rely on appropriate safeguards such as standard contractual clauses. \[Describe the transfer mechanisms you use.\] ## 7\. Cookies We use only cookies that are needed for the service to work: - **Session cookie** (dashboard): keeps you signed in. Encrypted and HttpOnly. - **bb\_vid** (free tools): a random, signed identifier that counts your free runs. HttpOnly, kept for up to one year. - **Cloudflare Turnstile**: Cloudflare may use cookies or similar signals to tell people from bots when you run a free tool. We do not use advertising or cross-site tracking cookies. ## 8\. How long we keep data We keep account and workspace data while your account is active and for \[period\] afterwards, financial records for as long as the law requires, free-tool counters for the length of the free-run window, and logs for \[period\]. \[Set retention periods.\] ## 9\. Your rights Depending on where you live, you may have the right to access, correct, delete or export your personal data, and to object to or restrict certain processing. To exercise these rights, email [support@border.bot](mailto:support@border.bot). You can also complain to your local data-protection authority. ## 10\. Children border.bot is a business service and is not directed at children. ## 11\. Changes to this policy We will update this page when our practices change and, for material changes, tell account holders in advance by email or in the dashboard. ## 12\. Contact Questions about privacy? Email [support@border.bot](mailto:support@border.bot). Last updated 2026-10-09 --- # Terms of service > Template terms of service for border.bot covering accounts, prepaid credits, acceptable use, classification results as guidance, liability and termination. Source: https://border.bot/legal/terms The rules for using border.bot: accounts, prepaid credits, acceptable use, and what classification and landed-cost results can and can’t be used for. This is a template that a lawyer has not reviewed. It is a starting point drafted for border.bot and must be reviewed and completed by a qualified lawyer before anyone relies on it. Items in \[square brackets\] need your details. ## 1\. Agreement These terms govern your use of border.bot, including the website, dashboard, REST API, MCP server and free tools (the “service”), provided by \[legal entity name\] (“we”, “us”). By using the service you agree to them. If you use it for an organization, you confirm you may bind that organization. ## 2\. Accounts and workspaces - Keep your sign-in details secure and tell us promptly about any unauthorised use. - Workspace admins control billing, API keys, team membership and settings for their workspace. - You are responsible for activity under your account, your API keys and the AI clients you connect. ## 3\. Credits and payment - The service is paid for with prepaid credits. The credits each action uses are shown before you buy or run it. - If a billable call fails, the credits it used are returned to your balance automatically. Otherwise credits are non-refundable except where the law requires or as we agree in writing. \[Confirm refund and expiry rules.\] - Payments are processed by Stripe. Prices exclude taxes unless stated. We may change prices for future purchases. ## 4\. Free tools The free classifier, calculator and origin finder are offered for evaluation, with a limited number of runs per visitor that we may change at any time. Automated or bulk use of the free tools, or attempts to get around their limits, is not allowed. Use the API instead. ## 5\. Acceptable use - Don’t use the service to break the law, including customs, export-control and sanctions laws. - Don’t probe, overload or disrupt the service, or try to access other customers’ data. - Don’t resell or rebrand the service, or copy its results into a competing database, without our written permission. ## 6\. Classification and landed-cost results Results are generated automatically and are provided as guidance to help you prepare declarations. They are not legal, tax or customs advice and they are not a binding ruling. The importer of record remains responsible for the classification, origin and values declared to customs. For high-value, regulated or disputed goods, confirm results with a licensed customs broker or request a binding ruling from the relevant authority. Tariffs, thresholds and rules change; final charges are assessed by customs. ## 7\. Your data You keep all rights in the data you submit. You give us permission to process it to provide and secure the service, as described in our privacy policy. We may use aggregated, de-identified information to improve the service. ## 8\. Our intellectual property The service, its software, design and content belong to us or our licensors. These terms don’t transfer any of those rights to you beyond the right to use the service as described. ## 9\. Availability and changes We work to keep the service available and accurate, but it is provided “as is” and “as available”. We may add, change or remove features, and will give reasonable notice of changes that materially reduce what you have paid for. ## 10\. Liability To the extent the law allows, we are not liable for indirect or consequential losses, or for duties, taxes, penalties or delays arising from declarations you make, and our total liability is limited to \[the amount you paid us in the 12 months before the claim\]. Nothing in these terms limits liability that cannot be limited by law. \[Review with counsel.\] ## 11\. Suspension and termination You can stop using the service at any time. We may suspend or close accounts that break these terms or put the service or other customers at risk, and will tell you why unless the law prevents it. ## 12\. Governing law These terms are governed by the laws of \[jurisdiction\], and disputes are subject to the courts of \[venue\]. ## 13\. Changes and contact We may update these terms and will notify account holders of material changes in advance. Questions? Email [support@border.bot](mailto:support@border.bot). Last updated 2026-10-09