Skip to main content
Listeners and webhooks are in beta.
A collection’s sync runs on its schedule. When the provider can notify you that something changed, declare a listener on the collection so it updates automatically, soon after the change, instead of at the next scheduled sync. A notification is a hint. It asks Bijection to sync the collection again; the records still come from the sync, checked against the collection’s evidence contract like any other. A notification never writes a record by itself, and a collection with a listener still declares its sync.

Receiving webhooks

A push listener receives the provider’s webhook deliveries at a URL your deployment serves. Its ingress declares how a delivery is authenticated and identified:
bijection/billing.ts
  • delivery is where a delivery names itself, in a header or the body. Repeated deliveries with the same identity are recognized as duplicates.
  • authentication is the provider’s signature scheme. The signing secret is never in the definition: you provide it as a credential when you configure the listener.
  • body and max_body_bytes bound what a delivery may contain. Larger deliveries are refused before any verification work.
  • proves: "refresh_hint" makes each accepted delivery request a sync.
The supported signature schemes are: Where the provider opens and closes notification channels through its API, add a subscription naming the HTTP contracts that do it (watch and stop), and Bijection manages the channel’s lifecycle. Where you register the webhook URL in the provider’s own console, declare no subscription.

Configuring the listener

Store the provider’s signing secret as a credential. Unlike an HTTP credential, it is the raw secret, not a JSON envelope:
Then enable the listener on the installed source with your deployment’s public listener URL:
Bijection appends an endpoint identifier to the URL and reports the full webhook URL back. Register that URL with the provider. The identifier stays the same when you disable and re-enable the listener with --disable. bijection integration listener-status <source> shows the listener’s health separately from the source’s syncs: syncs can keep data current while notifications are failing, and a healthy listener can coexist with a blocked sync.

Polling for changes

When a provider publishes a feed of change events rather than calling you, declare a pull listener instead. It names the HTTP contract to poll, its polling interval bounds, and how the poll continues from one request to the next. Each change it observes requests a sync, exactly as a delivery does. A pull listener takes no --callback-url.

Webhook events for operations

Some webhooks announce business events you want to act on one by one, rather than changes to re-read. Declare proves: "occurrence" to keep each verified event and hand it to one operation:
  • The delivery identity must be in the body, and the body must be { kind: "json", validator: v.any() } with a max_body_bytes of at most 61,440.
  • shared_token authentication and a subscription aren’t allowed.
Bind the source to an operation and the event types it accepts:
Each event is stored with its identity, deduplicated, and passed to the operation. The operation reads the verified body with ctx.occurrence.payload(), which returns the exact JSON string the provider sent. webhook-status, webhook-event and webhook-control inspect and manage the retained events; see the CLI reference.