> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getoliver.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Service Reminder Webhook

> Receive notifications about due service reminders

## 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:

<ResponseField name="practice_id" type="string" required>
  Oliver's unique identifier for the veterinary practice.
</ResponseField>

<ResponseField name="practice_name" type="string" required>
  The name of the veterinary practice associated with the reminder.
</ResponseField>

<ResponseField name="id" type="string" required>
  Oliver's unique identifier for the service reminder group.
</ResponseField>

<ResponseField name="client_id" type="string" required>
  Oliver's unique identifier for the client who should be notified.
</ResponseField>

<ResponseField name="remote_client_id" type="string">
  The unique identifier for the client in the PIMS, if applicable.
</ResponseField>

<ResponseField name="patient_id" type="string" required>
  Oliver's unique identifier for the patient (pet) who has services due.
</ResponseField>

<ResponseField name="remote_patient_id" type="string">
  The unique identifier for the patient in the PIMS, if applicable.
</ResponseField>

<ResponseField name="notification_rule_name" type="string">
  The name of the notification rule that triggered this webhook.
</ResponseField>

<ResponseField name="due_at" type="string" required>
  The date and time when the service reminder group is due, in ISO 8601 format.
</ResponseField>

<ResponseField name="reminders" type="array" required>
  An array of service reminder objects for the services that are due.

  <Expandable title="Reminder object properties">
    <ResponseField name="id" type="string" required>
      Oliver's unique identifier for this service reminder.
    </ResponseField>

    <ResponseField name="code" type="string">
      The service code identifier from the PIMS, or the display name if no remote ID exists.
    </ResponseField>

    <ResponseField name="description" type="string">
      A human-readable description of the service.
    </ResponseField>

    <ResponseField name="due_at" type="string">
      The date and time when this service is due, in ISO 8601 format.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="group_status" type="string" required>
  The status of the reminders in the group. Possible values: `completed`, `partially_completed`, `deleted`, `incomplete`.
</ResponseField>

<ResponseField name="custom_fields" type="object">
  Optional object containing additional fields for practices with a server ID configured.

  <Expandable title="Custom fields properties">
    <ResponseField name="server_id" type="string">
      The server ID from the practice's metadata.
    </ResponseField>

    <ResponseField name="client_id" type="string">
      A composite identifier combining the remote client ID and server ID in the format `{remote_client_id}-{server_id}`.
    </ResponseField>
  </Expandable>
</ResponseField>

## Example Payload

```json theme={null}
{
  "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

```python theme={null}
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)
```

```javascript theme={null}
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)
  );
}
```

<Warning>
  Always use constant-time comparison functions (like `hmac.compare_digest` in Python or `crypto.timingSafeEqual` in Node.js) to prevent timing attacks.
</Warning>

## 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

<Note>
  If your endpoint fails to respond with a success status code, Oliver may retry the webhook delivery.
</Note>
