Webhooks
Receive real-time notifications when events occur in your KLIQ tenant. Webhooks are the recommended way to react to observation processing, CV job completion, and other events.
Setup
POST
/v1/tenants/{tenantId}/webhooksCreate a webhook subscriptionGET
/v1/tenants/{tenantId}/webhooksList webhook subscriptionsDELETE
/v1/tenants/{tenantId}/webhooks/{id}Delete a webhook subscriptionconst webhook = await tenant.webhooks.create({
url: 'https://your-server.com/api/kliq-webhook',
events: ['observation.created', 'cv.job.completed', 'cv.job.failed'],
secret: 'whsec_your_signing_secret',
});
console.log(webhook.id); // "wh_abc123"Event types
| Event | Description |
|---|---|
observation.created | A new observation was submitted |
observation.updated | An observation was modified |
cv.job.completed | A CV job finished successfully |
cv.job.failed | A CV job failed |
visit.submitted | A field visit was submitted |
Payload format
All webhook payloads follow this structure:
{
"id": "evt_abc123",
"type": "cv.job.completed",
"tenantId": "t_xyz789",
"timestamp": "2026-04-28T12:00:00Z",
"data": {
"jobId": "job_xyz789",
"observationId": "obs_abc123",
"model": "shelf-detection-v2",
"status": "completed",
"result": {
"detections": [...],
"summary": {...}
}
}
}
Signature verification
Every webhook request includes an X-Kliq-Signature header containing an HMAC-SHA256 signature of the request body. Always verify this signature to ensure the webhook came from KLIQ.
Express (Node.js)
import express from 'express';
import crypto from 'crypto';
const app = express();
app.use(express.json({ verify: (req: any, _res, buf) => { req.rawBody = buf; } }));
app.post('/api/kliq-webhook', (req: any, res) => {
const signature = req.headers['x-kliq-signature'] as string;
const expected = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET!)
.update(req.rawBody)
.digest('hex');
if (signature !== expected) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = req.body;
switch (event.type) {
case 'cv.job.completed':
console.log('CV job completed:', event.data.jobId);
// Process results...
break;
case 'cv.job.failed':
console.error('CV job failed:', event.data.jobId);
break;
}
res.status(200).json({ received: true });
});Retry policy
If your endpoint returns a non-2xx status code or times out (30 seconds), KLIQ retries with exponential backoff:
| Retry | Delay |
|---|---|
| 1st | 1 minute |
| 2nd | 5 minutes |
| 3rd | 30 minutes |
| 4th | 2 hours |
| 5th | 24 hours |
After 5 failed retries, the webhook is disabled and you will receive an email notification.
Testing locally
Use tools like ngrok or webhook.site to test webhooks during development:
# Start ngrok tunnel
ngrok http 3000
# Use the ngrok URL as your webhook endpoint
# https://abc123.ngrok.io/api/kliq-webhook
Next steps
- CV Jobs — Start CV analysis jobs
- Observations — Submit observation data
- Authentication — Secure your API access