Browse the docs

Public API

Webhooks: Know When a Job Ends

Get a signed message at your own address when a job ends, and check that it really came from Kritiverse.

This page shows how to get a message at your own address when a job ends, without asking again and again.

What it does

When a job started with the Public API ends, Kritiverse sends a signed POST to your address, usually within a minute.

Step by step

  1. Open the API tab in My account.
  2. Under Webhooks, enter your address and press Add webhook. It must be a public https address on port 443.
  3. Copy the secret. It starts with whsec_ and it is shown only once.
  4. Press Send test to see a ping arrive.
  5. Check the signature of every message, as shown below.

Every option explained

What arrives

{
  "id": "01jc...",
  "type": "job.finished",
  "created_at": "2026-11-01T10:00:00Z",
  "job": { "id": "01jb...", "type": "image", "status": "done", "credits": 25, "charged": 25, "assets": [] }
}

The message comes for done, partial, failed, blocked and canceled.

Check the signature

Each message has three headers: Kriti-Event-Id, Kriti-Timestamp and Kriti-Signature. The signature is v1= and the HMAC SHA-256 of the timestamp, a full stop and the raw body, with your secret as the key.

const expected = 'v1=' + crypto.createHmac('sha256', secret)
  .update(timestamp + '.' + rawBody).digest('hex');

Compare it with a constant time compare. Refuse a message whose timestamp is more than 5 minutes old, so an old one cannot be replayed. Use the raw body, before any JSON parsing.

Answers and retries

Answer with any 2xx within 5 seconds. Do the slow work after you answer.

Anything else is tried again after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 24 hours. A message can arrive twice, so use Kriti-Event-Id to skip one you have already handled.

After 10 messages fail for good, the webhook is paused and the API tab says so. Fix your address, then press New secret to start it again.

New secret

New secret stops the old one at once. Update your server straight away.

Common problems

My address is refused

It must start with https://, use port 443, and be reachable from the internet.

The signature does not match

Your framework may have parsed the body. Use the raw bytes as they arrived.

Related guides

Updated 1 Nov 2026