Overview
Instead of pollingGET /jobs/{id}, give Krea a webhook URL. Krea sends the job to that URL when it finishes.
Using webhooks
Add theX-Webhook-URL header to any generation request. When the job completes, fails, or is cancelled, Krea sends a POST request to that URL.
Webhook payload
The request body has the same shape as theGET /jobs/{id} response:
Verifying signatures
Krea signs every webhook with Ed25519. Verify the signature before you trust a payload, and reject requests that have no signature.
Krea signs the lowercase hex SHA-256 of the timestamp, URL, metadata, and raw request body, joined with newlines:
- Check that
X-Krea-Webhook-Urlexactly matches theX-Webhook-URLyou sent with the job. - Check that the timestamp is within 5 minutes of your server’s current time.
- Accept the request if the signature verifies with any key in
https://api.krea.ai/.well-known/jwks.json. Cache the keys for at most 24 hours. Krea publishes a new key 24 hours before it starts signing with it.
express.raw() in Express, await request.arrayBuffer() in Fetch API frameworks, or request.get_data() in Flask. Treat a missing X-Krea-Webhook-Metadata header as an empty string.
Delivery and retries
Return a2xx within 15 seconds. If the request times out, can’t connect, or gets a 5xx, 408, 423, 425, or 429, Krea retries for about 10 minutes with a new timestamp and signature each time. Krea doesn’t retry any other 4xx.
The same job can arrive more than once, so deduplicate on job_id and status.
Webhooks vs. polling
Use webhooks when you have a server that can receive HTTP requests. Use polling for client-side apps or when you can’t expose a public endpoint.
Next steps
Job Lifecycle
Learn about job states and status polling
Code Examples
Generate an image with the API, end to end