Webhooks and Zapier for Sage 100 Contractor
Find out when an AP invoice, purchase order, journal entry, service invoice or inventory allocation is entered or changed in Sage 100 Contractor, without polling it yourself. Twinn sends a signed event to your own endpoint, or starts a Zap, within about five minutes of the change, whether it was made in Sage or through Twinn.
How it works
Changes made anywhere
Twinn watches Sage 100 Contractor’s own change stamps, so an invoice keyed at the desk is found as surely as one posted through the API. Each event says which it was.
Within about five minutes
The Twinn service on your network checks for changes every five minutes, and only for the documents someone has subscribed to, so your Sage server is not kept busy.
Pick the events you want
Subscribe each endpoint to just the documents it cares about: AP invoices for the approvals tool, purchase orders for the warehouse.
Only what you may see
An event carries only what the person who set it up is allowed to read. Take away their access and the endpoint pauses. Payroll is never sent.
Never lost when you are down
If your endpoint is offline, Twinn keeps trying for three days, and you can resend any event from the delivery log.
Zapier when you don’t code
The same events start Zaps, so office staff can connect Sage 100 Contractor to the apps they already use.
The events
Each document comes as a .created and an .updated event, and carries the document’s header with the event, so a Zap can use its fields straight away.
| Event | Sent when |
|---|---|
| payable_invoice.created | An AP invoice is entered, in Sage or through a PO receipt or AP import. |
| payable_invoice.updated | An AP invoice is changed: approved, put on hold, paid, re-coded. |
| purchase_order.created | A purchase order is entered. |
| purchase_order.updated | A purchase order is changed or received against. |
| ledger_transaction.created | A journal entry is posted to the general ledger. |
| ledger_transaction.updated | A journal entry is changed. |
| service_invoice.created | A service invoice is entered. |
| service_invoice.updated | A service invoice is changed or invoiced. |
| inventory_allocation.created | Stock is allocated to a job or moved between locations. |
| inventory_allocation.updated | An inventory allocation is changed. |
Signed, retried, and safe to repeat
- Signed to the open Standard Webhooks spec, so the libraries you already use can verify it.
- Retried with back-off for three days when your endpoint is down. Every event has an id, so a repeat is easy to ignore.
- A delivery log for 30 days, with Resend and Send test event buttons.
- Sent from a fixed address you can allow through your firewall.
- Managed by your company admin, and every change is logged.
POST /your/endpoint
webhook-id: evt_01JA9Q4M7Z3T8K2D6F0B5N1R2C
webhook-timestamp: 1791832800
webhook-signature: v1,K5o0…
{
"type": "payable_invoice.updated",
"timestamp": "2026-10-12T19:04:11Z",
"data": {
"entity": "payable_invoice",
"source": "sage",
"changedAt": "2026-10-12T19:02:57Z",
"changedBy": "lisa",
"record": {
"invoiceNumber": "INV-20871",
"vendor": "Southern Supply Co.",
"job": "24-118",
"status": "Approved",
"total": "12480.00"
}
}
}Zapier · Invite only at first
No code? Use Zapier.
Sign in to Twinn from Zapier, pick a company and an event, and send it to Slack, Teams, Google Sheets, email or any of Zapier’s apps. A new AP invoice over $10,000 can post in your project managers’ channel, or every new purchase order can land in a sheet, without anyone writing code.
Testing against your own machine
Webhooks only go to public https addresses, so localhost is refused. A free Cloudflare tunnel gives your development server a public https address in one command, with no account needed. Paste the address it prints into Twinn as your endpoint, then press Send test event.
The quick address changes every time the tunnel starts. For an address that stays the same, use a named tunnel on a domain you have in Cloudflare.
# Windows: winget install Cloudflare.cloudflared
# macOS: brew install cloudflared
# Your app listening on port 3000:
cloudflared tunnel --url http://localhost:3000
# It prints something like:
# https://quiet-river-1234.trycloudflare.com
# Use that, plus your path, as the endpoint:
# https://quiet-river-1234.trycloudflare.com/webhooks/twinnQuestions
- Which Sage 100 Contractor changes can I get webhooks for?
- AP invoices, purchase orders, general ledger journal entries, service invoices and inventory allocations, each when it is created and when it is changed. These are the documents Twinn can also write, and more will follow.
- How quickly do webhooks arrive?
- Within about five minutes of the change being saved in Sage 100 Contractor. The Twinn service on your network checks for changes every five minutes.
- Do I get an event when something is deleted?
- No. Webhooks cover documents being created and changed. If your system needs to know a document is gone, reading it through the OPDC API returns not found.
- Does it work with Zapier?
- Yes. Twinn will have a Zapier app, invite-only at first, that signs in to Twinn and starts a Zap from any of the events.
- How do I test webhooks on my own computer?
- Run a Cloudflare tunnel (cloudflared tunnel --url http://localhost:3000) to give your development server a public https address, use that address as the endpoint, and press Send test event.
- How do I know a webhook came from Twinn?
- Every request is signed with a secret only you and Twinn hold, following the Standard Webhooks spec. Check the webhook-signature header before trusting the body.
Want Sage 100 Contractor to tell your systems what changed?
Tell us which events you need first, and we’ll add you to early access.