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

# Events

> Webhook event types and payload structures

# Webhook Events

RxScale sends webhooks for the following event types:

| Event Type                       | Description                                                    |
| -------------------------------- | -------------------------------------------------------------- |
| `pharmacy_order_created`         | A new pharmacy order was created and assigned to your pharmacy |
| `pharmacy_order_updated`         | An existing pharmacy order's status changed                    |
| `pharmacy_sku_stock_updated`     | A pharmacy SKU's stock level changed                           |
| `appointment_reminder_due`       | A scheduled appointment reminder became due                    |
| `patient_doctor_meeting_updated` | A patient-doctor meeting changed lifecycle state               |

## HTTP Headers

Every webhook request includes the following HTTP headers:

| Header                | Description                                                                    |
| --------------------- | ------------------------------------------------------------------------------ |
| `Content-Type`        | Always `application/json`                                                      |
| `X-Webhook-Event`     | The event type (e.g. `pharmacy_order_created`)                                 |
| `X-Webhook-Signature` | HMAC-SHA256 signature of the request body (see [Security](/webhooks/security)) |

If you configured a custom header when creating the subscription, it will also be included.

***

## pharmacy\_order\_created

Sent when a new pharmacy order is created and assigned to your pharmacy.

**Possible `status` values:** `init`, `waiting for pharmacy`, `pending review`, `in-progress`, `ready_for_pickup`, `completed`

### Payload Example

```json theme={null}
{
  "event_type": "pharmacy_order_created",
  "timestamp": 1711900000,
  "payload_version": "1",
  "data": {
    "uid": "po-abc123",
    "status": "init",
    "name": "#1001",
    "data": {},
    "external_status": "OPEN",
    "created_at": 1711899000,
    "updated_at": 1711899000,
    "deleted_at": null,
    "pharmacy": {
      "uid": "ph-xyz",
      "display_name": "City Pharmacy"
    },
    "order": {
      "uid": "ord-123",
      "delivery_address": {
        "first_name": "Max",
        "last_name": "Mustermann",
        "street": "Hauptstr.",
        "house_number": "1",
        "zip_code": "10115",
        "city": "Berlin",
        "country": "Germany",
        "additional_address": null,
        "province": null
      },
      "invoice_address": {
        "first_name": "Max",
        "last_name": "Mustermann",
        "street": "Hauptstr.",
        "house_number": "1",
        "zip_code": "10115",
        "city": "Berlin",
        "country": "Germany",
        "additional_address": null,
        "province": null
      },
      "shipping_costs_amount": 499,
      "shipping_costs_currency": "EUR",
      "priority": 5
    },
    "delivery_type": {
      "uid": "dt-001",
      "display_name": "Standard Shipping",
      "identifier": "standard"
    },
    "shop_shipping_methods": [
      {
        "uid": "ssm-001",
        "display_name": "DHL Standard",
        "external_id": "shopify-standard",
        "pharmacy_mapping": {
          "pharmacy_uid": "ph-xyz",
          "shipping_method_identifier_for_pharmacy": "DHL_STANDARD"
        }
      }
    ],
    "order_items": [
      {
        "uid": "oi-789",
        "amount": 1,
        "sku": {
          "uid": "sku-456",
          "display_name": "Medication X 100mg",
          "pzn": "12345678",
          "product_uid": "prod-789",
          "product_display_name": "Medication X",
          "standard_selling_unit": 1.0,
          "unit": "ml",
          "product_handle": "medication-x"
        },
        "pharmacy_sku": {
          "uid": "psku-456",
          "external_id": "EXT-001",
          "price": 1299,
          "stock": 50
        },
        "total_paid_amount": 1299
      }
    ],
    "payouts": [
      {
        "status": "projected",
        "amount": 999,
        "currency": "EUR",
        "component_type": "item_rest",
        "routing_description": "Medication X 100mg item rest",
        "provider_route_id": null,
        "pharmacy_order_uid": "po-abc123",
        "pharmacy_order_name": "#1001",
        "pharmacy_order_created_at": 1711899000,
        "routing_created_at": null
      },
      {
        "status": "projected",
        "amount": 300,
        "currency": "EUR",
        "component_type": "item_markup",
        "routing_description": "Medication X 100mg markup",
        "provider_route_id": null,
        "pharmacy_order_uid": "po-abc123",
        "pharmacy_order_name": "#1001",
        "pharmacy_order_created_at": 1711899000,
        "routing_created_at": null
      },
      {
        "status": "projected",
        "amount": 499,
        "currency": "EUR",
        "component_type": "shipping",
        "routing_description": "Standard Shipping",
        "provider_route_id": null,
        "pharmacy_order_uid": "po-abc123",
        "pharmacy_order_name": "#1001",
        "pharmacy_order_created_at": 1711899000,
        "routing_created_at": null
      }
    ],
    "patient_data": {
      "uid": "pat-123",
      "display_name": "Max Mustermann",
      "email": "max@example.com",
      "date_of_birth": "15.06.1990",
      "phone_number": "+49 170 1234567"
    },
    "doctor_data": {
      "uid": "doc-456",
      "display_name": "Dr. Schmidt"
    },
    "prescription_file": {
      "filename": "prescription_001.pdf",
      "content_base64": "JVBERi0xLjQK..."
    },
    "prepaid": 1
  }
}
```

### Field Reference

| Field                                                                                   | Type            | Description                                                                                                                                                                                                                                                                                    |
| --------------------------------------------------------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data.uid`                                                                              | string          | Pharmacy order UID                                                                                                                                                                                                                                                                             |
| `data.status`                                                                           | string          | Current order status                                                                                                                                                                                                                                                                           |
| `data.name`                                                                             | string or null  | Human-readable order name (e.g. `#1001`)                                                                                                                                                                                                                                                       |
| `data.data`                                                                             | object          | Custom data attached to the order                                                                                                                                                                                                                                                              |
| `data.external_status`                                                                  | string          | External status identifier                                                                                                                                                                                                                                                                     |
| `data.created_at`                                                                       | integer         | Unix timestamp of creation                                                                                                                                                                                                                                                                     |
| `data.updated_at`                                                                       | integer         | Unix timestamp of last update                                                                                                                                                                                                                                                                  |
| `data.deleted_at`                                                                       | integer or null | Unix timestamp of soft-deletion, or `null`                                                                                                                                                                                                                                                     |
| `data.pharmacy`                                                                         | object          | Pharmacy summary with `uid` and `display_name`                                                                                                                                                                                                                                                 |
| `data.order`                                                                            | object          | Parent order with `uid`, `delivery_address`, and `invoice_address`                                                                                                                                                                                                                             |
| `data.order.shipping_costs_amount`                                                      | integer or null | Shipping costs in cents. `null` when no shipping costs are available.                                                                                                                                                                                                                          |
| `data.order.shipping_costs_currency`                                                    | string or null  | ISO 4217 currency code for shipping costs, such as `EUR`.                                                                                                                                                                                                                                      |
| `data.order.priority`                                                                   | integer         | Priority hint for handling order sooner. Higher = more urgent. `0` means no special priority.                                                                                                                                                                                                  |
| `data.delivery_type`                                                                    | object or null  | Delivery type with `uid`, `display_name`, and `identifier`. Resolved from the connected shop's fulfillment method (configured per shop), otherwise from the receiving pharmacy's default delivery type. `null` when neither is set — do not assume a delivery type is always present.          |
| `data.shop_shipping_methods`                                                            | array           | Shop shipping methods attached to the connected shop order. Empty array when the order has no shop shipping methods.                                                                                                                                                                           |
| `data.shop_shipping_methods[].uid`                                                      | string          | Shop shipping method UID                                                                                                                                                                                                                                                                       |
| `data.shop_shipping_methods[].display_name`                                             | string          | Shop shipping method display name as configured on the shop                                                                                                                                                                                                                                    |
| `data.shop_shipping_methods[].external_id`                                              | string or null  | Identifier of the shipping method on the connected shop (e.g. the Shopify shipping line code)                                                                                                                                                                                                  |
| `data.shop_shipping_methods[].pharmacy_mapping`                                         | object or null  | Per-pharmacy mapping configured in the RxScale pharmacy settings, or `null` when no mapping has been configured for the receiving pharmacy yet. Configure this in the pharmacy *Settings → Shipping method mappings* screen.                                                                   |
| `data.shop_shipping_methods[].pharmacy_mapping.pharmacy_uid`                            | string          | UID of the receiving pharmacy this mapping applies to                                                                                                                                                                                                                                          |
| `data.shop_shipping_methods[].pharmacy_mapping.shipping_method_identifier_for_pharmacy` | string          | Pharmacy-specific identifier the receiving pharmacy expects for this shipping method (e.g. `DHL_STANDARD`). Use this value when handing the order off to your downstream shipping/labelling system.                                                                                            |
| `data.order_items`                                                                      | array           | Items in the order                                                                                                                                                                                                                                                                             |
| `data.order_items[].sku`                                                                | object          | SKU info including `pzn`, `product_uid`, `product_display_name`, `standard_selling_unit`, `unit`, and `product_handle`                                                                                                                                                                         |
| `data.order_items[].sku.standard_selling_unit`                                          | number or null  | Standard selling unit for the SKU                                                                                                                                                                                                                                                              |
| `data.order_items[].sku.unit`                                                           | string or null  | Unit for the SKU, such as `ml` or `g`                                                                                                                                                                                                                                                          |
| `data.order_items[].pharmacy_sku`                                                       | object or null  | Pharmacy-specific SKU data with `uid`, `external_id`, `price` (cents), `stock`                                                                                                                                                                                                                 |
| `data.order_items[].total_paid_amount`                                                  | integer or null | Amount the patient paid for this line item, in cents (gross). `null` when no payment information is available.                                                                                                                                                                                 |
| `data.payouts`                                                                          | array           | Payout components for this pharmacy order where the current pharmacy is the receiver. Paid physical-prescription orders include `projected` previews based on current values and routing configuration. Completed orders include `routed` payouts once a persisted split-payment route exists. |
| `data.payouts[].status`                                                                 | string          | `projected` for an indicative preview, or `routed` for a persisted split-payment route created after pharmacy order completion.                                                                                                                                                                |
| `data.payouts[].amount`                                                                 | integer         | Payout amount in cents.                                                                                                                                                                                                                                                                        |
| `data.payouts[].currency`                                                               | string          | ISO 4217 currency code, such as `EUR`.                                                                                                                                                                                                                                                         |
| `data.payouts[].component_type`                                                         | string          | Payout component. Possible values are `item_rest`, `item_markup`, and `shipping`.                                                                                                                                                                                                              |
| `data.payouts[].routing_description`                                                    | string or null  | Human-readable description of the routed or projected component.                                                                                                                                                                                                                               |
| `data.payouts[].provider_route_id`                                                      | string or null  | Payment provider route identifier. Populated for routed payouts when the provider returned an identifier, and `null` for projected payouts.                                                                                                                                                    |
| `data.payouts[].pharmacy_order_uid`                                                     | string          | UID of the related pharmacy order.                                                                                                                                                                                                                                                             |
| `data.payouts[].pharmacy_order_name`                                                    | string or null  | Human-readable pharmacy order name.                                                                                                                                                                                                                                                            |
| `data.payouts[].pharmacy_order_created_at`                                              | integer         | Unix timestamp when the pharmacy order was created.                                                                                                                                                                                                                                            |
| `data.payouts[].routing_created_at`                                                     | integer or null | Unix timestamp when the split-payment route was created. `null` for `projected` payouts.                                                                                                                                                                                                       |
| `data.patient_data`                                                                     | object or null  | Patient info with `uid`, `display_name`, `email`, `date_of_birth`, `phone_number`                                                                                                                                                                                                              |
| `data.doctor_data`                                                                      | object or null  | Doctor who signed the prescription, with `uid` and `display_name`                                                                                                                                                                                                                              |
| `data.prescription_file`                                                                | object or null  | Signed prescription PDF with `filename` and `content_base64`                                                                                                                                                                                                                                   |
| `data.prepaid`                                                                          | integer         | `1` if the order has a physical (prepaid) prescription, `0` otherwise                                                                                                                                                                                                                          |

<Warning>
  Actual payment routing happens only when the pharmacy order is completed. `projected` payouts in webhook payloads are indicative, only shown for paid physical-prescription orders, and can change before completion. `routed` payout values are only populated after completion and routing exists.
</Warning>

***

## pharmacy\_order\_updated

Sent when an existing pharmacy order's status changes.

The payload structure is identical to `pharmacy_order_created`. The `status` field reflects the new status.

### Payload Example

```json theme={null}
{
  "event_type": "pharmacy_order_updated",
  "timestamp": 1711910000,
  "payload_version": "1",
  "data": {
    "uid": "po-abc123",
    "status": "in-progress",
    "name": "#1001",
    "data": {},
    "external_status": "IN_PROGRESS",
    "created_at": 1711899000,
    "updated_at": 1711910000,
    "deleted_at": null,
    "pharmacy": {
      "uid": "ph-xyz",
      "display_name": "City Pharmacy"
    },
    "order": {
      "uid": "ord-123",
      "delivery_address": {
        "first_name": "Max",
        "last_name": "Mustermann",
        "street": "Hauptstr.",
        "house_number": "1",
        "zip_code": "10115",
        "city": "Berlin",
        "country": "Germany",
        "additional_address": null,
        "province": null
      },
      "invoice_address": {
        "first_name": "Max",
        "last_name": "Mustermann",
        "street": "Hauptstr.",
        "house_number": "1",
        "zip_code": "10115",
        "city": "Berlin",
        "country": "Germany",
        "additional_address": null,
        "province": null
      },
      "shipping_costs_amount": 499,
      "shipping_costs_currency": "EUR",
      "priority": 5
    },
    "delivery_type": {
      "uid": "dt-001",
      "display_name": "Standard Shipping",
      "identifier": "standard"
    },
    "shop_shipping_methods": [
      {
        "uid": "ssm-001",
        "display_name": "DHL Standard",
        "external_id": "shopify-standard",
        "pharmacy_mapping": {
          "pharmacy_uid": "ph-xyz",
          "shipping_method_identifier_for_pharmacy": "DHL_STANDARD"
        }
      }
    ],
    "order_items": [
      {
        "uid": "oi-789",
        "amount": 1,
        "sku": {
          "uid": "sku-456",
          "display_name": "Medication X 100mg",
          "pzn": "12345678",
          "product_uid": "prod-789",
          "product_display_name": "Medication X",
          "standard_selling_unit": 1.0,
          "unit": "ml",
          "product_handle": "medication-x"
        },
        "pharmacy_sku": {
          "uid": "psku-456",
          "external_id": "EXT-001",
          "price": 1299,
          "stock": 50
        },
        "total_paid_amount": 1299
      }
    ],
    "payouts": [
      {
        "status": "projected",
        "amount": 999,
        "currency": "EUR",
        "component_type": "item_rest",
        "routing_description": "Medication X 100mg item rest",
        "provider_route_id": null,
        "pharmacy_order_uid": "po-abc123",
        "pharmacy_order_name": "#1001",
        "pharmacy_order_created_at": 1711899000,
        "routing_created_at": null
      },
      {
        "status": "projected",
        "amount": 300,
        "currency": "EUR",
        "component_type": "item_markup",
        "routing_description": "Medication X 100mg markup",
        "provider_route_id": null,
        "pharmacy_order_uid": "po-abc123",
        "pharmacy_order_name": "#1001",
        "pharmacy_order_created_at": 1711899000,
        "routing_created_at": null
      },
      {
        "status": "projected",
        "amount": 499,
        "currency": "EUR",
        "component_type": "shipping",
        "routing_description": "Standard Shipping",
        "provider_route_id": null,
        "pharmacy_order_uid": "po-abc123",
        "pharmacy_order_name": "#1001",
        "pharmacy_order_created_at": 1711899000,
        "routing_created_at": null
      }
    ],
    "patient_data": {
      "uid": "pat-123",
      "display_name": "Max Mustermann",
      "email": "max@example.com",
      "date_of_birth": "15.06.1990",
      "phone_number": "+49 170 1234567"
    },
    "doctor_data": {
      "uid": "doc-456",
      "display_name": "Dr. Schmidt"
    },
    "prescription_file": {
      "filename": "prescription_001.pdf",
      "content_base64": "JVBERi0xLjQK..."
    },
    "prepaid": 1
  }
}
```

### Organisation-Level Webhooks

When the webhook subscription was created via the Management API (organisation-level), order events include additional data:

* The `sku` objects inside `order_items` and `fulfillment.items` are enriched with Shopify identifiers (`shop_variation_id`, `shop_product_external_id`).
* A `fulfillment` object is added with fulfillment order details.

```json theme={null}
{
  "event_type": "pharmacy_order_updated",
  "timestamp": 1711910000,
  "payload_version": "1",
  "data": {
    "uid": "po-abc123",
    "status": "in-progress",
    "...": "... same fields as above ...",
    "order_items": [
      {
        "uid": "oi-789",
        "amount": 1,
        "sku": {
          "uid": "sku-456",
          "display_name": "Medication X 100mg",
          "pzn": "12345678",
          "product_uid": "prod-789",
          "product_display_name": "Medication X",
          "standard_selling_unit": 1.0,
          "unit": "ml",
          "product_handle": "medication-x",
          "shop_variation_id": "48372910234",
          "shop_product_external_id": "93847261045"
        },
        "pharmacy_sku": {
          "uid": "psku-456",
          "external_id": "EXT-001",
          "price": 1299,
          "stock": 50
        },
        "total_paid_amount": 1299
      }
    ],
    "fulfillment": {
      "uid": "fo-abc123",
      "external_id": "EXT-FO-001",
      "items": [
        {
          "uid": "foi-001",
          "amount": 1,
          "status": "init",
          "external_id": "EXT-FOI-001",
          "order_item": {
            "uid": "oi-789",
            "amount": 1,
            "sku": {
              "uid": "sku-456",
              "display_name": "Medication X 100mg",
              "pzn": "12345678",
              "product_uid": "prod-789",
              "product_display_name": "Medication X",
              "standard_selling_unit": 1.0,
              "unit": "ml",
              "product_handle": "medication-x",
              "shop_variation_id": "48372910234",
              "shop_product_external_id": "93847261045"
            }
          }
        }
      ],
      "order": {
        "uid": "ord-123",
        "shop_order": {
          "uid": "so-456",
          "external_id": "SHOP-789",
          "shop_identifier": "my-shopify-store"
        }
      }
    }
  }
}
```

| Field                                                              | Type           | Description                                   |
| ------------------------------------------------------------------ | -------------- | --------------------------------------------- |
| `data.order_items[].sku.shop_variation_id`                         | string or null | Shopify variant ID                            |
| `data.order_items[].sku.shop_product_external_id`                  | string or null | Shopify product ID                            |
| `data.fulfillment.uid`                                             | string         | Fulfillment order UID                         |
| `data.fulfillment.external_id`                                     | string or null | External identifier for the fulfillment order |
| `data.fulfillment.items[].order_item.sku.shop_variation_id`        | string or null | Shopify variant ID                            |
| `data.fulfillment.items[].order_item.sku.shop_product_external_id` | string or null | Shopify product ID                            |
| `data.fulfillment.order.uid`                                       | string         | Parent order UID                              |
| `data.fulfillment.order.shop_order.uid`                            | string         | Shop order UID                                |
| `data.fulfillment.order.shop_order.external_id`                    | string or null | External shop order identifier                |
| `data.fulfillment.order.shop_order.shop_identifier`                | string         | Shop identifier                               |

<Note>
  The `fulfillment` field and the Shopify identifiers (`shop_variation_id`, `shop_product_external_id`) inside `sku` objects are only present in organisation-level webhook deliveries. Pharmacy-level webhooks do not include these fields.
</Note>

***

## pharmacy\_sku\_stock\_updated

Sent when a pharmacy SKU's stock level changes. This includes:

* Direct stock updates via the Pharmacy API (`PATCH /v1/.../pharmacy_skus/{uid}/stock` or inventory endpoints).
* Automatic stock reduction when a pharmacy order is completed. This fires for both manual completion (via the pharmacy UI / API) **and** automatic completion when RxScale detects the order has reached a shipped or completed state via its status-check integration with the pharmacy's backend. One event is emitted per pharmacy SKU on the completed order.

### Payload Example

```json theme={null}
{
  "event_type": "pharmacy_sku_stock_updated",
  "timestamp": 1711900000,
  "payload_version": "1",
  "data": {
    "uid": "psku-abc123",
    "pharmacy_uid": "ph-xyz",
    "sku_uid": "sku-456",
    "external_id": "EXT-001",
    "price": 1299,
    "stock": 45,
    "reserved_amount": 7,
    "markup": 0,
    "priority": 0,
    "type": "default",
    "created_at": 1711800000,
    "updated_at": 1711900000,
    "deleted_at": null,
    "sku": {
      "uid": "sku-456",
      "display_name": "Medication X 100mg",
      "pzn": "12345678",
      "product_uid": "prod-789",
      "product_display_name": "Medication X",
      "standard_selling_unit": 1.0,
      "unit": "ml",
      "product_handle": "medication-x"
    }
  }
}
```

### Field Reference

| Field                            | Type            | Description                                                                                                                                                                                                   |
| -------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data.uid`                       | string          | Pharmacy SKU UID                                                                                                                                                                                              |
| `data.pharmacy_uid`              | string          | Pharmacy UID                                                                                                                                                                                                  |
| `data.sku_uid`                   | string          | SKU UID                                                                                                                                                                                                       |
| `data.external_id`               | string or null  | External identifier in your own system                                                                                                                                                                        |
| `data.price`                     | integer         | Price in cents                                                                                                                                                                                                |
| `data.stock`                     | integer         | Current stock level                                                                                                                                                                                           |
| `data.reserved_amount`           | integer         | Units reserved against this SKU — sum of order item amounts across all in-flight pharmacy orders (i.e. orders not yet completed or cancelled). Useful to derive available stock as `stock - reserved_amount`. |
| `data.markup`                    | integer         | Markup value                                                                                                                                                                                                  |
| `data.priority`                  | integer         | Priority level                                                                                                                                                                                                |
| `data.type`                      | string          | Pharmacy SKU type                                                                                                                                                                                             |
| `data.created_at`                | integer         | Unix timestamp of creation                                                                                                                                                                                    |
| `data.updated_at`                | integer         | Unix timestamp of last update                                                                                                                                                                                 |
| `data.deleted_at`                | integer or null | Unix timestamp of soft-deletion, or `null`                                                                                                                                                                    |
| `data.sku`                       | object          | Nested SKU and product information                                                                                                                                                                            |
| `data.sku.uid`                   | string          | SKU UID                                                                                                                                                                                                       |
| `data.sku.display_name`          | string          | SKU display name                                                                                                                                                                                              |
| `data.sku.pzn`                   | string          | Pharmazentralnummer (PZN)                                                                                                                                                                                     |
| `data.sku.product_uid`           | string          | Parent product UID                                                                                                                                                                                            |
| `data.sku.product_display_name`  | string or null  | Display name of the parent product                                                                                                                                                                            |
| `data.sku.standard_selling_unit` | number or null  | Standard selling unit for the SKU                                                                                                                                                                             |
| `data.sku.unit`                  | string or null  | Unit for the SKU, such as `ml` or `g`                                                                                                                                                                         |
| `data.sku.product_handle`        | string or null  | URL handle/slug of the parent product                                                                                                                                                                         |

### Organisation-Level Webhooks

When the webhook subscription was created via the Management API (organisation-level), stock events include additional data:

* The `sku` object is enriched with Shopify identifiers (`shop_variation_id`, `shop_product_external_id`).
* A `shop_identifier` field is added at the `data` level.

```json theme={null}
{
  "event_type": "pharmacy_sku_stock_updated",
  "timestamp": 1711900000,
  "payload_version": "1",
  "data": {
    "uid": "psku-abc123",
    "pharmacy_uid": "ph-xyz",
    "sku_uid": "sku-456",
    "external_id": "EXT-001",
    "price": 1299,
    "stock": 45,
    "reserved_amount": 7,
    "markup": 0,
    "priority": 0,
    "type": "default",
    "created_at": 1711800000,
    "updated_at": 1711900000,
    "deleted_at": null,
    "shop_identifier": "my-shopify-store",
    "sku": {
      "uid": "sku-456",
      "display_name": "Medication X 100mg",
      "pzn": "12345678",
      "product_uid": "prod-789",
      "product_display_name": "Medication X",
      "standard_selling_unit": 1.0,
      "unit": "ml",
      "product_handle": "medication-x",
      "shop_variation_id": "48372910234",
      "shop_product_external_id": "93847261045"
    }
  }
}
```

| Field                               | Type           | Description        |
| ----------------------------------- | -------------- | ------------------ |
| `data.shop_identifier`              | string or null | Shop identifier    |
| `data.sku.shop_variation_id`        | string or null | Shopify variant ID |
| `data.sku.shop_product_external_id` | string or null | Shopify product ID |

<Note>
  The `shop_identifier` field and the Shopify identifiers (`shop_variation_id`, `shop_product_external_id`) inside the `sku` object are only present in organisation-level webhook deliveries. Pharmacy-level webhooks do not include these fields.
</Note>

***

## appointment\_reminder\_due

Sent when a configured appointment reminder becomes due. This event is delivered to organisation-level webhook subscriptions only.

### Payload Example

```json theme={null}
{
  "event_type": "appointment_reminder_due",
  "timestamp": 1893452400,
  "payload_version": "1",
  "data": {
    "appointment_uid": "appt-e2e-123",
    "organisation_uid": "org-abc123",
    "shop_uid": "shop-e2e-1",
    "appointment_type_reminder_uid": "reminder-e2e-1",
    "recipient_role": "doctor",
    "recipient_email": "doctor@example.com",
    "recipient_phone_number": "+491701234567",
    "recipient_display_name": "Dr. Grace Hopper",
    "patient_uid": "patient-e2e-1",
    "patient_display_name": "Ada Lovelace",
    "doctor_uid": "doctor-e2e-1",
    "doctor_display_name": "Dr. Grace Hopper",
    "appointment_type_uid": "type-e2e-1",
    "appointment_type_name": "Consultation",
    "visit_reason": "Medication review before changing dosage",
    "start_date": 1893456000,
    "end_date": 1893457800,
    "minutes_before": 60,
    "send_email": true,
    "send_sms": false
  }
}
```

### Field Reference

| Field                                | Type            | Description                                                                |
| ------------------------------------ | --------------- | -------------------------------------------------------------------------- |
| `data.appointment_uid`               | string          | Scheduled appointment UID                                                  |
| `data.organisation_uid`              | string          | UID of the organisation the appointment belongs to                         |
| `data.shop_uid`                      | string or null  | Shop UID associated with the patient, if available                         |
| `data.appointment_type_reminder_uid` | string          | Reminder rule UID                                                          |
| `data.recipient_role`                | string          | Recipient role: `patient`, `doctor`, or `admin`                            |
| `data.recipient_email`               | string or null  | Resolved recipient email, if available                                     |
| `data.recipient_phone_number`        | string or null  | Resolved recipient phone number, if available                              |
| `data.recipient_display_name`        | string or null  | Resolved recipient display name                                            |
| `data.patient_uid`                   | string          | Patient profile UID                                                        |
| `data.patient_display_name`          | string          | Patient display name                                                       |
| `data.doctor_uid`                    | string          | Doctor UID                                                                 |
| `data.doctor_display_name`           | string          | Doctor display name                                                        |
| `data.appointment_type_uid`          | string or null  | Appointment type UID                                                       |
| `data.appointment_type_name`         | string or null  | Appointment type name                                                      |
| `data.visit_reason`                  | string or null  | Optional reason supplied during booking                                    |
| `data.start_date`                    | integer         | Appointment start time (Unix timestamp)                                    |
| `data.end_date`                      | integer or null | Appointment end time (Unix timestamp), if known                            |
| `data.minutes_before`                | integer         | Reminder offset in minutes before the appointment                          |
| `data.send_email`                    | boolean         | Whether RxScale's notification handler should send email for this reminder |
| `data.send_sms`                      | boolean         | Whether RxScale's notification handler should send SMS for this reminder   |

***

## patient\_doctor\_meeting\_updated

Sent when a patient-doctor meeting changes lifecycle state. This event is delivered to organisation-level webhook subscriptions only (registered via the Management API).

**Possible `change` values:**

| Value       | When emitted                                                                                                    |
| ----------- | --------------------------------------------------------------------------------------------------------------- |
| `held`      | A scheduled appointment was held (the meeting window opened)                                                    |
| `confirmed` | A scheduled appointment was confirmed                                                                           |
| `expired`   | A scheduled appointment expired without being joined                                                            |
| `cancelled` | A meeting was cancelled                                                                                         |
| `rebooked`  | A meeting was rebooked (a new meeting replaced this one)                                                        |
| `completed` | A meeting was completed — an on-demand meeting ended, or a doctor recorded a confirmed appointment as completed |
| `no_show`   | A doctor recorded a confirmed appointment as a no-show (the patient did not attend)                             |

<Note>
  Use `change` as the authoritative indicator of what happened. `status` reflects the meeting's current database status and is `null` for on-demand meetings.
</Note>

### Payload Example

```json theme={null}
{
  "event_type": "patient_doctor_meeting_updated",
  "timestamp": 1893456000,
  "payload_version": "1",
  "data": {
    "organisation_uid": "org-abc123",
    "meeting_uid": "m-e2e-1",
    "change": "confirmed",
    "status": "confirmed",
    "meeting_type": "consultation",
    "meeting_format": "digital",
    "start_date": 1893456000,
    "end_date": 1893456900,
    "estimated_duration_minutes": 15,
    "confirmed_at": 1893450000,
    "cancelled_at": null,
    "cancellation_reason": null,
    "visit_reason": "Medication review before changing dosage",
    "expires_at": null,
    "previous_meeting_uid": null,
    "appointment_type_uid": "at-1",
    "doctor_uid": "doc-1",
    "patient_profile_uid": "pat-1"
  }
}
```

### Field Reference

| Field                             | Type            | Description                                                                                                                                   |
| --------------------------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `data.organisation_uid`           | string          | UID of the organisation the meeting belongs to                                                                                                |
| `data.meeting_uid`                | string          | Unique identifier for the meeting                                                                                                             |
| `data.change`                     | string          | The lifecycle transition that triggered this event — see the table above                                                                      |
| `data.status`                     | string or null  | Current status of the meeting. `null` for on-demand meetings; use `change` for logic instead                                                  |
| `data.meeting_type`               | string          | Type of meeting (e.g. `consultation`)                                                                                                         |
| `data.meeting_format`             | string          | Format of the meeting (e.g. `digital`)                                                                                                        |
| `data.start_date`                 | integer or null | Unix timestamp of the scheduled start (scheduled appointments only)                                                                           |
| `data.end_date`                   | integer or null | Unix timestamp of the planned end for scheduled appointments. This is the originally scheduled end time, not the actual end                   |
| `data.estimated_duration_minutes` | integer or null | Estimated duration in minutes                                                                                                                 |
| `data.confirmed_at`               | integer or null | Unix timestamp of when the meeting was confirmed, or `null`                                                                                   |
| `data.cancelled_at`               | integer or null | Unix timestamp of cancellation, or `null`                                                                                                     |
| `data.cancellation_reason`        | string or null  | Reason for cancellation, or `null`                                                                                                            |
| `data.visit_reason`               | string or null  | Optional reason supplied during booking. May also appear in reminder content and synced calendar invite descriptions                          |
| `data.expires_at`                 | integer or null | Unix timestamp after which the meeting link expires, or `null`                                                                                |
| `data.previous_meeting_uid`       | string or null  | UID of the meeting this one was rebooked from, or `null`. Set when `change` is `rebooked`                                                     |
| `data.appointment_type_uid`       | string or null  | UID of the appointment type (scheduled appointments only)                                                                                     |
| `data.doctor_uid`                 | string or null  | UID of the assigned doctor                                                                                                                    |
| `data.patient_profile_uid`        | string          | UID of the patient profile. This is the only patient identifier in the payload — no PII (name, date of birth, or contact details) is included |

### Subscribing

Subscribe via the Management API to receive this event:

```bash theme={null}
curl -X POST "https://api.rxscale.com/v1/management/notification-subscriptions/" \
  -H "X-API-Key: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "notification_type": "patient_doctor_meeting_updated",
    "target": "https://your-system.com/webhooks/rxscale"
  }'
```

### Delivery and Idempotency

Webhooks are delivered at least once. Your endpoint should treat deliveries as idempotent using the combination of `data.meeting_uid` and `data.change` as the unique key — retried deliveries will carry the same values.
