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

# Receive webhook events

> Create a webhook subscription, decrypt delivered events, and manage the subscription lifecycle.

Webhook subscriptions let your integration receive supported Peerlogic events as they occur. A subscription connects one practice and one trigger type to an HTTPS endpoint that you control.

Use the [Subscriptions and events API reference](/peerlogic-api-reference/subscriptions-and-events/list-subscriptions) for complete request and response schemas. This guide explains the delivery flow and the responsibilities of your webhook receiver.

## How webhook delivery works

<Steps>
  <Step title="Create a subscription">
    Create a `webhook` subscription for a practice, trigger type, and HTTPS destination.
  </Step>

  <Step title="Store the secret key">
    The create response includes a `secret_key`. Store it securely and associate it with the returned subscription `id`.
  </Step>

  <Step title="Receive the event">
    Peerlogic sends an HTTP `POST` request to your destination. The request body is a Fernet token and the headers identify the subscription and practice.
  </Step>

  <Step title="Decrypt the event">
    Use `X-Subscription-ID` to select the corresponding secret key, then decrypt the request body with a compatible Fernet implementation.
  </Step>

  <Step title="Process and acknowledge">
    Parse the decrypted JSON event and return a successful `2xx` response after your endpoint accepts it.
  </Step>
</Steps>

## Create a webhook subscription

Send an authenticated request to `POST /api/subscriptions/`. The destination must use HTTPS.

```bash theme={null}
curl --request POST \
  --url https://api.prod.peerlogic.com/api/subscriptions/ \
  --header 'Authorization: Bearer <ACCESS_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
    "destination": "https://partner.example.com/webhooks/peerlogic",
    "subscription_type": "webhook",
    "trigger": {
      "trigger_type": "missed_call"
    },
    "name": "Missed-call events",
    "description": "Notify our integration when a call is missed",
    "practice_id": "<PRACTICE_ID>"
  }'
```

The create response includes the subscription and its encryption key:

```json theme={null}
{
  "id": "<SUBSCRIPTION_ID>",
  "destination": "https://partner.example.com/webhooks/peerlogic",
  "subscription_type": "webhook",
  "trigger": {
    "trigger_type": "missed_call"
  },
  "name": "Missed-call events",
  "description": "Notify our integration when a call is missed",
  "practice_id": "<PRACTICE_ID>",
  "is_active": true,
  "secret_key": "<FERNET_SECRET_KEY>"
}
```

<Warning>
  The `secret_key` is returned only when you create the subscription. It cannot be retrieved or changed later. Store it in a secrets manager, never expose it in client-side code or logs, and associate it with the subscription `id`. If the key is lost or exposed, delete the subscription and create a replacement.
</Warning>

See [Create subscriptions](/peerlogic-api-reference/subscriptions-and-events/create-subscriptions) for the current trigger types and complete schema.

## Receive an event

Webhook deliveries use `POST` with a `text/plain` body containing the encrypted Fernet token.

| Header | Description |
| - | - |
| `X-Subscription-ID` | The subscription that produced the delivery. Use it to select the correct secret key. |
| `X-Practice-ID` | The practice associated with the event. |
| `Content-Type` | `text/plain` for the encrypted request body. |

Do not treat the request body as JSON until after you decrypt it.

## Decrypt the request body

Use a Fernet implementation for your language. The receiver should follow this sequence:

1. Read `X-Subscription-ID` from the request headers.
2. Look up the secret key stored for that subscription.
3. Decrypt the raw request body as a Fernet token.
4. Parse the decrypted plaintext as JSON.
5. Validate that the envelope identifies the expected subscription and practice.

The decrypted event uses this envelope:

```json theme={null}
{
  "meta": {
    "subscription_id": "<SUBSCRIPTION_ID>",
    "created_at": "2026-09-15T19:18:09Z",
    "practice_id": "<PRACTICE_ID>"
  },
  "data": {
    "call": {
      "id": "<CALL_ID>",
      "call_direction": "inbound",
      "call_connection": "missed",
      "has_audio": true,
      "has_transcript": true
    }
  }
}
```

The contents of `data` depend on the subscription trigger. Treat the API reference as the contract for supported values and retrieve related resources through the API when your workflow needs additional information.

<Note>
  A webhook event is a notification, not necessarily a complete representation of every related resource. For example, a caller-recognition workflow can use the event identifiers and phone data to retrieve the current contact, patient, appointment, or call details from the corresponding API endpoints.
</Note>

## Manage subscriptions

Use the subscription endpoints to review and control existing deliveries:

* [List subscriptions](/peerlogic-api-reference/subscriptions-and-events/list-subscriptions) and filter them by practice, active state, or name.
* [Get a subscription](/peerlogic-api-reference/subscriptions-and-events/get-subscription) to inspect its current configuration and `system_message`.
* [Update a subscription](/peerlogic-api-reference/subscriptions-and-events/update-subscriptions) to change its name, description, or active state.
* [Delete a subscription](/peerlogic-api-reference/subscriptions-and-events/delete-subscriptions) when the destination or encryption key must be replaced.

Because each subscription has its own key, receivers that share one destination should maintain a secure mapping from subscription ID to secret key.

## Receiver checklist

* Expose an HTTPS endpoint that accepts `POST` requests with a `text/plain` body.
* Store keys outside source code and logs.
* Select the key using `X-Subscription-ID`; do not try every stored key.
* Decrypt before parsing JSON.
* Make event processing idempotent so repeated deliveries do not create duplicate work.
* Return a `2xx` response after accepting the event.
* Monitor subscription `is_active` and `system_message` values for delivery problems.


## Related topics

- [VoIP webhooks](/voip-platform/webhooks.md)
- [Get event](/peerlogic-api-reference/subscriptions-and-events/get-event.md)
- [List events](/peerlogic-api-reference/subscriptions-and-events/list-events.md)
- [Create subscriptions](/peerlogic-api-reference/subscriptions-and-events/create-subscriptions.md)
- [EHR and PMS integration requirements for partners](/integrations/ehr-practice-management/ehr-pms-integration-requirements.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.