Webhook Integration Guide

Receive real-time event notifications via HTTPS POST to your endpoints.

Overview

Webhooks push event data to your server via HTTPS POST requests in real-time. Instead of polling the API for changes, webhooks notify you immediately when events occur — such as a candidate connecting, a profile updating, or a credential being issued.

  • Events are delivered as JSON payloads to your configured endpoint
  • Each delivery is signed with HMAC-SHA256 for verification
  • Failed deliveries are retried with exponential backoff
  • Events are guaranteed at-least-once delivery

Setup Steps

  1. Create Endpoint — Developer Portal → Webhooks → Add Endpoint. Provide your HTTPS URL.
  2. Select Events — Choose which events to subscribe to (or select all).
  3. Copy Signing Secret — Store the whsec_... secret securely for signature verification.
  4. Test & Activate — Send a test event to verify your endpoint responds with HTTP 2xx.

Available Events

EventDescription
candidate.connectedCandidate connected to your organization
candidate.disconnectedCandidate disconnected from your organization
candidate.profile_updatedCandidate updated their profile information
candidate.record_addedNew verified record added to candidate profile
candidate.tei_changedCandidate's Trust & Employability Index score changed
assessment.result_publishedAssessment results published for a candidate
assessment.certificate_generatedAssessment certificate generated and available
credential.issuedVerifiable credential issued to candidate
credential.verifiedCredential verification completed

Payload Format

All webhook payloads follow a consistent structure:

{ "id": "evt_abc123def456", "type": "candidate.connected", "api_version": "v1", "created_at": "2026-08-12T14:30:00Z", "data": { "gpin": "GPIN12345", "organization_id": "org_xyz789", "candidate": { "name": "Jane Smith", "email": "jane@example.com", "tei_score": 82 } } }
  • id — Unique event identifier (use for deduplication)
  • type — Event type from the table above
  • api_version — API version that generated the event
  • created_at — ISO 8601 timestamp
  • data — Event-specific payload

Signature Verification

Every webhook delivery includes a cryptographic signature so you can verify it came from GenuineIN.

Headers Included

HeaderDescription
X-Webhook-Signaturesha256= + HMAC-SHA256 hex digest of the raw JSON body
X-Webhook-TimestampISO 8601 timestamp of when the delivery was sent
X-Webhook-EventEvent category (e.g. career_api)

Verification Formula

expected = "sha256=" + HMAC-SHA256(webhook_secret, raw_json_body) valid = (expected === X-Webhook-Signature header)

Node.js Example

const crypto = require('crypto'); function verifyWebhook(req, webhookSecret) { const signatureHeader = req.headers['x-webhook-signature']; // "sha256=abc123..." const body = req.rawBody; // Raw JSON string const expected = 'sha256=' + crypto .createHmac('sha256', webhookSecret) .update(body) .digest('hex'); if (!crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected))) { throw new Error('Invalid webhook signature'); } return JSON.parse(body); }

Python Example

import hmac, hashlib def verify_webhook(headers, body, webhook_secret): signature_header = headers['X-Webhook-Signature'] # "sha256=abc123..." expected = 'sha256=' + hmac.new( webhook_secret.encode(), body.encode(), hashlib.sha256 ).hexdigest() if not hmac.compare_digest(signature_header, expected): raise ValueError('Invalid webhook signature') return json.loads(body)

Retry Policy

If your endpoint does not respond with HTTP 2xx within 30 seconds, we retry with exponential backoff:

AttemptDelay After Failure
1Immediate
21 minute
32 minutes
44 minutes
58 minutes
FAILEDEvent marked as permanently failed (~15 minutes total elapsed)
Success criteria: Your endpoint must respond with HTTP 2xx within 30 seconds. Any other response (including 3xx redirects) triggers a retry.

Best Practices

PracticeWhy
Respond quickly (return 200 immediately)Process async after acknowledging to avoid timeouts
Verify the signatureEnsure the request came from GenuineIN
Check timestamp (reject > 5 min old)Prevent replay attacks
Handle duplicates gracefullyAt-least-once delivery may send the same event twice
Use event id as dedup keyIdempotent processing prevents side-effect duplication

Testing

Use the Developer Portal to send test events to your endpoint:

  1. Go to Developer Portal → Webhooks → your endpoint
  2. Click "Send Test Event"
  3. Select the event type to simulate
  4. Verify your endpoint responds with 200

Manual Test with curl

curl -X POST https://your-server.com/webhooks/genuinein \ -H "Content-Type: application/json" \ -H "X-Webhook-Signature: sha256=test_signature_here" \ -H "X-Webhook-Timestamp: 2026-08-12T14:30:00.000Z" \ -H "X-Webhook-Event: career_api" \ -d '{"id":"evt_test123","type":"candidate.connected","api_version":"v1","created_at":"2026-08-12T14:30:00Z","data":{"gpin":"GPIN12345"}}'
GenuineIN Products
Loading products...