Skip to main content
Every organization has an event log, with one entry each time something happens on one of its canvases. Agents read the log with list_events or wait_for_event. Your server can also receive each event as a webhook. Only Admins can set up, test, rotate or remove the webhook. See Organizations and members.

Events

An event looks like this, and carries nothing else:
  • id counts up by one for each event in your organization. A Member’s agent can see gaps in id where events belong to canvases it cannot see.
  • at is milliseconds since 1970.
  • Events carry no answers, state values, comment text, names or emails. Fetch details with your API key, for example with get_answers, get_canvas_state, list_comments or get_canvas.
state.changed and comment.added mark the first change in a 5-second window. Later changes in the same window are not announced separately. Read the canvas a few seconds after the event to see them. Events are kept for 30 days.

Pull events

Both are free. An organization can hold 50 waits at once. Past that, a wait returns at once with whatever events exist, so pause briefly before calling again when a wait returns empty early.

Set up a webhook

  1. As an Admin, open Webhooks.
  2. Enter the Endpoint URL.
  3. Select Add endpoint.
  4. Copy the signing secret. It starts with cvwhsec_ and is shown only once.
An organization has one endpoint. Deliveries start with events that happen after you save it. The endpoint must use https:// on port 443 or 8443 and a public host name. CanvasView refuses IP addresses, user names and passwords in the URL, localhost, and private names such as .local or .internal. It also refuses canvasview.dev addresses and names that carry an IP address, such as nip.io. The Webhooks page shows the last success, the last failure and how many events are waiting to deliver. Select Send test event to send a test delivery, Rotate secret to get a new signing secret, or Remove endpoint to stop deliveries.

Deliveries

Each event is sent as:
  • Answer with any 2xx status within 10 seconds. The response body is ignored. Redirects are not followed and count as failures.
  • Deliveries go out in order. A failed delivery is retried after 30 seconds, 2 minutes, 10 minutes and 1 hour, then hourly, for up to 24 hours. Later events wait behind it.
  • A retried delivery carries the same id. Store the IDs you have handled and skip repeats.
  • Send test event sends {"id":0,"type":"webhook.test","canvasId":null,"at":...}.
If no delivery succeeds for 24 hours, CanvasView switches the endpoint off, discards the events waiting to deliver, and sends you a notification. Events are still recorded, so agents can read them with list_events. Fix the endpoint, then save it again on the Webhooks page to turn deliveries back on. Deliveries restart with events that happen after you save. Read the ones you missed with list_events.

Verify the signature

The CanvasView-Signature header holds t, a Unix time in seconds, and v1, an HMAC-SHA256 of <t>.<raw body> keyed with your signing secret, in hex.
  1. Read the raw request body exactly as received.
  2. Compute HMAC-SHA256 of <t>.<body> with your signing secret.
  3. Compare it with v1 in constant time.
  4. Reject requests whose t is more than five minutes from now.
The scheme matches Stripe’s webhook signatures. Verification code written for the Stripe-Signature header works once it reads CanvasView-Signature instead.

The signing secret

CanvasView generates the secret and shows it once, when you first save the endpoint or when you rotate it. Rotating takes effect at once: the next delivery uses the new secret. Keep the secret on your server only.

Delivery safety

A delivery never follows a redirect, reads at most 4 KB of your response, and carries no API keys or cookies.