Skip to main content

Overview

Webhooks push lifecycle events to your server as they happen, so you can react to a finished training job or a deployment coming online without polling. Veri signs every delivery using the Standard Webhooks scheme, the same signing convention used by OpenAI and Replicate, so existing verification libraries work out of the box. Register an endpoint once, then receive a POST for each event you subscribe to.
The response includes the endpoint’s signing secret (a whsec_... string). This is the only time the full secret is returned by a create or list call. Store it; you need it to verify deliveries. You can retrieve it again with GET /v1/webhooks/{id}/secret, and it stays masked everywhere else. Omit event_types (or pass []) to subscribe to all event types. Endpoint URLs must be https and publicly routable: requests to private, loopback, or cloud-internal addresses are rejected at registration and again at delivery time.

Events

Each event fires exactly once per real state transition. Deliveries, however, are at-least-once (see Idempotency).

Payload

Deliveries are POST requests with Content-Type: application/json and a deliberately thin body: enough to know what happened and which object to fetch. Payloads never contain secrets, tokens, or endpoint URLs.
Job events use "object": "job" and carry "model" (the base model for managed jobs, null for custom-script jobs) instead of "name". Fetch the full resource (GET /v1/deployments/{id}, GET /v1/training_jobs/{id}) when you need more than the transition itself.

Verifying deliveries

Every delivery carries three headers: The signature is computed as:
Verify with a timing-safe comparison, and reject deliveries whose timestamp is more than 5 minutes old (replay protection). Always verify against the raw request body bytes, before any JSON parsing or re-serialization.
Respond with any 2xx status to acknowledge the delivery. The response body is ignored. Redirects are not followed.

Retries

A delivery that fails (non-2xx response, timeout after 10 seconds, or connection error) is retried on a fixed backoff schedule: Retries stop 72 hours after the event was created; the delivery is then marked exhausted. Inspect recent attempts, response codes, and errors with:

Automatic disabling

After 50 consecutive failed deliveries (across events), the endpoint is disabled: disabled_at is set and it stops receiving events. Any successful delivery resets the counter. Re-enable a disabled endpoint with:

Idempotency and ordering

  • Dedupe on webhook-id. Deliveries are at-least-once: a retry after a timeout can arrive even though your server processed the original. The webhook-id header (equal to the payload id) is identical across every retry of the same event; keep a short-lived record of processed ids and skip duplicates.
  • No ordering guarantees. Retries mean a deployment.serving event can arrive after a later deployment.scaled_to_zero for the same deployment. Do not reconstruct state from event order.
  • The API is the source of truth. Treat an event as a hint that something changed, then GET the resource for its current state before acting on it.

Testing an endpoint

Send a synthetic webhook.test event through the real delivery pipeline (signed, retried on failure, visible in /deliveries):
The event targets only this endpoint and bypasses its event_types filter, so it works even for endpoints subscribed to a narrow set of events.

Endpoint management

See the API reference for request and response schemas.