Skip to content
Webhooks SDK
Esc
↑↓navigate↵open⌘Jpreview
On this page

Replicate

Verify and handle Replicate webhooks — prediction status updates from starting to succeeded, failed, or canceled.

Pass a webhook URL when you create a prediction, fetch your account’s signing secret, and handle prediction statuses by name:

import { createWebhookHandler } from 'webhooks-sdk'
import { replicate } from 'webhooks-sdk/replicate'

const handler = createWebhookHandler({
  provider: replicate({ secret: process.env.REPLICATE_WEBHOOK_SIGNING_SECRET! }),
  on: {
    succeeded: async (event) => {
      await store(event.payload.id, event.payload.output)
    },
    failed: async (event) => {
      await report(event.payload.id, event.payload.error)
    },
  },
})

export const POST = handler.fetch

The secret is account-wide rather than per-endpoint, and lives behind the API instead of a dashboard page:

curl -s -H "Authorization: Bearer $REPLICATE_API_TOKEN" \
  https://api.replicate.com/v1/webhooks/default/secret
# {"key": "whsec_..."}

Replicate signs with Standard Webhooks over the spec’s webhook-* headers — the id and timestamp are inside the signed material, so a replayed request is rejected on its own.

Options

Option Type Default
secret string | string[] — The whsec_… signing secret(s). Pass an array during rotation.
tolerance number 300 Replay window in seconds.

Events are statuses, not types

The webhook body is the prediction object itself — there is no type field. The event name is the prediction’s status:

starting · processing · succeeded · failed · canceled — plus aborted, for a prediction that exceeded its deadline before it could start.

These autocomplete in the on map; any other string still routes. Which deliveries arrive is set per prediction by webhook_events_filter — start, output, logs, completed — defaulting to output and completed. output and logs fire repeatedly during the run, throttled to at most one request per 500ms, so a handler for a non-terminal status must expect the same status more than once; dedupe on event.id, which is unique per delivery. Only the terminal delivery is retried on failure; intermediate ones are not.

The payload is the whole prediction

Unlike vendors that send a thin pointer, Replicate delivers the prediction in the same shape the predictions API returns — id, status, input, output, error, logs, metrics, and the timestamps. No re-fetch needed:

succeeded: async (event) => {
  const { id, output, metrics } = event.payload
},

The envelope

  • event.id — the webhook-id header, the spec’s canonical idempotency key, unique per delivery.
  • event.type — the prediction’s status.
  • event.timestamp — the signed webhook-timestamp.
  • event.payload — the prediction object; the result is at payload.output.

Standalone & testing

The wrapper is the Standard Webhooks provider with id: 'replicate' and eventType: 'status', so the standalone triple lives there:

import {
  verifyStandardWebhook,  // (raw, { secret }) — throws on failure
  parseStandardWebhook,   // (raw, { eventType: 'status' }) — the envelope
  signStandardWebhook,    // (body, secret) — all three webhook-* headers, for tests
} from 'webhooks-sdk/standard-webhooks'

signStandardWebhook’s default webhook-* header names are exactly what Replicate sends. See Testing.

Last updated on September 1, 2026

Was this page helpful?