Scanner runs are asynchronous. Your integration needs a terminal-state handoff before it queries observations, opens a review task, or optionally requests a render.
GET /v1/runs/{run_id} today unless the Webhooks page in your console confirms that delivery is enabled.Polling pattern available now
Poll every 5–10 seconds with jitter. Stop at completed or failed. On completion, request /v1/runs/{run_id}/observations; do not repeatedly fetch observations while processing.
Target webhook handler
POST /your/webhooks/chatclipthat
X-CCT-Event-Id: evt_...
X-CCT-Timestamp: 1786730400
X-CCT-Signature: v1=...
{"type":"scanner.run.completed","data":{"run_id":"run_..."}}
- Read the raw body before JSON parsing.
- Reject stale timestamps outside your replay window.
- Compute HMAC-SHA256 over
timestamp.raw_bodywith the endpoint secret. - Compare signatures in constant time.
- Deduplicate on event ID and enqueue internal work.
- Return 2xx quickly; fetch the canonical run and observations from the API.
Design for retries and reordering
Event delivery is at-least-once, not exactly-once. A handler must tolerate duplicates, and downstream state should be derived from the current run resource rather than assuming events arrive in order.
Keep rendering separate
A completion event means structured observations are ready. Render only selected timestamped Moments after your own policy or reviewer chooses them.