Webhooks

Overview of the Webhooks API

Hand off to an LLM

bem POSTs a JSON event to your configured webhook URL each time a subscribed function call, workflow output, or collection-processing job fires. This section is the reference for those deliveries: the payload shape per event type, plus the endpoints you use to manage the signing secret.

Every variant shares the same envelope — function/workflow IDs, timestamps, the inbound email that triggered the call, and so on — and adds a payload field that depends on the function type. The eventType field on the body is the discriminator: dispatch on it to select which payload shape to expect. SDKs generated from this spec expose a webhooks.unwrap() helper that performs the dispatch and returns a typed event.

Payloads

eventTypePayloadSchema
extractExtract eventExtractEvent
classifyClassify eventClassifyEvent
parseParse eventParseEvent
split_collectionSplit collection eventSplitCollectionEvent
split_itemSplit item eventSplitItemEvent
joinJoin eventJoinEvent
enrichEnrich eventEnrichEvent
payload_shapingPayload shaping eventPayloadShapingEvent
sendSend eventSendEvent
evaluationEvaluation eventEvaluationEvent
collection_processingCollection processing eventcollectionProcessingEvent
errorError eventErrorEvent

Signing secret

Every delivery includes a bem-signature header in the format t={unix_timestamp},v1={hex_hmac_sha256}. The signature covers {timestamp}.{raw_request_body} and is computed with HMAC-SHA256 using the active signing secret for your environment.

To verify a payload:

  1. Parse bem-signature: t={timestamp},v1={signature}.
  2. Construct the signed string: {timestamp}.{raw_request_body}.
  3. Compute HMAC-SHA256 of that string using your secret.
  4. Reject the request if the hex digest doesn't match v1, or if the timestamp is more than a few minutes old.

Manage the secret with these endpoints:

For zero-downtime rotation, briefly accept both the old and new secret in your verification logic before revoking the old one.

Retries

bem treats any non-2XX response (or a transport failure) as a delivery error and retries with exponential backoff. Return a 2XX as soon as you have durably queued the payload — do not block on downstream work.

See also

On this page