Loopfour
Triggers

App event triggers

Reference for the HubSpot and Airwallex event triggers, the event names a workflow can listen for and the payload each event delivers.

An app event trigger starts a run when a connected app reports a change, such as a deal moving stage in HubSpot or a deposit settling in Airwallex. It is a provider-specific form of the webhook trigger: the event arrives on the provider's inbound route, Loopfour turns it into a standard envelope, and every active workflow whose trigger matches gets one run.

How an event reaches a workflow

  1. The provider posts to POST /webhooks/hubspot or POST /webhooks/airwallex on the API host.
  2. Loopfour checks the signature. A bad signature gets 401 and no run starts.
  3. Loopfour reads the provider account from the event (the HubSpot portalId, or the Airwallex account_id) and looks for a connection with that account. If no connection has it, the event is dropped.
  4. The event is turned into the envelope below and matched against the triggers of the active workflows in the company that owns the connection.
  5. Each matching workflow starts one run, recorded with triggerType: "webhook".

The route answers 200 with {"received": true, "count": <events accepted>} once it has processed the batch. Other answers are 400 for a body it cannot parse, 404 for an unknown provider and 500 when verification itself fails.

The event envelope

Both providers deliver the same envelope. In the run input it sits at input.webhookEvent.payload.

FieldMeaning
idLoopfour's ID for this event
providerhubspot or airwallex
eventTypeThe provider event name, such as deal.propertyChange
occurredAtWhen the event happened, as an ISO 8601 timestamp
externalAccountIdThe provider account the event belongs to
externalEventIdThe provider's own event ID
dataThe event details. The fields depend on the provider and event
rawThe original provider payload, unchanged

So a step reads the HubSpot record ID as {{input.webhookEvent.payload.data.objectId}} and the event name as {{input.webhookEvent.eventType}}. See Variable references for the rest of the reference syntax.

HubSpot

Configuration

{
  "trigger": {
    "type": "hubspot_event",
    "eventKind": "deal.propertyChange",
    "propertyName": "dealstage",
    "filter": { "data.propertyValue": { "$eq": "closedwon" } }
  }
}
FieldTypeRequiredMeaning
type"hubspot_event"Yes
eventKindstringYesThe event to listen for. See the table below
propertyNamestringNoFor *.propertyChange events only: the HubSpot property that must have changed
filterobjectNoExtra conditions on the envelope. See Filters

In Studio, add a HubSpot block and switch it to trigger mode. The block shows Event, Filter (JSON) and, for property-change events, Property Name.

Events

ObjecteventKind values
Contactcontact.creation, contact.deletion, contact.merge, contact.restore, contact.privacyDeletion, contact.propertyChange
Companycompany.creation, company.deletion, company.merge, company.restore, company.propertyChange
Dealdeal.creation, deal.deletion, deal.merge, deal.restore, deal.propertyChange
Ticketticket.creation, ticket.deletion, ticket.merge, ticket.restore, ticket.propertyChange
Conversationconversation.creation, conversation.deletion, conversation.newMessage, conversation.privacyDeletion, conversation.propertyChange
Quotequote.creation, quote.propertyChange, quote.published

Matching rules:

  • An exact value such as deal.creation matches only that event.
  • A prefix such as deal.* matches every event for that object.
  • * matches every HubSpot event.
  • quote.published is a Loopfour shortcut. It matches a quote.propertyChange event where hs_status changes to APPROVED, APPROVAL_NOT_NEEDED or PUBLISHED.

Event data

Every HubSpot event carries these fields in data:

FieldType
objectIdnumber
objectTypeIdstring
portalIdnumber
subscriptionIdnumber
subscriptionTypestring
changeSourcestring
changeFlagstring
sourceIdstring
attemptNumbernumber

Property-change events add propertyName and propertyValue. Merge events add mergedObjectIds, newObjectId and numberOfPropertiesMoved.

The event tells you which record changed, not the whole record. To get the deal amount or the contact's email, add a HubSpot step that fetches the record by {{input.webhookEvent.payload.data.objectId}}.

Subscriptions

The HubSpot events Loopfour receives are set in Loopfour's HubSpot app, not per connection. Connecting HubSpot is enough; you do not register a webhook URL in HubSpot yourself.

Airwallex

Configuration

{
  "trigger": {
    "type": "airwallex_event",
    "selectedTriggerId": "deposit.settled",
    "filter": { "currency": { "$in": ["USD", "EUR"] } }
  }
}
FieldTypeRequiredMeaning
type"airwallex_event"Yes
selectedTriggerIdstringYesThe event to listen for. Must equal the event name exactly
filterobjectNoExtra conditions on the event data. See Filters

In Studio, add the Airwallex block from the Triggers group. It shows Event and Advanced JSON filter (optional).

Events

selectedTriggerIdWhen it fires
payment_attempt.paidA payment attempt is paid
payment_attempt.settledA payment attempt is settled
deposit.pendingA deposit is pending
deposit.settledA deposit is settled

There is no wildcard. To react to more than one event, use one workflow per event.

Event data

data holds the Airwallex event's data.object: the payment attempt or deposit itself. externalAccountId is the Airwallex account_id. The full event, including its name and created_at, is in raw.

Subscriptions

Airwallex webhook subscriptions are set in the Airwallex dashboard. Loopfour does not create them when you connect.

Filters

A filter is a JSON object. Each key is a dot path and each value is either a plain value (must be equal) or an operator object. All keys must pass.

OperatorPasses when
$eqThe value equals this
$neThe value does not equal this
$inThe value is in this array
$existstrue: the path has a value. false: it has none

The paths start from a different place for each provider:

  • HubSpot: paths start at the envelope, so write data.propertyValue or eventType.
  • Airwallex: paths start inside data, so write currency or amount.

In Studio, the HubSpot Filter (JSON) placeholder shows propertyName without the data. prefix. A filter written that way does not match, because HubSpot filter paths start at the envelope. Write data.propertyName, or use the Property Name field.

Repeated events

Providers resend events they think were not delivered. Each delivery can start a new run. Use externalEventId to spot a repeat, for example by checking it against a record your workflow writes, and make the steps safe to run twice.

Test without the provider

Start the workflow by hand with the envelope as input. See Run any workflow on demand for the request; put the envelope fields from this page under webhookEvent.payload.

On this page