Webhooks
RobotRock can notify your application when a task is handled via webhooks.
Configure webhook on the client
Set webhook on createClient in your shared client module. It applies to every action when you call sendToHuman:
// lib/robotrock.ts
import { createClient } from "robotrock";
export const robotrock = createClient({
app: "my-service",
webhook: {
url: "https://your-app.com/api/robotrock/webhook",
headers: {
// place your headers here
},
},
});import { robotrock } from "@/lib/robotrock";
const response = await robotrock.sendToHuman({
type: "approval",
name: "Budget Approval",
actions: [
{ id: "approve", title: "Approve" },
{ id: "reject", title: "Reject" },
],
});headers is optional and defaults to {}.
Set app on createClient to control dashboard inbox grouping. When omitted, tasks use your API key name.
Webhook Payload
When a task is handled, RobotRock sends a POST request to your webhook URL:
{
"taskId": "task_123abc",
"action": {
"id": "approve",
"title": "Approve",
"data": {
"notes": "Looks good!"
}
},
"handledBy": "user@example.com",
"handledAt": "2024-01-15T10:30:00Z",
"handlerType": "webhook"
}Next.js API route example
Use a Route Handler in your Next.js app to receive webhook events:
// app/api/robotrock/webhook/route.ts
import { NextResponse } from "next/server";
import {
verifyRobotRockWebhook,
RobotRockWebhookError,
type RobotRockWebhookPayload,
} from "robotrock";
export async function POST(req: Request) {
let payload: RobotRockWebhookPayload;
try {
payload = await verifyRobotRockWebhook(req);
} catch (error) {
if (error instanceof RobotRockWebhookError) {
// Use `error.code` in your own audit logs and monitoring.
return NextResponse.json({ error: error.code }, { status: 401 });
}
return NextResponse.json({ error: "Unknown error" }, { status: 500 });
}
if (payload.action.id === "approve") {
// TODO: run your approved flow
} else if (payload.action.id === "reject") {
// TODO: run your rejection flow
}
// Request headers are included in payload.headers
console.log("RobotRock request id:", payload.headers["x-request-id"]);
return NextResponse.json({ ok: true });
}Audit Trail
Each webhook execution creates an audit log entry with:
- Handler type (webhook)
- URL called
- HTTP status code
- Success/failure status
- Error message (if failed)
- Response time in milliseconds
Verifying Webhooks
Use the SDK helper instead of implementing crypto verification yourself:
import { verifyRobotRockWebhook } from "robotrock";
const payload = await verifyRobotRockWebhook(request);verifyRobotRockWebhook():
- validates
x-robotrock-signature - reads
ROBOTROCK_WEBHOOK_SECRET - parses and validates required payload fields
- returns typed payload data including request headers
- throws
RobotRockWebhookErrorwith machine-readable error codes
Webhook signing secret
You must set ROBOTROCK_WEBHOOK_SECRET in your app environment. For example in Next.js:
# .env.local
ROBOTROCK_WEBHOOK_SECRET=rrwhsec_your_shared_secretCreate or rotate this secret in the RobotRock app from your workspace settings where webhook secrets are managed, then update your deployment env vars to match.
Trigger.dev Integration
When you use the Trigger.dev tasks in the SDK, you do not need to configure a client webhook yourself. sendToHumanTask creates a wait token and sets the token URL as the client webhook automatically.
Vercel Workflow Integration
When you use sendToHumanInWorkflow, the SDK creates a workflow webhook and sets webhook.url as the RobotRock handler URL automatically. See Vercel Workflow.
No webhook?
If you omit webhook on createClient, sendToHuman() blocks and polls the API until the task is handled. You cannot set webhook and polling on the same client. See Polling for intervalMs, timeoutMs, and error handling.