Webhooks
How to receive real-time events from Vetigen via webhooks.
Webhooks Guide
Webhooks allow you to receive real-time notifications when events occur in Vetigen — such as new appointments, completed examinations, or lab results arriving.
Registering a Webhook
Send a POST request to register your webhook endpoint:
curl -X POST https://api.vetigen.com/api/v1/webhooks \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/vetigen",
"events": ["appointment.created", "appointment.cancelled", "soap.signed", "lab.completed"],
"secret": "your_webhook_secret"
}'Available Events
| Event | Description |
|---|---|
appointment.created | New appointment scheduled |
appointment.updated | Appointment details changed |
appointment.cancelled | Appointment was cancelled |
appointment.completed | Visit completed |
soap.created | New SOAP record created |
soap.signed | SOAP record signed by veterinarian |
lab.completed | Cortex lab result received |
patient.created | New patient added |
Webhook Payload
Each event is delivered as a POST request with a JSON body:
{
"event_id": "evt_01JQMKXXXXX",
"event_type": "appointment.created",
"occurred_at": "2026-04-11T10:30:00Z",
"clinic_fp": "clinic_01JQMKXXXXX",
"data": {
"fp": "event_01JQMKXXXXX",
"type": "CHECKUP",
"status": "SCHEDULED",
"patient": { "fp": "patient_01JQMKXXXXX", "name": "Luna" },
"start_at": "2026-04-15T10:00:00+03:00"
}
}Signature Verification
Vetigen signs all webhook requests with HMAC-SHA256. Verify the signature to ensure authenticity:
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expected, 'hex')
);
}
// In your Express handler:
app.post('/webhooks/vetigen', (req, res) => {
const signature = req.headers['x-vetigen-signature'];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process the event
const { event_type, data } = req.body;
console.log(`Received event: ${event_type}`);
res.status(200).send('OK');
});Retry Policy
If your endpoint fails to respond with a 2xx status, Vetigen will retry the delivery:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 12 hours |
After 5 failed attempts, the event is marked as failed and no further retries are made.
Best Practices
- Respond quickly — return
200 OKimmediately, process asynchronously - Verify signatures — always validate the
x-vetigen-signatureheader - Handle duplicates — use
event_idfor idempotency - Use HTTPS — webhook endpoints must use HTTPS in production
Related
Inventory
How to query inventory items and products via the Vetigen API.
List patients
Returns a paginated list of patients accessible to the clinic associated with your API key. ### Access Model Patients in Vetigen are **global entities** — a single patient record may be shared across multiple clinics via `CustomerClinicConnection`. This endpoint returns patients that have an active connection to the caller's clinic, regardless of which clinic originally created the record. ### Sorting Results are sorted by `updated_at DESC` by default — most recently modified first. ### Pagination Use `page` and `page_size` query parameters. The response includes `has_more: true` when additional pages are available. Prefer cursor-style iteration over random page access for large datasets — page numbers may shift as records change. ### Common Errors - `PATIENT.ACCESS_DENIED` — API key's clinic has no connection to the requested patients. - `AUTH.RATE_LIMITED` — see rate-limit headers.