# Customs desk for international orders with an HS code register

> See which international orders are blocked on customs classification, approve each commodity code once, and reuse it automatically on every future order.

- Workflow type: app
- Services: EasyPost, Shopify, Google Sheets
- Categories: Operations, Finance
- Published: 2026-08-21

## What it does

- Lists your international orders waiting to ship and shows, line by line, which ones still need a commodity code, country of origin, or declared value, so you can tell at a glance what is blocked and what is ready.
- Keeps one approved classification per product in a shared register, so repeat items are filled in for you automatically and the classification work shrinks every week.
- A Classify button hands an order to an assistant that reads your product details and proposes a commodity code with its reasoning and a confidence level, always as a suggestion waiting for your approval.
- Once you approve the codes, it builds the customs paperwork, buys the international label, and exports the whole register to a spreadsheet your customs broker can audit.

## What you'll need

- A Shopify store that receives international orders
- An EasyPost account, with a live key if you want to buy real labels or a test key to trial the flow first
- A carrier on your EasyPost account that ships to the countries you sell into
- A Google account, if you want to export the register for your broker
- Someone who can sign off on classifications, since nothing is ever approved automatically

## Prompt

Build me a customs desk app for international orders, organised around an HS code register that gets smarter every time we use it. The whole idea is that classifying a product is work we do once per SKU, not once per order, and that a human always signs off before a code reaches real customs paperwork.

The main view is the order queue. Use Shopify List Orders to pull orders that are awaiting shipment, filtered to international destinations (the shipping country differs from my store's home country), and Shopify Get Order for the full line item detail on each one. For every order show the order number, customer, destination country, order value and the line items. For each line item show three readiness fields: an approved commodity code, a country of origin, and a declared value. Roll those up into a single per-order status so I can instantly see which orders are blocked on classification and which are ready to ship. Show the ratio too, for example 'ready to ship' or '3 of 5 line items classified', and let me filter the queue to just the blocked orders. When a line item's SKU already exists in the register with an approved code, fill it in automatically and mark it as coming from the register, so a repeat product never needs classifying twice.

The second view is the register itself. Persist one row per SKU containing the SKU, the product title, the approved commodity code, the country of origin, the declared value basis, the current status (pending or approved), the confidence level and reasoning from the proposal, the name of the person who approved it, and the date they approved it. This is the app's own persisted data and it is the source of truth that every future order reads from. Make it searchable and sortable, and let me edit a row directly when a classification needs correcting. If a code changes, keep the previous value visible in the row's history so we can explain past declarations to an auditor.

Every unclassified order gets a 'Classify these items' button that kicks off a background agent. The agent takes the order's unclassified line items, reads the product title, description, product type, tags and any material details from Shopify using Get Product (and Get Variant where the variant carries the detail), and proposes a commodity code for each item. For every proposal it must record three things: the proposed code, a short written explanation of why that code fits the product, and a confidence level of high, medium or low. It writes all of them into the register as pending rows. The agent must never approve its own proposals and must never write directly onto an order. If it cannot find enough product detail to classify something responsibly, it says so and leaves the item unclassified with a note rather than guessing. While the agent is running, show its progress on the order, and when it finishes, surface the new pending proposals in the register and on the order for review.

The human approval gate is the core of the app, not a nicety. Pending proposals are shown with the agent's reasoning and confidence next to the product details it read, so a person can judge the proposal rather than rubber-stamp it. I can approve a proposal as is, edit the code or country of origin before approving, or reject it and write my own. Approving stamps the row with my name and the date, flips it to approved, and from that moment that code is the one reused on every future order containing that SKU. Bulk approve should exist for straightforward high-confidence rows, but must never be able to sweep up flagged rows.

Flag anything risky in red for mandatory review: low-confidence proposals, and any item that falls into a restricted or high-duty category (things like batteries, alcohol, cosmetics, food, textiles, leather and anything with a materials-dependent code). Red rows must be opened and approved individually, cannot be bulk approved, and should carry a short note explaining why they were flagged. Let me maintain the list of categories treated as restricted or high duty from within the app.

Once every line item on an order is approved, the order becomes ready to ship and I can build the declaration and buy the label from the order view. Use EasyPost Create Customs Item to create one customs line per approved line item, carrying the approved commodity code, country of origin, declared value, quantity, weight and description. Bundle those with EasyPost Create Customs Info to form the declaration, including the contents type and any required certification and signer details. Then use EasyPost Create Shipment with the customs info attached to the shipment, show me the returned international rates, and let me pick one and purchase it with EasyPost Buy Shipment. Store the resulting label URL, tracking number and customs info identifier on the order so the app can show them afterwards, and use EasyPost Retrieve Customs Info and Retrieve Customs Item to display exactly what was filed for any past shipment. If EasyPost rejects the declaration, show me the specific field it complained about next to the register row responsible, so I can fix the classification at the source rather than re-entering data.

Finally, give me an export button on the register that writes the whole thing to Google Sheets using Append Values, or Update Values when refreshing an existing sheet, with one row per SKU including the code, origin, declared value basis, confidence, status, approver and approval date. My customs broker uses that export to audit our classifications, so it should be readable on its own without needing the app open. Somewhere visible, show me how the register is paying off over time, for example how many of this week's line items were auto-filled from previously approved classifications versus how many needed fresh work.

## How to customize

- Choose which product categories count as restricted or high duty, so they are always flagged in red for mandatory review no matter how confident the proposal is
- Set the confidence level below which a proposed code cannot be approved in bulk and has to be opened and read by a person
- Decide which destinations, order values, or sales channels the desk covers, and how often the register is exported for your broker
- Adjust what the register stores per product, for example a default declared value basis or a preferred description for customs paperwork

## FAQ

### Does this classify and file customs codes automatically?

No, and that is deliberate. The assistant proposes a commodity code for each item and explains its reasoning, but every proposal lands in the register as pending. Only a person can approve it, and only approved codes are ever used on real paperwork.

### What happens the second time I sell the same product?

Nothing, which is the point. Once a product has an approved code in the register, every future order picks it up automatically. The first international order for a product takes work, and after that it is filled in for you.

### Will this buy real shipping labels?

Yes, once you approve the classifications for an order, the desk builds the customs declaration and buys the international label in one step. If you want to try the flow without spending money, connect a test key first and switch to a live key when you are ready.

### Can my customs broker review the classifications?

Yes. You can export the entire register to a Google spreadsheet, including the approved code, country of origin, who approved it, and when, so your broker can audit the whole history rather than one shipment at a time.

### What if the assistant is not confident about an item?

Low-confidence proposals and anything falling into a restricted or high-duty category are flagged in red and marked for mandatory review. They cannot be waved through in a bulk approval, so the riskiest classifications always get a human read.

### Why does incorrect classification matter so much?

Wrong commodity codes are one of the biggest causes of customs delays, and the cost runs both ways. Overpaying duty quietly erodes margin, while underpaying invites fines and audits. Customs systems also flag mismatches between the code, the product description, and the declared value quickly, which is why keeping one approved and re-verified classification per product is the recommended practice.

Use this prompt in General Input: https://www.generalinput.com/prompts/customs-desk-for-international-orders-with-an-hs-code-register