Skip to main content

Event Webhooks

Webhooks allow external applications and ATS platforms to subscribe to real-time events in your XeCubes organization. When an event triggers, XeCubes delivers an HTTP POST request with a JSON payload to your configured webhook URL.


Supported Event Types​

Event NameTrigger Condition
interview.scheduledA candidate confirms an interview slot with Google Calendar or Zoom.
interview.startedCandidate enters the WebRTC AI interview room.
interview.completedAI interview finishes, generating video recordings and raw transcripts.
candidate.evaluatedFinal AI evaluation scorecard, competency breakdown, and hire recommendation ready.
assessment.submittedTechnical coding assessment submitted by candidate with test results.
resume.parsedAsync resume batch parsing completes entity extraction.

Webhook Payload Schema​

interview.scheduled Example​

{
"event_type": "interview.scheduled",
"data": {
"interviewId": "int_90J823K481",
"org_id": "org_92A838HDK8",
"job_id": "job_37H283J8K",
"candidate": {
"name": "Sarah Connor",
"email": "sarah.connor@example.com"
},
"start_time": "2026-06-12T15:00:00Z",
"end_time": "2026-06-12T15:30:00Z",
"meeting_link": "https://meet.google.com/xyz-qprs-tuv"
},
"created_at": "2026-06-05T12:00:00Z"
}

candidate.evaluated Example​

{
"event_type": "candidate.evaluated",
"data": {
"interview_id": "int_90J823K481",
"candidate_id": "cand_1829381928",
"job_id": "job_37H283J8K",
"overall_score": 92.5,
"recommendation": "STRONG_HIRE",
"summary": "Demonstrated deep expertise in distributed caching, Raft consensus, and Go concurrency. Clean code with 100% test pass rate.",
"report_url": "https://app.xecubes.com/reports/int_90J823K481"
}
}

Verifying Webhook Signatures​

Each webhook request contains an X-XeCubes-Signature header to verify authenticity and protect against replay attacks:

X-XeCubes-Signature: t=1717588800,v1=9f8d7c6b5a4e3f2...

Verification Implementation​

import express from 'express';
import crypto from 'crypto';

const app = express();
const WEBHOOK_SECRET = process.env.XECUBES_WEBHOOK_SECRET!;

app.post('/webhooks/xecubes', express.raw({ type: 'application/json' }), (req, res) => {
const signatureHeader = req.headers['x-xecubes-signature'] as string;
const rawBody = req.body.toString();

// Extract timestamp and hash
const [tPart, vPart] = signatureHeader.split(',');
const timestamp = tPart.split('=')[1];
const signature = vPart.split('=')[1];

// Compute expected HMAC SHA256
const expectedSignature = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(`${timestamp}.${rawBody}`)
.digest('hex');

if (signature !== expectedSignature) {
return res.status(400).send('Invalid signature');
}

const payload = JSON.parse(rawBody);
console.log(`Received verified event: ${payload.event_type}`);

// Return HTTP 200 promptly
res.status(200).json({ received: true });
});

Delivery & Retry Policy​

  • Your webhook endpoint must respond with an HTTP 2xx within 10 seconds.
  • If your server returns an error (4xx or 5xx) or times out, XeCubes retries delivery with exponential backoff:
    • Retry 1: 1 minute later
    • Retry 2: 5 minutes later
    • Retry 3: 30 minutes later
    • Retry 4: 2 hours later
    • Retry 5: 8 hours later