Skip to main content
Preview — sandbox webhooks are newly available and still evolving; the shape may change. We’d love your feedback.
Register a destination and OpenComputer delivers a sandbox’s lifecycle events to it as a small, signed delivery envelope — signed, retried, and redeliverable. Use it to react when a sandbox boots, hibernates, stops, or scales, without polling. The envelope is camelCase, with top-level routing fields and the full event nested under event:
Dedupe on deliveryIdverifyWebhook sets it from the svix-id header (stable across retries and redelivery). Need to route on your own metadata? Attach metadata when you register the destination and it rides as custom HTTP headers on every request — there’s no metadata in the body.

Events

Subscribe to all events, or filter with eventTypes (exact like sandbox.stopped, or a prefix like sandbox.*).

Destinations

A destination is org-scoped by default (all your sandboxes), or pinned to one sandbox with sandboxId. Set enabled: false to pause a destination — it stops receiving deliveries until you re-enable it; events that occur while it’s paused aren’t backfilled.
Every destination is signed. If you don’t pass a secret, OpenComputer generates one (whsec_…) and returns it on create. The secret is re-fetchable any time via webhooks.getSecret(id) (GET /api/webhooks/:id/secret), and rotatable via webhooks.update(id, { rotateSecret: true }).

Subscribe at create

sandbox.created and sandbox.ready fire before a separate webhooks.create call could know the sandbox id. To capture a sandbox’s full lifecycle, register the webhook with the sandbox — it’s pinned to that sandbox and gets every event from created on:

Deliveries

Every send and its outcome — the data behind a deliveries dashboard.
Each record is a Svix delivery attempt with its status and the consumer’s responseStatusCode; Svix retries failed attempts on its managed schedule and retains recent attempt history (the attempt index lags a send by a few seconds). A deleted destination’s history is no longer queryable.
Redelivery re-sends the same message to the endpoint (same svix-id) — for when the original never landed. A receiver that dedupes on svix-id treats it as the same message.

Signing, retries, and dedupe

  • HTTPS only, checked at registration. The delivery layer (Svix) additionally blocks private, loopback, link-local, and cloud-metadata addresses at send time.
  • Always signed with Standard Webhooks (delivery is by Svix). Every request carries svix-id, svix-timestamp, and svix-signature = v1,<base64(HMAC-SHA256(secret, "{svix-id}.{svix-timestamp}.{rawBody}"))>. Verify against the raw request body, before parsing it; the timestamp guards replay. Any custom headers you attached as destination metadata ride along too. Your signing secret is re-fetchable any time via GET /api/webhooks/{id}/secret and rotatable via update (rotateSecret: true).
  • At-least-once. Once an event is handed off it’s retried until it succeeds or the delivery layer gives up. A duplicate can still arrive, so dedupe on svix-id (the verifier exposes it as both deliveryId and dedupeId).
  • Not strictly ordered. Events for one sandbox can arrive out of order (e.g. sandbox.ready before sandbox.created). Treat each event independently and key off event.type; don’t assume an ordering.
  • Success / retry / give-up. A delivery succeeds on HTTP 2xx. Failures are retried on Svix’s managed backoff (immediately, then 5s, 5m, 30m, 2h, 5h, 10h, 10h); an endpoint that keeps failing for ~5 days is auto-disabled. Inspect attempts and recover failed messages via the deliveries API. Unsafe targets (private / loopback / cloud-metadata addresses) are blocked by the delivery layer.

Verify a webhook

The SDK ships a verifier — no extra dependency, runs in Node / Cloudflare Workers / browsers — that checks the signature and returns the parsed envelope. It’s the same verifyWebhook used for session webhooks; pass SandboxLifecycleEvent to type the nested event:
Or verify with any Standard Webhooks / Svix library directly, against the raw body and the svix-id / svix-timestamp / svix-signature headers.
Webhooks here cover sandbox lifecycle. To deliver an agent’s session events (turns, messages, results), see Agent Sessions webhooks — verified with the same verifyWebhook helper. Session webhooks differ in a couple of specifics today: their webhook-id is the event id, and signing is opt-in (set a secret).