Webhooks Configuration Guide¶
This guide explains how to configure webhooks for real-time ticket updates from PSA systems (Freshservice, SuperOps) to HiveMatrix Codex.
Overview¶
By default, Codex polls your PSA system every 5 minutes to check for ticket updates. With webhooks enabled, your PSA can push updates to Codex immediately when tickets change, reducing latency from 5 minutes to under 1 second.
Benefits of Webhooks¶
| Aspect | Polling (Default) | With Webhooks |
|---|---|---|
| Update latency | Up to 5 minutes | < 1 second |
| API calls | 288/day | ~24/day (hourly backup) |
| Deleted ticket detection | 5 min delay | Instant |
| Complexity | Simple | Requires PSA configuration |
Architecture¶
PSA System (Freshservice/SuperOps)
│
│ HTTP POST (on ticket change)
▼
Nexus (443)
│
│ Proxy to internal
▼
Codex (5010)
/webhooks/<provider>/ticket
│
│ Update database
▼
PostgreSQL
│
│ Next refresh
▼
Beacon Dashboard
Configuration¶
Step 1: Generate a Webhook Secret¶
Generate a secure secret key that will authenticate webhook requests:
Save this secret - you'll need it for both Codex and Freshservice configuration.
Step 2: Configure Codex¶
Edit /path/to/hivematrix-codex/instance/codex.conf:
[webhooks]
# Enable webhook receivers
enabled = true
# Secret key (must match what you configure in Freshservice)
secret = YOUR_GENERATED_SECRET_HERE
# Optional: Restrict to specific IPs (comma-separated, leave empty to allow all)
allowed_ips =
# Log payloads for debugging (disable in production)
log_payloads = true
Step 3: Restart Codex¶
Step 4: Verify Webhook Endpoint¶
Test that the webhook endpoint is accessible:
# Health check (no auth required)
curl https://yourdomain.com/codex/webhooks/health
# Test authentication
curl -X POST https://yourdomain.com/codex/webhooks/test \
-H "X-Webhook-Secret: YOUR_SECRET_HERE" \
-H "Content-Type: application/json"
Expected response:
{
"status": "ok",
"message": "Webhook authentication successful",
"source_ip": "x.x.x.x",
"timestamp": "2024-01-15T10:30:00Z"
}
Freshservice Configuration¶
Step 1: Open Workflow Automator¶
- Log into Freshservice as an admin
- Go to Admin (gear icon) → Helpdesk Productivity → Workflow Automator
- Click New Automator → Ticket
Step 2: Create Ticket Updated Workflow¶
Basic Info:
- Title: HiveMatrix Webhook - Ticket Updated
- Description: Send ticket updates to HiveMatrix Codex
Event:
- Select: Ticket is Updated
Conditions (Optional): - You can add conditions to filter which updates trigger webhooks - For all updates, leave conditions empty
Actions:
1. Click Add Action → Trigger Webhook
2. Configure:
- Request Type: POST
- URL: https://yourdomain.com/codex/webhooks/freshservice/ticket
- Encoding: JSON
- Requires Authentication: Yes
- Select API Key
- Header Name: X-Webhook-Secret
- API Key: YOUR_SECRET_HERE
- Click Advanced and enter this JSON payload:
{
"event": "ticket.updated",
"ticket_id": {{ticket.id}},
"subject": "{{ticket.subject}}",
"status_id": {{ticket.status}},
"priority_id": {{ticket.priority}},
"requester_email": "{{ticket.requester.email}}",
"requester_name": "{{ticket.requester.name}}",
"requester_id": {{ticket.requester.id}},
"responder_id": {{ticket.agent.id}},
"group_id": {{ticket.group.id}},
"department_id": {{ticket.department.id}},
"updated_at": "{{ticket.updated_at}}"
}
- Click Save and Activate the workflow
Step 3: Create Ticket Created Workflow¶
Repeat the above steps with:
- Title: HiveMatrix Webhook - Ticket Created
- Event: Ticket is Created
- JSON payload:
{
"event": "ticket.created",
"ticket_id": {{ticket.id}},
"subject": "{{ticket.subject}}",
"status_id": {{ticket.status}},
"priority_id": {{ticket.priority}},
"requester_email": "{{ticket.requester.email}}",
"requester_name": "{{ticket.requester.name}}",
"requester_id": {{ticket.requester.id}},
"responder_id": {{ticket.agent.id}},
"group_id": {{ticket.group.id}},
"department_id": {{ticket.department.id}},
"created_at": "{{ticket.created_at}}",
"updated_at": "{{ticket.updated_at}}"
}
Step 4: Create Ticket Deleted Workflow (Optional)¶
For deleted/spam ticket detection:
- Title: HiveMatrix Webhook - Ticket Deleted
- Event: Ticket status is changed → Status changed to Spam or Deleted
- JSON payload:
{
"event": "ticket.deleted",
"ticket_id": {{ticket.id}},
"status_id": {{ticket.status}},
"updated_at": "{{ticket.updated_at}}"
}
Step 5: Test the Workflow¶
- Create or update a test ticket in Freshservice
- Check Codex logs for webhook receipt:
- Verify the ticket updated in Beacon dashboard
Webhook Endpoints Reference¶
Health Check¶
Returns webhook configuration status (no authentication required).Test Authentication¶
Verifies authentication is working.Freshservice Ticket Webhook¶
POST /webhooks/freshservice/ticket
Headers: X-Webhook-Secret: <secret>
Content-Type: application/json
SuperOps Ticket Webhook (Coming Soon)¶
Placeholder for SuperOps integration.Troubleshooting¶
Webhook Not Received¶
-
Check webhook is enabled:
Should showwebhooks_enabled: true -
Check Freshservice workflow is active:
- Go to Workflow Automator
-
Ensure the workflow shows "Active" status
-
Check Codex logs:
-
Test from command line:
Authentication Failed (401)¶
- Verify the secret in
codex.confmatches the API key in Freshservice - Check for extra spaces or newlines in the secret
- Ensure
X-Webhook-Secretheader is being sent (notAuthorization)
IP Rejected (403)¶
- If using
allowed_ips, verify Freshservice's IP ranges are included - Freshservice uses AWS infrastructure - IPs can change
- Consider leaving
allowed_ipsempty and relying on secret authentication
Webhook Timeout¶
- Freshservice has a 15-second timeout
- If Codex is slow to respond, webhooks may fail
- Check database performance and server load
Rate Limits¶
- Freshservice limit: 1,000 webhook calls per hour
- Retry behavior: Failed webhooks retry 4 times at 3, 5, 9, 17 minute intervals
- Typical usage: ~50-200 tickets/day = well under limit
Security Considerations¶
- Secret Key: Use a strong, randomly generated secret (32+ characters)
- HTTPS: Always use HTTPS for webhook endpoints
- IP Allowlist: Consider restricting to known PSA IP ranges
- Log Payloads: Disable
log_payloadsin production to avoid logging sensitive data - Rate Limiting: Codex applies standard rate limits to webhook endpoints
Reducing Polling After Webhooks¶
Once webhooks are working reliably, you can reduce polling frequency:
Edit codex.conf:
The light sync will still run hourly to catch any webhooks that may have failed.