Skip to main content

Webhook Integration Guide

Download this 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

Webhooks are signed and retried according to retryAttempts. These delivery mechanics — retries, signing, and backoff — are identical in sandbox and production; the delivery service has no environment-conditional logic for them. Any “best-effort” feel to sandbox testing is a function of how you configure your own test organization and webhook receiver, not a platform guarantee that differs by environment. See Environments.

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 organization program; illustrative fragments only: Employment (verified)
Education (verified)
Action required (third-party / manual)
Complete field lists: Webhook events.

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
For complete details on event types, payload structures, and when events are triggered, see Webhook Events.

Webhook Configuration

Webhooks can be configured at two levels:

Request-Level Configuration

Configure webhooks per verification request:

Organization-level Configuration

Configure webhooks at the organization level (applies to all verifications unless overridden): Contact your SNH AI account manager to configure organization-level webhook settings.

Endpoint Resolution

Webhook configuration comes from two sources: your organization-level settings (stored against your account) and the request-level webhookConfig on a given order. These are not an all-or-nothing override — they are merged field by field:
  • enabled, secret, retryAttempts: the request-level value is used if present, otherwise the organization-level value applies.
  • closeoutEndpoints: merged per search type key. If the request supplies targets for EMPLOYMENT but not EDUCATION, the request’s EMPLOYMENT targets fully replace the organization’s EMPLOYMENT targets, while the organization’s EDUCATION targets still apply — even though the request did supply a closeoutEndpoints object overall. Providing config for one search type never suppresses the organization’s config for a different, unmentioned search type.
  • fallbackEndpoint: replaced wholesale, not merged per-field. If the request supplies a fallbackEndpoint, it fully replaces the organization’s fallback; otherwise the organization’s fallback is used.
Once the config is merged, the API resolves delivery targets per event and search type, independently:
  1. Type-specific targets: targets configured under closeoutEndpoints[searchType] that allow the event (events array) are included.
  2. Fallback targets: targets under fallbackEndpoint that allow the event and, if the target sets searchTypes, include the resolved search type, are also included.
Type-specific and fallback targets are not mutually exclusive tiers — a fallback target can still receive an event alongside a type-specific target for the same search type if both match the event’s filters. The API delivers to every matching target concurrently. Notes:
  • If events is omitted on a target, it will receive only verification.completed (backward compatible).
  • Per-target headers are merged into the request headers. If basicAuth is set, an Authorization: Basic ... header is included.

Webhook Payload Structure

All webhook payloads follow a consistent structure with event, 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: Notes:
  • If neither the organization config nor the target defines a signing secret, X-Webhook-Signature is 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’s sha256= hex computation when given the exact raw UTF-8 POST body ($BODY) and $WEBHOOK_SECRET:

Python Example

For detailed event payload structures and examples, see Webhook Events.

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.completed is async.
  • Ignoring idempotencyX-Event-Id can repeat across retries (retryAttempts); dedupe deliveries.
  • Missing event handlers — implement verification.completed, verification.action_required, verification.notification as needed for your UX.

Integration Examples

Express.js Webhook Handler

Flask Webhook Handler (Python)

Retry Logic

The API automatically retries failed webhook deliveries, identically in sandbox and production:
  • 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
Rely on this retry behavior for both environments when validating handlers and building alerting.

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 the X-Event-Id header to track processed events.

4. Use HTTPS Endpoints

Always use HTTPS endpoints for webhook delivery in production. Non-production environments may also accept http://localhost and http://127.0.0.1 for local testing.

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:
  1. The API retries based on your retryAttempts configuration
  2. After all retries are exhausted, delivery stops for that attempt
  3. Make your handler idempotent with X-Event-Id, and consider a dead-letter queue for events you could not process
  4. Prefer polling Get specific search when you need to reconcile search state — webhook delivery history is not exposed as a separate order-events API

Testing Webhooks

Using ngrok

Using webhook.site

  1. Visit webhook.site
  2. Copy the unique URL provided
  3. Use it in your webhook configuration for testing
  4. View incoming webhooks in real-time

Troubleshooting

Webhooks Not Received

  1. Check endpoint URL: Ensure your endpoint is accessible via HTTPS
  2. Verify signature: Check that your secret matches the one in the webhook config
  3. Check firewall: Ensure your server allows incoming connections from SNH AI
  4. Review logs: Check API logs for webhook delivery errors

Invalid Signature Errors

  1. Verify secret: Ensure the secret in your code matches the one in webhook config
  2. Check payload format: Ensure you’re serializing the payload correctly
  3. Encoding: Verify HMAC-SHA256 is using the correct encoding (hex)

Webhooks Received Multiple Times

  1. Idempotency: Implement idempotency checks using X-Event-Id
  2. Retry logic: This is expected behavior - the API retries failed deliveries
  3. Duplicate detection: Store processed event IDs to prevent duplicate processing

Footnotes

  1. “Theary” is the product/platform name reflected in this wire-level identifier. It refers to the same product as “SNH AI,” the company name used elsewhere in these docs.