Webhook Integration Guide
The SNH AI Background Check API provides comprehensive webhook support to receive real-time notifications throughout the verification lifecycle. This guide covers practical webhook configuration, security implementation, payload handling, and complete integration examples. For a high-level overview of the webhook system and when events are triggered, see the Webhook System Overview.Delivery model
Production webhooks are signed and retried according toretryAttempts. Sandbox is suitable for handler validation, but delivery is best-effort. See Sandbox reference.
Overview
Webhooks are HTTP callbacks that notify your application when verification events occur. The API sends POST requests to your configured endpoints with event payloads and HMAC-SHA256 signatures for security verification.Illustrative terminal payloads (verification.completed)
Structures vary by tenant program; illustrative fragments only:
Employment (verified)
Webhook Events
The API sends three types of webhook events:verification.completed- Sent when a verification search reaches a terminal outcome (VERIFIED, NO_RECORD, WRONG_ORG, THIRD_PARTY, etc., per your program)verification.action_required- Sent when the verification cannot proceed without action (THIRD_PARTY_RECORD, UPSTREAM_ISSUE, SYSTEM_FAILURE, SLA_REACHED, HUMAN_ESCALATION, OTHER)verification.notification- Intermediate progress updates (contact plan, outbound attempts, inbound messages) when those notifications are enabled for your routing
Webhook Configuration
Webhooks can be configured at two levels:Request-Level Configuration
Configure webhooks per verification request:Tenant-Level Configuration
Configure webhooks at the tenant level (applies to all verifications unless overridden): Contact your SNH AI account manager to configure tenant-level webhook settings.Endpoint Resolution
The API resolves webhook endpoints using the following priority:- Search-specific endpoint: If configured for the search type (e.g.,
EMPLOYMENT), that endpoint is used - Fallback endpoint: If no search-specific endpoint is configured, the fallback endpoint is used
- Tenant-level configuration: If no request-level configuration is provided, tenant-level settings are used
- When a search type is configured with multiple webhook targets, the API will deliver to all matching targets that allow the event.
- If
eventsis omitted on a target, it will receive onlyverification.completed(backward compatible). - Per-target
headersare merged into the request headers. IfbasicAuthis set, anAuthorization: Basic ...header is included.
Webhook Payload Structure
All webhook payloads follow a consistent structure withevent, occurredAt, and data fields. For detailed payload structures and examples, see Webhook Events.
Terminal events (verification.completed, verification.action_required) always include a single channel field representing the primary verification channel. Intermediate notifications keep the original channels array to provide full auditing of concurrent communication paths.
Webhook Headers
Each webhook request includes these headers:| Header | Description |
|---|---|
Content-Type | Always application/json. |
X-Event-Type | Event type (verification.completed, verification.action_required, verification.notification). |
X-Event-Id | Unique delivery ID for this webhook (use for idempotency). |
X-Search-Type | Optional; resolved search type: EMPLOYMENT or EDUCATION. |
X-External-Search-Id | Optional; echoes the external search identifier provided when the order was created. |
X-Endpoint-Source | Indicates whether the request used a type-specific or fallback endpoint. |
User-Agent | Always Theary-Webhook-Delivery/1.0. |
Authorization | Present only when the webhook target specifies Basic Auth credentials (Authorization: Basic <base64(username:password)>). |
X-Webhook-Signature | Included when a tenant-level or per-target secret is configured; value is sha256=<hex> for HMAC validation. |
- If neither the tenant config nor the target defines a signing secret,
X-Webhook-Signatureis omitted. - Per-target custom headers are merged into the request when configured (for example
X-Customer: acme).
Security: Signature Verification
All webhook payloads are signed using HMAC-SHA256. Verify the signature to ensure authenticity:Node.js Example
Bash / OpenSSL (compare hex digest)
Matches the server’ssha256= hex computation when given the exact raw UTF-8 POST body ($BODY) and $WEBHOOK_SECRET:
Python Example
Common webhook mistakes
- Skipping signature verification — never trust unsigned or unvalidated payloads when a secret applies.
- Assuming synchronous completion — polls return before terminal outcomes;
verification.completedis async. - Ignoring idempotency —
X-Event-Idcan repeat across retries (retryAttempts); dedupe deliveries. - Missing event handlers — implement
verification.completed,verification.action_required,verification.notificationas needed for your UX.
Integration Examples
Express.js Webhook Handler
Flask Webhook Handler (Python)
Retry Logic
Production: The API automatically retries failed webhook deliveries:- Retry attempts: Configurable (default: 3, max: 10)
- Backoff strategy: Exponential backoff with jitter
- Retry timing: 2^attempt seconds (e.g., 2s, 4s, 8s)
- Client errors (4xx): Not retried
- Server errors (5xx): Retried with exponential backoff
Best Practices
1. Always Verify Signatures
Never process webhooks without verifying the HMAC signature. This ensures the webhook is from SNH AI and hasn’t been tampered with.2. Respond Quickly
Respond with HTTP 200 status code as soon as you receive the webhook. Perform heavy processing asynchronously.3. Handle Idempotency
Webhooks may be retried, so ensure your handlers are idempotent. Use theX-Event-Id header to track processed events.
4. Use HTTPS Endpoints
Always use HTTPS endpoints for webhook delivery. The API only sends to HTTPS URLs.5. Monitor Webhook Delivery
Track delivery status and set up alerts for failed deliveries. Monitor your logs for webhook processing errors.6. Store Secrets Securely
Never hardcode webhook secrets. Use environment variables or secure secret management services.7. Test with Webhook Testing Tools
Use tools like ngrok or webhook.site to test your webhook endpoints during development.Error Handling
HTTP Status Codes
Your webhook endpoint should return appropriate HTTP status codes:- 200 OK: Webhook received and processed successfully
- 400 Bad Request: Invalid payload format (not retried)
- 401 Unauthorized: Invalid signature (not retried)
- 500 Internal Server Error: Server error (will be retried)
Handling Failures
If your endpoint fails to process a webhook:- The API will retry based on your
retryAttemptsconfiguration - After all retries are exhausted, the webhook is marked as failed
- You can check webhook delivery status via the API (if available)
- Consider implementing a dead-letter queue for failed webhooks
Testing Webhooks
Using ngrok
Using webhook.site
- Visit webhook.site
- Copy the unique URL provided
- Use it in your webhook configuration for testing
- View incoming webhooks in real-time
Troubleshooting
Webhooks Not Received
- Check endpoint URL: Ensure your endpoint is accessible via HTTPS
- Verify signature: Check that your secret matches the one in the webhook config
- Check firewall: Ensure your server allows incoming connections from Theary
- Review logs: Check API logs for webhook delivery errors
Invalid Signature Errors
- Verify secret: Ensure the secret in your code matches the one in webhook config
- Check payload format: Ensure you’re serializing the payload correctly
- Encoding: Verify HMAC-SHA256 is using the correct encoding (hex)
Webhooks Received Multiple Times
- Idempotency: Implement idempotency checks using
X-Event-Id - Retry logic: This is expected behavior - the API retries failed deliveries
- Duplicate detection: Store processed event IDs to prevent duplicate processing
Related Documentation
- WebhookConfigDto Schema - Webhook configuration schema
- Create Order - Creating orders with webhook configuration
- Error Handling - Error handling best practices