# Webhooks

You don't write routes for a provider's webhooks: Jadpo generates them
from the provider's package
([Webhooks as events](/docs/receiving-from-outside.md#webhooks-as-events)). A connection
with a webhook secret gets `POST /webhooks/<connection>` in the `webhooks`
API. For each request, the runtime:

- checks the provider's signature over the raw body;
- drops repeats, by the provider's event id;
- answers a handshake, where the package names one;
- writes each event to the outbox, where events wait to be delivered to
  subscribers ([Subscribers](/docs/subscribers.md)).

A webhook that needs a reply runs the app's answering action inside the
request
([Webhooks that need a reply](/docs/receiving-from-outside.md#webhooks-that-need-a-reply)).
You can change a webhook route's path, but you can't switch it off.

The route is `<prefix>/<connection>` under the prefix of the `webhooks` API
the app declares, whose record and OpenAPI document list it. Outside every
declared API, it is `/webhooks/<connection>`. `jadpo routes` shows it as
`generated webhook`, with `signature` for its authentication. An app route
at the same path is `route.path_overlap`. Replies and
handshakes are in
[Webhook replies, handshakes and further signature schemes](/docs/webhook-replies-handshakes-and-further-signature-schemes.md).

Two kinds of sender have no provider package:

- A system that signs its webhooks but has no package gets the app's own
  integration in `shared/providers/`, whose webhooks are generated the
  same way ([Senders with no package](/docs/receiving-from-outside.md#senders-with-no-package)).
- A partner with an agreement signs in as a `Service`, with a service key
  ([Service credentials](/docs/service-credentials.md)), and calls an
  ordinary route.
