Developers

Starting an automation via webhook

With a webhook, another piece of software, such as Zapier, Make, your management software or your website's form, starts an automation and passes it its data, which become variables.

View as Markdown
Video: Webhooks and APIs for your management software AC-34Starting an automation from Zapier or Make, calling an external API.

#What it's for

A webhook is a web address that another piece of software sends data to when something happens. Every automation with the Webhook trigger has its own address: when a request arrives there, the automation starts.

  • Your website's “Request a quote” form sends the name, email and phone: the automation saves the contact and calls them back.
  • Your e-commerce store sends an order: the automation writes to the customer on WhatsApp.
  • Zapier and Make connect hundreds of apps: any of their events can start an automation.
Your softwareSends a POST request with the data in JSON.
→
The automation's addressAccepts the request and responds.
→
The automationStarts and uses the data as {{webhook.*}} variables.

Before you start

  • The “API and webhooks” feature in your plan.
  • An external service that can send an HTTP POST request with a JSON body.

#Getting the address

  1. Choose the Webhook source

    In the automation's Playground, press the trigger card, the starting node. In Starting source, choose Webhook (API). You can also do it while creating the automation, in the “New Automation” window, at the Trigger step.

  2. Generate the address

    Press Generate address. The full address appears, unique to this automation, ending with /incoming/ and a code. Below it you read its three characteristics: Post, Application/json, No Auth.

  3. Copy it into the external service

    Press Copy and paste the address where the external service asks for the webhook URL.

#Running the test

The test is required: without it, webhook events don't start the automation and the automation can't be published. It also lets the console learn the fields that will arrive.

  1. Start listening

    In Test Webhook, press Start listening. The status changes to “Listening...”.

  2. Send the test request

    From the external service, send a POST to the address with /test added right after the code. If you also send parameters, /test goes before the “?”: for example WEBHOOK-ADDRESS/test?source=website.

  3. Check what arrived

    “Test received” appears, with Received data and Received headers. From now on the fields are in the variables panel, Input tab, “Data received by the webhook” section.

  4. Build, save and publish

    Use the variables in the nodes, then press Save changes and Publish.

Listening stops when the test arrives, when you press Stop listening, when you leave the Playground or, if you run the test while creating the automation, when you close the “New Automation” window. To run the test again, press Listen again.

After the test, remove /test. In production the address is used as it is. If the address with /test stays in Zapier, in Make or in your software, real requests get 404 and the automation doesn't start.

The Webhook trigger panel after the test: generated address with Copy and Regenerate, Post, Application/json and No Auth pills, and the Test Webhook section with Test received and the Received data.
After the test, the panel shows the data and headers received, which become {{webhook.*}} variables.

#Authentication and headers

The address accepts POST requests with a JSON body. Always send the Content-Type: application/json header: without it, or with another type, the body isn't read. The request is accepted anyway, with 202, but the automation starts without the body data; only the address parameters and the headers arrive. A test sent this way records an empty structure.

The code in the address works as a key: keep it like a password, give it only to the services that need it, don't put it in a web page's code and, if needed, regenerate it.

Custom headers you send become variables with a lowercase name: a Store header is read with {{webhook.headers.store}}. Standard headers, such as host, content-type and user-agent, are removed.

#The data format

The body is a JSON object, 1 MB at most: beyond that, the request is rejected with 413 and the automation doesn't start. Every field in the body, every address parameter (the ones after the “?”) and every custom header becomes a {{webhook.*}} variable: nested fields are read with a dot, list items by their position starting from 0. The table in Examples shows each case.

Use simple field names, with letters, digits and “_”. In the test, send the same structure you'll really use: the variables panel offers the fields from the test, and a field that then doesn't arrive stays empty. If the structure changes, run the test again with Listen again.

#Examples

In place of WEBHOOK-ADDRESS, paste the address copied from the console.

curl · a request with a parameter and a header

curl -X POST "WEBHOOK-ADDRESS?source=website" \
  -H "Content-Type: application/json" \
  -H "Store: officina-rossi" \
  -d '{"first_name":"Mario","last_name":"Rossi","email":"mario.rossi@esempio.it","phone":"+39 02 1234 5678","order":{"number":"A-1029","total":149.9},"items":[{"sku":"OIL-FILTER","quantity":1}]}'
Data sentVariableValue
first_name{{webhook.first_name}}Mario
order.total{{webhook.order.total}}149.9
items, first item, sku{{webhook.items[0].sku}}OIL-FILTER
parameter source{{webhook.source}}website
header Store{{webhook.headers.store}}officina-rossi

With Zapier or Make. In the scenario, add the step that sends an HTTP request: in Zapier the POST action of the Webhooks by Zapier app, in Make the HTTP module. Set the POST method, the copied address and the data in JSON format.

#The response

If the request is accepted and the flow doesn't have the Webhook Response node, the address responds with 202 right away and the execution starts:

JSON · the default response

{"success": true, "message": "Webhook received"}

To decide yourself what the caller receives, add the Webhook Response node to the flow. It appears in the menu only with the Webhook trigger and has three fields:

Response status Menu

The HTTP code to return: 200, 201, 202, 204, 400, 401, 403, 404 or 500.

Default: 200 OK

Headers Key and value, with variables

The headers to add to the response, with Add header.

Response body (JSON) JSON with variables

The body to return, for example {"ok": true, "lead": "{{CRM.id}}"}. A value written as a variable alone, such as "{{CRM.id}}", keeps its type.

With this node in the flow, the response is no longer immediate: the caller waits for it for up to 30 seconds. If the automation doesn't reach the node in time, the caller gets the default response, 202, and the automation continues anyway. That's why the node should go early in the flow, before Wait, Make Call and slow API calls. If the flow has more than one Webhook Response node, the first one counts.

RequestResponse
POST to the address, with valid JSON202 right away with the default response; with the Webhook Response node, its response within 30 seconds.
POST without Content-Type: application/json202, but the body isn't read: see Authentication and headers.
POST to the address with /test, while the test is listening200 with {"test": true, "data": …}, and listening stops.
POST to the address with /test, without listening404. Press Start listening and send the request again.
GET to the address200 with {"success": true} if the automation is ready to receive, otherwise 404.
Body that isn't valid JSON400, even if the address isn't ready: the body is checked first. Review quotes, commas and brackets.
Body over 1 MB413. Send less data, for example only the fields the automation uses.
More than 60 requests in one minute to the same address429 with {"error": "Too many requests", "retryAfter": 60} and the Retry-After: 60 header. Try again after the number of seconds shown.
Address not ready or not valid404 with {"error": "Webhook not found"}. The automation isn't active or has been deleted, the address has been regenerated, the trigger is no longer Webhook, the test was never run, or the plan doesn't include “API and webhooks”. Check that the automation is active and use the current address.

#Limits

  • At most 60 requests per minute to the same address, tests included. The count starts from the first request and resets after 60 seconds. Beyond that, the response is 429 with the Retry-After header, and the request doesn't start the automation: send it again after the number of seconds shown. Every response also carries the X-RateLimit-Limit and X-RateLimit-Remaining headers, with the limit and the requests left.
  • The body can be 1 MB at most: beyond that, the response is 413.

Spread your requests over time.

#How to check

  1. Send a real request

    If the response isn't the one you expect, look it up in the table above.

  2. Open the execution

    In AutomationsDashboard, in the Run log, open the new row. In the “Starting event” tab, the Event data shows the body received.

#Regenerating the address

Press Regenerate next to the address, then Confirm and Regenerate. The old address stops working immediately: update the new one in every external service that uses it. The test data stays: you don't need to run the test again.

A duplicated automation has an address of its own, to generate and test.

#See also