ml-connector
AcumaticaTwilio

Acumatica and Twilio integration

Acumatica Cloud ERP runs finance, distribution, and procurement. Twilio sends SMS, voice calls, and one-time passcodes. Connecting the two turns events in the ledger into messages people actually see: an approver gets a text when a high-value bill needs sign-off, a controller is called when a payment fails, and a buyer is notified when an overdue invoice crosses a threshold. Because Twilio is a communications platform with no invoices, vendors, or GL accounts, nothing financial moves into it; ml-connector reads the events from Acumatica and uses Twilio only to deliver and confirm the notification.

How Acumatica works

Acumatica Cloud ERP exposes vendors, AP bills, payments, sales invoices, GL accounts, and employees through its Contract-Based REST API, JSON over HTTPS on a tenant-specific URL whose endpoint version in the path must exactly match the running ERP release. Authentication uses OAuth 2.0 against the instance identity server, with a legacy cookie session as a fallback. Field values in every request and response are wrapped in value objects. Acumatica can fire Push Notifications on a record change, secured by a shared-secret header rather than a signed payload, and where that is not configured the same data is read by polling on LastModifiedDateTime.

How Twilio works

Twilio is a cloud communications platform, not an ERP, so it has no vendor, invoice, purchase order, or GL objects. It exposes Messages for SMS and MMS, Calls for voice, Verify for one-time passcodes, and Usage records, through versioned REST APIs that take HTTP Basic Auth on every call. The recommended production credential is an API Key SID and secret, while the account Auth Token is still required to validate inbound webhook signatures. Request bodies are form-encoded rather than JSON, phone numbers must be in E.164 format, and Twilio pushes message and call status callbacks signed with HMAC-SHA1.

What moves between them

The flow runs one direction in substance: Acumatica events drive Twilio messages. ml-connector watches Acumatica for the conditions you choose, such as a bill posting, a payment clearing or failing, a document awaiting approval, or an invoice going overdue, and for each one it sends an SMS or places a voice call through Twilio to the mapped recipients. Twilio then pushes delivery status callbacks back, queued through sending, sent, delivered, undelivered, or failed, which ml-connector records against the originating Acumatica record. No financial data is written into Twilio because it has no place to store it. The cadence follows Acumatica Push Notifications where they are enabled, otherwise a scheduled poll on LastModifiedDateTime.

How ml-connector handles it

ml-connector stores both credential sets encrypted. It obtains and refreshes an Acumatica OAuth 2.0 bearer token against the instance identity server, and pins the endpoint version in every URL so a release mismatch does not silently return a 404. For Twilio it sends the API Key SID and secret as HTTP Basic Auth, posts message and call requests as form-encoded bodies rather than JSON, and normalizes every destination number to E.164 with the plus prefix. Because Acumatica Push Notifications retry up to five times with no dead-letter queue and can deliver duplicates, ml-connector verifies the configured shared-secret header, deduplicates each event before it fires a message, and falls back to a LastModifiedDateTime poll as a catch-up. Twilio has no idempotency-key header, so a stable jobId built from the Acumatica record id prevents the same alert being sent twice on a re-read. Inbound Twilio status callbacks are validated against the X-Twilio-Signature HMAC-SHA1 using the Auth Token before they are trusted. Acumatica rate limits are license-tier dependent and return 429 once the per-minute count passes half the licensed limit, and Twilio returns 429 on concurrency limits, so both directions back off with exponential delay and jitter. Every notification carries a full audit trail and can be replayed if a send fails.

A real-world example

A mid-sized wholesale distributor with roughly 250 staff runs Acumatica Cloud ERP for purchasing, inventory, and finance, and pays a few hundred supplier bills a week. Before the integration, approvers only saw pending bills when they happened to open the ERP, so high-value invoices sat past their discount window and a failed ACH payment was not noticed until a supplier called. With Acumatica and Twilio connected, a bill above the approval threshold texts the responsible manager the moment it posts, a failed payment places a voice call to the controller, and each alert is logged against the document with its Twilio delivery status. Approvals happen the same day, missed payments are caught within minutes, and there is a record of who was notified and whether the message was delivered.

What you can do

  • Send Acumatica record events, such as a posted bill or a failed payment, as SMS or voice alerts through Twilio.
  • Record Twilio delivery status, from queued through delivered or failed, against the originating Acumatica document.
  • Gate sensitive Acumatica actions with a Twilio Verify one-time passcode where stronger confirmation is needed.
  • Bridge Acumatica OAuth 2.0 and Twilio HTTP Basic Auth, validating inbound Twilio callbacks with HMAC-SHA1.
  • Trigger on Acumatica Push Notifications where configured, with a LastModifiedDateTime poll as a reliable fallback.

Questions

Does any financial data move from Acumatica into Twilio?
No. Twilio is a communications platform with no vendor, invoice, payment, or GL objects, so there is nowhere to post financial records. The integration reads events from Acumatica and uses Twilio only to deliver SMS and voice notifications and to report whether they were received.
How does the integration know when to send a message?
Where the Acumatica admin has configured Push Notifications, Twilio messages fire from those events, with the configured shared-secret header verified first since Acumatica does not sign the payload. Where push is not set up, ml-connector polls the relevant entities on LastModifiedDateTime instead. Because push can deliver duplicates and retries up to five times, each event is deduplicated before a message is sent.
How are Twilio webhooks and duplicate sends handled?
Inbound Twilio status callbacks are validated against the X-Twilio-Signature header using HMAC-SHA1 with your Auth Token before they are trusted, so a forged callback is rejected. Twilio offers no idempotency-key header, so ml-connector assigns a stable jobId derived from the Acumatica record id, which stops the same alert being sent twice if an event is re-read. Failed sends are retried with backoff and remain in the audit trail for replay.

Related integrations

Connect Acumatica and Twilio

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started