Skip to main content

Overview

The Service Reminder webhook notifies your system when a notification rule is triggered indicating that a service reminder is due for a patient. Oliver sends an HTTP POST request to your configured endpoint with a JSON payload containing the reminder details.

Payload Structure

The webhook payload is sent as a JSON object with the following structure:
practice_id
string
required
Oliver’s unique identifier for the veterinary practice.
practice_name
string
required
The name of the veterinary practice associated with the reminder.
id
string
required
Oliver’s unique identifier for the service reminder group.
client_id
string
required
Oliver’s unique identifier for the client who should be notified.
remote_client_id
string
The unique identifier for the client in the PIMS, if applicable.
patient_id
string
required
Oliver’s unique identifier for the patient (pet) who has services due.
remote_patient_id
string
The unique identifier for the patient in the PIMS, if applicable.
notification_rule_name
string
The name of the notification rule that triggered this webhook.
due_at
string
required
The date and time when the service reminder group is due, in ISO 8601 format.
reminders
array
required
An array of service reminder objects for the services that are due.
group_status
string
required
The status of the reminders in the group. Possible values: completed, partially_completed, deleted, incomplete.
custom_fields
object
Optional object containing additional fields for practices with a server ID configured.

Example Payload

{
  "practice_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "practice_name": "Happy Paws Veterinary Clinic",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "client_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "remote_client_id": "12345",
  "patient_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
  "remote_patient_id": "67890",
  "notification_rule_name": "2 weeks before due",
  "due_at": "2025-01-15T05:00:00-05:00",
  "reminders": [
    {
      "id": "d4e5f6a7-b8c9-0123-def0-234567890123",
      "code": "WELL",
      "description": "Annual Wellness Exam",
      "due_at": "2025-01-15T05:00:00-05:00"
    },
    {
      "id": "e5f6a7b8-c9d0-1234-ef01-345678901234",
      "code": "VAC002",
      "description": "Rabies Vaccination",
      "due_at": "2025-01-20T05:00:00-05:00"
    }
  ],
  "group_status": "incomplete"
}

Verifying Webhook Signatures

To ensure that webhook requests are genuinely from Oliver and have not been tampered with, each request includes a signature in the X-Webhook-Signature header. You should verify this signature before processing the payload.

Signature Verification Process

  1. Extract the X-Webhook-Signature header from the request
  2. Compute an HMAC-SHA256 hash of the raw request body using your webhook secret
  3. Compare the computed signature with the one in the header

Example Verification

import hmac
import hashlib

def verify_webhook_signature(payload: bytes, signature: str, secret: str) -> bool:
    expected_signature = hmac.new(
        secret.encode('utf-8'),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected_signature, signature)
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf-8')
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature),
    Buffer.from(signature)
  );
}
Always use constant-time comparison functions (like hmac.compare_digest in Python or crypto.timingSafeEqual in Node.js) to prevent timing attacks.

Handling the Webhook

When receiving a service reminder webhook, your endpoint should:
  1. Verify the webhook signature
  2. Respond with a 200 OK status code to acknowledge receipt
  3. Process the reminder asynchronously if needed to avoid timeouts
  4. Use the client_id and patient_id to look up contact information
  5. Send appropriate reminder notifications to the client
If your endpoint fails to respond with a success status code, Oliver may retry the webhook delivery.