# Gateway overview

How Ensue Gateway receives, verifies, queues and delivers the webhooks your services depend on.

Receiving webhooks reliably takes more than an endpoint. Senders retry, burst and go quiet; your own services deploy, slow down and fail. Ensue Gateway sits between the two. It accepts a webhook, stores it durably, answers the sender straight away, and then delivers it to your service at a pace the service can handle, retrying on failure and keeping a record of every step.

```text
Stripe ─┐                                       ┌─▶ billing service
GitHub ─┼─▶ source URL ─▶ flow(s) ─▶ queue ─────┼─▶ analytics
Shopify ┘   verify · dedupe  filter · transform └─▶ agent inbox
```

## Core concepts

| Concept | What it is |
|---|---|
| **[Source](/gateway/sources/)** | A URL you give to a sender. Ensue verifies each request against the method you choose, stores it, and answers the sender at once. |
| **[Destination](/gateway/destinations/)** | Where events go: an HTTPS URL, or an [agent inbox](/agents/inbox-and-leases/). Each destination has its own queue, retry schedule and rate limit. |
| **[Flow](/gateway/flows/)** | Connects one source to one destination, with an optional [filter](/gateway/filters/) and [transformation](/gateway/transformations/). |
| **Request** | One HTTP request a source received. Rejected requests are kept too, with the reason. |
| **Event** | What a flow creates from an accepted request: one event per matching flow. This is what is delivered. |
| **Attempt** | One try at delivering an event, with the response and how long it took. |

A request that reaches a source with three active flows becomes three events, each delivered to its own destination and each retried independently.

## What happens to a request

1. **Verify.** The request is checked against the source's [verification](/gateway/verify-webhooks/) method. Failures get a `401` and are logged with the reason; nothing is delivered.
2. **Deduplicate.** If the source has a [deduplication key](/gateway/deduplication/) and Ensue has seen that value before, the sender gets the original answer and nothing new is created.
3. **Store and acknowledge.** The request, its events and the usage count are written together. Only then does the sender get its `200`, so an acknowledged webhook is never lost.
4. **Filter and transform.** Each flow decides whether the request matches its [filter](/gateway/filters/) and reshapes the body with its [transformation](/gateway/transformations/).
5. **Deliver.** The destination's queue sends the event, signs it, and applies the [delivery policy](/gateway/delivery-policy/): retries, backoff, rate limits and the [circuit breaker](/gateway/circuit-breaker/).
6. **Record.** Every step lands on the event's [timeline](/gateway/events-and-timeline/). Failures can be [replayed](/gateway/replay-and-dead-letters/).

## What Gateway guarantees

Gateway delivers **at least once**. A destination can see the same event more than once, for example after a timeout where your service had already processed it. Every delivery carries an `idempotency-key` header (the event ID) so your handler can ignore repeats. Gateway does not promise exactly-once delivery or global ordering; if you need order, [ordering](/gateway/ordering/) keeps events for the same key in sequence.

## Where to go next

- New to Ensue? Follow the [Quickstart](/gateway/quickstart/) and deliver your first event in a few minutes.
- Receiving from Stripe, GitHub or similar: [Verify incoming webhooks](/gateway/verify-webhooks/).
- Something failing: [Events and timeline](/gateway/events-and-timeline/) and [Replay and dead letters](/gateway/replay-and-dead-letters/).
- Sending webhooks to your own customers instead? See [Dispatch](/dispatch/overview/).