# Quickstart

Define an event type, add a customer and an endpoint, and send your first webhook with Dispatch.

In this quickstart you act as your own customer: you define an event, register a URL that should receive it, send a message, and verify what arrives. Any request inspector URL works as the endpoint.

You will:

1. Create an API key.
2. Create an event type.
3. Create a customer and an endpoint.
4. Send an event.
5. Check the delivery.

## 1. Create an API key

Open **Settings → API keys & MCP** and create a key. The secret is shown once. Use it as a bearer token:

```bash
export ENSUE_KEY=ens_live_…
```

## 2. Create an event type

Event types are your catalog. Sends are validated against the schema, so define the shape you will actually send.

```bash
curl -X POST https://api.getensue.com/v1/event-types \
  -H "authorization: Bearer $ENSUE_KEY" -H "content-type: application/json" \
  -d '{
    "name": "order.shipped",
    "description": "An order has left the warehouse.",
    "schema": {
      "type": "object",
      "properties": { "order_id": { "type": "string" }, "carrier": { "type": "string" } },
      "required": ["order_id"]
    }
  }'
```

## 3. Create a customer and an endpoint

Use your own ID for the customer. `PUT` creates it, or updates it if it already exists, so it is safe to call whenever a customer signs up.

```bash
curl -X PUT https://api.getensue.com/v1/dispatch/customers/acme \
  -H "authorization: Bearer $ENSUE_KEY" -H "content-type: application/json" \
  -d '{ "name": "Acme Inc" }'
```

Then add the URL that should receive webhooks:

```bash
curl -X POST https://api.getensue.com/v1/dispatch/customers/acme/endpoints \
  -H "authorization: Bearer $ENSUE_KEY" -H "content-type: application/json" \
  -d '{ "url": "https://acme.example.com/hooks", "event_types": ["order.shipped"] }'
```

The response includes the endpoint's signing secret, `whsec_…`. **It is shown once**; give it to the customer, or fetch it again with `GET /v1/dispatch/endpoints/:id/secret`.

## 4. Send an event

```bash
curl -X POST https://api.getensue.com/v1/dispatch/events \
  -H "authorization: Bearer $ENSUE_KEY" -H "content-type: application/json" \
  -H "idempotency-key: order-1042-shipped" \
  -d '{
    "type": "order.shipped",
    "customer": "acme",
    "data": { "order_id": "1042", "carrier": "UPS" }
  }'
```

Ensue answers `202 Accepted` once the message and its deliveries are stored. The response gives the message ID (`msg_…`) and `delivery_count`, how many endpoints it was queued for. Delivery happens right after.

## 5. Check the delivery

Open **Events** in the dashboard and set the product filter to Dispatch, or:

```bash
curl https://api.getensue.com/v1/dispatch/events/msg_… \
  -H "authorization: Bearer $ENSUE_KEY"
```

The message lists a delivery per endpoint with its status and attempts. Your endpoint received:

```http
POST /hooks HTTP/1.1
content-type: application/json
webhook-id: msg_…
webhook-timestamp: 1767225600
webhook-signature: v1,<base64>

{
  "id": "msg_…",
  "type": "order.shipped",
  "version": 1,
  "timestamp": "2026-11-10T09:30:00.000Z",
  "data": { "order_id": "1042", "carrier": "UPS" }
}
```

The body is an envelope: your `data` plus the message ID, event type, schema version and time, so a customer can route and de-duplicate without parsing your payload.

> [!NOTE]
> A request body containing a field the schema forbids, or missing a required one, is refused with `422` and the validation errors. Nothing is sent. See [Event types](/dispatch/event-types/).

## What you have learned

You used all four building blocks: an event type, a customer, an endpoint and a message. From here:

- [Verify signatures](/dispatch/verify-signatures/): what your customers do with `webhook-signature`.
- [Send events](/dispatch/send-events/): to one customer, one endpoint, or everyone.
- [Retries and recovery](/dispatch/retries-and-recovery/): what happens when their server is down.