Webhook

Estimated reading: 5 minutes 14 views

Pro · Destination step

Sends each record to a URL of your choice, such as your own API, Make, n8n, Slack or a CRM other than Zoho. Webhook feeds use the same queue, retries and log as Zoho feeds.

Set it up

  1. Switch to WebhookOn the Destination step, switch from Zoho app to Webhook. A webhook feed needs no Mapping step, so it disappears from the step list.
  2. Choose a method and URLPick POST, PUT, PATCH, GET or DELETE, then paste the URL.
  3. Build the requestWrite the body and add any headers, query parameters and auth. Use {{field_id}} wherever you want a form answer.
  4. Send a testPress Send test or Ctrl + Enter. Check what came back under Response.
  5. Save the feedThe button at the bottom of this step saves the feed (Create feed or Save feed).
Destination step
Zoho appWebhook
POST https://your-site.com/webhook/abc123 Send test
BodyForm fieldsHeadersQueryAuth

Body & placeholders

Choose a body format at the top of the Body tab:

FormatUse it forContent-Type
JSONMost APIs and automation tools. You write the JSON yourself.application/json
Form dataForms with file uploads. In each row, choose Text or File; for File, pick the upload field.multipart/form-data
URL encodedEndpoints that expect a classic form post: key=value&key2=value2.application/x-www-form-urlencoded

The Content-Type header is added automatically from the format you choose.

Placeholders

Write {{field_id}} anywhere in the body, a header or a query value. When the form is submitted, each placeholder is replaced with the visitor’s answer. A few more are filled in automatically:

PlaceholderBecomes
{{field_id}}The answer to that form field
{{all_fields}}The whole submission, as one object
{{date}}The time it was sent, in ISO 8601 (UTC), e.g. 2026-10-03T09:15:00+00:00
{{timestamp}}The same time as a Unix timestamp, e.g. 1790932500
{{uuid}}A new random ID for every request
{
  "name": "{{your-name}}",
  "email": "{{your-email}}",
  "interests": "{{interests}}",
  "note": "From {{your-name}}",
  "submitted_at": "{{date}}"
}
{
  "name": "Rahim Uddin",
  "email": "rahim@example.com",
  "interests": ["CRM", "Books"],
  "note": "From Rahim Uddin",
  "submitted_at": "2026-10-03T09:15:00+00:00"
}
  • Keep placeholders inside quotes, like "age": "{{age}}". That keeps the JSON valid while you edit it, and the editor tells you straight away if it isn’t.
  • A value that is only a placeholder keeps its type. A checkbox arrives as a list, an upload as its files, and "{{all_fields}}" as the whole submission. A placeholder mixed with other text, like "From {{your-name}}", always becomes text.
  • Leave the body empty to send every field as it is, under the form’s own field names.
  • Add to body inserts a form field, or All fields, for you. Format tidies the JSON. Sample fills in a starter body with every form field plus submitted_at.
  • GET and DELETE send no body. Whatever you set up in the Body tab is sent in the query string instead.

File uploads

An upload field arrives as a list of files. Each file has name, type, size and url. When the file has no public URL (Contact Form 7 keeps uploads in a private folder), the file itself is included as base64 content, up to 5 MB per file.

"resume": [
  { "name": "cv.pdf", "type": "application/pdf", "size": 182044,
    "url": "https://example.com/wp-content/uploads/2026/10/cv.pdf" }
]

Headers, query & auth

TabWhat it does
Form fieldsLists every placeholder used in the request. Type test values here to try a request now. They are only for testing and are not saved. Use Fill sample values to fill them all at once.
HeadersOne row per header. Quick-add buttons: Webhook secret, Accept JSON, Source and Request ID ({{uuid}}). Use Bulk edit to paste many at once. Headers added automatically from the Auth tab and the body format are listed below the rows.
QueryParameters added to the end of the URL. Names and values are encoded for you.
AuthNo auth, Bearer token, Basic (username + password) or API key. An API key can go in a header or in the URL.

Testing

Send test sends a real request with your test values. The output panel has four tabs:

TabShows
ResponseThe status code, response time, and the body and headers that came back
PayloadExactly what was sent, with the test values filled in. Has a Copy button.
CodeThe same request as cURL, fetch, PHP (WordPress) or Python code, ready to copy
HistoryYour recent tests. Stored only in this browser.

To capture a request without building an endpoint, paste a URL from a request inspector such as webhook.site, then press Send test.

Delivery & retries

  • Any 2xx status is a success. The log says, for example, Sent to My CRM, which answered 201.
  • 4xx errors are not retried. A 400 or 422 will fail the same way every time, so it is logged straight away with the status and the start of the endpoint’s reply.
  • 5xx, 429 and network errors are retried in the background, up to 4 attempts in total. Uploaded files are kept so a retry sends them too.
  • Each request waits up to 15 seconds for an answer.
Attempt 1on submit
+30 s →
Attempt 2retry
+2 min →
Attempt 3retry
+8 min →
Attempt 4last try, then logged

Retries are not logged one by one. The log shows the final result once, with the number of attempts it took. From the Logs screen you can resend a failed record.

Troubleshooting

What you seeWhat to do
The JSON body is not valid when savingOpen the Body tab, press Format, and put quotes around every placeholder.
The destination answered 401 / 403Check the Auth tab and your headers. Look under Headers → Added automatically to see what is actually sent.
This feed points at a destination that no longer existsOpen the feed, go to the Destination step and set up the webhook again.
Share this Doc

Webhook

Or copy link

CONTENTS
Get Free Consultation

Subscribe

×
Cancel