Introduction
When I talk about reading fax orders with AI, everyone gets curious about "how the AI reads." But the truth is, the foundation that comes before it — how to pick up every incoming fax without missing one — is the humble part that matters most.
This article explains the design of the intake pipeline that automatically fetches, on a schedule, the PDFs forwarded by email from the fax machine. It's the "pre-processing" stage that feeds the reading AI.
Faxes Arrive as Email
The Machine Forwards a PDF
Modern fax multifunction machines can turn an incoming fax into an image PDF, attach it to an email, and forward it to a designated address. With this, a fax arrives as digital data before it's ever printed on paper.
So what sits in front of the order clerk is no longer a "paper fax" but an "email with a PDF attached." That's the starting point for automation. Just not having to touch paper opens up a world of processing possibilities.
Consolidate into a Dedicated Inbox
For the forwarding destination, I set up a single dedicated email address for fax reception. When all client faxes gather in one place, there's only one place to monitor.
Keeping it separate from regular business email is also key. With a dedicated inbox, you can treat everything simply — "whatever arrives here is a processing target" — and the downstream logic doesn't need extra conditional branching.
Designing Retrieval by Polling
Checking the Inbox with the Gmail API
Email retrieval uses the Gmail API. Rather than "get notified (pushed) when new mail arrives," I adopted a polling approach where we periodically go and ask, "any unprocessed mail?"
The pipeline runs every 5 minutes
Fetch mail with the "unprocessed" label via the Gmail API
Pull the PDF attachment from each email
Pass the PDF to the LLM extraction stage
Relabel the completed email
Why Polling Instead of Push
Push notifications excel at "immediacy," but managing notification setup and handling missed notifications tends to get complex. Fax order intake isn't a task that demands second-by-second immediacy.
Since a few minutes of delay causes no practical problem, I chose simple, hard-to-break polling — just check every 5 minutes via Cron. Because the mechanism is simple, its behavior is easy to trace and failures are easy to pinpoint.
Managing Processed State
Preventing the same fax from being ingested twice is essential. In this system, once processing finishes, the email is labeled "processed," and the next poll targets only the unprocessed ones.
Leaving state on the Gmail side as a label means that even if the pipeline halts midway, a re-run can pick up where it left off. Not holding state solely in your own DB, but also leaving it on the email itself, is the trick to preventing dropped items.
Making It Hard to Break
Be Mindful of Idempotency
In a scheduled system, it's crucial that running the same process twice doesn't corrupt the result — so-called idempotency. It's perfectly normal for a partially completed process to be re-run due to a transient network error or timeout.
So we always check first, "has this email been processed?" and skip it if so. This small step of preventing double writes underpins the reliability of a system that runs unattended in the middle of the night.
Unattended Operation Assumes 'Safe to Run Twice'
A process that runs automatically on Cron must be designed to produce the same result no matter when it re-runs. Neglect this, and you'll be plagued by hard-to-spot double-registration bugs.
Don't Swallow Failures
Exceptions will happen — a corrupted PDF, an attachment in an unexpected format. If you let one stop the entire process, even the subsequent healthy faxes get stuck.
So we process each item independently, "record failures as errors," and move on to the next. Leave things so a person can review the error list and handle them later. Not silently swallowing failures, but leaving them in a visible form, pays off in operations.
Conclusion
I've explained the design of the automated intake pipeline from email reception.
- Faxes arrive as email: PDF forwarding from the machine puts you at the doorstep of digital processing, no paper needed
- Pick them up by polling: prioritize simplicity over immediacy, fetching every one via a 5-minute Cron
- Build it to not break: mind idempotency, and record failures rather than swallowing them before moving on
Only with this foundation does AI reading run stably. Next, we cover how ingested PDFs become structured data in "Structured Data Extraction from Forms with LLMs." For the overall picture, see "AI-OCR for Fax Orders."