API Reference
Webhooks
Receive real-time event notifications from NeuralRev via webhooks.
NeuralRev sends real-time HTTP notifications to your server when events occur. Configure webhook endpoints in Settings > Webhooks in your dashboard.
- Register a webhook URL and select the events you want to receive
- When an event occurs, NeuralRev sends an HTTP
POST to your URL with the event payload
- Your endpoint should respond with a
2xx status code within 10 seconds
Each webhook delivery includes these headers:
| Header | Description |
|---|
X-Webhook-ID | Unique delivery ID (use for deduplication) |
X-Webhook-Event | Event type (e.g., patient.created) |
X-Webhook-Timestamp | Unix timestamp (seconds) when the delivery was sent |
X-Webhook-Signature | HMAC-SHA256 signature prefixed with sha256= |
User-Agent | NeuralRev-Webhooks/1.0 |
Content-Type | application/json |
Every webhook is signed using your endpoint's secret (prefixed with whsec_). Always verify signatures to ensure the payload is authentic.
- Extract the timestamp from
X-Webhook-Timestamp
- Concatenate the timestamp and raw request body:
{timestamp}.{body}
- Compute HMAC-SHA256 using your webhook secret
- Compare with the signature from
X-Webhook-Signature (after removing the sha256= prefix)
const crypto = require('crypto');
function verifyWebhook(body, secret, timestamp, signature) {
const expected = crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + body)
.digest('hex');
return 'sha256=' + expected === signature;
}
// In your webhook handler:
app.post('/webhooks/neuralrev', (req, res) => {
const timestamp = req.headers['x-webhook-timestamp'];
const signature = req.headers['x-webhook-signature'];
const body = req.rawBody; // raw string body
if (!verifyWebhook(body, process.env.WEBHOOK_SECRET, timestamp, signature)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(body);
// Process the event...
res.status(200).json({ received: true });
});
import hmac
import hashlib
def verify_webhook(body: str, secret: str, timestamp: str, signature: str) -> bool:
message = f"{timestamp}.{body}"
expected = hmac.new(
secret.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
return f"sha256={expected}" == signature
- Failed deliveries (non-2xx response or timeout) are retried up to 3 times
- Retries use exponential backoff
- You can manually retry individual failed deliveries from the webhook delivery log in Settings
All events share a common envelope:
{
"event": "patient.created",
"entity_id": "PAT-001",
"data": { ... },
"timestamp": "2026-01-15T09:30:00.000Z"
}
| Field | Type | Description |
|---|
event | string | The event type identifier |
entity_id | string | Your integration id for the record |
data | object | Entity fields matching the integration upsert schema |
timestamp | string | ISO 8601 timestamp of the event |
| Event | Trigger |
|---|
patient.created | New patient record created |
patient.updated | Patient record modified (includes activate/deactivate) |
| Event | Trigger |
|---|
provider.created | New provider created |
provider.updated | Provider modified (includes activate/deactivate) |
| Event | Trigger |
|---|
facility.created | New facility created |
facility.updated | Facility modified (includes activate/deactivate) |
| Event | Trigger |
|---|
payer.created | New payer created |
payer.updated | Payer modified |
| Event | Trigger |
|---|
encounter.created | New encounter created |
encounter.updated | Encounter modified |
| Event | Trigger |
|---|
encounter_document.created | Document added to an encounter |
encounter_document.deleted | Document removed from an encounter |
| Event | Trigger |
|---|
charge_capture.created | Charge lines created or bulk-saved |
charge_capture.updated | Charge line modified |
charge_capture.deleted | Charge line removed |
| Event | Trigger |
|---|
claim.submitted | Claim submitted to clearinghouse |
eligibility.completed | Eligibility verification finished |
{
"event": "patient.created",
"entity_id": "PAT-001",
"data": {
"id": "PAT-001",
"first_name": "Jane",
"last_name": "Doe",
"date_of_birth": "1990-01-15T00:00:00Z",
"gender": "female",
"phone": "5551234567",
"email": "jane.doe@example.com",
"ssn_last4": "1234",
"address_line_1": "123 Main St",
"city": "Springfield",
"state": "IL",
"zip_code": "62701",
"country": "US",
"is_active": true
},
"timestamp": "2026-01-15T09:30:00.000Z"
}
{
"event": "claim.submitted",
"entity_id": "RH-12345",
"data": {
"encounter_id": "ENC-001",
"patient_id": "PAT-001",
"provider_id": "PROV-001",
"claim_id": "01JK2ABCDEFGHIJKLMNOPQRST",
"external_claim_id": "RH-12345",
"result": {
"claimId": "01JK2ABCDEFGHIJKLMNOPQRST",
"trackingId": "RH-12345",
"status": "submitted",
"clearinghouse": "stedi",
"totalCharge": 150
}
},
"timestamp": "2026-01-15T09:30:00.000Z"
}
{
"event": "eligibility.completed",
"entity_id": "PAT-001",
"data": {
"patient_id": "PAT-001",
"provider_id": "PROV-001",
"results": [
{
"insuranceType": "primary",
"result": {
"provider": "stedi",
"status": "active",
"member": {
"memberId": "MEM123",
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "1990-01-15"
},
"plan": {
"payerName": "Blue Cross Blue Shield",
"payerId": "BCBS",
"planName": "PPO Gold",
"planType": "PPO",
"groupNumber": "GRP-100"
},
"coverage": {
"active": true,
"effectiveDate": "2024-01-01",
"terminationDate": null,
"serviceTypes": ["30"],
"benefitSummary": []
}
}
}
]
},
"timestamp": "2026-01-15T09:30:00.000Z"
}
- Create a webhook endpoint in Settings > Webhooks
- Click Test to send a sample payload to your endpoint
- View Delivery Logs to inspect the full request and response
- Use Retry on failed deliveries to resend them
For local development, use a tunneling service (e.g., ngrok) to expose your local server to receive webhook deliveries.