Get started now

Zoho CRM Webhooks: A Developer's Implementation Guide

A Zoho CRM webhook is an HTTP POST request that Zoho sends to a URL you specify when a defined event occurs in the CRM — a deal is created, a field changes, a record is deleted. Your external application receives the webhook, processes the payload and takes whatever action the event requires. Webhooks are the mechanism for external systems to react to Zoho CRM events in real time without polling the API continuously. This guide covers the technical implementation: configuring outgoing webhooks in Zoho CRM, the payload structure and how to build a reliable webhook receiver. For Zoho’s incoming webhook patterns (where external systems trigger Zoho actions), see the API integrations hub.
Zoho CRM Webhooks: A Developer**'**s Implementation Guide — ABR Zoho guide

Configuring Outgoing Webhooks in Zoho CRM

Zoho CRM webhooks are configured as actions within workflow rules. Go to Setup → Automation → Workflow Rules → create or open a rule → Add Action → Webhooks. The webhook action sends a POST request to your endpoint URL when the workflow rule fires.

Key webhook configuration settings:

  • URL — your endpoint’s HTTPS URL. Zoho requires HTTPS for production webhooks. Use a tunneling tool like ngrok during development to expose a local endpoint.
  • Method — POST (standard) or GET.
  • User Agent — identifies Zoho as the sender.
  • Parameters — the fields from the triggering record to include in the payload. Select which CRM fields to send from a dropdown list — you do not need to send every field, only those your application needs.
  • Custom Headers — add a shared secret header for signature verification (strongly recommended).

The Webhook Payload

Zoho CRM sends webhook payloads as form-encoded POST bodies (not JSON by default). The parameters you selected in the webhook configuration arrive as key-value pairs in the request body:

# Example webhook payload (form-encoded) # from a Deal Stage Changed workflow rule POST /your-webhook-endpoint HTTP/1.1 Content-Type: application/x-www-form-urlencoded X-Zoho-Webhook-Secret: your-shared-secret dealId=1234567890& Deal_Name=Acme+Corp+-+Platform+Licence& Stage=Closed+Won& Amount=24000.0& Owner_Email=rep%40yourdomain.com& Account_Name=Acme+Corp

Building a Webhook Receiver in Python

# Python Flask webhook receiver from flask import Flask, request, jsonify import hmac, hashlib app = Flask(__name__) WEBHOOK_SECRET = “your-shared-secret” @app.route(“/zoho-webhook”, methods=[“POST”]) def handle_zoho_webhook(): # 1. Verify the shared secret header received_secret = request.headers.get(“X-Zoho-Webhook-Secret”, “”) if received_secret != WEBHOOK_SECRET: return jsonify({“error”: “Unauthorized”}), 401 # 2. Parse the form-encoded payload deal_id = request.form.get(“dealId”) deal_name = request.form.get(“Deal_Name”) stage = request.form.get(“Stage”) amount = float(request.form.get(“Amount”, 0)) # 3. Route to appropriate handler based on stage if stage == “Closed Won”: create_invoice_in_erp(deal_id, deal_name, amount) elif stage == “Proposal Sent”: notify_operations_team(deal_id, deal_name) # 4. Return 200 quickly — Zoho retries on non-200 responses return jsonify({“status”: “received”}), 200 def create_invoice_in_erp(deal_id, deal_name, amount): # Your ERP integration logic here pass

Reliability Considerations

  • Return 200 immediately — Zoho considers a webhook delivery failed if it does not receive a 200 response within a few seconds. Return 200 as soon as the payload is received, then process asynchronously. Use a message queue (AWS SQS, RabbitMQ) or a background task worker to process the event without blocking the HTTP response.
  • Handle duplicate deliveries — Zoho retries webhook delivery on failure. Your receiver may receive the same event multiple times. Implement idempotency: store the webhook’s unique identifier and skip processing if you have already processed that event.
  • Validate the secret header — always verify the shared secret header to ensure the webhook genuinely came from Zoho and was not spoofed by an external party.
  • Log every webhook — store the raw payload and a processing result for every webhook received. When an integration issue is reported, the webhook log provides the evidence trail to identify whether the issue was in the Zoho configuration (webhook not firing), the receiver (webhook received but processing failed) or the downstream system (processing succeeded but the external action failed).

Frequently Asked Questions

A Zoho CRM webhook sends an automatic HTTP POST notification to an external URL when a defined event occurs in Zoho CRM — a record is created, updated or deleted. The external system receives the notification and can take action without polling the CRM for changes.
An API call is initiated by your system requesting data from Zoho CRM. A webhook is initiated by Zoho CRM pushing data to your system when an event occurs. Webhooks are more efficient for real-time integration because they eliminate the need for constant polling.
In Zoho CRM: Settings → Automation → Workflow Rules → create a new rule → add a Webhook action → enter the target URL and configure the JSON payload with the fields you want to send.
Yes — validate incoming webhook payloads on the receiving system to confirm they originate from Zoho. Use HTTPS endpoints only. Implement payload signature verification if the receiving system supports it.
Yes — webhook configuration and integration development is a core ABR service. Book a free consultation →