Webhooks Integration Guide
This guide shows you how to set up and handle webhooks to receive real-time notifications from Oho about accreditation updates, ICR completions, and other important events.
Overview
Webhooks allow Oho to push event notifications to your application in real-time. Instead of polling the API for updates, your application receives HTTP POST requests from Oho whenever important events occur.
Base URL: https://app.weareoho.com/api
Authentication: Required (Bearer token)
Content-Type: application/json
Key Benefits:
- ✅ Real-time event notifications
- ✅ Automatic retry logic with exponential backoff
- ✅ Secure HMAC-SHA1 signature verification
- ✅ Event history tracking
- ✅ Support for multiple webhook endpoints
- ✅ Per-organization webhook configuration
Before setting up webhooks, ensure you have:
- An active Oho account with API access
- A valid API authentication token (see Authentication Guide)
- A publicly accessible HTTPS endpoint to receive webhooks
- Ability to respond within 10 seconds
Understanding Webhooks
What are Webhooks?
A webhook is an HTTP callback that Oho makes to your server when specific events occur. Think of it as a "reverse API" - instead of you requesting data from Oho, Oho sends data to you automatically when something important happens.
When to Use Webhooks
Use webhooks for:
- WWC Scan Results - Get notified when background check validations complete
- Accreditation Updates - Receive alerts when accreditations are updated, expire, or are revoked
- Status Changes - Track changes to constituent or accreditation status in real-time
Webhook Lifecycle
Event Occurs → Oho Creates Webhook → HTTP POST to Your Endpoint → Your Response
↓ (if failed)
Retry with Backoff (up to 5 times)
Oho operations like WWC scans are asynchronous. Webhooks are the recommended way to receive results without constant polling.
Setting Up Webhooks
Webhooks must be enabled for your Oho account before you can use them. Contact Oho Support to request webhook access for your organization. Once enabled, you can manage webhooks via the UI or API.
Managing Webhooks in the Oho UI
The easiest way to manage webhooks is through the Oho web interface:
Navigation: Settings > Webhooks
Available Actions:
- ✅ Create new webhooks with a user-friendly form
- ✅ View all configured webhooks and their status
- ✅ Edit webhook URLs, labels, and settings
- ✅ Enable/disable webhooks with a toggle
When to Use the UI:
- Setting up your first webhook
- Troubleshooting delivery issues
- Reviewing event history
- Quick configuration changes
When to Use the API:
- Automated webhook provisioning
- Managing webhooks programmatically
- Integrating webhook setup into your deployment process
- Bulk operations across multiple webhooks
Creating a Webhook via API
Endpoint: POST /api/webhooks
Example Request:
curl -X POST https://app.weareoho.com/api/webhooks \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-domain.com/webhooks/oho",
"label": "Production Webhook Handler",
"active": true,
"organization": {
"id": 123
}
}'
Request Fields:
url(required) - Your webhook endpoint URL (must be HTTPS)label(required) - Descriptive name for this webhookactive(optional) - Whether webhook is active (default: true)organization.id(optional) - Specific organization IDusername(optional) - HTTP Basic Auth username for your endpointpassword(optional) - HTTP Basic Auth password for your endpoint
Response:
{
"active": true,
"id": 210,
"label": "Production Webhook Handler",
"organization": {
"id": 123
},
"secret": "SS8arjMQmDh9SH6Y/oUFbTWYNdxBsEcl",
"status": "untriggered",
"url": "https://your-domain.com/webhooks/oho"
}
Response Fields:
id- Unique webhook identifier for updates/deletessecret- CRITICAL - Use this to verify webhook authenticity (see Security section)status- Current webhook status (active, failed, etc.)
The secret is only returned once during webhook creation. Store it securely - you'll need it to verify incoming webhooks. If lost, you'll need to delete and recreate the webhook.
Managing Webhooks
List All Webhooks
curl -X GET "https://app.weareoho.com/api/webhooks?organization_id=123" \
-H "Authorization: Bearer YOUR_TOKEN"
Response:
{
"items": [
{
"id": 210,
"url": "https://your-domain.com/webhooks/oho",
"label": "Production Webhook Handler",
"active": true,
"status": "active"
}
],
"total": 1,
}
Update a Webhook
curl -X PATCH https://app.weareoho.com/api/webhooks/210 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-domain.com/webhooks/oho-v2",
"label": "Production Webhook Handler v2",
"active": true
}'
Webhook Event Types
Oho sends webhooks for various events. Each webhook includes an event field to identify the type.
Accreditation Validation Complete
Event: accreditation_validation
Sent when a WWC scan or other accreditation validation completes.
Example Payload:
{
"event": "accreditation_validation",
"correlation_id": "a8f5d2e1-3c4b-4d5e-8f9a-1b2c3d4e5f6a",
"message_id": 12345,
"content": {
"notification_type": "accreditation-result",
"org_id": 123,
"previous": null,
"current": {
"id": 5354,
"identifier": "1076131A",
"type": "vicwwc",
"status": "active",
"status_flags": {
"current": true,
"may_engage": true,
"expired": false,
"expiring": false
},
"registry_response": {
"may_engage": true,
"response": ["Current", "May Engage"],
"oho_status": "active",
"card_type": "employee_wwc"
}
},
"constituent": {
"id": 113767,
"first_name": "Cameron",
"surname": "Schafer",
"email": "cameron@example.com"
}
}
}
Handling Webhooks
Endpoint Requirements
Your webhook endpoint must:
- ✅ Be publicly accessible via HTTPS (HTTP not supported)
- ✅ Respond with
200 OKwithin 10 seconds - ✅ Handle duplicate deliveries idempotently
- ✅ Verify the
X-Hub-Signatureheader - ✅ Process data asynchronously after responding
If your endpoint doesn't respond within 10 seconds, Oho will consider the delivery failed and schedule a retry. Keep your endpoint fast by responding immediately and processing data asynchronously.
Processing Pattern
Best Practice Flow:
- Receive webhook POST request
- Verify signature immediately
- Store raw payload (optional but recommended)
- Respond
200 OKquickly - Process data asynchronously (queue, background job, etc.)
Handling Duplicate Deliveries
Webhooks may be delivered more than once (network issues, retries, etc.). Ensure your processing is idempotent.
Strategies:
- Use
message_idas a unique key to track processed webhooks - Use
correlation_idfor WWC scans to match with your original request - Check database state before applying updates
- Use database transactions with unique constraints
Common Workflows
Workflow 1: WWC Scan Result Handling
Submit WWC Scan → API Returns correlation_id → Store correlation_id
↓
Wait for webhook
↓
Receive accreditation_validation event
↓
Match by correlation_id
↓
Update internal records
↓
Notify relevant parties
Workflow 2: Expiry Monitoring
Receive accreditation_validation webhook → Check if expiring/expired
↓
Update constituent status
↓
Trigger renewal workflow
↓
Notify manager and constituent
Troubleshooting
Webhook Not Receiving Events
Problem: Created webhook but not receiving any events
Solutions:
- ✅ Verify webhook is active:
GET /api/webhooks - ✅ Check webhook URL is publicly accessible (test with curl from external server)
- ✅ Ensure endpoint responds to POST requests
- ✅ Verify HTTPS is configured correctly (not self-signed certificate)
- ✅ Check firewall rules allow incoming connections
- ✅ Review webhook event history:
GET /api/webhooks/{id}/events
Webhooks Timing Out
Problem: Webhooks showing timeout errors in event history
Solutions:
- ✅ Ensure endpoint responds within 10 seconds
- ✅ Move slow processing to background jobs
- ✅ Check for database connection pooling issues
- ✅ Monitor server resources (CPU, memory)
- ✅ Implement proper async handling
Duplicate Webhook Processing
Problem: Same webhook processed multiple times
Solutions:
- ✅ Implement idempotency using
message_id - ✅ Use database transactions
- ✅ Add unique constraints on key fields
- ✅ Check for processing before applying updates
FAQ
Q: Can I have multiple webhook endpoints?
A: Yes, you can create multiple webhooks. Each can have a different URL and label. All active webhooks will receive events.
Q: What happens if my endpoint is down?
A: Oho will retry up to 5 times with exponential backoff (30s, 2min, 10min, 1hr, 6hr). After 5 failures, the webhook is marked as failed and you can manually retry from the dashboard.
Q: How do I test webhooks locally?
A: Use ngrok to expose your local development server to the internet. Create a webhook pointing to your ngrok HTTPS URL.
Q: Can I replay/retry old webhooks?
A: You can view webhook event history via GET /api/webhooks/{id}/events. For failed deliveries, you can manually trigger retries from your dashboard.
Q: What's the difference between message_id and correlation_id?
A:
message_id- Unique ID for the webhook delivery itself (use for idempotency)correlation_id- Links webhook back to your original API request (e.g., WWC scan submission)
Q: Can I filter which events a webhook receives?
A: Currently, webhooks receive all event types for your organization. Implement filtering in your webhook handler based on the event field.
Q: How long are webhook events stored?
A: Webhook event history is available through the API. Contact support for specific retention policies.
Related Documentation
- WWC Integration Guide - Working with Children Checks integration (uses webhooks)
- ICR Integration Guide - Information Capture Requests (uses webhooks)
- API Reference - Webhooks - Complete webhook API specification
- Authentication Guide - API authentication setup
Support
For questions or issues with webhook integration:
- Check webhook event history:
GET /api/webhooks/{id}/events - Review server logs for signature verification failures
- Test endpoint accessibility from external sources
- Contact Oho support with your webhook ID and example
message_id
Version: 1.0 Last Updated: 2026-01-23 Status: Production Ready