# Kosten per API

Sie können vor jeder Aktion sehen, was sie kostet, und danach nachvollziehen, was gebucht wurde. Alle Beträge sind Netto-Verkaufspreise Ihrer Organisation in EUR. Mit einem **Test-Schlüssel** sehen Sie dieselben Preise, es wird aber nie etwas berechnet (`charged: false`).

## 1. Vorab schätzen: `POST /v1/cost-estimates`

Beschreiben Sie, was Sie vorhaben – die Empfänger eines Vorgangs, Identitätsprüfungen oder Zertifikatskäufe. Es wird nichts angelegt, reserviert oder berechnet.

```http
POST /v1/cost-estimates
Authorization: Bearer qgw_test_…
Content-Type: application/json

{
  "recipients": [
    { "role": "SIGNER", "signatureLevel": "SES" },
    { "role": "SIGNER", "signatureLevel": "QES", "certificateKind": "OTP" },
    { "role": "CC" }
  ],
  "certificatePurchases": [{ "kind": "OTP" }]
}
```

Die Antwort (`object: cost_estimate`) enthält je Posten eine Zeile mit Menge, Einzelpreis und Betrag, die Summe `total` und Hinweise in `notes`. Was Sie dabei wissen sollten:

- Externe Unterzeichner werden je Empfänger berechnet, sobald ihre Signierrunde startet – auch wenn sie nicht unterschreiben – und nach einem Neustart der Runde erneut.
- Freigebende, Betrachter und Kopie-Empfänger (`APPROVER`, `VIEWER`, `CC`) kosten nichts.
- Live-Schlüssel bekommen zusätzlich `withinSpendLimit` und `spendLimit` (siehe unten).

Scope: `billing:read`.

## 2. Beim Senden prüfen: `dryRun`

Die Routen, die Vorgänge anlegen oder senden, kennen `?dryRun=true`: Die Antwort ist eine Vorschau mit Prüfung und Kosten, verändert aber nichts. Beispiele:

- `POST /v1/envelopes/{id}/send?dryRun=true` – Vorschau `envelope_send_preview` mit `costPreview` und `withinSpendLimit`,
- `POST /v1/envelopes?dryRun=true` (mit `send: true` im Body) – dasselbe für einen Vorgang, der noch gar nicht existiert,
- `POST /v1/templates/{id}/envelopes?dryRun=true` – Vorgang aus einer Vorlage,
- `POST /v1/submissions/{id}/envelope?dryRun=true` – Vorgang aus einem Formular-Eingang,
- `POST /v1/envelopes/{id}/restart-external-round?dryRun=true` – Kosten eines Neustarts der Signierrunde.

## 3. Monatliches Ausgabenlimit

Im Dashboard legen Sie für Ihre Organisation ein monatliches Ausgabenlimit fest. Mit einem **harten** Limit lehnt die API Live-Aktionen ab, die es überschreiten würden: 403 / 9017, bevor etwas passiert. Ob eine Aktion noch passt, zeigen `withinSpendLimit` in den Vorschauen und `spendLimit` in der Kostenschätzung. Für Test-Schlüssel gilt kein Limit.

## 4. Nachvollziehen, was gebucht wurde

| Route | Inhalt |
| --- | --- |
| `GET /v1/usage-events` | einzelne gebuchte Posten, neueste zuerst; Filter `usageType`, `envelopeId`, `invoiceId`, `billingClass`, Zeitraum (Scope `billing:read`) |
| `GET /v1/usage` | Summen eines Zeitraums, gruppiert nach Art, Produkt, Vorgang, Mitglied oder Tag; im laufenden Monat mit `projectedInvoice` (Live) |
| `GET /v1/invoices` | Rechnungen und Stornorechnungen, neueste zuerst, mit Zahlstatus `paymentStatus`, offenem Betrag `amountOpen` und Rechnungsnummer `documentNumber` |
| `GET /v1/invoices/{id}/content` | das Rechnungs-PDF |
| `GET /v1/invoices/{id}/usage.csv` | der Einzelnachweis der Rechnung als CSV, genau die bei der Ausstellung gespeicherte Datei (Scope `billing:read`) |

Posten mit Preis 0 (etwa das Siegel des Nachweisprotokolls) stehen mit `included: true` in der Liste und werden nie berechnet. Jeder Posten trägt seine Kontingent-Klasse `billingClass`: `INCLUDED` (aus dem Kontingent), `INCLUDED_COMPANION` (Aufschlag eines Postens aus dem Kontingent), `OVERAGE` (Mehrverbrauch zum Überschreitungspreis) oder `STANDARD` (ohne Kontingent). Die Klasse wird bei der Buchung festgelegt und ändert sich nicht. Neue Rechnungen meldet das Ereignis `invoice.created` (Scope `billing:read`).

## 5. Kontingent abfragen: `GET /v1/quota`

Hat Ihre Organisation einen Vertrag mit Kontingent, zeigt `GET /v1/quota` (Scope `billing:read`) den Stand im laufenden Kalendermonat (Europe/Berlin), je Kontingent:

- `granted` (Menge des Monats samt Bonus), `used`, `reserved` (von offenen Aktionen gehalten) und `remaining` (nie negativ),
- `overage`: bisher gebuchter Mehrverbrauch mit Menge und Betrag (netto) zum Überschreitungspreis,
- `forecast.exhaustedOn`: der Tag, an dem das Kontingent beim Tempo dieses Monats aufgebraucht ist (`null`, wenn es bis Monatsende reicht).

`contract.hardStop: true` heißt: Ist das Kontingent samt Kulanz aufgebraucht, lehnt die API neue kostenpflichtige Live-Aktionen mit 403 / 9017 ab. Ohne Vertrag ist `contract` `null` und `pools` leer. Kontingente gelten nur für Live-Nutzung: Test-Schlüssel erhalten `pools: []`. `creditLimit.status` ist eine Ampel (`ok`, `near`, `reached`) ohne Beträge; `billingHold.status` (`none`, `announced`, `active`) zeigt, ob neue kostenpflichtige Live-Aktionen wegen überfälliger Rechnungen pausiert sind oder eine Pause angekündigt ist.
