I’ve got the SignalWire service in the fax/SMS/Voice/Email module working for the community version. We can thank Sherwin @juggernautsei for the original contribution however we didn’t finish due to meeting ONC deadline. I’m making this effort because SignalWire built on the Twilio fax I originally had in first versions of the module. I really like this offering and think it will fit nicely for our smaller practices. I plan for upcoming 8.1.0 release and hope this will help many of you to decide to upgrade and please accept sending anonymous stats when asked. That data helped me decide to put effort into this.
Inbound faxes now list live from SignalWire’s Compatibility (LaML) Faxes API on a “check for faxes,” with status, sender, page count, and date.
(Aside for devs: the SignalWire PHP SDK doesn’t Composer-install cleanly into our tree, so rather than drag in its dependency weight I vendored a thin, Guzzle-backed shim covering only the fax surface we actually use — create/list/fetch/delete. Happy to write that up separately if there’s interest.)
Before I take this further, I’d like the community’s read on a design choice, because it affects storage, compliance, and long-term maintenance.
There are two models:
- Download every inbound fax to the OpenEMR filesystem on arrival. This is essentially what etherFAX forced on us — you download it or you lose it.
- Poll and retrieve on demand. Keep the fax on SignalWire, poll the list for status/metadata, and only download + store it as a patient document when a user actually files it — then delete the upstream copy. RingCentral and older Twilio allowed this; SignalWire does too.
I’m leaning toward the second — it’s closer to how RingCentral behaves and keeps PHI off our disk until someone commits to keeping it. But it has a genuine tradeoff: you depend on the provider’s retention window, and an unfiled fax could age out before anyone acts on it.
Rough pros and cons by practice size:
| Poll & retrieve on demand | Download every fax on arrival | |
|---|---|---|
| Small practice | Minimal local storage, little to maintain, no PHI piling up on disk. But relies on provider retention and being online to retrieve. | Everything local and offline-capable, simple mental model. But disk grows, more backup/encryption to manage, and junk faxes get stored too. |
| Enterprise | Lower storage cost at scale, provider handles primary retention. But provider retention windows may not satisfy legal-hold/compliance, and you must ensure faxes are filed before they purge. | Full custody for strict retention and legal hold, no provider dependency. But real storage/backup/egress cost at scale, plus lifecycle and purge management. |
Open questions for the group:
- Do you prefer inbound faxes pulled and stored locally on arrival, or kept upstream until a user files them?
- If deferred, what retention safety net would you want — e.g., a backstop that auto-files (or at least archives) anything older than N days so nothing ages out unhandled?
- For faxes that do get stored, how should we handle on-disk retention and purge?
Separately: once the retrieval model settles, I’m planning a follow-up to restructure this module toward current coding standards — PSR-12, service extraction, a dependency-light HTTP layer, PHPStan-clean, and isolated tests. I’ll open a separate topic for that so this thread stays focused on the retrieval question.
Interested to hear how others are running fax at both ends of the size spectrum. Thanks.



