What are Webhooks?
Webhooks allow you to receive automated notifications when important compliance events occur for your downstream entities and agents. Instead of continuously polling our API for updates, we’ll automatically send HTTP POST requests to your specified endpoint whenever license statuses change or NIPR data is updated.Quick Start
Available Webhook Events
Agent Compliance Status Change
Triggered when an agent’s compliance status changes due to license, appointment, or requirement updates.
Agency Compliance Status Change
Triggered when a downstream entity’s (agency) compliance status changes due to license, appointment, or requirement
updates.
Compliance Data Synchronized
Triggered when NIPR data synchronization completes for an agent or downstream entity.
Producer Agreement Executed
Triggered when a downstream entity and your upstream entity have fully executed a producer agreement.
Planned Webhooks
We plan to build many more webhook events, including:- Downstream entity onboarding
- Downstream entity/agent authority status
- E&O compliance status changes
- E&O/Cyber policy renewals
Payload Envelope
All webhook payloads follow this general structure:| Field | Description |
|---|---|
webhookType | The event type (e.g., AGENT_COMPLIANCE_STATUS_CHANGE) |
upstreamEntityId | Your upstream entity ID |
payload | Event-specific data — see each event’s documentation for details |
Setting Up Your Webhook Endpoint
Your webhook endpoint must:Accept POST requests with JSON payloads
Respond with 2xx status codes (200-299) for successful processing
Respond within 30 seconds to avoid timeout
Handle duplicate events gracefully (use payload content for deduplication)
Verify the
X-Turris-Signature header using your client secretExample Endpoint Response
Webhook Security
All webhook requests are signed using HMAC-SHA256 with your client secret. This allows you to verify that the request originated from Turris and that the payload has not been tampered with. Webhook requests include the following headers:| Header | Description |
|---|---|
Content-Type | application/json |
X-Turris-Signature | HMAC-SHA256 hex signature of the payload |
X-Turris-Timestamp | Unix timestamp (seconds) when the request was signed |
Verifying Webhook Signatures
To verify a webhook request is authentic, recompute the HMAC-SHA256 signature and compare it to theX-Turris-Signature header.
How the Signature is Computed
The signature is computed over the string{timestamp}.{payload}, where:
{timestamp}is the value of theX-Turris-Timestampheader{payload}is the raw JSON request body (as a string)
Verification Example (Node.js)
Usage Example
Event Debouncing & Batching
Compliance status change webhooks use a sliding-window debounce to prevent webhook floods during bulk operations:| Parameter | Value | Description |
|---|---|---|
| Sliding window | 1 minute | Timer resets with each new change event |
| Maximum cap | 30 minutes | Forces delivery even during continuous activity |
- A compliance-relevant change is detected (e.g., license created, appointment updated)
- Turris starts a 1-minute timer for the affected upstream entity
- If another change occurs within that minute, the timer resets
- When 1 minute passes with no new changes (or the 30-minute cap is reached), all accumulated changes are evaluated
- A single webhook is sent containing only the entity/product/state combinations where the compliance status actually changed
Compliance Data Synchronized (
ENTITY_COMPLIANCE_DATA_SYNCHRONIZED) and Producer Agreement Executed
(PRODUCER_AGREEMENT_EXECUTED) webhooks are sent immediately — they are not debounced, since each is a discrete,
one-time event.Batched Payloads
Because changes are debounced, a single webhook delivery may contain multiple status changes in thepayload array. Each element represents a distinct entity + product + state combination that changed. Design your handler to iterate over the full array.
Reliable Delivery
Automatic Retries
If your endpoint is unavailable or returns an error, we’ll automatically retry delivery using exponential backoff:| Attempt | Timing |
|---|---|
| 1 | Immediate |
| 2 | ~5 seconds |
| 3 | ~30 seconds |
| 4+ | Exponential backoff continues |
Manual Resend
You can manually resend any webhook event through the Turris Web App. This will cancel any pending automatic retries to prevent duplicates.Testing Your Integration
You can test your webhook integration in the following ways:- Sandbox environment: Configure webhooks with your development endpoint and trigger compliance changes in a sandbox environment to receive real webhook payloads
- Manual resend: Use the Turris Web App to resend any previously delivered webhook event to your endpoint
Monitoring & Troubleshooting
Delivery History
In our web app you can view the status of all webhook deliveries, including:- Success/failure status
- Response times
- Number of retry attempts
- Error details
Common Issues
| Issue | Solution |
|---|---|
| Timeouts | Ensure your endpoint responds within 30 seconds |
| SSL Errors | Use a valid SSL certificate for HTTPS endpoints |
| Signature Verification Failures | Verify your client secret is correct and you’re signing {timestamp}.{rawBody} |
| Duplicate Processing | Use payload content (e.g., entity ID + state + product) for deduplication |
Best Practices
Idempotency
Use payload content (entity ID, state, product) to detect and handle duplicate deliveries gracefully.
Logging
Log all incoming webhook events for debugging and audit purposes.
Async Processing
Respond quickly (2xx status) then process the event asynchronously to avoid timeouts.
Security
Store your client secret securely and consider IP whitelisting for additional security.