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

# Quick start

> From nothing to one event received — create a subscription, activate the destination, trigger an event, and confirm the delivery.

This page takes you from nothing to one delivered event. It uses a `webhook` sink, because that is the shortest path: four calls to the hub, and one HTTP request arriving at your endpoint.

Every `/v1` call sends `Authorization: Bearer <token>` and `application/json`. The hub reads your tenant from the token. It never reads a tenant from a body, a path, or a query.

## Before you start

***

You need four things.

* **A running hub and a token.** The `/v1` control plane authenticates every route with a plugin-auth JWT. The catalog read below also needs `catalog` `get`. See [Operating Streaming Hub](/en/streaming-hub/operating-streaming-hub) for the deployment.
* **`STREAMING_HUB_MANIFEST_SOURCES` set on the hub**, if you want the catalog read to list your producers. It is empty by default, and an empty list leaves the catalog with the hub's own `hub.*` entries only. See [Operating Streaming Hub](/en/streaming-hub/operating-streaming-hub).
* **A public `https://` endpoint you control.** The hub validates the destination before it writes any row, and rejects private, loopback, and cloud-metadata addresses. A `localhost` endpoint cannot be stored.
* **A producer on the same stream, with publication turned on.** Publication is off by default on the producer side. On Midaz, set `STREAMING_ENABLED=true`, point `STREAMING_BROKERS` at the same brokers as `STREAMING_HUB_KAFKA_BROKERS`, and set `STREAMING_CLOUDEVENTS_SOURCE`. See [Streaming and outbox](/en/reference/byoc-configuration#streaming-and-outbox). The `ce-tenantid` the producer emits must also equal the hub's `STREAMING_HUB_TENANT_ID`. A mismatch drops every event with no error. [Operating Streaming Hub](/en/streaming-hub/operating-streaming-hub) states that rule.

## The five calls

***

```
1. GET  /v1/catalog                    → what your producer manifests declare
2. POST /v1/subscriptions              → id + signingSecret
3. POST /v1/subscriptions/{id}/ping    → active
4. POST /v1/organizations   (Midaz)    → emits organization.created
5. GET  /v1/subscriptions/{id}/health  → one successful delivery
```

## 1. Get the matching key

***

`GET /v1/catalog`

The catalog lists what the producer manifests in `STREAMING_HUB_MANIFEST_SOURCES` declare. Each entry gives an `eventType` and a `topic`.

**The catalog does not carry the matching key.** `eventType` is the event segment alone. The `topic` folds the producer's service name into its resource segment. So `lerian.streaming.ledger_organization.created` has `eventType` `created`, and the key you need is `organization.created`. Take the key from the per-product pages under [Event streaming](/en/reference/events/overview). The producer's own `/streaming/manifest` also reports `resourceType` next to `eventType`.

The hub accepts any well-formed key in `event_types`. A key that no producer emits matches nothing, and the subscription receives no events.

## 2. Create the subscription

***

`POST /v1/subscriptions`

Send the header `X-Idempotency` with a unique value. The hub rejects a create that omits it, before any write.

```json theme={null}
{
  "name": "quick-start",
  "sink_kind": "webhook",
  "endpoint": "https://hooks.example.com/lerian",
  "event_types": ["organization.created"]
}
```

`event_types` holds **matching keys**, not full CloudEvents types. A matching key is the `<resource>.<event>` tail — `organization.created`, and never the full `studio.lerian.organization.created`. Send the key you assembled in step 1. Omit `event_types` to receive every event the hub sees.

The per-product pages under [Event streaming](/en/reference/events/overview) describe each type in full — start from the [Midaz event catalog](/en/reference/events/midaz).

`plan_tier` defaults to `standard`. `schema_major` is optional — leave it out to follow the base version.

The `201` response carries the subscription `id` and the plaintext `signingSecret`. **Save the secret now.** No read path returns it, and if you lose it your only route is rotation.

## 3. Activate the destination

***

`POST /v1/subscriptions/{id}/ping`

A new webhook subscription is born `pending_verification`. The hub delivers to it only after a probe proves the destination answers, so **this call is required**. It sends one synthetic signed request through the production delivery path, then reports the result:

```json theme={null}
{ "outcome": "ok", "statusCode": 200, "errorClass": "" }
```

`outcome: "ok"` moves the subscription to `active`, which is the state that makes it deliverable. Your endpoint must answer with a `2xx` for that to happen, so deploy it before you ping.

A probe that ran and failed is still a `200` — read `outcome`, not the HTTP status. `outcome: "failed"` leaves the subscription unverified and names the cause in `errorClass`. Fix the endpoint and ping again. The call is safe to repeat and needs no idempotency key.

Delivery requires `enabled` **and** `verification_state = active`. [Managing subscriptions](/en/streaming-hub/managing-subscriptions) explains why the two fields stay separate.

## 4. Trigger an event

***

Do something in a Lerian product that emits the type you subscribed to. In Midaz, creating one organization emits the event above.

`POST /v1/organizations`

```json theme={null}
{
  "legalName": "Quick Start Ltda",
  "legalDocument": "00000000000191"
}
```

Midaz publishes the event to the stream right after it persists the organization. The delivery reaches your endpoint moments later, not inside this call.

## 5. Confirm the delivery

***

Your endpoint receives a `POST` carrying the event payload, an HMAC signature, and the hub's context headers — `X-Lerian-Event-Id`, `X-Lerian-Event-Type`, and `X-Lerian-Delivery-Id` among them. Verify the signature before you trust the body: an unverified request proves nothing. [Consuming events](/en/streaming-hub/consuming-events) has the verification steps, the full header list, and the deduplication rule.

Then ask the hub what it recorded.

`GET /v1/subscriptions/{id}/health`

| Field                | What it tells you                                        |
| -------------------- | -------------------------------------------------------- |
| `verification_state` | `active` once the ping succeeded.                        |
| `status`             | The rolled-up verdict: `Healthy`, `Degraded`, or `Down`. |
| `delivery_outcomes`  | Attempt counts for the window, keyed by outcome.         |
| `last_success_at`    | When the last delivery succeeded.                        |
| `dead_lettered`      | Attempts that exhausted their retries.                   |

One success in `delivery_outcomes` and a fresh `last_success_at` mean the path works end to end. If nothing arrived, `status` and `delivery_outcomes` tell you whether the hub tried and failed, or never matched the event at all.

## Prefer to pull?

***

A `pull` subscription needs no endpoint and no probe. Create it with `sink_kind: "pull"` and no `endpoint` — the hub synthesizes one, and the subscription is `active` from birth. Read pages of events with `GET /v1/events?subscription_id=<id>`. The read is the acknowledgment, so read the cursor rules in [Consuming events](/en/streaming-hub/consuming-events) before your first call.

## Next steps

***

<CardGroup cols={2}>
  <Card title="Managing subscriptions" icon="gear" href="/en/streaming-hub/managing-subscriptions">
    Queue sinks, AWS delegated grants, secret rotation, and recovery.
  </Card>

  <Card title="Consuming events" icon="inbox" href="/en/streaming-hub/consuming-events">
    Verify signatures, deduplicate deliveries, and pull with a cursor.
  </Card>

  <Card title="How Streaming Hub works" icon="diagram-project" href="/en/streaming-hub/how-streaming-hub-works">
    Matching, dispatch, the retry curve, and auto-disable.
  </Card>

  <Card title="Operating Streaming Hub" icon="server" href="/en/streaming-hub/operating-streaming-hub">
    Deploy the hub, configure it, and watch it run.
  </Card>
</CardGroup>
