Integrations

Event Channels

Event channels receive events from external systems through webhooks, SSE, HTTP polling, or CloudEvents. They enable reactive workflows triggered by external changes.

Event channels define how the platform receives events from external systems. They are part of an integration definition and create the bridge between external services and the platform's internal event system.

When an event arrives through a channel, the platform matches it against defined event types, extracts the payload, and publishes it to the event bus — where it can trigger flows, update data, or send notifications.

Channel kinds

KindHow events arriveUse case
WebhookExternal system POSTs to a platform URLMost common. Used by services that send webhooks (Stripe, GitHub, Salesforce)
SSEPlatform subscribes to an external SSE streamReal-time event streams from services that offer SSE endpoints
HTTP pollingPlatform periodically GETs an external endpointFor services without push capabilities — the platform checks for new data on a schedule
CloudEventsStandard CloudEvents formatFor services that emit events in the CloudEvents specification format

Webhook channels

Webhooks are the most common event channel type. When you define a webhook channel in an integration:

  1. The platform generates a webhook URL for each app installation: https://api.bivariant.com/hooks/{channelId}
  2. You configure the external system to send events to this URL
  3. When events arrive, the platform processes them

Event processing flow

External system
  → POST /hooks/{channelId}
    → Platform receives request
      → Find event channel by ID
        → For each event definition:
          → Extract event type via JSONPath (typePath)
          → Match against defined event types
        → Extract event ID (idPath)
        → Extract payload (payloadPath)
        → Publish to event bus
          → Subscribed flows and handlers execute
  → 200 OK

Event definitions

Each event channel contains one or more event definitions that describe how to identify and extract events from incoming payloads:

PropertyDescription
typeThe event type string (for example, order.created, payment.completed)
typePathJSONPath expression to extract the event type from the payload (for example, $.event.type)
idPathJSONPath expression to extract the event's unique ID (for example, $.event.id)
payloadPathJSONPath expression to extract the event data (for example, $.event.data)
schemaJSON Schema describing the expected payload structure

For example, a Stripe webhook event definition:

{
  "type": "invoice.paid",
  "typePath": "$.type",
  "idPath": "$.id",
  "payloadPath": "$.data.object",
  "schema": { ... }
}

When the platform receives a POST to the webhook URL, it evaluates each event definition's typePath against the request body. When a match is found, the event ID and payload are extracted and published.

SSE channels

For SSE (Server-Sent Events) channels, the platform maintains a persistent connection to the external service's SSE endpoint:

  • The platform subscribes to the SSE stream
  • As events arrive, they are processed using the event definitions
  • Events are published to the internal event bus

SSE channels are useful for services that provide real-time streams (for example, activity feeds, live data updates).

HTTP polling channels

For services that don't support push events, the platform can poll an endpoint periodically:

  • A polling interval is configured (for example, every 60 seconds)
  • The platform calls the external endpoint and checks for new data
  • A discriminator configuration identifies what's new (for example, comparing timestamps or IDs)
  • New events are published to the event bus

CloudEvents channels

CloudEvents is a standard specification for describing events. For CloudEvents channels, the extraction paths are predefined:

  • Type: $type
  • ID: $id
  • Data: $data

This simplifies configuration for services that emit CloudEvents-formatted events.

Subscribing to events

After an event channel is defined and the app is installed, you can subscribe to specific events:

POST /v1/apps/{appId}/events/subscribe
{
  "eventUid": "webhook_channel:order.created",
  "connectionId": "conn_abc"
}

Subscriptions are persisted and automatically restored when the platform restarts. They route events to the appropriate handlers — typically flow triggers.

Event routing

Events from channels are published to the event bus with structured topics:

events.{orgId}.apps.app.event_received.{appId}.{channelUID}.{eventType}

This topic structure enables precise subscriptions — you can subscribe to all events from an app, all events from a specific channel, or only specific event types.