> ## 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.

# Event publisher

> Publish Midaz transaction lifecycle CloudEvents to Kafka-compatible brokers for downstream integrations.

## Why this matters

***

Transaction lifecycle events let downstream systems react without coupling to the transaction API. Use them for notifications, reconciliation, analytics, and compliance workflows.

For the complete catalog and consumer contract, see [Receiving Midaz events](/en/products/midaz/receiving-midaz-events).

## Enable transaction lifecycle events

***

Midaz publishes lifecycle CloudEvents through the Kafka-compatible lib-streaming surface. Publication is off by default. Configure the ledger application with a broker list and its roster source:

```env theme={null}
STREAMING_ENABLED=true
STREAMING_BROKERS=<broker-list>
STREAMING_CLOUDEVENTS_SOURCE=ledger
```

You must set `STREAMING_CLOUDEVENTS_SOURCE` when you enable streaming. The ledger, CRM, and Fees binary uses `ledger`. The transaction facts publish to `lerian.streaming.ledger`.

If you enable streaming without `STREAMING_BROKERS`, Midaz refuses to start. When streaming is off, Midaz uses a no-op emitter.

## Lifecycle events

***

Midaz emits these public facts for eligible persisted transaction state changes:

| Fact                    | When Midaz emits it                                                      |
| ----------------------- | ------------------------------------------------------------------------ |
| `transaction.posted`    | A newly created transaction is `APPROVED` and has no parent transaction. |
| `transaction.reverted`  | A newly created `APPROVED` transaction has a parent transaction.         |
| `transaction.committed` | A transaction status update reaches `APPROVED`.                          |
| `transaction.canceled`  | A transaction status update reaches `CANCELED`.                          |

Midaz does not emit a lifecycle fact for a newly created `PENDING` transaction, a `NOTED` transaction, or a no-op state change. A pending transaction emits only when a later status update commits or cancels it.

## Consume events

***

Subscribe to `lerian.streaming.ledger` and select the facts you need using the CloudEvents headers. Do not infer event type from the Kafka topic: Midaz uses one application topic for ledger, CRM, and Fees facts.

Use the producer manifest as the deployment-time contract:

```http theme={null}
GET /v1/streaming/manifest
```

The manifest remains available even when publication is off. The [Midaz event reference](/en/reference/events/midaz) lists the event payloads.

<Note>
  Event publication is best effort and does not make the broker write transactional with the ledger mutation. Consumers must be idempotent and deduplicate on `(ce-source, ce-id)`.
</Note>
