Skip to content

Receive annotations (webhook)

The annotation webhook receives human annotations captured in the live browser’s annotation overlay. Submitted annotations are persisted to the session and broadcast to any connected WebSocket clients.

POST /api/sessions/:sessionId/annotations/webhook
{
"event": "submit",
"output": "User annotated: change the hero text",
"annotations": [
{
"type": "click",
"selector": "h1.hero-title",
"comment": "This headline needs work"
}
],
"url": "https://example.com/landing"
}
StatusBodyDescription
200{ "ok": true }Annotation accepted
400{ "error": "invalid JSON body" }Malformed or missing body
405{ "error": "method not allowed" }Non-POST method used

The webhook accepts cross-origin requests from the live browser. Preflight (OPTIONS) returns:

HeaderValue
access-control-allow-originReflects the request Origin
access-control-allow-methodsPOST, OPTIONS
access-control-allow-headerscontent-type
  1. The annotation overlay is injected into each page loaded in the live browser.
  2. When a user submits an annotation, the overlay POSTs an AnnotationSubmission to this webhook.
  3. The webhook validates the body and records it against the session.
  4. The annotation is broadcast to all connected WebSocket clients.

If you don’t want to run a webhook endpoint at all, embed the annotated browser instead. That iframe handles the live browser, the annotation overlay, and the WebSocket internally, and re-emits each annotation to your app via postMessage — no webhook or WebSocket plumbing on your side.