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

# APERAK (Quittungen)

> Acknowledging every received message, as the Sparte Strom requires

In der Sparte Strom the receiver of a Geschäftsvorfall owes its sender the
result of the *Verarbeitbarkeitsprüfung* — and owes it in **both**
directions: an **Anerkennungsmeldung** (`BGM+312`) when the Geschäftsvorfall
is free of errors, a **Verarbeitbarkeitsfehlermeldung** (`BGM+313`) when it
is not. APERAK AHB 1.1 (01.04.2026), ch. 2.4:

> Das Ergebnis der Verarbeitbarkeitsprüfung aller in einer Übertragungsdatei
> enthaltenen Geschäftsvorfälle hat der Empfänger der Übertragungsdatei dem
> Absender unverzüglich, jedoch spätestens bis zum nächsten Werktag 12 Uhr
> gesetzlicher deutscher Zeit nach Eingang der Übertragungsdatei, per APERAK
> mitzuteilen \[…]

Saying nothing is not one of the options. Two deadlines apply:

| Received message   | Answer due                                                             |
| ------------------ | ---------------------------------------------------------------------- |
| **UTILMD**, ORDERS | **45 minutes** after the interchange arrives (Saturdays: Sunday 12:00) |
| everything else    | next working day, 12:00 German legal time                              |

<Note>
  This is the mirror image of what the bridge already receives: the positive
  APERAKs partners send for our PARTIN and Zuordnungsermächtigung messages are
  their side of the same obligation.
</Note>

## What the bridge sends

One APERAK per **Geschäftsvorfall**, bundled into a single interchange back
to the sender (AHB ch. 2.2.1):

* `RFF+ACE` — the interchange reference of the message being answered, with
  `DTM+171` carrying that interchange's UNB clock.
* `RFF+AGO` — the document number (`BGM` 1004) of the answered message.
* `RFF+TN` — the Vorgangsnummer, **only** for IFTSTA, INSRPT, UTILMD and
  UTILTS (condition \[16]). A UTILMD with 20 Vorgängen is therefore answered
  by 20 Anerkennungsmeldungen in one envelope; a PARTIN, which has no
  Vorgänge, by exactly one without `RFF+TN`.
* `NAD+MS`/`NAD+MR` with each party's own code-list qualifier (293 BDEW,
  9 GS1) — as everywhere else in the bridge.

References are content-derived, so re-acknowledging the same interchange
produces byte-identical output rather than a second opinion.

## Only the positive answer is automated

A message the bridge cannot even parse is **not** auto-rejected. Guessing an
error code produces a wrong rejection, which is worse for the partner than a
late one — so such a message raises an `aperak_needs_review` warning for a
human instead, and no `BGM+313` is invented. Negative answers stay a
deliberate act.

## Running it

The loop rides on the 15-minute orchestrator (`AUTO_APERAK`, on by default),
which leaves head-room even against the 45-minute UTILMD deadline. Each
interchange is acknowledged once; the ledger `aperak_sent.json` in the audit
share keys on MakoFlow's message id.

In the console the **PARTIN tab** has *Empfangene Nachrichten quittieren*:
*Prüfen* lists what is open, *Prüfen & quittieren* sends. Over the API:

```bash theme={null}
# what is still unanswered
curl -X POST "$BASE/v1/process/aperak/acknowledge" \
  -H "X-API-Key: $PROCESS_API_KEY" -H "Content-Type: application/json" \
  -d '{"dry_run": true}'

# answer it
curl -X POST "$BASE/v1/process/aperak/acknowledge" \
  -H "X-API-Key: $PROCESS_API_KEY" -H "Content-Type: application/json" -d '{}'
```

The response names every acknowledgement, whether it went out after its
deadline (`late`), and how many are left for the next run (`remaining`,
capped by `APERAK_MAX_PER_RUN` so a backlog cannot stall the orchestrator).

## Settings

| Variable               | Default | Meaning                                                   |
| ---------------------- | ------- | --------------------------------------------------------- |
| `AUTO_APERAK`          | `true`  | Acknowledge received messages on every orchestrator run   |
| `APERAK_LOOKBACK_DAYS` | `30`    | How far back the inbox is scanned for unanswered messages |
| `APERAK_MAX_PER_RUN`   | `40`    | Ceiling per run; the remainder follows on the next one    |
