How an inbound parcel gets tracked
Between issuing a label and getting the box back, the system has nothing to do but wait — and waiting well is harder than it sounds. This post is about the await-inbound step: how a Step Functions execution pauses cheaply for days, how a real carrier scan wakes it back up, and how a daily sweep makes sure a parcel that never ships doesn’t sit open forever.
Key takeaways
- After the label goes out, the state machine pauses on an “await inbound” step that can wait for days at no cost.
- The paused execution holds a task token, stored on the return and findable by the parcel’s tracking number.
- A real carrier scan arrives as a webhook, is routed through EventBridge, and resumes the exact waiting execution.
- A daily EventBridge Scheduler sweep catches parcels that were never sent, so a return never sits open forever.
- The wait ends on a genuine delivered scan — never on a guess that the box probably arrived.
Waiting well
Between handing the customer a label and getting the box back, there’s nothing to do but wait — and that waiting is where naive systems either burn money or lose track. You don’t want a Lambda sitting spinning for a week, and you don’t want to poll the carrier every hour for a parcel that hasn’t moved. Step Functions handles this properly: the execution reaches an await inbound step, hands out a task token, and goes to sleep. It costs nothing while it sleeps — Step Functions bills state transitions, not the days a parcel spends in a van — and it wakes only when something real happens.
Two things can wake it: a carrier scan that says the parcel was delivered back to you, or a scheduled sweep that decides the parcel is never coming.
The paused execution
When rmar-label finishes, the state machine moves to a task step configured to wait for a task token. Step Functions generates the token and the step hands it off — the function writes it onto the return record, alongside the tracking number from Part 3 — then the execution simply parks. There’s no compute running, no queue being drained, nothing being polled. The whole return is now represented by one sleeping execution and one row in rmar-returns that says, in effect, “when tracking number XYZ is delivered, resume with this token.”
The carrier scan that wakes it
Carriers will post tracking events to a webhook if you register one — collected, in transit, out for delivery, delivered. The handler behind the rmar-track Function URL takes each event, verifies it against a signing secret from Secrets Manager, and publishes it onto an EventBridge bus, rmar-events. A rule on that bus — matching only the events that matter, the “delivered to the return address” ones — triggers rmar-track. It looks up the return by tracking number using a GSI, reads the stored task token, and calls SendTaskSuccess with the scan details. That, and only that, resumes the execution, which moves straight on to the inspect stage. Putting EventBridge in the middle means the noisy in-transit scans are filtered out cheaply and the only thing that ever wakes a return is the scan that genuinely matters.
The sweep for parcels that never come
Plenty of returns are requested and never sent — the customer changes their mind, or the label sits in their inbox until they forget. Those executions would otherwise wait forever. rmar-sweep, fired daily by EventBridge Scheduler, scans for returns still parked past a sensible deadline — say 21 days after the label was issued — and resolves them: a gentle reminder a few days in, and a clean timeout that closes the return at the deadline so it isn’t left dangling. A timed-out return is never refunded; it’s simply closed, because nothing came back. The sweep is also where a stuck-in-transit parcel gets noticed and handed to a person, so a return that’s genuinely lost in the post gets a human rather than silence.
Design rules for the inbound wait
- Pause, don’t poll. The execution sleeps on a task token; nothing runs and nothing is billed while a parcel travels.
- Wake on a real scan. Only a genuine delivered event resumes a return — never an assumption that it arrived.
- Filter at EventBridge. In-transit noise is dropped by the rule; only the delivered scan reaches the resume function.
- Find it by tracking number. The GSI on the returns table ties a scan back to the one execution waiting on it.
- Sweep the strays. A daily timeout closes returns that never shipped — closed, not refunded — and flags the genuinely lost.