Webhooks
Webhooks let ALOT send event notifications to your system in real time. Use them to sync candidate lifecycle activity into your ATS, CRM, analytics, or internal tools.
Before You Start
- Configure a public HTTPS endpoint that accepts JSON POST requests.
- Store your webhook signing secret securely.
- Always verify signatures before processing payloads.
Events
| Event | Description |
|---|---|
candidate.invited | Triggered when a new candidate invite is created |
candidate.completed | Triggered when a candidate completes an assessment flow |
candidate.disqualified | Triggered when a candidate fails a required stage gate |
assessment.published | Triggered when an assessment becomes publicly available |
Payload Format
{
"id": "evt_01jcc7...",
"type": "candidate.completed",
"timestamp": "2026-05-25T14:23:00.000Z",
"organizationId": "org_123",
"data": {
"sessionId": "sess_123",
"assessmentId": "asm_456",
"candidateName": "Jane Smith",
"candidateEmail": "jane@example.com",
"score": 82,
"status": "COMPLETED"
}
}Signature Verification
Every webhook request includes an X-Alot-Signature header:
X-Alot-Signature: sha256=a3f2c1b9...Verify it on your server before processing the payload:
import crypto from 'crypto'
function verifyWebhook(rawBody: string, signature: string, secret: string): boolean {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody, 'utf8')
.digest('hex')
const expected_buf = Buffer.from(`sha256=${expected}`)
const sig_buf = Buffer.from(signature)
if (expected_buf.length !== sig_buf.length) return false
return crypto.timingSafeEqual(expected_buf, sig_buf)
}Create a Webhook Endpoint
In the dashboard, navigate to Settings → Webhooks to register an endpoint and select events.
You can also create endpoints with the API:
POST /v1/webhooks
Authorization: Bearer <your-jwt>
Content-Type: application/json
{
"url": "https://yourapp.com/alot/webhook",
"events": ["candidate.completed"],
"secret": "your-signing-secret"
}Delivery and Retries
Delivery is asynchronous. If your endpoint returns a non-2xx status or times out, retries are attempted automatically:
- Attempt 1: immediately
- Attempt 2: short backoff retry
- Attempt 3: final retry with longer backoff
Design your consumer to be idempotent and resilient to duplicate deliveries.
Observability
Use webhook history in Settings → Webhooks to inspect status codes, attempts, and failure reasons for each event delivery.
Testing locally
Use a tool like ngrok to expose your local server:
ngrok http 3000
# Use the HTTPS URL from ngrok as your webhook URLNext Steps
- Review authentication for secure API access.
- Use the JavaScript SDK for faster integration.