# Receive webhook events
URL: https://docs.awellhealth.com/docs/automate-with-events/receive-webhook-events

> For the complete documentation index, see [llms.txt](https://docs.awellhealth.com/llms.txt).



These steps cover building an endpoint that receives events from Awell, from picking the events worth
acting on to registering a production URL.

For the concepts first, read
[Webhooks and events](/docs/automate-with-events/webhooks-and-events). To switch webhooks on for a care
flow without writing any code, see
[Configure webhooks in Studio](/docs/automate-with-events/configure-webhooks-in-studio) instead.

## 1. Subscribe only to events worth acting on [#1-subscribe-only-to-events-worth-acting-on]

Start from the [event catalog](/docs/automate-with-events/webhook-event-catalog) and subscribe only to
what the integration will act on. Every extra event is traffic to authenticate, log, and ignore.

## 2. Create an endpoint [#2-create-an-endpoint]

The endpoint needs a URL that accepts `POST` over HTTPS. Plain HTTP is not supported; the transport is
part of how the payload stays private.

Do as little as possible before acknowledging: verify the request, put the work on a queue, respond. A
slow handler causes a retry, which arrives as a duplicate.

## 3. Verify the request came from Awell [#3-verify-the-request-came-from-awell]

A URL that accepts anonymous POSTs will eventually receive something Awell didn't send. Awell signs
every request, so the receiver can tell a genuine request from a forged one.

### Check the signature [#check-the-signature]

Awell signs each request with a **2048-bit RSA private key** held for your organization, and sends the
signature in an `x-awell-signature` header. You verify it with the matching public key.

This is asymmetric signing, so there is nothing to recompute and no shared secret to compare against
— you hand the signature, the body and the public key to your platform's RSA verification function
and it answers yes or no.

1. Read the signature from the `x-awell-signature` header.
2. Verify it against the **raw** request body. Parsing to JSON first can change bytes and fail a
   signature that was actually valid.
3. If verification fails, reject the request and don't process it.

The public key comes from **Integrations → Outgoing webhooks → Public key** and is the same for every
outgoing webhook in your organization — it is not issued per webhook. See
[Configure webhooks in Studio](/docs/automate-with-events/configure-webhooks-in-studio) for handing it
over, and [Configure webhooks for all care flows](/docs/automate-with-events/configure-webhooks-for-all-care-flows)
for where to find it.

Being a public key, it is not a secret and needs no special handling. The private key never leaves
Awell.

> Verify the signature **before** trusting anything in the payload, including identifiers headed for a
> lookup; every step after this one assumes the request is genuine.

### An address allowlist is a second layer, not a replacement [#an-address-allowlist-is-a-second-layer-not-a-replacement]

Signature verification is the strong control. Restricting which addresses may reach the endpoint, where
the infrastructure allows it, is a reasonable second layer.

## 4. Return the right response [#4-return-the-right-response]

Return a `2xx` status as soon as the event is accepted. Anything else tells Awell the delivery failed,
and it gets retried.

Acknowledge *accepting* the work, not *finishing* it. If a downstream system is slow, respond first and
process asynchronously.

## 5. Handle repeats and out-of-order arrival [#5-handle-repeats-and-out-of-order-arrival]

Because delivery can repeat and order isn't guaranteed:

* Make handling **idempotent**. Key on the event's identifiers so processing twice is harmless.
* Don't infer sequence from arrival order.

## 6. Test against a separate endpoint first [#6-test-against-a-separate-endpoint-first]

Point a webhook at a test endpoint and confirm the whole path: signature verification passes, the
`2xx` comes back quickly, and the handler does the right thing with a real payload.

Keep test and production endpoints separate, so live patient events never reach a staging listener.

## 7. Go live [#7-go-live]

When the test endpoint behaves, register the production URL in the care flow's settings. Check the logs
after the first real events arrive rather than assuming success.
[Configure webhooks in Studio](/docs/automate-with-events/configure-webhooks-in-studio) covers where
to look and how to retry a failure.

## A worked example [#a-worked-example]

For an end-to-end example with a specific vendor (receiving events and acting on them in an AWS
Lambda), see the Healthie listener guide in **Connect systems**.

## Next steps [#next-steps]

**Next:** [Configure webhooks in Studio](/docs/automate-with-events/configure-webhooks-in-studio). With
the endpoint ready, turn the webhook on and check the first deliveries.
