Webhooks
A webhook-mode trigger fires the instant the source event happens, instead of waiting for the next polling check. Today, Stripe's Payment Event trigger and any custom connector's inbound trigger work this way — see Connector Reference for the full, current list of which connector triggers are polling vs. webhook.
Finding your webhook URL
Once a workflow with a webhook-mode trigger step is activated, that step's card shows a real, unique URL — copy it from there. It only appears after activation, because the URL is generated (and its security token issued) at activation time, not when the step is first created.
Security model
Every webhook URL embeds a long, unguessable random token as part of the path itself — that token is the credential. There's nothing to configure beyond pasting the URL where the provider (or your own system) asks for a webhook endpoint. Stripe additionally supports a signing secret, entered as part of connecting Stripe, which Gate97 uses to verify each event really came from Stripe before acting on it — set this if you want that extra check; without it, events are still accepted, just unverified.
How delivery works
Gate97 acknowledges a webhook request immediately and processes it in the background, so the provider never times out waiting on you. Both POST and PUT are accepted. Duplicate deliveries (providers commonly retry if they don't get a fast enough response) are detected and only produce one run.
Custom connector inbound webhooks
A custom connector with Supports inbound trigger enabled works exactly the same way — its trigger step gets a real webhook URL once activated, and whatever you send there is parsed according to the format you configured (JSON, XML, CSV, or plain text) and becomes the trigger data available to the rest of the workflow as {{trigger.*}}. This is the mechanism for having your own systems push data into Gate97, rather than Gate97 polling them. See Custom Connectors for how to set one up.
Calling it with curl
The URL you copy from an activated trigger step already has the exact shape below — nothing to fill in yourself. A few worked examples, one per supported format:
JSON (the default — a trigger configured for json):
curl -X POST "https://gate97.com/api/webhooks/custom:3f2a1b4c-9d21-4e3f-8a6b-1c2d3e4f5a6b/8f3e9c2a1b4d5e6f7a8b9c0d1e2f3a4b" \
-H "Content-Type: application/json" \
-d '{"orderId": "1234", "status": "paid"}'PUT works identically — both methods are accepted on the same URL:
curl -X PUT "https://gate97.com/api/webhooks/custom:3f2a1b4c-9d21-4e3f-8a6b-1c2d3e4f5a6b/8f3e9c2a1b4d5e6f7a8b9c0d1e2f3a4b" \
-H "Content-Type: application/json" \
-d '{"orderId": "1234", "status": "shipped"}'XML (a trigger configured for xml):
curl -X POST "https://gate97.com/api/webhooks/custom:3f2a1b4c-9d21-4e3f-8a6b-1c2d3e4f5a6b/8f3e9c2a1b4d5e6f7a8b9c0d1e2f3a4b" \
-H "Content-Type: application/xml" \
-d '<order><id>1234</id><status>paid</status></order>'CSV (a trigger configured for csv) — each row becomes its own run, with that row's columns available as {{trigger.*}}:
curl -X POST "https://gate97.com/api/webhooks/custom:3f2a1b4c-9d21-4e3f-8a6b-1c2d3e4f5a6b/8f3e9c2a1b4d5e6f7a8b9c0d1e2f3a4b" \
-H "Content-Type: text/csv" \
--data-binary $'name,email\nJane Doe,jane@example.com\nJohn Smith,john@example.com'The Content-Type header above is for readability — Gate97 always parses the body using the format you chose when defining the connector, not whatever header the sender happens to set. A successful call gets back a fast, empty 200 immediately; the run itself happens in the background; check that workflow's Run History to see the result. An empty request body is dropped without creating a run rather than erroring.