Webhooks
Webhooks push near-real-time events to an HTTPS endpoint you control. Each delivery is a JSON document signed with a shared secret so you can verify it came from Aware.
Every delivery shares the same envelope: id, type, timestamp, and payload. Branch on type to handle the event; payload holds the domain object(s) for that event. Check-in deliveries are documented as WebhookDelivery; subscribe using the event types in WebhookEventType.
Create a webhook in the dashboard
Section titled “Create a webhook in the dashboard”Public API webhooks are managed in the Aware dashboard under Settings → APIs & Integrations → Webhooks.
- Open your company in the Aware app and go to Settings → APIs & Integrations → Webhooks.
- Click Add webhook.
- Enter your endpoint URL.
- Select one or more events (see below).
- Leave Enabled checked and click Create.
- Copy the signing secret from the confirmation screen. It is shown once — store it in your secret manager. You cannot retrieve it later.
You can register one webhook per company. Use Update in the list to change the URL, events, or enabled flag.
That webhook receives events from all sites under the company — there is no per-site filter. If you only care about certain sites, filter on payload.siteId in your handler.
Events
Section titled “Events”When creating or updating a webhook, choose which events to receive. The same type value appears on each delivery:
Event type | Meaning |
|---|---|
CHECKIN_ENTERED | Person is on site. |
CHECKIN_EXITED | Person has checked out. |
CHECKIN_PENDING | Check-in is recorded but not yet admitted (clearance pending). |
CHECKIN_STOPPED | Check-in was hard-stopped — compliance or clearance failed. |
For check-in events, payload is a CheckinResponse — the same object returned by the check-in REST endpoints. Status meanings match the Check-ins guide.
Delivery format
Section titled “Delivery format”Aware POSTs to your URL with:
| Header | Purpose |
|---|---|
Content-Type | application/json |
X-Aware-Delivery-Id | UUID for this delivery (same as the id field in the body). |
X-Aware-Signature | t=<unix-seconds>,v1=<hex> — HMAC-SHA256 of the raw body. |
Example body (trimmed). Full schema: WebhookDelivery.
{"id": "a502c3e3-4c33-4f38-9297-6a05bb3b07b4","type": "CHECKIN_ENTERED","timestamp": "2026-06-26T02:49:22.656685Z","payload": { "id": "4faa23fa-3f0c-4507-b60a-e53eaff1696d", "siteId": 34009, "timestamp": "2026-06-26T02:49:22.391Z", "entry": { "source": "MANUAL", "timestamp": "2026-06-26T02:49:00.000Z" }, "exit": {}, "status": "IN", "personId": 12345}}id— delivery id (also sent asX-Aware-Delivery-Id).type— event name (CHECKIN_ENTERED,CHECKIN_EXITED, …); see WebhookEventType.timestamp— when Aware emitted the event (UTC).payload— event body; shape depends ontype. Check-in events use CheckinResponse.
Return any 2xx response quickly. Your endpoint must answer the POST directly — redirects are not followed. Non-2xx responses are logged; duplicate deliveries for the same underlying event may be suppressed for 24 hours.
Verify the signature
Section titled “Verify the signature”Read the raw request body (before JSON parsing). Parse X-Aware-Signature:
t=<unix-seconds>,v1=<hex-digest>Compute:
HMAC_SHA256(secret, "<t>." + rawBody)Compare the digest to v1 with a constant-time comparison.
import { createHmac, timingSafeEqual } from 'node:crypto'
function verifyAwareWebhook(secret, rawBody, signatureHeader) {const parts = Object.fromEntries( signatureHeader.split(',').map((part) => { const [key, ...rest] = part.trim().split('=') return [key, rest.join('=')] }),)
const timestamp = parts.tconst expected = parts.v1if (!timestamp || !expected) return false
const signed = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex')const a = Buffer.from(signed, 'hex')const b = Buffer.from(expected, 'hex')return a.length === b.length && timingSafeEqual(a, b)}Reject requests that fail verification before acting on the payload.
Related
Section titled “Related”- Check-in fields in
payload— Check-ins guide and CheckinResponse. - API clients — REST calls use a separate M2M client and JWT; webhooks are configured in the dashboard. See Authentication.