Skip to content

Creating & managing webhooks

Webhooks can be managed two ways, and both act on the same webhooks with the same rules: from the dashboard by a human, or by the agent itself as a self-service action. Whichever path you use, a webhook always belongs to exactly one agent, and only that agent’s owner can see or change it.

To create a webhook you provide:

  • name — a label for your own reference (required).
  • provider — one of generic, github, stripe, or slack (optional, defaults to generic).

In return you get back:

{
"webhookId": "whk_01J9Z8Q…",
"url": "https://webhooks.alfe.ai/v1/hooks/whk_01J9Z8Q…",
"signingSecret": "",
"name": "GitHub pushes",
"provider": "github",
"active": true,
"createdAt": "2026-07-01T12:00:00.000Z"
}

Two of those fields matter most:

  • url is the address you register with the external service (for example, paste it into GitHub’s Settings → Webhooks).
  • signingSecret is shown once, here, and never again. Copy it now and store it wherever your receiver or verification code can read it. If you lose it, rotate the secret to get a new one.

Open your agent, go to its Webhooks section, and create a webhook. The dashboard shows the URL and the freshly generated signing secret. The secret is revealed a single time on this screen — copy it before you leave the page.

An agent can create and manage its own webhooks through its built-in webhook tools. A typical flow: the agent creates a webhook, receives the URL and signing secret, and then calls the external service’s own API to register that URL — for example configuring a GitHub repository webhook — all within a single task, with no human involved.

Because the secret is only returned at creation time, an agent that needs it for signature verification should capture it from the create response and keep it in its own secure storage.

Listing returns the webhooks for an agent with their metadata — id, name, provider, whether they’re active, who created them, and timestamps. It does not return the signing secret; secrets are never re-served after creation.

{
"webhooks": [
{
"webhookId": "whk_01J9Z8Q…",
"name": "GitHub pushes",
"provider": "github",
"active": true,
"createdBy": "agent",
"createdAt": "2026-07-01T12:00:00.000Z",
"updatedAt": "2026-07-01T12:00:00.000Z"
}
]
}

Rotating replaces the webhook’s signing secret with a new one and returns the new plaintext value — again, exactly once:

{ "webhookId": "whk_01J9Z8Q…", "signingSecret": "" }

Rotate when a secret may have been exposed, or on a routine schedule. After you rotate, update the secret everywhere you verify signatures (and in the external service, if it holds a copy). The webhook url and webhookId stay the same — only the secret changes.

Deleting a webhook deactivates it. Once inactive, its URL stops accepting deliveries: inbound requests to a deactivated or unknown webhook are rejected with 404 Not Found. Remember to remove the URL from the external service too, so it isn’t left calling a dead endpoint.

Deliveries that couldn’t be handed to your agent immediately — because it was offline — are retained so they can be delivered when the agent reconnects. You can review recent delivery activity for a webhook to confirm events are arriving and being processed. See Delivery and retries for the full delivery model.

Every webhook is scoped to one agent under one account. Requests to read or change a webhook are checked against the caller’s ownership of that agent, and a webhook that belongs to someone else is reported as not found rather than forbidden — so no one can probe for the existence of webhooks they don’t own. The dashboard path and the agent self-service path enforce the same ownership rules and act on the same underlying webhooks.