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

# Lerian SPI events

> The CloudEvents that Lerian SPI publishes for Pix payments, DICT, BR Code, participants, and settlements: their types, their topics, and how Streaming Hub delivers them.

Lerian SPI publishes business facts as CloudEvents 1.0 in binary content mode. Each of its four binaries, `spi`, `dict`, `brcode`, and `core`, publishes under its own `ce-source` on its own topic. [Streaming Hub](https://docs.lerian.studio/en/platform/streaming-hub/what-is-streaming-hub.md) delivers these events to your institution's systems. The [event streaming overview](https://docs.lerian.studio/en/reference/events/overview.md) describes the shared envelope.

## How the events reach you

***

| Binary | `ce-source` | Topic |
| - | - | - |
| `spi` | `br-spi` | `lerian.streaming.br-spi` |
| `dict` | `br-spi-dict` | `lerian.streaming.br-spi-dict` |
| `brcode` | `br-spi-brcode` | `lerian.streaming.br-spi-brcode` |
| `core` | `br-spi-core` | `lerian.streaming.br-spi-core` |

* **Streaming Hub.** The hub reads the `lerian.streaming.<ce-source>` topics and delivers each matching event to your subscriptions. See [How Streaming Hub works](https://docs.lerian.studio/en/platform/streaming-hub/how-streaming-hub-works.md).
* **One exception.** The seven `dict_med_operations` events travel on the topic `br-spi.dict.med.operations`. Streaming Hub does not read that topic, so it does not deliver them. Read them with your own Kafka consumer.
* **Subscribe by catalog key.** A subscription's `event_types` takes the `eventKey` of the Streaming Hub catalog (`GET /v1/catalog`). For these events, the key is the last two segments of the `ce-type`, for example `spi_payment.settled`. See [Managing subscriptions](https://docs.lerian.studio/en/platform/streaming-hub/managing-subscriptions.md).
* **Pin the origin for settlements.** Lerian SPB also publishes `settlement.settled` and `settlement.failed`. To receive only the Lerian SPI settlements on a webhook or queue subscription, set the subscription `origin` to `br-spi-core`.
* **At least once.** An event can arrive more than once. Deduplicate on the `(ce-source, ce-id)` pair.
* **Do not rely on arrival order.** Order events by their lifecycle, not by the order in which they arrive.
* **Fixed headers.** Every event carries `ce-tenantid` `default`, `ce-schemaversion` `1.0.0`, and `ce-datacontenttype` `application/json`.

## Streaming manifest

***

Each binary serves its manifest at `GET /v1/streaming/manifest`. The manifest lists the events that the binary publishes to Streaming Hub, with the key, resource, event, and schema version of each one. The `dict` manifest leaves out the seven `dict_med_operations` events. The route requires the Access Manager resource `streaming-manifest` with the action `get`.

## Catalog

***

Every `ce-type` has the form `studio.lerian.<ce-source>.<resource>.<event>`. The tables give the full value.

### `spi`: payments, messages, and approvals

#### Payments

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi.spi_payment.initiated` | The rail recorded a payment order that you created, or a new attempt on a payment that you sent again after it never left for BACEN. |
| `studio.lerian.br-spi.spi_payment.sent` | The rail sent a payment to BACEN (`pacs.008`). The payment is not settled. |
| `studio.lerian.br-spi.spi_payment.status_callback_received` | The rail applied a BACEN status reply (`pacs.002`) to a payment. |
| `studio.lerian.br-spi.spi_payment.submission_timeout` | The submission of a payment to BACEN timed out. Its outcome is unknown. |
| `studio.lerian.br-spi.spi_payment.submission_deferred` | The submission of a payment to BACEN failed, and the payment did not end. |
| `studio.lerian.br-spi.spi_payment.failed` | The rail could not submit a payment, and the payment ended `FAILED`. When the rail answered `503` with `SPI-1001` or `SPI-1004`, you can send it again, and the stream then carries a new `spi_payment.initiated` for the same payment. |
| `studio.lerian.br-spi.spi_payment.received` | An incoming Pix arrived. The rail records it as `PENDING` for the decision of your client, until the instant in `decisionDeadline`. |
| `studio.lerian.br-spi.spi_payment.accepted` | The rail answered an incoming Pix as accepted (`ACSP`). The Pix is not settled. |
| `studio.lerian.br-spi.spi_payment.rejected` | A payment that you sent, or an incoming Pix, was refused. |
| `studio.lerian.br-spi.spi_payment.settled` | A Pix settled: BACEN confirmed a payment that you sent, an operator declared it settled through manual resolution, or the SPI confirmed an incoming credit. |

#### Returns

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi.spi_payment.return_initiated` | You requested the full return of a Pix that you received. |
| `studio.lerian.br-spi.spi_payment.med_return_requested` | You requested a return with the reason `FR01`. |
| `studio.lerian.br-spi.spi_payment.return_submission_deferred` | The rail could not confirm that BACEN received a full return. The return stays open. |
| `studio.lerian.br-spi.spi_payment.return_rejected` | A full return that you sent did not settle: BACEN refused it, or an operator declared it rejected. |
| `studio.lerian.br-spi.spi_payment.return_failed` | A full return that you requested ended with no money moved. |
| `studio.lerian.br-spi.spi_payment.returned` | A full return settled. It can be a return that you sent or a return that you received. |
| `studio.lerian.br-spi.spi_payment.partial_return_deferred` | The rail could not confirm that BACEN received a partial return. The return stays open. |
| `studio.lerian.br-spi.spi_payment.partial_return_failed` | A partial return that you requested ended with no money moved. |
| `studio.lerian.br-spi.spi_payment.partial_returned` | A partial return settled. It can be a return that you sent or a return that you received. |
| `studio.lerian.br-spi.spi_payment.return_received` | A return of a Pix that you sent arrived. The rail holds it for the decision of your client. |
| `studio.lerian.br-spi.spi_payment.return_accepted` | The rail answered a received return as accepted (`ACSP`). The return is not settled. |
| `studio.lerian.br-spi.spi_payment.return_declined` | A received return ended with no money moved: your client or the SPI refused it. |

#### Settlement on the rail

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi.spi_settlement.completion_observed` | A Pix reached settlement on the rail. |
| `studio.lerian.br-spi.spi_settlement.termination_observed` | A settled Pix was returned, or a payment ended without settlement. |

#### Pix Automático

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi.spi_mandate.requested` | A recurrence confirmation request (`pain.009`) arrived. |
| `studio.lerian.br-spi.spi_mandate.request_sent` | BACEN accepted the `pain.009` that the rail sent for a recurrence request. |
| `studio.lerian.br-spi.spi_mandate.request_received` | The participant of the payer acknowledged the receipt of that `pain.009` (`pain.012`). |
| `studio.lerian.br-spi.spi_mandate.cancellation_requested` | A recurrence cancellation (`pain.011`) arrived. |
| `studio.lerian.br-spi.spi_mandate.resolved` | A Pix Automático mandate reached a verdict. |
| `studio.lerian.br-spi.spi_schedule.requested` | A recurring charge schedule (`pain.013`) arrived and matched an active mandate. A retry of a charge publishes its own event. |
| `studio.lerian.br-spi.spi_schedule.cancellation_requested` | A schedule cancellation request (`camt.055`) arrived. |
| `studio.lerian.br-spi.spi_schedule.cancellation_resolved` | A `camt.029` answered a schedule cancellation request, with an acceptance or a refusal. |
| `studio.lerian.br-spi.spi_schedule.resolved` | A schedule reached a verdict: confirmed or rejected (`pain.014`), or cancelled. |

#### Messages, reports, and participants

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi.spi_admi.rejection_received` | BACEN refused a message that the rail sent (`admi.002`). |
| `studio.lerian.br-spi.spi_admi.system_event_received` | BACEN sent a system event notice (`admi.004`). |
| `studio.lerian.br-spi.spi_camt.member_change` | A `camt.014` broadcast reported that a participant joined or left. |
| `studio.lerian.br-spi.spi_camt.split_tax_declared` | A `camt.054` entry carried a tax split declaration. |
| `studio.lerian.br-spi.spi_tracking.internal_settlement_reported` | The rail sent a MED 2.0 internal settlement report (`trck.002`) to BACEN. |
| `studio.lerian.br-spi.spi_tracking.receipt_observed` | The receipt (`camt.025`) of a sent report arrived, with an acceptance or a rejection. |
| `studio.lerian.br-spi.spi_participant.registration_resolved` | BACEN answered a participant registration request: confirmed or refused. |
| `studio.lerian.br-spi.spi_participant.offboard_resolved` | BACEN answered a participant offboarding request. |
| `studio.lerian.br-spi.spi_participant.attributes_changed` | BACEN broadcast a change of participant attributes (`reda.041`). |
| `studio.lerian.br-spi.spi_participant.portability_deadline_notified` | BACEN set a portability deadline for a participant (`reda.017`). |

#### Approvals and operations

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi.spi_approval.approved` | An approver approved a requested approval. |
| `studio.lerian.br-spi.spi_approval.denied` | An approver denied a requested approval. |
| `studio.lerian.br-spi.spi_approval.expired` | A requested approval reached its deadline with no decision. |
| `studio.lerian.br-spi.spi_operation.manually_resolved` | An operator closed a stuck operation through [manual resolution](https://docs.lerian.studio/en/reference/rails/spi/spi/manual-resolve-operation.md). |

### `dict`: Pix keys, claims, and MED

#### Keys

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi-dict.dict_key.created` | BACEN confirmed the registration of a Pix key. |
| `studio.lerian.br-spi-dict.dict_key.updated` | BACEN accepted an update to a Pix key. |
| `studio.lerian.br-spi-dict.dict_key.deleted` | A Pix key left this deployment: BACEN confirmed its deletion, or a claim moved it to another participant. |
| `studio.lerian.br-spi-dict.dict_key.transferred` | A claim moved a Pix key to a participant that this deployment serves. |

#### Claims

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi-dict.dict_claim.initiated` | BACEN registered a claim that you opened. |
| `studio.lerian.br-spi-dict.dict_claim.acknowledged` | BACEN accepted the acknowledgment of a claim. |
| `studio.lerian.br-spi-dict.dict_claim.confirmed` | A claim moved to `CONFIRMED`: the donor agreed to release the key. |
| `studio.lerian.br-spi-dict.dict_claim.completed` | A claim moved to `COMPLETED`: the key moved to the claimer. |
| `studio.lerian.br-spi-dict.dict_claim.cancelled` | A claim moved to `CANCELLED`. |
| `studio.lerian.br-spi-dict.dict_claim.resolved` | The deadline of a claim passed, and the rail completed or cancelled the claim. |
| `studio.lerian.br-spi-dict.dict_claim.received` | A claim that another participant opened against one of your keys appeared or changed status. The payload names the claimer (tax ID, name, trade name and type), the branch, number, type and opening date of the account the key would move to, and `lastModified`. |

#### MED records

The rail emits a MED record event when it observes a new version of the record at BACEN. The event names the status that the record reached. `updated` means that the record changed and its status did not.

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi-dict.dict_infraction.created` | An infraction report is `OPEN`. |
| `studio.lerian.br-spi-dict.dict_infraction.acknowledged` | An infraction report reached `ACKNOWLEDGED`. |
| `studio.lerian.br-spi-dict.dict_infraction.closed` | An infraction report reached `CLOSED`. |
| `studio.lerian.br-spi-dict.dict_infraction.cancelled` | An infraction report reached `CANCELLED`. |
| `studio.lerian.br-spi-dict.dict_infraction.updated` | An infraction report changed, and its status did not. |
| `studio.lerian.br-spi-dict.dict_refund.created` | A refund request is `OPEN`. |
| `studio.lerian.br-spi-dict.dict_refund.closed` | A refund request reached `CLOSED`. |
| `studio.lerian.br-spi-dict.dict_refund.cancelled` | A refund request reached `CANCELLED`. |
| `studio.lerian.br-spi-dict.dict_refund.updated` | A refund request changed, and its status did not. |
| `studio.lerian.br-spi-dict.dict_fraud_marker.created` | A fraud marker is `ACTIVE`. |
| `studio.lerian.br-spi-dict.dict_fraud_marker.cancelled` | A fraud marker reached `INACTIVE`. |
| `studio.lerian.br-spi-dict.dict_fraud_marker.updated` | A fraud marker changed, and its status did not. |
| `studio.lerian.br-spi-dict.dict_funds_recovery.created` | A funds recovery is `CREATED`. |
| `studio.lerian.br-spi-dict.dict_funds_recovery.tracked` | A funds recovery reached `TRACKED`. |
| `studio.lerian.br-spi-dict.dict_funds_recovery.awaiting_analysis` | A funds recovery reached `AWAITING_ANALYSIS`. |
| `studio.lerian.br-spi-dict.dict_funds_recovery.analysed` | A funds recovery reached `ANALYSED`. |
| `studio.lerian.br-spi-dict.dict_funds_recovery.refunding` | A funds recovery reached `REFUNDING`. |
| `studio.lerian.br-spi-dict.dict_funds_recovery.completed` | A funds recovery reached `COMPLETED`. |
| `studio.lerian.br-spi-dict.dict_funds_recovery.cancelled` | A funds recovery reached `CANCELLED`. |
| `studio.lerian.br-spi-dict.dict_funds_recovery.updated` | A funds recovery changed, and its status did not. |

#### Statistics and CID set files

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi-dict.dict_person_statistics.observed` | The BACEN antifraud counters of a CPF or CNPJ on your watchlist changed. |
| `studio.lerian.br-spi-dict.dict_cid_set_file.available` | BACEN reports a requested CID set file as `AVAILABLE`. |
| `studio.lerian.br-spi-dict.dict_cid_set_file.unavailable` | BACEN reports a requested CID set file as `UNAVAILABLE`. |
| `studio.lerian.br-spi-dict.dict_cid_set_file.error` | BACEN reports a requested CID set file as `ERROR`. |

#### MED operations

These events travel on the topic `br-spi.dict.med.operations`, which Streaming Hub does not read.

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi-dict.dict_med_operations.sync_pending` | BACEN confirmed a MED operation, and its answer was incomplete. |
| `studio.lerian.br-spi-dict.dict_med_operations.unknown_outcome` | The outcome of a MED operation sent to BACEN is unknown. |
| `studio.lerian.br-spi-dict.dict_med_operations.manual_review` | A MED operation that BACEN accepted needs operator review. |
| `studio.lerian.br-spi-dict.dict_med_operations.local_failure` | A MED operation did not reach BACEN. |
| `studio.lerian.br-spi-dict.dict_med_operations.inconsistent_projection` | The rail recorded a BACEN MED state that conflicts with a local rule. |
| `studio.lerian.br-spi-dict.dict_med_operations.feed_blocked` | A DICT discovery feed stopped, because the BACEN answer gives it no valid way to continue. |
| `studio.lerian.br-spi-dict.dict_med_operations.feed_record_abandoned` | An operator abandoned a record that a discovery feed could not read or store. |

### `brcode`: charges and recurrences

> [!WARNING]
>
> Do not post a ledger movement on `brcode_charge.paid` or `brcode_cobr.concluded`. These events record the lifecycle of a charge. A consumer that posts on the charge event and on a settlement event of the same Pix posts the Pix twice.

#### Charges

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi-brcode.brcode_charge.created` | A charge (Cob or CobV) was created. |
| `studio.lerian.br-spi-brcode.brcode_charge.revised` | A charge was revised. |
| `studio.lerian.br-spi-brcode.brcode_charge.paid` | A charge reached `CONCLUIDA`: a Pix paid it. |
| `studio.lerian.br-spi-brcode.brcode_charge.settlement_amount_mismatch` | A settled Pix concluded a charge, and its amount is not the amount of the charge. |
| `studio.lerian.br-spi-brcode.brcode_charge.cancelled` | A charge was removed. |

#### Recurrences, recurring charges, and requests

Each of these resources emits one event for each status that it reaches.

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi-brcode.brcode_recurrence.created` | A recurrence (Rec) reached `CRIADA`. |
| `studio.lerian.br-spi-brcode.brcode_recurrence.approved` | A recurrence reached `APROVADA`. |
| `studio.lerian.br-spi-brcode.brcode_recurrence.rejected` | A recurrence reached `REJEITADA`. |
| `studio.lerian.br-spi-brcode.brcode_recurrence.expired` | A recurrence reached `EXPIRADA`. |
| `studio.lerian.br-spi-brcode.brcode_recurrence.cancelled` | A recurrence reached `CANCELADA`. |
| `studio.lerian.br-spi-brcode.brcode_cobr.created` | A recurring charge (CobR) reached `CRIADA`. |
| `studio.lerian.br-spi-brcode.brcode_cobr.active` | A recurring charge reached `ATIVA`. |
| `studio.lerian.br-spi-brcode.brcode_cobr.concluded` | A recurring charge reached `CONCLUIDA`. |
| `studio.lerian.br-spi-brcode.brcode_cobr.expired` | A recurring charge reached `EXPIRADA`. |
| `studio.lerian.br-spi-brcode.brcode_cobr.rejected` | A recurring charge reached `REJEITADA`. |
| `studio.lerian.br-spi-brcode.brcode_cobr.cancelled` | A recurring charge reached `CANCELADA`. |
| `studio.lerian.br-spi-brcode.brcode_solicrec.created` | A recurrence request (SolicRec) reached `CRIADA`. |
| `studio.lerian.br-spi-brcode.brcode_solicrec.sent` | A recurrence request reached `ENVIADA`. |
| `studio.lerian.br-spi-brcode.brcode_solicrec.received` | A recurrence request reached `RECEBIDA`. |
| `studio.lerian.br-spi-brcode.brcode_solicrec.accepted` | A recurrence request reached `ACEITA`. |
| `studio.lerian.br-spi-brcode.brcode_solicrec.rejected` | A recurrence request reached `REJEITADA`. |
| `studio.lerian.br-spi-brcode.brcode_solicrec.expired` | A recurrence request reached `EXPIRADA`. |
| `studio.lerian.br-spi-brcode.brcode_solicrec.cancelled` | A recurrence request reached `CANCELADA`. |
| `studio.lerian.br-spi-brcode.brcode_lote.created` | A CobV batch (lote) was created, with the status `CRIADA`. |

### `core`: participants and settlements

| `ce-type` | When it is emitted |
| - | - |
| `studio.lerian.br-spi-core.core_participant.registration_requested` | Core recorded a new indirect participant as `PENDING` and requested its registration at BACEN. |
| `studio.lerian.br-spi-core.core_participant.offboard_requested` | A participant moved to `OFFBOARD_PENDING`, and Core requested its offboarding at BACEN. |
| `studio.lerian.br-spi-core.settlement.settled` | A Pix settled, and Core tracks the settlement of its operation. |
| `studio.lerian.br-spi-core.settlement.returned` | A settled Pix was returned, and Core tracks the settlement of its operation. |
| `studio.lerian.br-spi-core.settlement.failed` | A Pix ended without settlement, and Core tracks the settlement of its operation. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.