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";
2
3const workflow = relay
4 .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");
18
19// Deploy the webhook
20await workflow.deploy();
21
22// Your webhook URL: https://hooks.relayplane.com/your-team/github/pull-request

Configuration Options

1.webhook(endpoint, {
2 // HTTP method (default: POST)
3 method: "POST" | "PUT",
4
5 // Required headers for validation
6 headers: {
7 "X-Custom-Header": "expected-value"
8 },
9
10 // Secret for signature verification
11 secret: process.env.WEBHOOK_SECRET,
12
13 // Rate limiting
14 rateLimit: {
15 requests: 100,
16 window: "1m" // 100 requests per minute
17 }
18})

Webhook Payload

The webhook payload is available as the workflow input:

1// Incoming webhook payload
2{
3 "event": "order.created",
4 "data": {
5 "orderId": "ord_123",
6 "amount": 99.99,
7 "customer": {
8 "email": "user@example.com"
9 }
10 }
11}
12
13// Access in your workflow
14.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:

1relay
2 .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

1relay
2 .workflow("github-issues")
3 .webhook("/github/issues", {
4 headers: { "X-GitHub-Event": "issues" },
5 secret: process.env.GITHUB_WEBHOOK_SECRET
6 })
7 .step("triage")
8 .with("openai:gpt-4o")
9 .prompt("Triage this issue: {{input.issue.title}}")

Stripe

1relay
2 .workflow("stripe-invoices")
3 .webhook("/stripe/invoices", {
4 secret: process.env.STRIPE_WEBHOOK_SECRET
5 })
6 .step("process-payment")
7 .with("openai:gpt-4o")
8 .prompt("Generate receipt for: {{input.data.object.customer_email}}")

Slack

1relay
2 .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 server
2npx relay dev --webhook
3
4# Test with curl
5curl -X POST http://localhost:3000/github/pull-request \
6 -H "Content-Type: application/json" \
7 -d '{"action": "opened", "pull_request": {"body": "Test PR"}}'