Skip to content

Receive a webhook

Webhooks let your agent react the moment something happens elsewhere, instead of polling for changes. In this tutorial you’ll create a webhook, send it a signed event from your terminal, and watch your agent receive it.

For the concepts behind everything here, see the Webhooks overview.

A webhook belongs to exactly one agent and gives it a private inbound URL. Ask your agent to create one, in chat:

Chat
Create a webhook named build-events and tell me its URL and signing secret.

Agents have built-in webhook tools and manage their own webhooks. Creating one returns two fields that matter:

{
"webhookId": "whk_01J9Z8Q…",
"url": "https://webhooks.alfe.ai/v1/hooks/whk_01J9Z8Q…",
"signingSecret": "…",
"provider": "generic",
"active": true
}
  • url is where you send events.
  • signingSecret is the key you sign them with. Alfe rejects any request without a valid signature.

Every request needs an X-Alfe-Signature-256 header: sha256= followed by an HMAC-SHA256 of the raw request body, keyed with your signing secret. Set the two values from step 1, then send an event:

Terminal
WEBHOOK_URL="https://webhooks.alfe.ai/v1/hooks/whk_..."
SIGNING_SECRET="..."
BODY='{"event":"build.finished","status":"passed"}'
SIGNATURE="sha256=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SIGNING_SECRET" -hex | sed 's/^.* //')"
curl -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "X-Alfe-Signature-256: $SIGNATURE" \
-d "$BODY"

A 200 response with a deliveryId means Alfe accepted the event. A 401 means the signature didn’t match, usually because the body changed after it was signed.

Alfe hands each accepted event to your agent in real time. If your agent is offline, the event waits and is delivered when it reconnects. To confirm events are arriving, ask the agent for the webhook’s recent deliveries — see Delivery and retries.

4. Connect a service that signs its own requests

Section titled “4. Connect a service that signs its own requests”

GitHub, Stripe, and Slack sign webhooks with their own schemes, so they can’t call an Alfe webhook URL directly: Alfe would answer 401. Put a small relay between them that checks the service’s signature and re-signs the body for Alfe. A working example is in Webhook signatures.

When you’re done, ask the agent to delete the webhook. This deactivates its URL, and inbound requests then get a 404.

  • Each agent gets its own signed, inbound webhook endpoint.
  • The agent can create and manage its own webhooks, and each one belongs to exactly one agent.
  • Requests are signed with HMAC-SHA256 of the raw body, which any language can do.