Skip to main content
Your users connect GitHub, Linear, or Sentry once; their events fire your agents from then on. There are two honest deployment shapes: use an ingress aggregator your deployment supplies, or host a small verify-and-resign relay in your application. Both end at the same signed Automation ingest route, so dedupe, AdmissionFilter, filtered-delivery, and firing semantics stay identical. Providers sign webhooks with their own schemes, so they cannot call Checkfu’s signed ingest directly. The component that verifies that provider signature is the trust owner. Checkfu never treats an arbitrary POST as a verified GitHub, Linear, or Sentry event.
Checkfu does not ship a universal provider verifier or perform provider-side webhook registration. D215 removed the former bundled aggregator. WebhookSource remains the binding for a deployment that supplies an aggregator; @checkfu/integration-host supplies the stock customer-hosted relay kernel when it does not. You still implement or import the selected provider’s verifier and register your relay URL with that provider.
Before you start, set the shared variables. CHECKFU_API_KEY is bound to the Workspace; no selector header is sent.
PRINCIPAL and AGENT are the prin_… and agent_… the Automation acts as and targets, WHSEC is the whsec_… ingest secret you mint for it, CONNECTION is the conn_… from step 1, and AUTOMATION is the auto_… step 2 returns. The TypeScript tabs below use the TypeScript SDK with this client:
1

Connect the provider

Authorize a Connection for your end user (see the Connections concept page for the full flow). What matters here: the Connection is owned by a Principal.
2

Create the webhook Automation

The Automation is the trigger’s brain: its prompt template renders the provider payload as {{event}}, its dedupe pointer makes redelivery idempotent, and its admission filter decides which events deserve a Session at all.
3

Choose the provider trust owner

If your deployment has an ingress aggregator, bind the governed Connection as a source. If it does not, skip this binding and use the customer-hosted relay in step 4; the relay calls ordinary signed ingest directly.
The binding becomes active when your deployment’s aggregator forwards a verified event for that Connection. The resource is optional for delivery and useful for provider-side registration bookkeeping.
4

Verify and relay exact bytes

Register your aggregator or application receiver URL in the provider’s UI/API. For the customer-hosted path, read the raw body before a JSON parser, verify it with the provider’s SDK, then relay the exact same bytes:
A rejected provider signature never reaches the forwarding callback. The helper retains neither credential nor transport; your server owns both.

What your users see

  • “Why did it fire?” Every firing links the Automation to the Session and Run it created.
  • “Why didn’t it fire?” GET /v1/automations/{id}/filtered-deliveries records every deliberately dropped delivery with a reason. Silence is always explainable.
  • Replays are safe: the dedupe pointer settles identical redeliveries against the original firing.

Cleanup semantics worth knowing

  • Deleting a source stops delivery for that binding immediately; deleting the Automation cascades its sources.
  • Revoking the Connection ends forwarding without touching the Automation.
  • A provider-side webhook you registered out-of-band keeps sending until you remove it at the provider; deliveries for a deleted source are acknowledged and dropped.