When something important happens, Kilo POSTs JSON to your HTTPS URL.
Why webhooks feel “faster than the HTTP response”
Your POST /deliveries returns as soon as Kilo saves the job.
Separately, we enqueue the webhook with Upstash QStash, so:
- Your create API stays fast.
- Your webhook URL is called with retries if it is down.
- You still verify that the POST really came from Kilo.
Create an endpoint
- Dashboard → Settings → API & Webhooks.
- Add endpoint with an
https://URL. - Choose events (start with all delivery events).
- Copy the
whsec_...signing secret (shown once).
Events
| Event | When |
|---|---|
delivery.created |
After a successful create (API or other sources that emit) |
delivery.cancelled |
Delivery cancelled |
delivery.status_changed |
Status moved (when emitted) |
delivery.updated |
General update (when emitted) |
delivery.completed |
Delivery completed (when emitted) |
Headers on every webhook
| Header | Meaning |
|---|---|
Content-Type |
application/json |
Kilo-Signature |
t=<unix>,v1=<hex> |
Kilo-Event |
Event name |
Verify the signature (do this for real)
- Read
Kilo-Signature. - Split into
tandv1. - Reject if
tis older than 5 minutes. - Compute HMAC-SHA256 of
${t}.${rawBody}using yourwhsec_...secret. - Compare hex digests in constant time.
Example Node.js:
import crypto from "node:crypto";
function verify(secret, rawBody, header) {
const parts = Object.fromEntries(
header.split(",").map((p) => {
const [k, ...rest] = p.split("=");
return [k, rest.join("=")];
}),
);
const t = Number(parts.t);
const v1 = parts.v1;
if (!t || !v1) return false;
if (Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}
Respond
Return HTTP 2xx quickly. Do heavy work in your own queue after verifying the signature.
Handle customer messages yourself
Many bots already own the conversation with the customer. In that case:
- Dashboard → Settings → Notifications → turn Customer delivery messages off.
- Subscribe to the events above (especially
delivery.status_changed/delivery.completed). - Send WhatsApp / SMS / push from your product when those webhooks arrive.
Kilo will not send tracking links, pickup/nearby/arrived updates, or completion/feedback WhatsApps to your customers while that setting is off. Delivery OTPs and rider notifications still work.