Webhooks

View as Markdown

Webhooks let BCTRL notify your server when automation changes state. Create an HTTPS endpoint, subscribe it to event types, and process each delivery after verifying its signature.

Create an endpoint

1const webhook = await bctrl.webhooks.create({
2 name: "automation-events",
3 url: "https://example.com/bctrl/webhook",
4 events: ["run.completed", "run.failed", "recording.ready"],
5});
6
7console.log(webhook.id);
8console.log(webhook.secret); // save it now; it is returned only once

The URL must use HTTPS and cannot contain embedded credentials. name is optional. events must contain at least one event type.

The create response includes the signing secret. Store it securely. get() and list() return the endpoint configuration but never return the secret again.

Event types

EventSent when
run.startedA Run starts.
run.completedA Run completes successfully.
run.failedA Run fails.
tool_input.requestedA Tool requests human input.
tool_input.respondedHuman input is submitted.
tool_input.expiredA human-input request expires.
view.createdA View is created.
view.revokedA View is revoked.
recording.readyA recording becomes available.

A delivery body is a webhook envelope:

FieldTypeAlways presentDescription
idstringYesEvent identifier.
typestringYesEvent type, such as run.completed.
createdAtstringYesEvent timestamp.
subaccountIdstring | nullYesSubaccount that produced the event.
dataobjectYesEvent-specific payload.

Verify the delivery signature with the secret before using data. Keep the raw request body available to your verification code; do not parse and reserialize it before verification. The SDK manages webhook endpoints and delivery records; your HTTP server is responsible for receiving and verifying incoming requests.

Manage an endpoint

1const all = await bctrl.webhooks.list();
2const current = await bctrl.webhooks.get(webhook.id);
3
4await bctrl.webhooks.update(webhook.id, {
5 events: ["run.completed", "run.failed"],
6 enabled: false,
7});
8
9await bctrl.webhooks.delete(webhook.id);

Update any combination of name, url, events, and enabled. Deleting an endpoint does not remove its historical delivery records.

Webhook fields

FieldTypeAlways presentDescription
idstringYesEndpoint identifier used by the SDK methods.
subaccountIdstring | nullYesSubaccount context for the endpoint.
namestring | nullYesHuman-readable label.
urlstringYesHTTPS destination.
eventsWebhookEventType[]YesEvents sent to the endpoint.
enabledbooleanYesWhether new deliveries are sent.
createdAt, updatedAtstringYesResource timestamps.

Rotate the signing secret

Rotation replaces the current secret immediately. The new secret is returned only in the rotation response.

1const rotated = await bctrl.webhooks.rotateSecret(webhook.id);
2console.log(rotated.id, rotated.secret); // save the new secret

Update your receiver to use the new secret before rotating in production, or be prepared for deliveries signed with the new secret immediately after rotation.

Test and troubleshoot deliveries

Send a signed test event and inspect the resulting delivery record:

1const testDelivery = await bctrl.webhooks.test(webhook.id);
2console.log(testDelivery.id, testDelivery.status);
3
4const deliveries = await bctrl.webhooks.deliveries.list(webhook.id);
5for await (const delivery of bctrl.webhooks.deliveries.iter(webhook.id)) {
6 console.log(delivery.eventType, delivery.status, delivery.lastError);
7}

When the receiver is fixed, queue another attempt for a failed delivery:

1await bctrl.webhooks.deliveries.redeliver(webhook.id, delivery.id);

Delivery fields

FieldTypeAlways presentDescription
idstringYesDelivery identifier used for redelivery.
webhookIdstring | nullYesEndpoint that received the delivery.
eventIdstringYesEvent identifier in the webhook envelope.
eventTypestringYesEvent type being delivered.
status"pending" | "sending" | "sent" | "failed" | "cancelled"YesDelivery state.
attemptCountnumberYesNumber of attempts made.
responseStatusnumber | nullYesHTTP response status from your endpoint.
nextAttemptAtstring | nullYesNext scheduled attempt, if any.
sentAtstring | nullYesSuccessful send timestamp.
lastErrorstring | nullYesMost recent delivery error.
createdAt, updatedAtstringYesDelivery timestamps.

Next

  • Runs — inspect the automation events that webhooks reference
  • Views — create live or replayable automation views
  • Account and organization — scope endpoints and manage API keys