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

# Reporter events

> Subscribe to Reporter's report and deadline events: the streaming manifest operation, the logical topic, the CloudEvents envelope, delivery policies, and what each payload carries.

Reporter publishes a business event whenever a template, a report, or a deadline changes state. Subscribe to those events and you learn that a report finished without polling `GET /v1/reports/{id}` for it.

`GET /v1/streaming/events` describes the contract in machine-readable form. This page covers the consumer side: what the manifest tells you, what arrives on the wire, and what each event carries.

## The manifest operation

***

[Get streaming events](/en/reference/reporter/get-streaming-events) returns the static event catalog. It is authenticated like every other operation, answers `Cache-Control: no-store`, and is served whether or not this deployment publishes events. Read it at startup to check that your consumer and Reporter agree on the contract.

The response has four fields:

| Field       | What it carries                                                                                                                                                                                |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `version`   | Semantic version of the manifest wire format.                                                                                                                                                  |
| `publisher` | Who publishes: `serviceName` is `reporter`, `sourceBase` is `//lerian.studio/reporter`, `routePath` is this operation, `outboxSupported` is `true`, plus the application and library versions. |
| `events`    | One entry per event definition, with its key, resource type, event type, schema version, description, and default delivery policy.                                                             |
| `routes`    | Empty. Reporter publishes no broker topology through the API.                                                                                                                                  |

## The topic is a routing key

***

Each event entry carries a `topic`. It is a **logical routing key**: a stable identifier for one event stream, composed from the publisher source and the event definition. With the source Reporter advertises, `report.requested` composes to:

```
lerian.studio-reporter.report.requested
```

That string is not a broker address. Do not bind a queue to it, and do not treat it as a destination. It exists so a consumer can key on one event stream across transports.

What you bind to lives in deployment configuration instead. Reporter publishes to the exchange that `RABBITMQ_REPORT_EVENTS_EXCHANGE` names, and the routing key of each message is the event definition key verbatim — `report.finished`, `deadline.delivery_reverted`, underscores included.

## The event catalog

***

Twelve event definitions exist across the two run modes.

| Event                        | Emitted when                                                      | Class     |
| ---------------------------- | ----------------------------------------------------------------- | --------- |
| `template.created`           | A template is uploaded.                                           | Important |
| `template.updated`           | A template's file or metadata changes.                            | Important |
| `template.deleted`           | A template is removed, with the count of deadlines that cascaded. | Important |
| `report.requested`           | A report request is accepted and queued.                          | Important |
| `report.finished`            | Every data section succeeded and the artifact is stored.          | Critical  |
| `report.partial`             | Some sections failed. An artifact exists.                         | Critical  |
| `report.errored`             | The report ended in error.                                        | Critical  |
| `deadline.created`           | A deadline is created.                                            | Important |
| `deadline.updated`           | A deadline changes.                                               | Important |
| `deadline.deleted`           | A deadline is removed.                                            | Important |
| `deadline.delivered`         | A deadline is marked delivered.                                   | Critical  |
| `deadline.delivery_reverted` | A delivery mark is cleared.                                       | Critical  |

This channel is publish-only. Reporter emits these events and consumes none of them.

## Delivery

***

The class in the table above selects a delivery policy.

| Class     | Direct publish | Outbox                                          | Dead letter         |
| --------- | -------------- | ----------------------------------------------- | ------------------- |
| Important | Yes            | Falls back to the outbox when the circuit opens | On routable failure |
| Critical  | No             | Always                                          | On routable failure |

A critical event therefore never publishes straight to the broker. It lands in a durable outbox inside the same transaction, and a dispatcher replays it after a broker outage. Nothing is lost to a broker restart.

Emission happens after the commit and never fails the work. A publication problem does not turn a stored report into an errored one.

<Warning>
  Delivery is at-least-once. Deduplicate on `ce-id`. Report events key on the report identifier and its terminal status, in the form `reporter.report.<status>.<reportId>`, so every re-emission of the same fact carries the same identifier. Deadline events key on the deadline identifier, the event type, and the transition timestamp.
</Warning>

## The CloudEvents envelope

***

Messages travel in CloudEvents binary mode, version 1.0. Context attributes ride as message headers.

| Header             | Value                                                                           |
| ------------------ | ------------------------------------------------------------------------------- |
| `ce-specversion`   | `1.0`                                                                           |
| `ce-id`            | The deduplication key described above                                           |
| `ce-source`        | The value of `STREAMING_CLOUDEVENTS_SOURCE`                                     |
| `ce-type`          | `studio.lerian.<resource>.<event>`, for example `studio.lerian.report.finished` |
| `ce-time`          | RFC 3339 emission timestamp                                                     |
| `ce-subject`       | The identifier of the report, template, or deadline                             |
| `ce-resourcetype`  | `report`, `template`, or `deadline`                                             |
| `ce-eventtype`     | `finished`, `created`, `delivery_reverted`, and so on                           |
| `ce-schemaversion` | `1.0.0`                                                                         |
| `ce-tenantid`      | The tenant that owns the change                                                 |

Messages are marked persistent. A single-tenant deployment still stamps a tenant value, so one consumer handles both deployment shapes with the same code.

## What a payload carries

***

Payload keys are `snake_case`, unlike the camelCase REST surface. A `report.finished` body:

```json theme={null}
{
  "report_id": "019826f4-6a9c-7b31-9d40-2f1e8c5a4b77",
  "template_id": "8f2c1a9e-4b30-4c02-9a1b-2d5e6f7a1c33",
  "output_format": "pdf",
  "status": "Finished",
  "artifact_object_key": "8f2c1a9e-4b30-4c02-9a1b-2d5e6f7a1c33/019826f4-6a9c-7b31-9d40-2f1e8c5a4b77.pdf",
  "artifact_content_type": "application/pdf",
  "completed_at": "2026-07-29T14:22:08Z",
  "duration_ms": 8421,
  "section_count": 3
}
```

`artifact_object_key` is the artifact path relative to the report storage prefix, in the form `<templateId>/<reportId>.<format>`. [Download a report](/en/reference/reporter/download-report) is the supported way to fetch the file, and it serves a report in the `Finished` state. [Deployment](/en/reporter/reporter-deployment) shows where that prefix sits in the bucket.

`report.partial` adds `section_failures` and `failed_section_count` alongside the same artifact fields, so a consumer can route a usable-but-incomplete report differently from a clean one.

`report.errored` replaces the artifact fields with `error_code` and `error_summary`. Both come from a fixed vocabulary — `report_generation_failed`, `report_generation_timeout`, or `report_generation_canceled` — each paired with a fixed summary. Raw error text never travels on the wire, so a payload cannot leak a query, a connection string, or tenant data. Branch on `error_code`.

## Enabling event publication

***

Event publication is a deployment choice, set with `STREAMING_ENABLED`. Turn it on and Reporter requires three more settings at startup:

| Setting                           | Value                                                                                                         |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `RABBITMQ_REPORT_EVENTS_EXCHANGE` | The exchange that carries the events. Operator-configured; the reference value is `reporter.events`.          |
| `STREAMING_BROKERS`               | Must be present and non-empty.                                                                                |
| `STREAMING_CLOUDEVENTS_SOURCE`    | Copied verbatim into `ce-source`. Give each deployment its own value when several producers share one broker. |

Reporter refuses to start when publication is on and any of the three is blank, so a misconfigured deployment fails at startup instead of dropping events quietly.

## Next steps

***

<CardGroup cols={2}>
  <Card title="Reporter REST API" icon="code" href="/en/reporter/reporter-rest-api">
    The 23 operations, authentication, pagination, and errors.
  </Card>

  <Card title="API Reference" icon="list" href="/en/reference/introduction">
    The streaming manifest operation, with its full response shape.
  </Card>

  <Card title="Environment variables" icon="gear" href="/en/reporter/reporter-environment-variables">
    Every setting behind the streaming, exchange, and run-mode surfaces.
  </Card>

  <Card title="What is Reporter?" icon="book" href="/en/reporter/what-is-reporter">
    Templates, reports, deadlines, and where they fit.
  </Card>
</CardGroup>
