Skip to main content
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 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.
  • 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. 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 states that rule.

The five calls


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. 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.
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 describe each type in full — start from the Midaz event catalog. 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:
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 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
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 has the verification steps, the full header list, and the deduplication rule. Then ask the hub what it recorded. GET /v1/subscriptions/{id}/health 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 before your first call.

Next steps


Managing subscriptions

Queue sinks, AWS delegated grants, secret rotation, and recovery.

Consuming events

Verify signatures, deduplicate deliveries, and pull with a cursor.

How Streaming Hub works

Matching, dispatch, the retry curve, and auto-disable.

Operating Streaming Hub

Deploy the hub, configure it, and watch it run.