> ## Documentation Index
> Fetch the complete documentation index at: https://docs.energy.nlead.ch/llms.txt
> Use this file to discover all available pages before exploring further.

# Nachrichten an den Lieferanten

> What the market sends the Lieferant, read from its inbox and kept per Marktlokation

> [!NOTE]
>
> Only where the Lieferant's role is on (`LIEFERANT_AKTIV`, off by default).
> n:lead is its own supplier and its stack switches it on.

The Netzbetreiber and Messstellenbetreiber send the Lieferant its market
messages:

| Type | What it carries |
| - | - |
| UTILMD | Supply changes (registration, deregistration, their answers) and master data per Marktlokation, the Bilanzierungsdaten (55126/55672) among them |
| MSCONS | Metered values per Marktlokation (e.g. 13025), meter readings, normalized profiles (13010) |
| INVOIC | Invoices for grid usage and metering |
| REMADV | Payment advice - in electricity the Lieferant sends it as its answer to an INVOIC and receives none; read in case one arrives |
| PRICAT | Price sheets: the Messstellenbetreiber's (27002, Preisblatt A and B) and the Netzbetreiber's (27003) - what an MSB-Rechnung (31009) or a Rechnung sonstige Leistung (31011) bills by |

The routine `lieferant-nachrichten` reads them for `LIEFERANT_MP_ID` and
keeps each with what its header says: type, Prüfidentifikator, sender,
date, and the Marktlokationen (LOC+Z16/172, eleven digits) and Zählpunkte it
names, and per message its case, one line and the key data (see below).
The message itself stays on the audit share
(`lieferant_nachrichten/`, ledger `lieferant_nachrichten`). The first read
goes 60 days back; later ones start at the last read, with a day's overlap.
A message read twice is kept once.

**Answered like the BKV's.** Where the messages come from the mako365
inbox (`LIEFERANT_QUELLE` `makoflow`), the bridge is the Lieferant's MaKo
system: the [APERAK routine](https://docs.energy.nlead.ch/setup/aperak.md) answers each from the
Lieferant's MP-ID - an Anerkennungsmeldung within the deadline (45 minutes
for a UTILMD), a CONTRL for a syntax fault; a message it cannot read goes
to a person, as for the BKV. From Engrate (`engrate`), Engrate's market
access answers them and the bridge does not. The routine
`lieferant-nachrichten` itself only reads.

## What is read from each message

Every message is named by its Prüfidentifikator as the BDEW
*Anwendungsübersicht der Prüfidentifikatoren* (3.1) names it, with its
group: Lieferantenwechsel, Stammdaten, Bilanzierung, Messwerte, Rechnung,
Preisblatt.
The list holds every electricity PID the Lieferant receives; another is
shown by its number.

| Type | Read in full |
| - | - |
| UTILMD | Per Vorgang (IDE+24): Marktlokation, Messlokation, the dates (Beginn zum, Ende zum, gültig ab ...), the status (Transaktionsgrund, Antwortstatus) and references |
| MSCONS | Per Lokation and OBIS code: the values, their number, sum, unit, period and qualities - a Zählerstand with its point in time |
| INVOIC | Invoice number, kind (IMD), period, due date, Marktlokation, currency, the amounts, taxes (MOA+161) and per position article, quantity - in the price's unit, e.g. the days of a Grundpreis per day -, price and amount; a Stornorechnung names the invoice it cancels (RFF+OI) |
| REMADV | Per document answered: amounts, reasons and texts |
| PRICAT | Along the PRICAT AHB 2.1: which sheet (BGM - the MSB's Messstellenbetrieb, Konfigurationen, Technik; the NB's Sperren/Entsperren, Netznutzung, Blindarbeit, Konzessionsabgaben), whether the sender uses it (BGM 1373 `11`), from when it holds (DTM+157), the sheet it replaces (RFF+ACW), the Netzbetreiber (RFF+Z56), and per position the Artikel-ID or Artikelnummer (LIN), Preisschlüsselstamm (PIA), category - the Preisobergrenze it is for or a Zusatzleistung - and voltage level (IMD), description, and each price with its basis, unit and range (PRI, RNG) |

The readers are tested against AHB-conform messages made by the
edifact-forge for Formatversion FV2610 (`tests/forge/`). Dates are given in
German time. Names and addresses (NAD) are never read,
only MP-IDs. The ledger keeps per message its case, one line - e.g.
"Rechnung R-2026-11 über 117,52 EUR, fällig 17.11.2026" - and the key
data; the full reading is made on request from the kept message, so it
also covers messages read before. Messages kept before the content was
read get their line at the next read.

**Zuordnung per Marktlokation.** The latest supply-change message for a
Marktlokation says whether the Lieferant supplies it: a confirmed
registration (55002, 55078, 55602, 55603, 55607) *beliefert ab*, a
confirmed deregistration or ended Zuordnung (55005, 55037) *beendet zum*,
a refused registration (55003, 55080, 55604, 55605) *abgelehnt*, a
cancelled future Zuordnung (55038) *aufgehoben*.

## Where the data comes from

`LIEFERANT_QUELLE` (console group Lieferant):

* `makoflow` (the default): the mako365 inbox;
* `engrate`: Engrate's market access - supplier switches, accounting
  points with their master data, allocations per Marktlokation and the
  Lieferantensummenzeitreihen (ZA1-ZA3) - once n:lead is set up there as
  supplier. It is not yet, so the inbox is read under `engrate` too and
  every result says so (`hinweis`).

## Endpoints

Process scope; `409` while the role is off.

| Call | Purpose |
| - | - |
| `POST /v1/process/lieferant/nachrichten/lesen` | Read now (`{"dry_run": true}` counts, keeps nothing) |
| `GET /v1/process/lieferant/nachrichten?marktlokation=&typ=&limit=` | The kept messages, newest first |
| `GET /v1/process/lieferant/nachrichten/{schluessel}` | One message read in full (`inhalt`, per message in it) |
| `GET /v1/process/lieferant/nachrichten/{schluessel}/edifact` | One message as it arrived |
| `GET /v1/process/lieferant/marktlokationen` | Per Marktlokation: messages per type, Prüfidentifikatoren with their case, the latest, the Zuordnung |
| `GET /v1/process/lieferant/stand` | Source, MP-ID, the last read, messages and Marktlokationen kept, whether the bridge answers them |

The console shows them on the page *Lieferant*, there only while the role
is on - see [Console](https://docs.energy.nlead.ch/setup/console.md).

The event `lieferant_nachrichten_gelesen` and the Slack log carry counts
per type, never a Marktlokation.


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