Loopfour
Triggers

Webhook trigger

Receive provider events on a webhook trigger, verify their signatures and map the event payload into the input of your workflow run.

A webhook trigger starts a run when an event reaches Loopfour over HTTP: from a provider your company has connected, or from any system that posts to your custom webhook URL. This page is about events coming in. To have Loopfour send run events to your own endpoint, see the Webhooks API.

Configuration

{
  "trigger": {
    "type": "webhook",
    "path": "vendor-portal",
    "provider": "stripe"
  }
}
FieldTypeRequiredMeaning
type"webhook"Yes
pathstringYesThe match key for the custom route. Required by the schema even when provider is set
providerstringNoMatch events that arrived from this provider, such as stripe
eventsstring arrayNoAccepted, but not used for matching. See Filter events
verifySignaturebooleanNoAccepted, but not read. Each route decides how it verifies

The webhook trigger has no Studio block. Set it in the definition through the API.

Inbound routes

These routes sit at the API host root, outside /api/v1, and do not take an API key.

RouteUsed forVerification
POST /webhooks/custom/:companyId/:pathAny system you controlNone. The URL is the shared secret
POST /webhooks/stripeStripe Connect eventsWhen the request has a stripe-signature header and the platform's Stripe secret is set: HMAC-SHA256 over <timestamp>.<raw body>, within five minutes
POST /webhooks/hubspotHubSpot events for a connected portalA Standard Webhooks signature (svix-id, svix-timestamp, svix-signature). Refused when no signing secret is configured
POST /webhooks/airwallexAirwallex events for a connected accountx-signature header: HMAC-SHA256 over <x-timestamp><raw body>, within five minutes
POST /webhooks/nangoEvents forwarded for Stripe, Salesforce, QuickBooks, PandaDoc, NetSuite, Slack and Gmail connectionsHMAC-SHA256 of the raw body. Refused when the secret is missing or the signature is wrong

Any other provider name on POST /webhooks/:provider returns 404 with { "error": "Unknown provider: <name>" }. A failed signature returns 401 with { "error": "Invalid signature" }.

The routes are limited per sending IP address to 10,000 requests a minute.

Which workflows start

An event starts every active workflow in the receiving company whose trigger matches:

  1. Custom route: the trigger's path equals the URL's :path segment. The comparison ignores case and treats ., - and _ as the same, so bill.received matches bill-received. Do not start path with a slash.
  2. Provider routes: the trigger's provider equals the provider the event came from. Without provider, a trigger whose path equals the provider name also matches.

For HubSpot and Airwallex, the dedicated trigger types give event-level matching; see App event triggers.

Provider events are tied to a company through the connected account they name. A Stripe event with no account field, or for an account no company has connected, is answered { "received": true, "ignored": true } and starts nothing.

Run input

Each matched workflow gets a run with triggerType: "webhook" and this input:

{
  "webhookEvent": {
    "id": "a3f1c2d4-...",
    "provider": "custom",
    "eventType": "vendor-portal",
    "payload": {
      "billNumber": "B-2291",
      "vendor": "Northwind Supplies",
      "amount": 4180.5
    }
  }
}
FieldMeaning
webhookEvent.idLoopfour's id for the stored event
webhookEvent.providercustom, stripe, hubspot and so on
webhookEvent.eventTypeThe custom :path, or the provider's event type
webhookEvent.payloadThe parsed JSON body. A body that is not JSON arrives as { "rawBody": "<text>" }

Request headers are not passed to the run. Steps read the body with {{input.webhookEvent.payload.<path>}}.

Responses

The custom and Stripe routes answer:

{ "received": true, "eventId": "a3f1c2d4-...", "workflowsTriggered": 1 }

POST /webhooks/hubspot and POST /webhooks/airwallex answer { "received": true, "count": 1 }, where count is the number of events in the delivery that matched a connected account.

The route answers after the runs are queued; it does not wait for them to finish.

Filter events

The events field is not applied. Every event that reaches a matching route starts the workflow. To narrow it:

  • Subscribe only to the events you need in the provider's own webhook settings.
  • Put a Condition step first and branch on {{input.webhookEvent.eventType}} or a payload field.

Repeated events

Loopfour stores each event and its provider event id, but a redelivered event starts the workflow again. Make the workflow safe to repeat: look the record up before you create it, or use an action that updates a record by its number.

Test a webhook workflow

The custom route needs no signature:

curl -X POST https://workflow.loopfour.ai/webhooks/custom/$COMPANY_ID/vendor-portal \
  -H "Content-Type: application/json" \
  -d '{ "billNumber": "B-2291", "vendor": "Northwind Supplies", "amount": 4180.5 }'

For a provider workflow, call POST /api/v1/workflows/:id/run with an input.webhookEvent object shaped like the one above. See API trigger.

Anyone who has a custom webhook URL can start the workflow. Share it only with the system that needs it, and check the payload in the first steps before the workflow writes to another system.

On this page