Webhooks
Events
Every webhook event OnePageCRM sends — the entity × reason matrix, dynamic deal status events, triggers, and privacy exclusions.
Last updated Jun 12, 2026
Every webhook carries a type (the entity that changed) and a
reason (what happened to it). This page lists every combination.
The event matrix
reason | contact | company | deal | action | note | call | meeting |
|---|---|---|---|---|---|---|---|
created | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
updated | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
deleted | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
undeleted | ✓ | — | ✓ | ✓ | ✓ | ✓ | ✓ |
completed | — | — | — | ✓ | — | — | — |
uncompleted | — | — | — | ✓ | — | — | — |
expected_close_date_updated | — | — | ✓ | — | — | — | — |
changed_to_<status> | — | — | ✓ | — | — | — | — |
Reasons are lowercase plain strings, exactly as shown.
Note the one asymmetry: companies have no undeleted event.
Every other entity sends one when a deleted record is restored.
Reason reference
reason | Fires when |
|---|---|
created | The record is created. |
updated | The record is edited. |
deleted | The record is deleted. data contains only the id — see Payloads. |
undeleted | A deleted record is restored. |
completed | An action is marked done. |
uncompleted | A completed action is reopened. |
expected_close_date_updated | A pending deal’s expected close date changes. |
changed_to_<status> | A deal’s status changes — see below. |
Dynamic deal status events
changed_to_<status> fires when a deal’s status changes, with the
new status substituted in. Deal status is constrained to exactly
three values — pending, won, lost — so the possible reasons
are:
changed_to_won— deal marked wonchanged_to_lost— deal marked lostchanged_to_pending— deal moved back to pending
Pipeline stages are a separate concept and do not produce
changed_to_ events. Matching on the changed_to_ prefix and
treating the suffix as data is still a reasonable way to
future-proof your receiver — but today the suffix is always one of
those three.
What triggers webhooks
Changes fire the same events no matter where they come from:
| Source | Fires webhooks? |
|---|---|
| The OnePageCRM web app | Yes |
| The REST API v3 | Yes |
| The MCP server | Yes |
| Bulk operations (bulk status, tag, or owner updates) | Yes — one event per affected record |
| CSV, Google Contacts, or Highrise imports | No |
Two things to plan for:
- A bulk update of 500 contacts means 500
contact/updatedevents arriving at your endpoint. - Imports are silent. If your integration needs imported records, reconcile with a periodic API poll — see Delivery.
No deduplication
There is no dedupe window. Three rapid edits to the same contact
produce three updated events. Build your receiver to be
idempotent — type + the entity id + timestamp makes a good
deduplication key. The entity id lives at data.<type>.id
(data.contact.id, data.deal.id, …), or data.id for
deleted events. See Delivery for the
pattern.
Privacy exclusions
Webhooks respect contact privacy:
- No
created,updated, or other full-payload webhook is sent for a private contact, or for any record (deal, note, action, call, meeting) belonging to a private contact. - Company events are skipped if the company has no contacts, or if any of its contacts is private.
deletedevents are the exception — they are still sent for private contacts. The privacy check never runs for deletes becausedatacarries only theid, nothing private.
If you’re testing and an event never arrives, check whether the record’s contact is private before debugging your endpoint.