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

# How Lerian BC Correios works

> How Lerian BC Correios collects mail from BC Correio, stores mail and attachments, sends messages to BACEN, analyzes mail with AI, and applies retention.

Lerian BC Correios runs one polling worker per tenant. Each cycle asks BC Correio for the folders and the mail of the tenant's Sisbacen user, and stores what is new.

## Polling cycle

***

The tenant sets the polling interval in its settings: 5, 15, 30, or 60 minutes. A change to the interval takes effect without a restart.

Each cycle runs these steps:

1. Lists the BC Correio folders that the Sisbacen user can see.
2. Reads each folder page by page, until a page comes back empty.
3. Reads each new mail and fetches its attachments, then stores them.
4. For a mail that it already stores, fetches the attachments that failed in an earlier cycle.

An error on one folder or one mail does not stop the cycle. The next cycle tries that work again.

## Folders

***

When Lerian BC Correios stores a new mail, it puts the mail in the local folder that matches its BC Correio folder:

| BC Correio folder | Local folder |
| - | - |
| `CaixaEntrada` | `INBOX` |
| `Transmitidos` | `SENT` |
| `Arquivados` | `ARCHIVED` |
| `Cancelados` | `CANCELLED` |
| `Destinados`, `Reservados`, `Setor` | `INBOX` |

A later move of the mail in BC Correio does not change its local folder. You cannot restore a mail from `CANCELLED`.

## Initial synchronization

***

The first cycle of a tenant stores the mail that already exists in BC Correio. Lerian BC Correios does not send that backlog to the AI provider. You can still ask for an analysis of a mail from it.

A cycle that fails to read a folder does not complete the initial synchronization. The next cycle runs it again.

## Storing mail and attachments

***

Lerian BC Correios stores each mail in PostgreSQL. It stores attachments in S3-compatible object storage or on the local filesystem, with the SHA-256 checksum of each file.

When you download an attachment, the service checks the file against its checksum. A file that fails the check returns `BCC-0010`.

## Sending a message

***

`POST /mails/send` sends a text message to a BACEN department through BC Correio. The message goes to the destination in the request. Without one, it goes to the default destination of the tenant. Without both, it goes to `DEINF`.

The tenant needs stored BC Correio credentials. Without them, the request returns `401` `BCC-2001`, and Lerian BC Correios stores nothing.

Lerian BC Correios records the message as `PENDING` before it calls BC Correio. The outcome then decides the status and the answer:

| Outcome | Stored status | Answer |
| - | - | - |
| BC Correio accepts the message. | `CONFIRMED` | `201`, with the protocol number in `bcbConfirmationId`. |
| The service cannot tell whether BC Correio received the message, for example after a timeout. | `AMBIGUOUS` | `409` `BCC-2010` |
| BC Correio refuses the message, or the service does not send it. | `FAILED` | `503` `BCC-2002` |

A repeat of the request with the same `X-Idempotency` key does not send the message again. While the first request runs, the repeat can return `409` `BCC-0012` with a `Retry-After` header. Otherwise the stored status of the first request decides the answer:

| Status of the first request | Answer |
| - | - |
| `CONFIRMED` | The original `201` answer. |
| `PENDING`, inside the grace window | `409` `BCC-2009`. Wait, then retry with the same key. |
| `PENDING`, after the grace window | The status changes to `AMBIGUOUS`, and the answer is `409` `BCC-2010`. |
| `AMBIGUOUS` | `409` `BCC-2010` |
| `FAILED` | `409` `BCC-2011`. Send the message again with a new key. |

`TRANSMISSION_PENDING_GRACE_SEC` sets the grace window, 30 seconds by default.

Do not send a message again after `BCC-2010`. BC Correio can already hold it. Confirm with BACEN through its manual channel that the message did not arrive, and only then send it with a new key.

Lerian BC Correios does not retry a send by itself.

## Local mail actions

***

Mark as read, archive, and restore change your local copy of a mail. Lerian BC Correios does not send these actions to BC Correio.

A restore of a mail in the `CANCELLED` or `SENT` folder returns `409` `BCC-0014`.

## AI insight

***

A tenant can configure an AI provider: `openai`, `anthropic`, or `gemini`, with its own API key. Lerian BC Correios sends the mail body to that provider, together with the text it extracts from TXT, CSV, XML, PDF, and DOCX attachments.

When the tenant has an AI provider, each new mail waits for analysis. Lerian BC Correios analyzes a mail with no attachments and a body of at least `AI_BODY_INLINE_THRESHOLD` characters in the polling cycle. A background worker analyzes the other mail.

You can ask for a new analysis of a mail with `POST /mails/{id}/reanalyze`. When the provider answers within 20 seconds, the response carries the analysis. Otherwise the response is `202`, and the analysis continues in the background.

## Retention

***

Each tenant sets a retention period between 1825 and 36500 days in its settings.

A retention worker runs once every 24 hours. For mail that passes the retention period, it deletes the attachment files from storage and hides the mail. It then deletes the mail records from the database.

## Audit trail

***

The audit trail records these actions:

| Action | When |
| - | - |
| `VIEW_MAIL` | A user reads the detail of a mail. |
| `MAIL_READ` | A user marks a mail as read. |
| `DOWNLOAD_ATTACHMENT` | A user downloads an attachment. |
| `SEND_MESSAGE` | A user sends a message to BACEN. |
| `MAIL_ARCHIVED` | A user archives a mail. |
| `MAIL_RESTORED` | A user restores a mail. |
| `SETTINGS_UPDATED` | A user creates or changes the tenant settings. |
| `RETENTION_POLICY_APPLIED` | A retention run deletes mail. |

`GET /audit` lists the entries. `GET /audit/export` exports them as CSV. Send `Accept: application/pdf` to get a PDF.


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