Entry statuses, explained
Every stage an entry can be in, what it means, and what happens next.
Canonical reference for every status a customs entry can hold in Commers, mapped to the workflow phase it represents and the action that moves it forward.
This doc is the single source of truth for:
- What each DB status means (the
customs_clearance.shipments.statuscolumn) - Which broker / CBP / Autopilot action triggers the next transition
- How the Dashboard filter buckets and the "Needs review" KPI tile map to these statuses
For the visual workflow this maps onto, see the visual workflow — open it in any browser to see the 9-step end-to-end flow (Pre-shipment → Document review → Entry filing → Post-entry).
For the state-machine code itself, see Autopilot.
The 8 statuses
Listed in lifecycle order. Every entry walks this path; some terminate early at released if the broker doesn't need to settle duty separately, or detour through hold / exam if CBP escalates.
| # | DB status | Workflow phase | What it means | What moves it forward |
|---|---|---|---|---|
| 1 | draft | Pre-shipment (Steps 1–3) | PO received; ISF may or may not be filed; documents may or may not be in. Nothing has been classified yet. | Document Extractor runs → enough fields populated → Autopilot fires Classifier + Screener → ai_review |
| 2 | ai_review | Document review & classification (Steps 4–6) | HTS Classifier, Duty Calculator, and Denied-Party Screener have all run. Broker is reviewing the result. | Broker approves OR Autopilot auto-approves if (every line confidence ≥ threshold AND no blocking screening hits) → ready |
| 3 | hold | Document review — escalation | A blocking screening hit (UFLPA / Entity List) is preventing the entry from advancing. Broker must dismiss with reason or stop the shipment. | Broker dismisses hit with documented reason → re-enters ai_review |
| 4 | exam | Entry filing — CBP intensive exam | CBP has selected the entry for inspection. 2–10 day delay, $300–1,500 in fees. | CBP releases the exam → released |
| 5 | ready | Entry filing (Step 7, broker side) | Classification approved, screening cleared, duty computed. Broker has not yet transmitted to CBP. This is the "I need to file this" pile. | Broker transmits ABI message → filed |
| 6 | filed | Entry filing (Step 7, CBP side) | ABI message has been sent to CBP. Awaiting CBP response (Release / Exam / Hold). This is the "waiting on CBP" pile. | CBP releases cargo → released or selects for exam → exam or issues a hold → hold |
| 7 | released | Entry filing outcome | CBP released the cargo from the port. Importer can take possession. Broker still has 10 days to pay CBP — that's the "Capital float" risk on the workflow map (Step 8). | Broker pays CBP (duty + MPF + HMF) within 10 days → cleared |
| 8 | cleared | Post-entry (Step 8 complete) | Entry summary fully processed. Duty paid. Importer invoiced. Entry is in the 4-year CBP audit window (Step 9) until that window closes. | Terminal status from the lifecycle's perspective. May be re-touched if CBP issues a CF-28 / CF-29 post-entry inquiry. |
Status vs. Stage (the pipeline)
The 8 statuses above are the state-machine — the durable value in shipments.status. On top of that, every list + detail response also carries a pipeline stage: a broker-facing reading of where the entry is in the 9-step workflow and what's left to do. It is derived, never stored, by the pure deriveShipmentStage, and it is the single source of truth behind both the Shipments table (the Stage / Next action columns) and the drawer stepper — so the two can never disagree.
The 9 canonical stage names (STAGE_NAMES) — the same words in the table, the KPI cards, and the drawer stepper:
PO & Shipment · ISF · Documents · HTS Classification · Duty Calc · PGA / UFLPA · ACE Filing · CBP · Post-Entry
Two axes are kept deliberately separate:
- Position (
step/stage+ the 9-dotstates[]) reads the furthest step reached, exactly like a "you are here" stepper. A step is "done" only when the underlying work actually happened (lines classified, duty computed, screening cleared, entry filed). A soft concern does not move the entry backward. - Health (
ontrack/attention/blocked) + the one-lineaction. This is where a concern surfaces.
Hard blockers genuinely gate forward movement, so they un-do the step they sit behind (the entry parks there; the dot never shows a false green tick):
| Blocker | Parks at | Health |
|---|---|---|
CBP intensive exam (status=exam / cbp_intensive_exam) | CBP (8) | blocked |
Denied-party screening block (screening-block) | PGA / UFLPA (6) | blocked |
UFLPA high-risk (uflpa_high) | PGA / UFLPA (6) | blocked |
Compliance hold (status=hold) | PGA / UFLPA (6) | blocked |
| Sub-70% HTS classification (see below) | HTS Classification (4) | blocked |
The HTS confidence gate (HTS_REVIEW_THRESHOLD = 70)
Any line classified below 70% confidence un-does the HTS Classification step, so the entry parks at HTS Classification with a red "Blocked — HTS at N% (< 70%), broker review required" — it can never read as "ready to transmit" on an unreviewed low-confidence code. The block:
- bites only while the entry is still in review (
draft/ai_review); once a broker approves it to file, it's their call and the entry moves on; - lands the broker in the drawer's HTS Classification section — exactly where each line's confidence and any invoice-mismatch warnings are shown.
Two thresholds, don't conflate them: the 70% floor here is the review gate (hard-blocks for a human to look). The 92% floor in Autopilot is the higher auto-file bar (Autopilot only transmits at or above it). A sub-70% entry was never going to auto-file anyway; this gate just makes the manual review queue honest about why it's parked.
The owner axis (StageOwner) — whose move is it?
Alongside position and health, deriveShipmentStage names who the next move belongs to: broker (the default — it's your workbench), cbp (filed / under exam — the government has it), supplier (UFLPA high-risk — you're waiting on their traceability docs), or importer (an empty draft — waiting on their commercial documents). Chasing a supplier or importer is still your move (send the reminder); only owner: 'cbp' counts as genuinely waiting on others, because there is no useful action to take against CBP's clock.
The Needs-You action feed (GET /today/actions)
The Today home renders ONE ranked list across three sources — entries needing work, CF-28/29 notices, and in-force rate-change proposals — built by getActionFeed: deterministic, zero LLM calls, ≤3 SQL statements. Each item carries the plain-language action, the owner above, an honest deadline (only real due_by / effective_date dates — "Overdue 37d", "Due in 3d", "In force — unreviewed"; no fabricated urgency), and value at risk. Ranking: blocked first → nearest deadline → highest value. The feed is split yourMove vs waiting on the owner rule above. This is the notification surface — Today is the inbox, Shipments is the workbench.
State transitions
(broker dismisses hit)
┌──────────────────────────────────────────────┐
▼ │
┌─────────┐ ┌───┴───┐
│ draft │──extract+classify+screen──┐ │ hold │◄──┐
└─────────┘ ▼ └───────┘ │ (UFLPA / entity)
┌─────────────┐ │
│ ai_review │───────────────┘
└──────┬──────┘
(approve / auto-approve)
▼
┌─────────┐ transmit ABI ┌─────────┐
│ ready │───────────────────►│ filed │
└─────────┘ └────┬────┘
│
┌──────────────────────────────┤
▼ ▼ ▼
┌──────────┐ ┌───────┐ ┌──────────┐
│ exam │ │ hold │ │ released │
└────┬─────┘ └───────┘ └─────┬────┘
│ │ pay duty
▼ ▼ within 10d
┌──────────┐ ┌─────────┐
│ released │──────────────────►│ cleared │
└──────────┘ └─────────┘
Mapping to the Dashboard
The Dashboard filter exposes one bucket per status plus two meta-filters:
| Filter bucket | Maps to status(es) | Why it exists |
|---|---|---|
| All | every status | Default view |
| Needs review (meta) | hold + exam + (ai_review AND confidence < 92%) | Daily triage. Same set is reachable via the "Needs review" KPI tile at the top of the Dashboard. |
| Draft | draft | New stuff that hasn't been touched. Triggers Autopilot when documents are complete. |
| AI review | ai_review | Awaiting broker confirmation. "AI is done, you decide." |
| On hold / Exam | hold + exam | Both are CBP-intervention states with the same broker response shape (compile documents, respond by deadline). |
| Ready to file | ready | Broker action pile — transmit ABI. |
| Filed | filed | Waiting on CBP. Broker can do nothing but watch. |
| Released | released | CBP let the cargo through. Duty may still be owed. Capital-float risk lives here. |
| Cleared | cleared | Fully done. In the 4-year audit window until CBP's lookback expires. |
The hold + exam and ai_review (low confidence) combo is the only deliberate lumping — those three are the entries a broker triages first thing each morning, so they cluster as "Needs review" both in the KPI tile and in the Filter popover preset.
What this status model does NOT yet capture
These are workflow steps from the visual workflow that don't currently have a dedicated status because they live in adjacent modules or aren't yet built:
- ISF Filing (Step 2) — Importer Security Filing, 24h-before-departure. Not modelled today. Late ISF = $5,000 CBP penalty per violation. Will live in the
customs-clearancemodule as a separate filing alongside the entry, not as a status of the entry itself. - Duty Payment (Step 8) — sits inside the
released → clearedtransition today. We don't separately track "duty paid" vs "duty pending past 10 days" — that distinction is needed to surface the capital-float risk to the broker. Q3 2026 roadmap. - Post-Entry Audit (Step 9) — CF-28 / CF-29 inquiries. Lives in the
post-entry-auditmodule (13 active cases today, see sidebar). Not surfaced on the Dashboard yet. Would be a new KPI tile: "Cleared entries within audit window".
Roadmap
- Q3 2026 — Rename
ai_review→awaiting_brokerto disambiguate from "AI is currently reviewing". - Q3 2026 — Add
duty_pendingstatus betweenreleasedandclearedto make capital-float visible. - Q4 2026 — Add an ISF entity (not a status) — separate filing tracked alongside the entry.
- Q4 2026 — Surface
cleared+ audit-window-overlap as a Dashboard KPI tile linking into post-entry audit.
Put your own book of entries through Commers.