# GovStack-Bausteine

> nexxus bietet zwei GovStack-Bausteine über ihre GovStack-Schnittstellen an. Digital Registries läuft auf den Datensätzen installierter Pakete, Messaging auf der Warteschlange für ausgehende Mails. Diese Seite erklärt, worauf jeder Baustein abbildet, wie Sie ihn aufrufen, wo nexxus von den Vorlagen abweicht und welche Bausteine es nicht abdeckt.

[GovStack](https://specs.govstack.global) beschreibt digitale Verwaltungsleistungen als Satz von **Bausteinen** (Building Blocks): ein Register, Nachrichtenversand, eine Workflow-Engine, Identität, Zahlungen und weitere. Jeder Baustein hat eine Spezifikation mit Schnittstelle. So kann eine Behörde Produkte verschiedener Anbieter kombinieren und eines austauschen, ohne die Leistung neu zu schreiben.

nexxus setzt zwei Bausteine mit den Schnittstellen ihrer GovStack-Vorlagen um. Sie bauen auf dem auf, was nexxus schon hat. Es gibt also nichts zu installieren: Jede nexxus-Instanz antwortet unter `/api/govstack`.

<Flow
  steps={[
    { icon: 'key-round', title: 'API-Token', text: 'Ein GovStack-Client ruft mit einem persönlichen API-Token auf.' },
    { icon: 'shield-check', title: 'Dieselben Rechte', text: 'nexxus prüft die Rechte der Person, der das Token gehört, wie in der App.' },
    { icon: 'blocks', title: 'Baustein', text: 'Registries oder Messaging antworten im GovStack-Format.' },
  ]}
  caption="Ein GovStack-Aufruf ist ein gewöhnlicher Aufruf der nexxus-API, mit den Pfaden und Rümpfen von GovStack."
/>

## Was nexxus abdeckt

| Baustein | In nexxus | Basispfad |
|---|---|---|
| [Digital Registries](#digital-registries) | Die Datensätze installierter [Pakete](/de/modules/overview/): Jedes Datenobjekt eines Pakets ist ein Register | `/api/govstack/registries` |
| [Messaging](#messaging) | E-Mail über die Warteschlange für ausgehende Mails | `/api/govstack/messaging` |

Diese Bausteine bietet nexxus **nicht** als GovStack-Schnittstelle an:

| Baustein | Warum, und was nexxus stattdessen hat |
|---|---|
| Identity | nexxus ist [OpenID-Connect-Anbieter](/de/setup/sign-in/) für andere Anwendungen, hat aber kein Identitätsregister und keine GovStack-Identity-Schnittstelle. |
| Consent | Kein Einwilligungsregister. Pakete können in ihren Formularen Einwilligungen abfragen und beim Datensatz ablegen. |
| Registration | Keine GovStack-Registration-Schnittstelle. Pakete können Formulare mit persönlichen Links und ein Portal veröffentlichen. |
| Scheduler | Keine Schnittstelle für Termine oder Ereignisse. |
| Workflow | Keine Prozess-Engine. Das Workflow-Modul und mit ihm die GovStack-Workflow-Schnittstelle sind im November 2026 entfallen. Wer erfahren will, wann Datensätze bestimmte Bedingungen erfüllen, legt unter <Ui>Mein Profil</Ui> › <Ui>Regeln</Ui> eine Benachrichtigungsregel an. |
| Information Mediator | Nicht Teil von nexxus. Schalten Sie einen X-Road-Security-Server davor, wenn Ihre Dienste darüber sprechen. nexxus nimmt den Header `Information-Mediator-Client` an und verlangt ihn nicht. |
| E-Signature, Payments, Wallet, GIS, E-Marketplace, Cloud Infrastructure | Nicht angeboten. nexxus hat Karten für Pakete, aber keine GovStack-GIS-Schnittstelle. |

## Bevor Sie anfangen

- Ein **persönliches API-Token** des Kontos, als das der Client handelt. Siehe [Persönliche API-Tokens](/de/setup/security/#persönliche-api-tokens). Das Token hat genau die Rechte seines Besitzers: Ein GovStack-Client sieht und ändert nie mehr, als diese Person in der App könnte.
- Die **Rechte** des Bausteins:

| Baustein | Lesen | Schreiben |
|---|---|---|
| Digital Registries | `<paket>.<datenobjekt>.read`, z. B. `curiaos.kanzlei.akte.read` | `<paket>.<datenobjekt>.write` |
| Messaging | `communication.email.read` (Status) | `communication.email.send` (Senden) |

`communication.email.send` ist ein eigener Schlüssel und heißt im Rollen-Editor <Ui>Neue E-Mails senden (Schnittstelle)</Ui>, beim Modul <Ui>E-Mails</Ui>. Sonst lässt nexxus niemanden eine neue Mail an eine beliebige Adresse schreiben. Deshalb haben ihn nur Administratoren, bis eine Rolle ihn vergibt.

## Anmeldung

Senden Sie das Token als `Authorization: Bearer cx_...`. Die GovStack-Vorlagen benennen den Header anders, deshalb nehmen die GovStack-Pfade auch `Authorization: cx_...` und `apiKey: cx_...` an.

```bash
# Welche Bausteine dieses nexxus anbietet, mit Links zu den verwendeten Schnittstellenbeschreibungen
curl -H "Authorization: Bearer cx_..." https://<Ihre nexxus-Adresse>/api/govstack
```

## Digital Registries

Ein **Register** ist ein Datenobjekt eines installierten Pakets. Sein Name ist `<paket>.<datenobjekt>`, zum Beispiel `curiaos.kanzlei.akte` für die Akten von CuriaOS. Seine **Version** ist die installierte Version des Pakets: GovStack hält Schema- und Schnittstellenversion gleich, und in nexxus ändert sich ein Schema nur, wenn eine neue Paketversion installiert wird. Die Pfade folgen den Vorlagen 1.3.0 der Daten- und der Datenbank-Schnittstelle des Bausteins.

nexxus baut die Schemas aus dem Paket-Manifest. `GET /api/govstack/registries/openapi.json` liefert ein OpenAPI-3.1-Dokument mit konkreten Pfaden und einem JSON Schema für jedes Register, das Sie lesen dürfen: Auswahlfelder nennen ihre Schlüssel als `enum`, Verweise sagen, worauf sie zeigen.

### Ein Datensatz

Ein Datensatz besteht aus seinen Feldern und fünf Hüllschlüsseln. Feldschlüssel beginnen nie mit `$`, die beiden können also nicht kollidieren.

```json
{
  "$id": 61,
  "$title": "2026/0206",
  "$version": 1,
  "$createdAt": "2026-10-20T07:08:31.104Z",
  "$updatedAt": "2026-10-20T07:08:44.927Z",
  "betreff": "Auffahrunfall B 15",
  "status": "in_bearbeitung",
  "mandant": 9
}
```

| Schlüssel | Bedeutung |
|---|---|
| `$id` | Id des Datensatzes. Für Pfade (`/{id}/delete`) und Abfragen. |
| `$title` | Anzeigename, wie die App ihn zeigt. |
| `$version` | Version des Datensatzes. Schicken Sie sie in `write.content` mit, und nexxus lehnt die Änderung mit einem [Konflikt](#problemtypen) ab, wenn jemand den Datensatz zwischendurch geändert hat. |
| `$createdAt`, `$updatedAt` | Zeitpunkte in UTC. |

Hüllschlüssel in dem, was Sie schreiben, übergeht nexxus, außer `$version`.

### Pfade

Alle Pfade beginnen mit `/api/govstack/registries`. `{r}` ist der Name des Registers, `{v}` seine installierte Version.

| Methode | Pfad | Was er tut |
|---|---|---|
| GET | `/databases` | Jedes Register, das Sie lesen dürfen, nach Paket gruppiert, mit Schema und Pfaden. |
| GET | `/database/{id}` | Ein Register, über seine numerische `id` oder seinen Namen. |
| GET | `/openapi.json` | Das OpenAPI-3.1-Dokument Ihrer Register. |
| GET | `/data/{r}/{v}` | Eine Seite Datensätze. Siehe [Auflisten](#auflisten). |
| POST | `/data/{r}/{v}/create` | Legt einen Datensatz aus `write.content` an. |
| POST | `/data/{r}/{v}/read` | Der eine Datensatz, auf den `query.content` passt. |
| POST | `/data/{r}/{v}/exists` | Ob ein Datensatz auf `query.content` passt. |
| PUT | `/data/{r}/{v}/update` | Ändert die Felder aus `write.content` an dem einen Datensatz, auf den `query.content` passt. |
| PUT | `/data/{r}/{v}/updateEntries` | Ändert jeden passenden Datensatz, höchstens 1.000, alle oder keinen. |
| POST | `/data/{r}/{v}/updateOrCreate` | Ändert den einen passenden Datensatz oder legt ihn aus `write.content` an. |
| DELETE | `/data/{r}/{v}/{id}/delete` | Löscht den Datensatz. |
| GET | `/data/{r}/{v}/{id}/readValue/{field}.{ext}` | Ein Feld als Datei. Ein Dokumentfeld liefert das Dokument, jedes andere Feld `json` oder `txt`. |

### Abfragen

`query.content` nennt Felder und ihre genauen Werte. Alle müssen zutreffen.

```bash
curl -X POST https://<Ihre nexxus-Adresse>/api/govstack/registries/data/curiaos.kanzlei.akte/1.1.0/read \
  -H "Authorization: Bearer cx_..." -H "Content-Type: application/json" \
  -d '{"query": {"content": {"aktenzeichen": "2026/0192"}}}'
```

- Jedes Feld lässt sich abfragen, nicht nur die, die ein Paket als indiziert kennzeichnet.
- `$id` wählt einen Datensatz über seine Id.
- Ein Listenfeld passt, wenn es den Wert enthält.
- `read`, `update` und `updateOrCreate` brauchen genau einen Treffer. Mehrere Treffer sind ein [Problem](#problemtypen) vom Typ `ambiguous-query` mit der Anzahl in `count`, nie eine stille Wahl des ersten.

### Auflisten

`GET /data/{r}/{v}` liefert `count`, `next` und `previous` (Links auf die Nachbarseiten oder null) und `results`.

| Parameter | Bedeutung |
|---|---|
| `search` | Freitextsuche über die Suchfelder des Registers, wie das Suchfeld in der App. |
| `query.<feld>` | Genauer Wert eines Felds. Für weitere Felder wiederholen. |
| `filter`, `ordering` | Sortierung, wie die Vorlage sie benennt: `filter` ist das Feld, `ordering` ist `ascending` oder `descending`. `ordering` allein nimmt ein Feld mit optionalem `-` davor (`-$updatedAt`). Sortieren braucht ein indiziertes Feld, `$id`, `$createdAt` oder `$updatedAt`. |
| `page` | Seitennummer, ab 1. |
| `pageSize` | Datensätze je Seite, 1 bis 200. Vorgabe 10. |

### Wo nexxus von der Vorlage abweicht

- Schemas kommen aus signierten Paketen. `POST /database/modify` und `DELETE /database/{id}` antworten mit `not-supported`: Installieren oder aktualisieren Sie das Paket stattdessen unter <MenuPath to="Administration > Betrieb > Module" />, Reiter <Ui>Pakete</Ui>.
- `GET /data/mypersonalDataUsage` antwortet mit `not-supported`. nexxus protokolliert nicht, wer einen Datensatz gelesen hat. Änderungen stehen im [Änderungsprotokoll](/de/setup/security/#das-änderungsprotokoll).
- `GET /databases` liefert eine Liste von Gruppen, eine je Paket, jede mit ihren `databases`.
- Löschen ist ein weiches Löschen, wie überall in nexxus.

## Messaging

Die Messaging-Pfade folgen dem E-Mail-Teil der GovStack-Messaging-Schnittstelle. Alle Pfade beginnen mit `/api/govstack/messaging`.

| Methode | Pfad | Was er tut |
|---|---|---|
| POST | `/send/email/single` | Reiht eine Mail ein. Antwortet mit einer `requestUID`. |
| POST | `/send/email/batch` | Reiht je Empfänger aus `recipientInfo.batchEmailAsBase64` eine Mail ein, höchstens 1.000, unter einer `requestUID`. nexxus prüft jeden Empfänger, bevor es den ersten einreiht. |
| GET | `/status/email` | Zählt die Mails einer Anfrage nach Zustand. Header `requestUid`, optional `status`, um Zustände zu wählen. |

```bash
curl -X POST https://<Ihre nexxus-Adresse>/api/govstack/messaging/send/email/single \
  -H "Authorization: Bearer cx_..." -H "Content-Type: application/json" \
  -d '{"senderInfo": {"replyTo": "buero@example.org"},
       "recipientInfo": {"email": "buergerin@example.org"},
       "emailContent": {"encoding": "UTF-8", "title": "Ihr Antrag", "content": "Guten Tag,\nIhr Antrag ist eingegangen."}}'
```

Was nexxus mit einer Anfrage macht:

- **Absender** ist immer die Absenderadresse des Mandanten, die bei der [Einrichtung](/de/setup/first-run/) für den Postausgangsserver eingetragen wurde. `senderInfo.replyTo`, sonst `senderInfo.email`, wird zur Antwortadresse (Reply-To). Ein GovStack-Client kann nicht im Namen anderer senden.
- `emailContent.content` ist reiner Text. nexxus maskiert ihn für den HTML-Teil, er kann also keine Links oder Auszeichnungen tragen. Zeilenumbrüche bleiben.
- `emailContent.title` ist eine Zeile mit höchstens 998 Zeichen, der Inhalt höchstens 100.000 Zeichen lang. Nur UTF-8 wird angenommen.
- Jede Adresse ist eine einzelne Adresse. `emailCC` und `emailBCC` nehmen je eine.
- `callback.uri` übergeht nexxus. Fragen Sie stattdessen `/status/email`.

### Zustände

| GovStack-Zustand | In nexxus |
|---|---|
| `scheduled` | In der Warteschlange, noch nicht versucht. Ohne Postausgangsserver bleiben Mails hier. |
| `deferred` | Nach einem Fehlversuch in der Warteschlange, oder angehalten. |
| `delivered` | Vom Postausgangsserver angenommen. Danach erfährt nexxus nichts mehr. |
| `notSent` | Nach dem letzten Versuch aufgegeben, oder endgültig gescheitert. |
| `processing`, `bounced` | Immer 0. nexxus verschickt jede Mail in einem Schritt und sieht keine Rückläufer. |

`POST /callback/email` antwortet mit `not-supported`. Antworten erreichen nexxus als eingehende Mail eines Postfachs.

## Problemtypen

Jeder Fehler der GovStack-Pfade ist ein Problem-Dokument nach RFC 9457 mit dem Medientyp `application/problem+json`. Verzweigen Sie über `type`. `detail` erklärt den Fall für einen Menschen, und `errors` nennt die Felder, die ihn ausgelöst haben. Diese Texte kommen von der Plattform und können deutsch sein; `type` und die Schlüssel von `errors` ändern sich nie mit der Sprache.

```json
{
  "type": "https://nexxus-ai.systaro.de/docs/reference/govstack/#problem-version-not-installed",
  "title": "This registry version is not installed",
  "status": 404,
  "detail": "Registry 'curiaos.kanzlei.akte' is installed at version 1.1.0, not 1.0.0.",
  "instance": "/api/govstack/registries/data/curiaos.kanzlei.akte/1.0.0",
  "installedVersion": "1.1.0"
}
```

| Typ | Status | Wann |
|---|---|---|
| <span id="problem-validation">`validation`</span> | 400 | Die Anfrage verletzt eine Regel: ein fehlendes oder unbekanntes Feld, ein unpassender Wert, eine Adresse, die keine einzelne Adresse ist. |
| <span id="problem-forbidden">`forbidden`</span> | 403 | Der Person, der das Token gehört, fehlt das Recht. |
| <span id="problem-not-found">`not-found`</span> | 404 | Kein solches Register, kein solcher Datensatz oder Auftrag. `read` antwortet mit `no record found`. |
| <span id="problem-version-not-installed">`version-not-installed`</span> | 404 | Der Pfad nennt eine andere als die installierte Version. `installedVersion` sagt, welche installiert ist. |
| <span id="problem-conflict">`conflict`</span> | 409 | `$version` ist veraltet. |
| <span id="problem-ambiguous-query">`ambiguous-query`</span> | 409 | Die Abfrage passt auf mehr als einen Datensatz. `count` sagt, auf wie viele. |
| <span id="problem-unique">`unique`</span> | 409 | Ein Wert, der eindeutig sein muss, ist vergeben. `errors` nennt das Feld. |
| <span id="problem-not-supported">`not-supported`</span> | 501 | nexxus bietet diesen Pfad nicht an. `detail` sagt, was stattdessen geht. |
| <span id="problem-internal">`internal`</span> | 500 | Auf dem Server ist etwas gescheitert. Das Server-Log hat die Einzelheiten. |

Ein fehlendes oder ungültiges Token lehnt nexxus schon vor den GovStack-Pfaden ab, mit Status 401 und dem JSON der Anmeldung, nicht mit einem Problem-Dokument.

## Wie es weitergeht

<CardGrid>
  <LinkCard title="Sicherheit" description="Persönliche API-Tokens anlegen, rotieren und zurückziehen." href="/de/setup/security/#persönliche-api-tokens" />
  <LinkCard title="Berechtigungen" description="Jeder Berechtigungsschlüssel, auch communication.email.send." href="/de/reference/permissions/" />
  <LinkCard title="Module (NXM)" description="Pakete, ihre Datenobjekte und wie sie installiert werden." href="/de/modules/overview/" />
</CardGrid>