How the work gets done

Landed Cost Simulator

Prices a pre-purchase what-if: duty stack, risk-adjusted landed cost, and supplier screen.

6 min readUpdated Jul 17, 2026

Deterministic service. Given a product the importer hasn't yet ordered (or a supplier quote, or a draft PO), runs it through the full agent pipeline and returns a methodology-cited landed cost estimate before the importer signs anything.

This is the agent that turns Commers from "broker software" into "importer software that the broker also uses." It's why the C-suite at an importer comes back, not just the customs ops team.

What it does

Reads a single product line (description + origin + supplier + value + quantity, OR a PDF quote/PO via the Document Extractor) and composes the classifier, denied-party screener, duty calculator, and risk modeler into one trip. Returns a structured landed cost: classification, full duty stack with Federal Register citations, screening result with sanctions-list source, a transparent detention-risk range, and a per- unit landed cost the importer can put in a margin model.

Persisted to the simulations table so the importer can compare runs side-by-side (e.g. "what if we sourced from Vietnam instead of China?").

This isn't a single Claude call — it's a single-purpose orchestrator that calls 4 agents and 1 retrieval layer in sequence. Same shape as the Audit Responder (Agent #7), just at a different point in the lifecycle: Audit Responder fires after clearance, Simulator fires before the PO.

Inputs

Manual entry:

{
  description: string;             // "100% cotton men's t-shirts, knit, crew neck"
  originCountry: string;           // "CN"
  supplierName: string;            // "Xinjiang Western Cotton Trading"
  valueCents: number;              // 12_000_000  ($120K declared FOB)
  quantity: number;                // 12_000
  mode?: 'ocean_fcl' | 'ocean_lcl' | 'air';  // affects HMF applicability
}

From a document (PDF / image of a quote or PO):

{
  file: File;     // multipart upload
}
// → extracted by the Document Extractor agent → SimulateInput

Outputs

{
  input: SimulateInput;
  classification: {
    htsCode: string;               // "6109.10.0027"
    confidence: number;            // 82
    rationale: string;             // cited CROSS rulings
  };
  screening: {
    band: 'block' | 'review' | 'watch' | 'clear';
    blocking: boolean;
    topHit: { matched, list, score } | null;
    hits: ScreeningHit[];
  };
  duty: {
    baseDutyCents: number;
    additionalDutyCents: number;
    mpfCents: number;              // 19 CFR 24.23
    hmfCents: number;              // 19 CFR 24.24, ocean only
    totalDutyCents: number;
    effectiveRatePct: number;      // 159 for Xinjiang cotton @ China origin
    components: Array<{            // every layer with its Federal Register citation
      label: string;
      source: 'base' | 'trade_program' | 'fee';
      program?: string;            // "Section 301", "IEEPA China", "Fentanyl Tariff"
      rate: number;
      valueCents: number;
      citation: string;            // "USTR Notice 84 FR 43304" etc.
    }>;
  };
  risk: {
    detentionProbabilityLow: number;
    detentionProbabilityHigh: number;
    delayDays: number;
    carryingCostCents: number;
    responseCostLowCents: number;
    responseCostHighCents: number;
    expectedAdditionLowCents: number;
    expectedAdditionHighCents: number;
  };
  landed: {
    productCostCents: number;       // input.valueCents
    baseLandedCostCents: number;    // product + duty + fees
    riskAdjustedLowCents: number;   // + risk expected addition low
    riskAdjustedHighCents: number;  // + risk expected addition high
    costPerUnitBaseCents: number;
    costPerUnitRiskHighCents: number;
  };
  flags: Array<{                    // high-severity surfaces
    level: 'high' | 'medium' | 'low';
    category: string;
    title: string;                  // human-readable
    detail: string;
  }>;
  simulationId: string;             // persisted; used for history + compare
}

The "marquee" demo number — the 159% effective rate on Xinjiang cotton tees — comes out of this output's duty.effectiveRatePct field. The components array under it lists base (16.5%) + Section 301 List 4A (7.5%) + IEEPA China (125%) + Fentanyl Tariff (10%), each with its Federal Register citation.

When it runs

  • Simulation screen — drag a quote, drop a PO, type a product. The primary user-facing surface.
  • /api/customs-clearance/simulate — direct JSON POST (importer systems can integrate it as a webhook).
  • /api/customs-clearance/simulate/from-document — multipart file upload that auto-extracts first.
  • /api/customs-clearance/simulations — list / read history.
  • /api/customs-clearance/simulations/:id — single full result.

Every fire persists a row in customs_clearance.simulations so the broker / importer can compare against past runs (different origins, different declared values, different suppliers).

Dependencies

Calls these agents in order:

  1. HTS Classifier (Agent #1) — gets the 10-digit HTS code + rationale + cited CROSS rulings.
  2. Denied-Party Screener (Agent #3) — runs the supplier name against us_trade_csl. Always runs even if classifier confidence is low.
  3. Duty Calculator (Agent #4) — stacks every active trade program (Section 301 / 232 / IEEPA / Fentanyl / etc.) against the assigned HTS + origin.
  4. Risk Modeler (Agent #5) — produces the detention probability band and the dollar exposure range.

Plus the Document Extractor (Agent #2) when the fire comes from a PDF/image upload.

The Simulator doesn't add any LLM call of its own — it's pure composition + persistence + flag aggregation. It adds no model cost beyond the one Classifier call when a description is provided fresh; the from-document path adds the Document Extractor on top.

What success looks like

MetricTargetToday
Methodology coverage — every number traces to a citation100%✓ — surfaced via in-app "How this is calculated" modal + How landed cost is calculated
Speed (description → full result)Fast✓ — returns a full result in seconds (most of that is the Classifier's model call)
Speed (PDF upload → full result)Fast✓ — returns a full result in seconds (Extractor + Classifier run in sequence)
Persisted for compare100%✓ — simulations table, history endpoint
Honest about model bands"modelled, range" labeled in UI✓ — risk model is labeled, never asserted as prediction

What it does NOT do

  • Does NOT submit anything to CBP. There is no entry created. No Form 7501. Nothing transmitted. The Simulator is read-only by design.
  • Does NOT include freight, insurance, broker fees, or bond cost in the landed cost. The methodology doc explicitly enumerates these exclusions and surfaces "Freight roadmap: Q3" so the importer knows it's intentional, not an omission.
  • Does NOT apply specific (per-unit) duty rates. Flagged for broker manual computation.
  • Does NOT account for U.S. Note 20(b) Section 301 exclusion granularity yet. Coverage is at the HTS-prefix level. Q3 roadmap.
  • Does NOT predict CBP behavior. The Risk Modeler section is explicitly a planning-grade range, not a prediction.
  • Does NOT override broker judgment. If a CFO uses the Simulator to commit to a $5M PO, the broker is still required to re-verify at file time. The Simulator's output is decision-support, not the decision.

Roadmap

See Landed cost — what we are still closing for the full plan — every missing cost category with concrete data sources, prioritized build order, partnership patterns, and eval discipline. Highlights:

  • Q3 2026 — Freight rate integration (Freightos / Xeneta API) so landed cost includes shipping. Today it's intentionally excluded and flagged; removing the flag will be the visible signal.
  • Q3 2026 — U.S. Note 20(b) Section 301 exclusion granularity, so importers running scenarios on goods covered by active exclusions see the lower rate rather than the headline 25/30/etc%.
  • Q4 2026 — Multi-line PO support (today the simulator runs on one line at a time; importers want to drop a 20-line PO and see the whole landed cost in one trip).
  • Q4 2026 — "What-if" compare mode — pin one simulation as the baseline, then run variants (different origin, different supplier, different HTS) and see the delta side-by-side. Partial: the history page already does paired compare on past runs.
  • Q1 2027 — Carbon-intensity field on the simulated line so the result includes the CBAM certificate cost (EU-only, but importers shipping into EU need this).
  • Q1 2027 — Webhook subscriptions — when a tariff rate changes, re-run all persisted simulations affected by the change and notify the importer that their landed cost has moved.

How this differs from a real entry filing

A Simulation is a dry run. It uses the same agents and the same methodology as a real entry, but:

AspectSimulationReal entry filing
Persistencesimulations tableshipments + line_items + …
State machinenone — terminal at resultdraft → ai_review → ready → filed → cleared
CBP transmissionneveryes (via Autopilot's transmit action)
Authoritativeno — decision-supportyes — broker signs
Broker requiredno — importer can run themselvesyes

The same agents power both. The Simulator just chains them at a different point in the importer's purchase lifecycle.

Ready to see it live?

Put your own book of entries through Commers.