Webhooks
This page has been cleared and is ready for updated Builder Studio documentation.
BuilderStudio supports webhooks in both directions: inbound webhooks that start a workflow when an external system calls BuilderStudio, and outbound callbacks that POST a run's result to a URL you supply when it triggers.
Inbound: webhook triggers
A webhook-trigger nodeon a canvas exposes a stable endpoint. Calling that endpoint with the node's secret starts an execution and passes the request body in as the workflow's inputs.
Add a webhook-trigger node
Place a webhook-trigger node on the canvas that should run when the webhook fires.
Register the webhook
Call
POST /api/mcp/webhooks/registerwith{ canvasId, triggerNodeId }(scopewrite:canvas). It returns thewebhookUrl, thewebhookSecret, and a ready-madewebhookAuthorizationHeadervalue. This step is also available as an MCP tool.Call the webhook URL
External systems POST to
/webhook/triggerwith the secret. BuilderStudio fires the trigger node and starts the run.
# 1. Register (returns webhookUrl + webhookSecret)curl -X POST https://<deployment>.convex.site/api/mcp/webhooks/register \ -H "Authorization: Bearer builder_..." \ -H "Content-Type: application/json" \ -d '{ "canvasId": "<id>", "triggerNodeId": "<webhookTriggerNodeClientId>" }' # -> { "webhookUrl": "https://<deployment>.convex.site/webhook/trigger",# "webhookSecret": "...", "webhookAuthorizationHeader": "Bearer ...",# "triggerNodeId": "...", "created": true } # 2. Fire it (authenticate with the per-trigger secret)curl -X POST "https://<deployment>.convex.site/webhook/trigger" \ -H "Authorization: Bearer <webhookSecret>" \ -H "Content-Type: application/json" \ -d '{ "topic": "new signup", "callbackUrl": "https://example.com/hook" }'Authorization: Bearer <secret> or in an x-webhook-secret header. Passing it as a ?secret= query parameter is rejected.- Methods:
/webhook/triggeraccepts GET, POST, PUT, PATCH, and DELETE (plus OPTIONS for CORS). - Body: JSON or
application/x-www-form-urlencoded. The parsed body becomes the workflow inputs. Payloads are capped (about 512 KB). - callbackUrl: if the body includes a
callbackUrlfield, it is stripped from the inputs and used to deliver the outbound callback described below.
Outbound: result callbacks
Both POST /api/run and inbound webhook triggers accept an optional callbackUrl. When the execution reaches a terminal state, BuilderStudio sends a single POST to that URL carrying the result payload. This lets you trigger a run asynchronously and be notified when it finishes instead of polling.
- The
callbackUrlmust be a valid HTTPS URL pointing to a public host. Private and loopback hosts are rejected. - Delivery is a single POST attempt with the execution result body.
Verifying callback authenticity
When a callback signing secret is configured for the deployment, outbound callbacks are signed with HMAC-SHA256 and carry these headers so you can verify them:
X-BuilderStudio-Signature sha256=<hex> (v1)X-BuilderStudio-Signature-V2 sha256=<hex> (v2)X-BuilderStudio-Signature-Timestamp <unix ms>X-BuilderStudio-Signature-Nonce <nonce>Calling external webhooks from a workflow
To call an outside service from a running workflow, BuilderStudio provides an SSRF-guarded outbound proxy at POST /api/webhook-relay. It validates the destination against an allowlist, pins DNS, follows a bounded number of redirects, and strips credential-bearing headers on cross-origin redirects. Access requires a signed-in session or a service bearer token; it is used by workflow execution rather than called directly with a builder_ key.
Provider webhooks BuilderStudio receives
BuilderStudio also receives webhooks from integrated providers. These are not part of your programmatic surface — they are verified by the provider's own signature scheme:
- GitHub —
POST /api/webhooks/github, verified by the GitHub App HMAC signature (X-Hub-Signature-256). - Stripe —
POST /api/stripe/webhooksand/api/stripe/plan-webhooks, verified by the Stripe signing secret.
builder_ key scopes used to register triggers.Was this page helpful?