Skip to main content

Overview

Instead of polling GET /jobs/{id}, give Krea a webhook URL. Krea sends the job to that URL when it finishes.

Using webhooks

Add the X-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 the GET /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:
To verify a request:
  1. Check that X-Krea-Webhook-Url exactly matches the X-Webhook-URL you sent with the job.
  2. Check that the timestamp is within 5 minutes of your server’s current time.
  3. 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.
Hash the raw body bytes, not re-serialized JSON. For example, use 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 a 2xx 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