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

# Snapshots

> Monatsabschlüsse und ihre Versionen abrufen, einen Monat erneut abschließen und Nachträge lesen.

Ein Snapshot hält die Zahlen eines abgeschlossenen Monats unveränderlich fest. Investoren und Gremien sehen so immer die Zahl, die zum Abschluss galt, auch wenn später ein Abo nachgetragen wird. Diese Seite zeigt, wie du Snapshots liest und neue Versionen anlegst.

## Was ein Snapshot enthält

Ein Snapshot kopiert die Zahlen, die aus Verträgen entstehen: MRR zu Beginn und am Ende des Monats, die fünf Bewegungen mit Ursachen und Kontenzahlen, Kohorten, Logo-Bewegungen, NRR und GRR, Kundenkonzentration, Verloren nach Kündigungsgrund, und den vertraglich gebundenen MRR. ARR, Umsatz-Churn-Rate und Wachstum werden aus diesen Werten mit denselben Formeln abgeleitet.

Seit dem 28.09.2026 friert ein Snapshot auch die Geldwerte des Monats ein: Zahlungseingang, Zahlungsausgang, Netto-Cash, offene Forderungen am Monatsende und DSO über drei und zwölf Monate. Ältere Snapshots haben diese Werte nicht. Nicht festgehalten werden Accounted MRR, die Differenz Vertrag zu Rechnung, einmaliger und variabler Umsatz und die Rechnungsprognose. Sie zeigen immer den aktuellen Stand und stehen in `meta.notSnapshotted`.

Jeder Snapshot merkt sich in `definitionsVersion`, unter welcher Version des [Definitionskatalogs](https://docs.fynn.eu/v2-finance-api/definitions.md) er entstanden ist.

## Versionen

Version 1 eines Monats entsteht automatisch am 1. des Folgemonats um 05:00 Uhr in der Zeitzone deiner Organisation. Jede weitere Version legst du selbst an, mit einem Grund. Eine neue Version überschreibt nie eine alte. Die Ansicht Stand zum Abschluss nutzt ohne weitere Angabe die neueste Version.

```bash theme={null}
curl https://coreapi.io/api/analytics/finance/snapshots \
  -H "Authorization: Bearer api_DEIN_TOKEN"
```

```json theme={null}
{
  "data": [
    {
      "month": "2026-09",
      "versions": [
        {
          "id": "0199c0de-5a09-7000-8000-000000000901",
          "month": "2026-09",
          "version": 1,
          "takenAt": "2026-10-01T03:00:00+00:00",
          "takenBy": null,
          "reason": null,
          "checksum": "b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6",
          "builtAt": "2026-10-01T02:00:00+00:00",
          "alertedAt": null,
          "latest": true,
          "definitionsVersion": "v5"
        }
      ]
    },
    {
      "month": "2026-08",
      "versions": [
        {
          "id": "0199c0de-5a09-7000-8000-000000000801",
          "month": "2026-08",
          "version": 1,
          "takenAt": "2026-09-01T03:00:00+00:00",
          "takenBy": null,
          "reason": null,
          "checksum": "9c2b6f1e0d4a8c3b7e5f2a1d6c9b0e4f8a7d3c2b1e0f9a8d7c6b5a4f3e2d1c0b",
          "builtAt": "2026-09-01T02:00:00+00:00",
          "alertedAt": null,
          "latest": true,
          "definitionsVersion": "v1"
        }
      ]
    }
  ]
}
```

Monate und Versionen stehen neueste zuerst. `takenBy` ist beim automatischen Abschluss `null`. `checksum` ist ein SHA-256 über die kopierten Zeilen, bei neuen Snapshots einschließlich der Geldwerte, und belegt, dass eine Version unverändert ist. `builtAt` nennt die Berechnung, aus der kopiert wurde. Der August wurde vor dem 28.09.2026 abgeschlossen und trägt deshalb `definitionsVersion: "v1"`, der September `v5`, die Version, die bei seinem Abschluss galt.

## Nachträge

Bei der Taktwerk GmbH hielt der Abschluss für August 2026 einen MRR am Monatsende von 51.646,00 € fest. Am 04.09.2026 wurde ein Abo der Rosenthal Einzelhandel GmbH mit Start im August angelegt. Die laufende Berechnung zeigt seitdem 51.846,00 €. Die Differenz von +200,00 € ist ein Nachtrag.

`GET /api/analytics/finance/snapshots/2026-08/1` liefert die Zahlen von Version 1 und unter `restatements` die Nachträge, die die neueste Berechnung gegenüber dem Snapshot findet:

```json theme={null}
{
  "restatements": [
    {
      "month": "2026-08",
      "level": "cell",
      "subject": "mrr_eop",
      "customer": null,
      "snapshotValue": "51646.00",
      "currentValue": "51846.00",
      "delta": "200.00",
      "cause": "segment_added",
      "causeLabel": "Konto hinzugekommen",
      "changedAt": "2026-09-04T09:31:05+00:00"
    },
    {
      "month": "2026-08",
      "level": "account",
      "subject": "0199c0de-0000-7000-8000-c00000000061",
      "customer": {
        "id": "0199c0de-0000-7000-8000-c00000000061",
        "number": "K-10061",
        "name": "Rosenthal Einzelhandel GmbH"
      },
      "snapshotValue": "0.00",
      "currentValue": "200.00",
      "delta": "200.00",
      "cause": "segment_added",
      "causeLabel": "Konto hinzugekommen",
      "changedAt": "2026-09-04T09:31:05+00:00"
    }
  ]
}
```

| Feld | Bedeutung |
| - | - |
| `level` | `cell` für eine Zahl der Tabelle, `account` für ein einzelnes Konto |
| `subject` | die Zahl (`mrr_eop`, `lost_mrr`, `reasons.lost.contract_end`) oder der Kontoschlüssel |
| `snapshotValue`, `currentValue`, `delta` | Wert im Snapshot, heutiger Wert, Differenz |
| `cause` | `voided`, `pause_changed`, `segment_added`, `segment_removed`, `contract_end_changed`, `price_history_changed`, `quantity_changed`, `discount_changed` oder `source_repair`, dazu `causeLabel` auf Deutsch |

Jeder Nachtrag ist zusätzlich ein Hinweis mit dem Code `RESTATEMENT`. Der Datensatz `recurring` markiert betroffene Zellen in `mrrCells[...].restatement`. Übersteigen die Nachträge eines Monats den Anteil `mrrRestatementAlertShare` seines MRR (Voreinstellung 1 %), entsteht einmalig eine Warnung, und `alertedAt` der Version wird gesetzt. Die +200,00 € im Beispiel sind 0,39 % von 51.646,00 € und lösen keine Warnung aus.

## Einen Monat erneut abschließen

Soll ein festgehaltener Monat die Korrektur enthalten, legst du eine neue Version an. Dafür brauchst du `analytics:write`. Der Grund ist Pflicht, höchstens 500 Zeichen lang und bleibt bei der Version gespeichert.

```bash theme={null}
curl -X POST https://coreapi.io/api/analytics/finance/snapshots \
  -H "Authorization: Bearer api_DEIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"month": "2026-08", "reason": "Abo der Rosenthal Einzelhandel GmbH mit Start im August nachgetragen"}'
```

Antwort `201 Created`:

```json theme={null}
{
  "id": "0199c0de-5a09-7000-8000-000000000802",
  "month": "2026-08",
  "version": 2,
  "takenAt": "2026-10-02T08:12:40+00:00",
  "takenBy": "Lena Hoffmann",
  "reason": "Abo der Rosenthal Einzelhandel GmbH mit Start im August nachgetragen",
  "checksum": "3e8d1a7c5b2f9e0d4c6a8b1f7e3d2c9a0b5f4e1d8c7a6b3e2f1d0c9b8a7e6f5d",
  "builtAt": "2026-10-02T08:00:00+00:00",
  "alertedAt": null,
  "latest": true,
  "definitionsVersion": "v5"
}
```

Version 2 kopiert die Zahlen der aktuellen Berechnung, der August endet darin mit 51.846,00 €. Weil sie nach dem 28.09.2026 entstanden ist, enthält sie auch die Geldwerte des August und trägt `definitionsVersion: "v5"`. Der Nachtrag gegenüber Version 1 bleibt in Version 1 lesbar, gegenüber der neuesten Version gibt es keinen mehr.

Ein Monat, der noch läuft, lässt sich nicht abschließen. Die API antwortet dann mit `422` und nennt das Feld:

```json theme={null}
{
  "status": 422,
  "type": "ANALYTICS_MRR_FINANCIALS__SNAPSHOT_MONTH_NOT_ENDED",
  "title": "An error occurred",
  "detail": "Der Monat 2026-10 ist noch nicht abgelaufen.",
  "month": "2026-10",
  "violations": [
    {
      "propertyPath": "month",
      "message": "Der Monat 2026-10 ist noch nicht abgelaufen.",
      "code": "analytics.finance.month_not_ended"
    }
  ]
}
```

Gibt es noch gar keine Berechnung, antwortet die API mit `409` und dem Typ `ANALYTICS_MRR_FINANCIALS__SNAPSHOT_WITHOUT_BUILD`. Lief die letzte Berechnung vor dem Monatsende, lautet der Typ `ANALYTICS_MRR_FINANCIALS__SNAPSHOT_BUILD_BEFORE_MONTH_END`. Starte dann eine neue Berechnung und nimm den Snapshot danach. Fehlt der Grund, antwortet die API mit `422` und `violations[reason]`.

## Einen Snapshot lesen

`GET /api/analytics/finance/snapshots/{month}/{version}` liefert den Snapshot-Monat und die elf Monate davor, jeden Monat so, wie sein eigener Snapshot beim Anlegen dieser Version stand. `versions` nennt je Monat die verwendete Version. Die Felder `kpis`, `movementMonths`, `cohorts`, `logos`, `retention`, `concentration`, `churnReasons` und `backlog` haben die Form der [Datensätze](https://docs.fynn.eu/v2-finance-api/datasets.md). `restatements` kommt aus der laufenden Berechnung.

Drei Felder sagen je Monat, woher die Zahlen stammen:

| Feld | Bedeutung |
| - | - |
| `frozen` | `true`, wenn die MRR-Zahlen des Monats aus einem Snapshot kommen. `false` für einen Monat ohne jeden Snapshot: Er zeigt die aktuelle Berechnung. |
| `moneyFrozen` | `true`, wenn die Geldwerte des Monats mit seinem Snapshot eingefroren sind |
| `money` | die eingefrorenen Geldwerte, `null` wo `moneyFrozen` `false` ist |

Ausschnitt aus `GET /api/analytics/finance/snapshots/2026-09/1` für die letzten drei der zwölf Monate:

```json theme={null}
{
  "months": [
    "2026-07",
    "2026-08",
    "2026-09"
  ],
  "frozen": [
    true,
    true,
    true
  ],
  "moneyFrozen": [
    false,
    false,
    true
  ],
  "money": [
    null,
    null,
    {
      "month": "2026-09",
      "collected": "59869.28",
      "refunded": "0.00",
      "net": "59869.28",
      "receivables": "28656.90",
      "dso3m": "13.3",
      "dso12m": "15.1"
    }
  ]
}
```

Juli und August wurden vor dem 28.09.2026 abgeschlossen, ihre Geldwerte kommen aus der aktuellen Berechnung. Der September hat sie eingefroren: 59.869,28 € Zahlungseingang und 28.656,90 € offene Forderungen am Monatsende.

Den bekannten MRR der Zukunft hält ein Snapshot nicht fest: `backlog.forward` enthält nur den Snapshot-Monat, `backlog.events` ist leer. Gibt es Monat oder Version nicht, antwortet die API mit `404` und dem Typ `ANALYTICS_FINANCE__SNAPSHOT_NOT_FOUND`.
