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.
Endpoint
Section titled “Endpoint”POST /api/sessions/:sessionId/annotations/webhookRequest body
Section titled “Request body”{ "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"}Responses
Section titled “Responses”| Status | Body | Description |
|---|---|---|
| 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:
| Header | Value |
|---|---|
access-control-allow-origin | Reflects the request Origin |
access-control-allow-methods | POST, OPTIONS |
access-control-allow-headers | content-type |
How it works
Section titled “How it works”- The annotation overlay is injected into each page loaded in the live browser.
- When a user submits an annotation, the overlay
POSTs anAnnotationSubmissionto this webhook. - The webhook validates the body and records it against the session.
- The annotation is broadcast to all connected WebSocket clients.
Prefer a drop-in iframe?
Section titled “Prefer a drop-in iframe?”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.