Overview
Webhooks allow you to receive annotation data at external URLs when users interact with annotations. This enables integrations with Slack, Discord, custom backends, CI/CD pipelines, and more.
Configure a webhook URL via the webhookUrl prop, and events will be sent automatically when annotations are created, updated, deleted, or submitted.
Configuration
Add the webhookUrl prop to enable webhooks:
import { Agentation } from "agentation";
function App() {
return (
<>
<YourApp />
<Agentation webhookUrl="https://your-server.com/webhook" />
</>
);
}
With a webhook URL configured, you have two options: enable Auto-Send to fire events automatically, or click "Send Annotations" in the toolbar manually. When Auto-Send is on, the toolbar button is hidden.
Events
Webhooks fire for the following events:
annotation.add— New annotation createdannotation.delete— Annotation deletedannotation.update— Annotation comment editedannotations.clear— All annotations clearedsubmit— "Send Annotations" clicked
Webhook Payload
All events send a POST request with the following JSON structure:
{
"event": "annotation.add",
"timestamp": 1706234567890,
"url": "https://example.com/dashboard",
"annotation": {
"id": "1706234567890",
"comment": "Button is cut off on mobile",
"element": "button",
"elementPath": "body > main > form > button.submit-btn",
"timestamp": 1706234567890
}
}
Event-specific payloads
annotation.add / annotation.delete / annotation.update
{
"event": "annotation.add",
"timestamp": 1706234567890,
"url": "https://example.com/page",
"annotation": { ... }
}
annotations.clear
{
"event": "annotations.clear",
"timestamp": 1706234567890,
"url": "https://example.com/page",
"annotations": [ ... ]
}
submit
{
"event": "submit",
"timestamp": 1706234567890,
"url": "https://example.com/page",
"output": "# Page Feedback\n\n...",
"annotations": [ ... ]
}
Combining with Callbacks
You can use webhooks alongside the onSubmit and other callback props. Both will fire when events occur:
<Agentation
webhookUrl="https://your-server.com/webhook"
onSubmit={(output, annotations) => {
// This fires in addition to the webhook
console.log("Submitted:", annotations.length, "annotations");
}}
onAnnotationAdd={(annotation) => {
// Track in analytics
analytics.track("annotation_created");
}}
/>
Use Cases
Slack Notifications
// Server webhook handler
app.post("/webhook/agentation", async (req, res) => {
const { event, annotation, url } = req.body;
if (event === "annotation.add") {
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
text: `New annotation on ${url}: "${annotation.comment}"`,
}),
});
}
res.json({ ok: true });
});
GitHub Issue Creation
app.post("/webhook/agentation", async (req, res) => {
const { event, output, annotations } = req.body;
if (event === "submit" && annotations.length > 0) {
await fetch("https://api.github.com/repos/owner/repo/issues", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
title: `[Feedback] ${annotations.length} annotation(s)`,
body: output,
labels: ["feedback"],
}),
});
}
res.json({ ok: true });
});
Real-time Dashboard
// Server with WebSocket broadcast
app.post("/webhook/agentation", (req, res) => {
const { event, annotation, url } = req.body;
// Broadcast to connected dashboard clients
wss.clients.forEach((client) => {
client.send(JSON.stringify({
type: "annotation_event",
event,
annotation,
url,
}));
});
res.json({ ok: true });
});
Security Considerations
- Use HTTPS — Always use encrypted connections for webhook URLs
- Validate origin — Check the request origin if your webhook is public
- Rate limiting — Implement rate limits to prevent abuse
- Sanitize content — Annotation comments may contain user-generated content; sanitize before rendering
Testing Webhooks
Tools for testing webhooks during development:
- webhook.site — Free public endpoint for testing payloads
- ngrok — Expose local server for testing with real URLs
- RequestBin — Inspect and debug webhook payloads
Quick Test Setup
// Use webhook.site for testing
<Agentation webhookUrl="https://webhook.site/your-unique-id" />
// Then create annotations and check webhook.site for payloads