Skip to main content
A webhook is a private web address that another app can send data to. Think of it as a letterbox for your workflow: when a website form, a payment app or your own code posts a message to the address, the workflow runs and can use everything in that message. In Connie, this is the Custom Webhook trigger. Where: open a workflow → Build → trigger card → Event → Webhooks tab → Custom Webhook · https://connie.ai/<workspace-id>/workflows/<workflow-id>

Set up a webhook trigger

1

Add the Custom Webhook trigger

Create a workflow with New → New workflow → Event, then choose Custom Webhook on the Webhooks tab. (In an existing workflow: trigger card ⋯ → Change.)
2

Copy the Webhook URL

The trigger panel shows your Webhook URL with a copy button. It looks like https://connie.ai/api/webhooks/ followed by a long ID. Each Custom Webhook trigger has its own URL.
3

Send a test request

Open the trigger’s Test panel and click Run Test (“Send a POST request to the webhook URL to capture test payloads.”). Then send a request from your app, or copy the Example request shown in the panel with Copy command and run it.
4

Pick the test event

The captured request appears in the list. Click Use as test event for Run Once. Its fields now appear under Custom Webhook in the variable picker.
5

Build the steps, then set it live

Add your steps, then Run → Set live. Until the workflow is live, requests are saved as test events but don’t start runs.

Send data to the webhook

  • Method: POST.
  • Body: valid JSON. Send the header Content-Type: application/json. A body that isn’t valid JSON (form-encoded, XML, empty) is refused with 400 {"error":"Invalid JSON body"}.
  • Address: always use the https:// URL exactly as copied.
  • Authentication: none needed. The URL itself is the key (see Security).
Each request starts one run, and each run adds a row to the Runs tab.

Use the payload in your steps

Every key in the JSON you send becomes a variable under the Custom Webhook group. With the example above: Insert them from the picker rather than typing them. Fields only appear in the picker after you’ve captured a test event, so capture one with the same shape your app will really send. Example: a website “Book a demo” form posts name, email and company. The workflow uses Search records in a list or object to look up {{Custom Webhook.email}}, Create or update a record in a list to add the lead to your Inbound list, and Send Slack Message to tell your team.

Responses

If Custom Response is on, your custom response replaces both 200 bodies above (including the draft one). Error responses are never replaced. A GET request to the URL returns a short description of how to call it; it doesn’t start a run.

Send your own response

Turn on Custom Response (“Return a custom JSON body to the webhook caller”). The default is {"status":"ok"}. You can echo values from the incoming request, for example {{body.email}} (“Use {{body.field}} to echo payload values”). If the text isn’t JSON, it’s returned as plain text, which is useful for apps (such as Slack) that verify a webhook by expecting a value echoed back. If any value in your custom response can’t be filled from the request, the default response is sent instead.

Duplicate requests

Many apps retry a webhook if they don’t hear back quickly. To stop the same event running twice, have the sending app include one of these headers with a unique value per event: Idempotency-Key, X-Idempotency-Key, X-Webhook-Id, X-Delivery-Id, X-Event-Id, X-Message-Id or X-Request-Id. A repeat with the same value is skipped ("skipped": 1). Without one of those headers, an identical request is only skipped while the previous identical run is still running. After that, it runs again.

Security

Anyone who has the URL can start your workflow. Connie doesn’t check signatures, and signature headers from the sending app are ignored. The panel reminds you: “Anyone with this URL can trigger this flow. Keep it private.” Don’t put the URL in public web pages or client-side code, and share it only with the systems that need it.
  • Add a Router or Filter Records by condition step early in the workflow to ignore requests that don’t look right (for example, missing a field only your app sends).
  • Duplicating a workflow gives the copy a new webhook URL. The original keeps its URL.

Good to know

  • Every request is saved as a test event, even in draft. That’s how capturing a test event works.
  • Running hours in Workflow settings apply to webhook runs. Outside those hours, requests wait (or are dropped if Queue triggers outside of window is off).
  • Credits are checked before every webhook run. Each run is charged for the paid steps it uses. See Credits.
  • The webhook is the only way to start a workflow from outside Connie, apart from MCP. See Developers.

Troubleshooting

Why: The workflow is in draft, so the request was stored as a test event only. Fix: Run → Set live.
Why: The body isn’t JSON (for example, it’s form-encoded or XML). Fix: Send a JSON body with the header Content-Type: application/json.
Why: The URL is mistyped, or the Custom Webhook trigger it belonged to has been removed. A duplicated workflow has its own, different URL. Fix: Copy the Webhook URL again from the trigger panel and update the sending app.
Why: The workspace is out of credits, or its balance is below the price of this workflow’s paid steps, so the run didn’t start. Fix: Add credits. See Top-ups.
Why: Either the workflow is in draft (the response says Webhook is inactive, or your custom response hides that), or the request was a duplicate (the response shows skipped 1). Fix: Set the workflow live. For duplicates, make sure each event has its own idempotency value.
Why: The sending app reused the same idempotency or delivery ID, or the events arrived outside running hours with queueing off. Fix: Use a unique ID per event. Check Running hours in Workflow settings.
Why: Without an idempotency header, identical requests are treated as separate events once the first run has finished. Fix: Have the sending app include an Idempotency-Key header.
Why: A value in the custom response couldn’t be filled from this request. Fix: Only echo keys that are present in every request.
Why: No test event has been captured yet. Fix: Open the trigger → Test → Run Test, send a request, then choose Use as test event for Run Once.
Why: The URL was entered with http://. Fix: Use the https:// URL exactly as copied.