Webhooks
Trigger workflows via HTTP endpoints from external services.
Webhooks require Cloud features to be enabled.
Overview
Webhooks let you trigger workflows from any service that can send HTTP requests. Connect to GitHub, Stripe, Slack, Zapier, or any custom integration.
Creating a Webhook
Add a webhook trigger to your workflow using the .webhook() method:
1import { relay } from "@relayplane/sdk";23const workflow = relay4 .workflow("github-pr-review")5 .webhook("/github/pull-request", {6 method: "POST",7 headers: {8 "X-GitHub-Event": "pull_request"9 }10 })11 .step("analyze")12 .with("openai:gpt-4o")13 .prompt("Analyze this PR: {{input.pull_request.body}}")14 .step("comment")15 .with("anthropic:claude-sonnet-4-20250514")16 .depends("analyze")17 .prompt("Generate review comment");1819// Deploy the webhook20await workflow.deploy();2122// Your webhook URL: https://hooks.relayplane.com/your-team/github/pull-requestConfiguration Options
1.webhook(endpoint, {2 // HTTP method (default: POST)3 method: "POST" | "PUT",45 // Required headers for validation6 headers: {7 "X-Custom-Header": "expected-value"8 },910 // Secret for signature verification11 secret: process.env.WEBHOOK_SECRET,1213 // Rate limiting14 rateLimit: {15 requests: 100,16 window: "1m" // 100 requests per minute17 }18})Webhook Payload
The webhook payload is available as the workflow input:
1// Incoming webhook payload2{3 "event": "order.created",4 "data": {5 "orderId": "ord_123",6 "amount": 99.99,7 "customer": {8 "email": "user@example.com"9 }10 }11}1213// Access in your workflow14.step("process")15.with("openai:gpt-4o")16.prompt(`17 Process order {{input.data.orderId}}18 Amount: {{input.data.amount}}19 Customer: {{input.data.customer.email}}20`)Webhook Authentication
Secure your webhooks with signature verification:
1relay2 .workflow("secure-webhook")3 .webhook("/stripe/events", {4 secret: process.env.STRIPE_WEBHOOK_SECRET,5 signatureHeader: "Stripe-Signature"6 })7 .step("process")8 .with("openai:gpt-4o")9 .prompt("Process Stripe event: {{input.type}}")Always use webhook secrets in production. Without signature verification, anyone could trigger your workflows.
Integration Examples
GitHub
1relay2 .workflow("github-issues")3 .webhook("/github/issues", {4 headers: { "X-GitHub-Event": "issues" },5 secret: process.env.GITHUB_WEBHOOK_SECRET6 })7 .step("triage")8 .with("openai:gpt-4o")9 .prompt("Triage this issue: {{input.issue.title}}")Stripe
1relay2 .workflow("stripe-invoices")3 .webhook("/stripe/invoices", {4 secret: process.env.STRIPE_WEBHOOK_SECRET5 })6 .step("process-payment")7 .with("openai:gpt-4o")8 .prompt("Generate receipt for: {{input.data.object.customer_email}}")Slack
1relay2 .workflow("slack-commands")3 .webhook("/slack/commands")4 .step("respond")5 .with("openai:gpt-4o")6 .prompt("Respond to Slack command: {{input.text}}")Testing Webhooks
Test your webhook locally before deploying:
1# Start local webhook server2npx relay dev --webhook34# Test with curl5curl -X POST http://localhost:3000/github/pull-request \6 -H "Content-Type: application/json" \7 -d '{"action": "opened", "pull_request": {"body": "Test PR"}}'See also: Scheduled Execution | Cloud Overview