webhookUrl to generations.submit or generations.run for each request, and Higgsfield POSTs the result there when the request reaches completed, failed or nsfw (see Overview for setup). In a multi-tenant app, put ?tenantId=<tenant> on that URL: nothing in a delivery names the account, and the handler below forwards the query to processWebhook. The signature covers the body but not the URL, so ?tenantId= only picks which tenant’s secret checks a delivery. When tenants share a secret, because they use one Higgsfield account or the webhookSecret option, anyone holding a signed delivery under 5 minutes old can resend it with another tenantId, and that tenant’s hooks run on it. Higgsfield signs with one secret per account, so tenants on one account must all store that account’s secret. Give each tenant its own Higgsfield account, or check in an after hook that the request_id is one that tenant submitted before acting on it. By then the plugin has logged the event under that tenant. A before hook runs ahead of the signature check, so it can receive an unsigned or forged delivery. Keep side effects in after.
Only signed deliveries are accepted. Higgsfield signs for an account once its secret has been revealed under Settings in the Higgsfield Console, and sends unsigned deliveries until then. Store the whsec_ secret with corsair.higgsfield.keys.set_webhook_signature(secret) or higgsfield({ webhookSecret }). If no secret is set, or a delivery fails verification, processWebhook reports a failure and no hook runs after it. The handler below then answers 500, and Higgsfield retries for up to two hours. It doesn’t retry a 4xx.
Webhook map
requestscompleted(requests.completed)
HTTP handler setup
app/api/webhook/route.ts
Events
Requests
Completed
requests.completed
A request reached completed (with its output), failed or nsfw. Signed with Standard Webhooks; only signed deliveries are accepted.
Payload
payload full type
payload full type
Response data full type
Response data full type
webhookHooks example