Webhooks and Executions
Trigger workflows by webhook, stream activity, and deliver signed execution events to external systems.
B3OS has two webhook directions:
| Direction | Purpose |
|---|---|
| Incoming workflow webhooks | External systems start a workflow run |
| Execution hooks | B3OS sends run and node lifecycle events to your external system |
Incoming Webhooks
Incoming webhooks are useful when an external service can send HTTP events but does not need a dedicated B3OS trigger.
bashcurl -X POST "https://api.b3os.org/v1/webhooks/YOUR_WORKFLOW_SECRET" \ -H "Content-Type: application/json" \ -d '{"event":"payment.created","amount":"42.00","asset":"USDC"}'
The workflow can reference the payload with expressions:
json{ "event": "{{$trigger.body.event}}", "amount": "{{$trigger.body.amount}}", "asset": "{{$trigger.body.asset}}"}
Execution Hooks
Execution hooks send event notifications when workflow runs or node executions change state. Use them to sync B3OS into your own observability, audit, billing, support, or orchestration systems.
Activity Streams
| Stream | Use |
|---|---|
| Run stream | Follow one run as nodes execute |
| Activity stream | Follow workflow or organization activity |
| Execution stream | Follow node-level execution detail |
Delivery Design
Create a hook endpoint
Accept signed JSON POSTs, respond quickly, and process heavy work asynchronously.
Verify signatures
Treat the hook secret as a credential and verify signatures before trusting events.
Use idempotency
Store event IDs or run/execution IDs so retries do not create duplicate side effects.
Handle retries
Return a 2xx only after accepting the event. Non-2xx responses can be retried.
Retry is delivery recovery for an event that failed to reach your endpoint. Replay is deliberate redelivery for backfill, debugging, or audit.
Security Notes
| Surface | Recommendation |
|---|---|
| Incoming workflow webhook | Treat the URL or secret as credential material |
| Execution hook destination | Use HTTPS and verify signatures |
| Hook payload | Avoid assuming every field is present; handle schema evolution |
| Side effects | Make handlers idempotent |
| Private networks | Do not route hooks to private or link-local addresses |
