Rather have us handle this?We set this up for clients every day.
See the Service

Guides/Zoho CRM

Zoho CRM Webhooks: Setup, Payloads, Limits and Troubleshooting

Configuring Zoho CRM webhooks and workflow rules to send real-time record events to your integration, with payloads, limits and troubleshooting.

Last verified: October 2026

How Zoho CRM Webhooks Work

Zoho CRM doesn’t have a “register a URL, pick events” webhook screen like Pipedrive. A Zoho webhook is an action: you define it once (URL, method, payload), then attach it to a workflow rule that decides when it fires: when a contact is created, a deal is edited, a field changes.

That design is flexible. You can filter with criteria and send exactly the fields you want. But it means one workflow rule per module and trigger, and it comes with limits worth knowing before you build.

There’s also a second option, the Notification API, which suits some integrations better. We cover both below.

Prerequisites

  • Admin access to Zoho CRM (Setup > Automation)
  • API credentials if the integration also writes back to Zoho (Zoho CRM API setup)
  • The webhook URL we provide for your integration

Step 1: Create the Webhook

  1. Go to Setup > Automation > Actions > Webhooks
  2. Click Configure Webhook
  3. Name it clearly, e.g. “New contacts to integration”
  4. Choose the method: POST (normal for integrations), GET, PUT or DELETE. POST and PUT can send headers, a body and URL parameters; GET and DELETE send URL parameters only
  5. Enter the URL to notify (the endpoint we provide)
  6. Choose the module (Contacts, Deals, Accounts, Leads…)
  7. Set authentication (see below)
  8. Build the body (see the next section) and save

(Zoho help: webhooks)

Authentication options

  • General: an API key or auth token you add yourself, typically as a header parameter. This is the common choice when the receiving endpoint checks a shared secret.
  • Connection: uses a Zoho connection (OAuth, API key and similar) when you’re calling a third-party API directly.

You can add up to 10 header parameters, built from module fields or custom values. We usually add one secret header so our endpoint can reject anything that didn’t come from your Zoho account.

Step 2: Build the Payload

You have two body formats:

  • Form-Data: name/value pairs, each mapped to a module field, a custom value or a user-defined value.
  • Raw: write the body yourself as JSON, XML, HTML or text (up to 15,000 characters). In the raw editor, type # to insert a merge field.

For integrations we use Raw JSON, because it’s explicit and easy to validate. A typical contact payload looks like this:

{
  "event": "contact.created",
  "contact_id": "${Contacts.Contact Id}",
  "first_name": "${Contacts.First Name}",
  "last_name": "${Contacts.Last Name}",
  "email": "${Contacts.Email}",
  "phone": "${Contacts.Phone}",
  "owner": "${Contacts.Contact Owner}"
}

Insert each ${…} placeholder with the # picker rather than typing it. Zoho fills in the exact field reference for your module, and field names vary by module and by any renaming you’ve done. Use the record ID as your key on the receiving end: names and emails change, IDs don’t. If you create webhooks through Zoho’s API instead of the UI, the merge-field syntax is slightly different (${!Leads.Email}), so don’t copy one into the other. (Create Webhook API)

Include an event value you set yourself (like "contact.created" above). If several workflow rules post to the same URL, it’s the easiest way for the receiving side to tell them apart.

Step 3: Attach It to a Workflow Rule

  1. Go to Setup > Automation > Workflow Rules and create a rule
  2. Pick the module and when the rule runs: On a record action. Choose Create, Edit, Create or Edit, Field Update or Delete
  3. For Edit triggers, decide whether to tick Repeat this workflow every time a record is edited. Leave it unticked and the rule fires only the first time the criteria are met
  4. Add criteria if only some records should trigger it (for example, only deals in a certain pipeline)
  5. Under Instant Actions, choose Webhook, select the webhook you created and Associate it
  6. Save, and confirm the rule is active

A rule can carry up to 6 webhooks (1 instant plus 5 time-based), and each condition can have one instant webhook. Delete-triggered rules can only run email notifications, webhooks and functions, and the record’s data is limited by then, so we capture the ID and handle the rest on our side.

Typical rule set

Integration needRule
New contacts to the integrationContacts, on Create
Contact updatesContacts, on Edit (repeat on every edit)
Deal stage changesDeals, on Field Update (Stage)
New dealsDeals, on Create
Deleted recordsEach module, on Delete
Let's talk about your systems.Tell us what tools you're using and what's not working. We'll tell you what's possible.
Get in touch

Limits to Plan Around

These are the ones that bite in production. (Zoho help: webhooks)

  • Daily webhook calls by edition (whichever is lower):
    • Professional: 50,000 per day or 100 per user per day
    • Enterprise: 500,000 per day or 500 per user per day
    • Ultimate: 1,000,000 per day or 1,000 per user per day
  • 10-second timeout. If your endpoint doesn’t respond within 10 seconds, Zoho records a socket timeout.
  • Failures are notified, not guaranteed to be redelivered. Zoho emails a failure notification (and another 15 minutes later). It doesn’t document automatic redelivery of a failed call. Treat a failed webhook as a missed event unless your integration backfills.
  • A small team on Professional can hit the per-user cap. 5 users means 500 calls a day. Bulk imports and mass updates burn through that fast.

So the receiving endpoint should respond immediately (store the payload, return 200, process in the background), and the integration should have a way to catch up on anything missed, usually a periodic API query for records modified since the last successful sync.

The Alternative: Zoho’s Notification API

For high-volume modules, or when you want every change rather than rule-filtered ones, Zoho’s Notification API is often a better fit. Instead of workflow rules, the integration subscribes a channel to events like Contacts.create, Contacts.edit, Deals.all, and Zoho posts a notification to the notify_url.

What’s different:

  • It tells you what changed, not the full record. The notification includes the module, the operation, the affected record ids and (optionally) the changed fields. The integration then fetches the details through the API.
  • Channels expire. The maximum channel_expiry is one week. If you omit it or ask for longer, Zoho sets one hour. The integration must re-enable channels before they lapse. (Update notification details)
  • You can set a token (up to 50 characters) that comes back with every notification, so you can verify the source.
  • No per-rule setup in the UI. Everything is configured through the API, which is easier to manage across many modules.

We often combine them: workflow webhooks for the few events that need rich, filtered payloads, and the Notification API with API fetches for broad sync.

Testing

  1. Point the webhook at a request inspector first (webhook.site or similar). Create or edit a test record and inspect exactly what Zoho sends, especially the merge-field values.
  2. Test each rule’s trigger. An Edit rule won’t fire on create, and an Edit rule without “repeat” only fires the first time the criteria match.
  3. Test the criteria edges. Use a record that should not trigger the rule and confirm nothing arrives.
  4. Test a delete if you subscribed to deletes, and check what data survives.
  5. Switch the URL to production once the payloads look right.

Troubleshooting

Webhook Not Firing

  • Is the workflow rule active, and does the record meet its criteria?
  • Is it an Edit rule without “Repeat this workflow every time a record is edited”? Then it only fires the first time.
  • Have you hit the daily limit? Zoho lists “daily limit reached” as a failure reason. Check usage under Setup > Automation > Actions > Webhooks.

Failure Notifications

Zoho’s failure reasons include bad request, unauthorized, page not found, server unavailable, third-party error and socket timeout. Unauthorized usually means the secret header or token changed. Socket timeout means the endpoint took longer than 10 seconds.

Payload Missing Fields or Showing Placeholders

Edit the webhook and re-insert the field with the # picker. Hand-typed placeholders with the wrong field name won’t resolve. Zoho also limits how many CRM fields a webhook can send to a third-party app (10), so send the ID plus the essentials and fetch the rest through the API.

Events Missed During an Outage

If the endpoint was down, those calls failed and won’t be replayed. Run a catch-up sync: query the API for records modified since the last event you processed.

Next Steps

Rather Have Us Handle It?

We set this up for clients every day. Tell us what you're connecting and we'll take it from here.