Webhooks notify your server when a job reaches a terminal state.
Persistent endpoints are configured per project in the dashboard. A generation request may also include webhook_url; this adds a callback for that job and does not replace persistent endpoints.
The one-job signing secret is returned once in the 202 response as webhook_signing_secret.
Verify signatures
Every delivery includes:
X-NSFW-Webhook-Id
X-NSFW-Webhook-Timestamp
X-NSFW-Webhook-Signature
The signed bytes are:
Compute HMAC-SHA256 using the webhook secret and compare signatures in constant time. Verify every comma-separated v1=<hex> value because one deduplicated URL may be covered by multiple secrets.
Reject timestamps outside your accepted clock-skew window.
Delivery behavior
Return any 2xx status to acknowledge the event. Network errors and non-2xx responses are retried with backoff before the delivery is marked dead.
Use X-NSFW-Webhook-Id as the deduplication key. Payloads can contain freshly signed result URLs with the same expiration behavior as polling. Last modified on September 17, 2026