Webhooks
Receive webhooks from external services and trigger workflows with verified, signed payloads.
What are webhooks?
Webhooks let external services push data into Sevro. When a webhook fires, Sevro verifies the signature, parses the body, and triggers any workflow with a webhook trigger.
How webhooks work
- You create a workflow with a
webhooktrigger - Sevro generates a unique webhook URL
- You configure the external service to POST to that URL
- When a payload arrives, Sevro verifies the HMAC-SHA256 signature and evaluates the transform expression
- The transformed data is passed to the workflow as input
Signature verification
Sevro checks the request signature using the webhook secret. It looks for the signature in these headers (in order):
| Header | Format |
|---|---|
X-Sevro-Signature | sha256=<hex> |
X-Hub-Signature-256 | sha256=<hex> |
X-Webhook-Signature | <hex> |
The signature is computed as HMAC-SHA256(body, webhook_secret). If the signature doesn't match, the request is rejected with 401 Unauthorized.
No Bearer token is required for webhook requests — authentication is via the webhook secret alone.
Transform expression
The transform is a CEL expression that maps the incoming JSON body to the workflow's input. The parsed JSON body is available as body:
trigger:
type: webhook
transform: |
{
"customer_email": body.customer.email,
"amount": body.payment.amount,
"invoice_id": body.payment.metadata.invoice_id
}The result of the transform is passed to the workflow as input.
Configuring a webhook
1. Create a workflow with a webhook trigger
name: billing
workflows:
- ref: stripe-payment-received
label: Stripe Payment Received
trigger:
type: webhook
transform: |
{
"invoice_id": body.metadata.invoice_id,
"amount": body.amount,
"customer_email": body.receipt_email
}
nodes:
- id: mark-paid
type: method_call
entity: invoice
method: markPaid
input: |
{
"record_id": input.invoice_id
}2. Apply the module
sevro module apply -f billing.yaml3. Get the webhook URL
The webhook URL is returned when you apply the module, or you can retrieve it:
sevro workflow get \
--module <module-id> \
--workflow stripe-payment-receivedThe URL looks like:
https://your-sevro-instance/webhooks/<workflow-id>4. Configure the external service
Point the external service (e.g. Stripe, GitHub, Shopify) at the webhook URL. Use the webhook secret as the signing key.
Testing webhooks
Test a webhook with curl:
# Generate the signature
SECRET="your-webhook-secret"
BODY='{"payment":{"amount":5000,"metadata":{"invoice_id":"abc-123"}}}'
SIGNATURE=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')
# Send the request
curl -X POST https://your-sevro-instance/webhooks/<workflow-id> \
-H "Content-Type: application/json" \
-H "X-Sevro-Signature: sha256=$SIGNATURE" \
-d "$BODY"Next steps
- Triggers — full trigger reference
- Workflows — build multi-step automation
- CEL expressions — write transform expressions