GECO AML Labs / Entwicklerreferenz

GECO AML API.

Ressourcen, Zustände und verantwortete Übergaben für Ihre Anwendung.

API-Vertragsvorschau · v0.1

Diese Referenz schlägt einen öffentlichen Integrationsvertrag auf Grundlage eines internen Prototyps vor. Eine freigegebene öffentliche API, produktive SDKs und selbst ausgestellte Testzugänge stehen derzeit nicht bereit. Wir vereinbaren einen API-Pilot anhand Ihres konkreten Arbeitsablaufs.

Stand 28.10.2026REST / JSONOpenAPI 3.1Fiktive Beispiele
WorkspaceMandatVorgangCheck + NachweiseMenschlicher Review

Vor der ersten Anfrage

Host, Zugang und Kontext.

GECO_BASE_URL und GECO_TOKEN sind Variablen für einen später vereinbarten Pilotzugang. Die Beispiele enthalten keinen öffentlichen API-Host und keine nutzbaren Zugangsdaten. Sie werden auf dieser Website nur angezeigt und kopiert.

Basis-URL
Im Pilot festlegen. Der OpenAPI-Download enthält deshalb keinen servers-Eintrag. Keine Kundendaten an eine angenommene Adresse senden.
Authentisierung
Vorgesehen ist ein Bearer-Zugang mit Workspace- und Rollenbindung. Ausstellung, Laufzeit, Rotation und menschlicher Review-Kontext werden vor Implementierung abgestimmt.
Referenzen
Eine Ressourcen-ID allein gibt keinen Zugriff. Mandat, Beteiligte, Nachweise und Checks müssen zum berechtigten Workspace und passenden Vorgang gehören.
Request und Antwort
UTF-8 und application/json. Schreibende Aufrufe tragen einen Idempotency-Key. Fehler verwenden application/problem+json mit technischem request_id.
Versionierung
Entwurf v0.1. Additive Antwortfelder müssen Clients tolerieren; neue Enum-Werte brauchen eine defensive Behandlung. Brechende Änderungen werden im Pilot vorab vereinbart, nicht still ausgeliefert.
Arbeitsbereiche

Arbeitsbereich lesen

GET/workspaces/{workspace_id}

Prüfen Sie zuerst, welchem vereinbarten Arbeitsbereich Ihre Integration zugeordnet ist. Workspaces werden im Pilot eingerichtet; dieser Vertrag bietet keine öffentliche Anlage oder automatische Mandanten-Provisionierung.

Die Workspace-ID strukturiert die Ressourcen. Jede Anfrage braucht zusätzlich eine auf diesen Workspace begrenzte Berechtigung.

Antwortfelder · Workspace

Antwort-Felder

Antwort-Felder: Workspace
Feld / TypBedeutung
idstring · PflichtIm Pilot zugewiesene Arbeitsbereichs-ID; Kenntnis der ID ersetzt keine Berechtigung.
namestring · PflichtVereinbarte Bezeichnung des Arbeitsbereichs.
statusstring · PflichtTechnischer Pilotstatus des Arbeitsbereichs.pilot_setup · pilot_active · suspended
Vorgeschlagenes Request-Beispielführt keine Anfrage aus

cURL

curl --request GET \
  "${GECO_BASE_URL}/workspaces/ws_demo" \
  --header "Authorization: Bearer ${GECO_TOKEN}"

JavaScript · Node.js

const response = await fetch(
  `${process.env.GECO_BASE_URL}/workspaces/ws_demo`,
  {
    method: "GET",
    headers: {
      Authorization: `Bearer ${process.env.GECO_TOKEN}`
    }
  }
);
const body = await response.json();
if (!response.ok) throw new Error(body.code);
console.log(body);

Python · Standardbibliothek

import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

headers = {
    "Authorization": "Bearer " + os.environ["GECO_TOKEN"]
}
request = Request(
    os.environ["GECO_BASE_URL"] + "/workspaces/ws_demo",
    headers=headers,
    method="GET"
)
try:
    with urlopen(request, timeout=30) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))

Vorgeschlagene Antwort200
{
  "id": "ws_demo",
  "name": "Fiktiver Integrationspilot",
  "status": "pilot_setup"
}

Fiktive Beispieldaten · kein Live-Ergebnis

Mandate

Mandat zuordnen

POST/workspaces/{workspace_id}/mandates

Legen Sie die Geschäftsbeziehung an, zu der Personen, Nachweise und einzelne Prüfanlässe gehören. Ihre externe Referenz hält die Verbindung zum bestehenden Kanzlei-, Mandanten- oder Fachsystem.

Ein Mandat kann mehrere Vorgänge enthalten. Die technische Anlage bestätigt weder die Verpflichteteneigenschaft noch eine abgeschlossene Sorgfaltsprüfung.

Request-Felder

Request-Felder: MandateCreate
Feld / TypBedeutung
external_referencestring · PflichtStabile Zuordnung in Ihrer Anwendung; keine Personenangaben im Schlüssel.
labelstring · PflichtArbeitsbezeichnung des Mandats oder der Geschäftsbeziehung.
purposestring · PflichtFachlicher Kontext; keine automatische Feststellung der Verpflichteteneigenschaft.professional_mandate · property_transaction
responsible_rolestring · PflichtFachlich verantwortliche Rolle in Ihrem vereinbarten Ablauf.
Antwortfelder · Mandate

Antwort-Felder

Antwort-Felder: Mandate
Feld / TypBedeutung
idstring · PflichtServerseitige Ressourcen-ID.
workspace_idstring · PflichtZugehöriger, im Pilot eingerichteter Arbeitsbereich.
external_referencestring · PflichtStabile Zuordnung in Ihrer Anwendung; keine Personenangaben im Schlüssel.
labelstring · PflichtArbeitsbezeichnung des Mandats oder der Geschäftsbeziehung.
purposestring · PflichtFachlicher Kontext; keine automatische Feststellung der Verpflichteteneigenschaft.professional_mandate · property_transaction
responsible_rolestring · PflichtFachlich verantwortliche Rolle in Ihrem vereinbarten Ablauf.
statusstring · PflichtBearbeitungsstand der Geschäftsbeziehung.open · on_hold · closed
created_atstring · PflichtServerseitiger Anlagezeitpunkt.
Vorgeschlagenes Request-Beispielführt keine Anfrage aus

cURL

curl --request POST \
  "${GECO_BASE_URL}/workspaces/ws_demo/mandates" \
  --header "Authorization: Bearer ${GECO_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: createMandate_demo_01" \
  --data '{
  "external_reference": "mandate_demo_2026_01",
  "label": "Beispielmandat",
  "purpose": "professional_mandate",
  "responsible_role": "mandate_team"
}'

JavaScript · Node.js

const response = await fetch(
  `${process.env.GECO_BASE_URL}/workspaces/ws_demo/mandates`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GECO_TOKEN}`,
      "Content-Type": "application/json",
      "Idempotency-Key": "createMandate_demo_01"
    },
    body: JSON.stringify({
      "external_reference": "mandate_demo_2026_01",
      "label": "Beispielmandat",
      "purpose": "professional_mandate",
      "responsible_role": "mandate_team"
    })
  }
);
const body = await response.json();
if (!response.ok) throw new Error(body.code);
console.log(body);

Python · Standardbibliothek

import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

payload = json.loads('''{
  "external_reference": "mandate_demo_2026_01",
  "label": "Beispielmandat",
  "purpose": "professional_mandate",
  "responsible_role": "mandate_team"
}''')
headers = {
    "Authorization": "Bearer " + os.environ["GECO_TOKEN"],
    "Content-Type": "application/json",
    "Idempotency-Key": "createMandate_demo_01"
}
request = Request(
    os.environ["GECO_BASE_URL"] + "/workspaces/ws_demo/mandates",
    headers=headers,
    method="POST",
    data=json.dumps(payload).encode("utf-8")
)
try:
    with urlopen(request, timeout=30) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))

Vorgeschlagene Antwort201
{
  "id": "mdt_demo",
  "workspace_id": "ws_demo",
  "external_reference": "mandate_demo_2026_01",
  "label": "Beispielmandat",
  "purpose": "professional_mandate",
  "responsible_role": "mandate_team",
  "status": "open",
  "created_at": "2026-10-28T09:01:00Z"
}

Fiktive Beispieldaten · kein Live-Ergebnis

Beteiligte

Beteiligte erfassen

POST/workspaces/{workspace_id}/parties

Erfassen Sie eine natürliche Person oder Gesellschaft im Kontext eines Mandats. Name und optionale Registerangabe sind zunächst Angaben mit offenem Prüfstand.

Identität, Vertretungsmacht und wirtschaftliche Berechtigung sind verschiedene Fragen. Ein neu erfasster Beteiligter hat verification_state = not_checked.

Request-Felder

Request-Felder: PartyCreate
Feld / TypBedeutung
mandate_idstring · PflichtÜbergeordnetes Mandat im selben Workspace.
kindstring · PflichtTyp der beteiligten Person oder Gesellschaft.natural_person · legal_entity
display_namestring · PflichtFiktiver Beispielname; im Pilot gelten Datenminimierung und vereinbarte Zugriffszwecke.
registrationobject · optionalOptionaler Registerbezug. Eine Angabe ist noch kein Identitätsnachweis.
Antwortfelder · Party

Antwort-Felder

Antwort-Felder: Party
Feld / TypBedeutung
idstring · PflichtServerseitige Ressourcen-ID.
workspace_idstring · PflichtZugehöriger, im Pilot eingerichteter Arbeitsbereich.
mandate_idstring · PflichtÜbergeordnetes Mandat im selben Workspace.
kindstring · PflichtTyp der beteiligten Person oder Gesellschaft.natural_person · legal_entity
display_namestring · PflichtFiktiver Beispielname; im Pilot gelten Datenminimierung und vereinbarte Zugriffszwecke.
registrationobject · optionalOptionaler Registerbezug. Eine Angabe ist noch kein Identitätsnachweis.
verification_statestring · PflichtDokumentierter Identitätsstand. Neu angelegte Angaben starten mit not_checked.not_checked · incomplete · verified · conflicting
Vorgeschlagenes Request-Beispielführt keine Anfrage aus

cURL

curl --request POST \
  "${GECO_BASE_URL}/workspaces/ws_demo/parties" \
  --header "Authorization: Bearer ${GECO_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: createParty_demo_01" \
  --data '{
  "mandate_id": "mdt_demo",
  "kind": "legal_entity",
  "display_name": "Fiktivpark Verwaltung GmbH"
}'

JavaScript · Node.js

const response = await fetch(
  `${process.env.GECO_BASE_URL}/workspaces/ws_demo/parties`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GECO_TOKEN}`,
      "Content-Type": "application/json",
      "Idempotency-Key": "createParty_demo_01"
    },
    body: JSON.stringify({
      "mandate_id": "mdt_demo",
      "kind": "legal_entity",
      "display_name": "Fiktivpark Verwaltung GmbH"
    })
  }
);
const body = await response.json();
if (!response.ok) throw new Error(body.code);
console.log(body);

Python · Standardbibliothek

import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

payload = json.loads('''{
  "mandate_id": "mdt_demo",
  "kind": "legal_entity",
  "display_name": "Fiktivpark Verwaltung GmbH"
}''')
headers = {
    "Authorization": "Bearer " + os.environ["GECO_TOKEN"],
    "Content-Type": "application/json",
    "Idempotency-Key": "createParty_demo_01"
}
request = Request(
    os.environ["GECO_BASE_URL"] + "/workspaces/ws_demo/parties",
    headers=headers,
    method="POST",
    data=json.dumps(payload).encode("utf-8")
)
try:
    with urlopen(request, timeout=30) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))

Vorgeschlagene Antwort201
{
  "id": "pty_demo",
  "workspace_id": "ws_demo",
  "mandate_id": "mdt_demo",
  "kind": "legal_entity",
  "display_name": "Fiktivpark Verwaltung GmbH",
  "verification_state": "not_checked"
}

Fiktive Beispieldaten · kein Live-Ergebnis

Vorgänge

Prüfvorgang eröffnen

POST/workspaces/{workspace_id}/cases

Ein Vorgang verbindet einen konkreten Anlass mit den betroffenen Beteiligten. Beim Wechsel einer Gesellschafterin bleiben das ursprüngliche Mandat und dessen ältere Prüfungen erhalten.

Der neue Vorgang startet in gathering mit version = 1. Zugeordnete Beteiligte müssen zum genannten Mandat im selben Workspace gehören.

Request-Felder

Request-Felder: CaseCreate
Feld / TypBedeutung
mandate_idstring · PflichtMandat, zu dem dieser konkrete Prüfanlass gehört.
party_idsstring[] · PflichtBeteiligte desselben Mandats. Beziehungen und Vertretungsmacht werden gesondert geklärt.
purposestring · PflichtAnlass der Bearbeitung.onboarding · ownership_change · periodic_review · transaction_review
external_referencestring · PflichtVerknüpfung zum Vorgang in Ihrer Anwendung.
Antwortfelder · Case

Antwort-Felder

Antwort-Felder: Case
Feld / TypBedeutung
idstring · PflichtServerseitige Ressourcen-ID.
workspace_idstring · PflichtZugehöriger, im Pilot eingerichteter Arbeitsbereich.
mandate_idstring · PflichtMandat, zu dem dieser konkrete Prüfanlass gehört.
party_idsstring[] · PflichtBeteiligte desselben Mandats. Beziehungen und Vertretungsmacht werden gesondert geklärt.
purposestring · PflichtAnlass der Bearbeitung.onboarding · ownership_change · periodic_review · transaction_review
external_referencestring · PflichtVerknüpfung zum Vorgang in Ihrer Anwendung.
statusstring · PflichtBearbeitungszustand; keine Aussage über gesetzliche Erfüllung.gathering · in_review · decision_recorded · closed
versioninteger · PflichtMonoton steigende Version bei Änderungen an Vorgang, Nachweisen, Checks oder Entscheidungen.
updated_atstring · PflichtServerseitiger Zeitpunkt der letzten Vorgangsänderung.
Vorgeschlagenes Request-Beispielführt keine Anfrage aus

cURL

curl --request POST \
  "${GECO_BASE_URL}/workspaces/ws_demo/cases" \
  --header "Authorization: Bearer ${GECO_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: createCase_demo_01" \
  --data '{
  "mandate_id": "mdt_demo",
  "party_ids": [
    "pty_demo"
  ],
  "purpose": "ownership_change",
  "external_reference": "change_demo_01"
}'

JavaScript · Node.js

const response = await fetch(
  `${process.env.GECO_BASE_URL}/workspaces/ws_demo/cases`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GECO_TOKEN}`,
      "Content-Type": "application/json",
      "Idempotency-Key": "createCase_demo_01"
    },
    body: JSON.stringify({
      "mandate_id": "mdt_demo",
      "party_ids": [
        "pty_demo"
      ],
      "purpose": "ownership_change",
      "external_reference": "change_demo_01"
    })
  }
);
const body = await response.json();
if (!response.ok) throw new Error(body.code);
console.log(body);

Python · Standardbibliothek

import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

payload = json.loads('''{
  "mandate_id": "mdt_demo",
  "party_ids": [
    "pty_demo"
  ],
  "purpose": "ownership_change",
  "external_reference": "change_demo_01"
}''')
headers = {
    "Authorization": "Bearer " + os.environ["GECO_TOKEN"],
    "Content-Type": "application/json",
    "Idempotency-Key": "createCase_demo_01"
}
request = Request(
    os.environ["GECO_BASE_URL"] + "/workspaces/ws_demo/cases",
    headers=headers,
    method="POST",
    data=json.dumps(payload).encode("utf-8")
)
try:
    with urlopen(request, timeout=30) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))

Vorgeschlagene Antwort201
{
  "id": "cas_demo",
  "workspace_id": "ws_demo",
  "mandate_id": "mdt_demo",
  "party_ids": [
    "pty_demo"
  ],
  "purpose": "ownership_change",
  "external_reference": "change_demo_01",
  "status": "gathering",
  "version": 1,
  "updated_at": "2026-10-28T09:02:00Z"
}

Fiktive Beispieldaten · kein Live-Ergebnis

Vorgänge

Vorgangsstand lesen

GET/workspaces/{workspace_id}/cases/{case_id}

Lesen Sie Bearbeitungsstand und aktuelle Version vor einem menschlichen Review erneut. Auch neue Nachweise und abgeschlossene Checks können die Version erhöhen.

expected_case_version einer Entscheidung bezieht sich auf diesen Stand. Ein veralteter Browser darf neu hinzugekommene Informationen nicht still übergehen.

Antwortfelder · Case

Antwort-Felder

Antwort-Felder: Case
Feld / TypBedeutung
idstring · PflichtServerseitige Ressourcen-ID.
workspace_idstring · PflichtZugehöriger, im Pilot eingerichteter Arbeitsbereich.
mandate_idstring · PflichtMandat, zu dem dieser konkrete Prüfanlass gehört.
party_idsstring[] · PflichtBeteiligte desselben Mandats. Beziehungen und Vertretungsmacht werden gesondert geklärt.
purposestring · PflichtAnlass der Bearbeitung.onboarding · ownership_change · periodic_review · transaction_review
external_referencestring · PflichtVerknüpfung zum Vorgang in Ihrer Anwendung.
statusstring · PflichtBearbeitungszustand; keine Aussage über gesetzliche Erfüllung.gathering · in_review · decision_recorded · closed
versioninteger · PflichtMonoton steigende Version bei Änderungen an Vorgang, Nachweisen, Checks oder Entscheidungen.
updated_atstring · PflichtServerseitiger Zeitpunkt der letzten Vorgangsänderung.
Vorgeschlagenes Request-Beispielführt keine Anfrage aus

cURL

curl --request GET \
  "${GECO_BASE_URL}/workspaces/ws_demo/cases/cas_demo" \
  --header "Authorization: Bearer ${GECO_TOKEN}"

JavaScript · Node.js

const response = await fetch(
  `${process.env.GECO_BASE_URL}/workspaces/ws_demo/cases/cas_demo`,
  {
    method: "GET",
    headers: {
      Authorization: `Bearer ${process.env.GECO_TOKEN}`
    }
  }
);
const body = await response.json();
if (!response.ok) throw new Error(body.code);
console.log(body);

Python · Standardbibliothek

import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

headers = {
    "Authorization": "Bearer " + os.environ["GECO_TOKEN"]
}
request = Request(
    os.environ["GECO_BASE_URL"] + "/workspaces/ws_demo/cases/cas_demo",
    headers=headers,
    method="GET"
)
try:
    with urlopen(request, timeout=30) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))

Vorgeschlagene Antwort200
{
  "id": "cas_demo",
  "workspace_id": "ws_demo",
  "mandate_id": "mdt_demo",
  "party_ids": [
    "pty_demo"
  ],
  "purpose": "ownership_change",
  "external_reference": "change_demo_01",
  "status": "gathering",
  "version": 1,
  "updated_at": "2026-10-28T09:02:00Z"
}

Fiktive Beispieldaten · kein Live-Ergebnis

Checks

Abgegrenzten Check anfordern

POST/workspaces/{workspace_id}/cases/{case_id}/checks

Benennen Sie eine einzelne Prüfaufgabe, ihre Beteiligten und die Nachweisbasis. Die tatsächlich zulässigen Datenquellen, fachlichen Kriterien und Anbieterzugänge werden im Pilot vereinbart.

202 Accepted heißt: Auftrag angenommen. status = queued und result_state = unknown sind kein negatives Suchergebnis. Der Vorgang bleibt fachlich offen.

Request-Felder

Request-Felder: CheckCreate
Feld / TypBedeutung
kindstring · PflichtGetrennte Prüfaufgabe. PEP- und Sanktionshinweise bleiben fachlich unterschiedliche Fragen.identity_consistency · beneficial_ownership · pep · sanctions
party_idsstring[] · PflichtFür diesen Check ausgewählte Beteiligte des Vorgangs.
evidence_idsstring[] · PflichtZum Start berücksichtigte Nachweise desselben Vorgangs; darf bei noch fehlenden Nachweisen leer sein.
source_scopestring · PflichtIm Pilot vereinbarte Quellenabdeckung. Der Wert löst keine unvereinbarte Anbieterabfrage aus.
Antwortfelder · Check

Antwort-Felder

Antwort-Felder: Check
Feld / TypBedeutung
idstring · PflichtServerseitige Ressourcen-ID.
workspace_idstring · PflichtZugehöriger, im Pilot eingerichteter Arbeitsbereich.
case_idstring · PflichtZugehöriger Vorgang.
kindstring · PflichtGetrennte Prüfaufgabe. PEP- und Sanktionshinweise bleiben fachlich unterschiedliche Fragen.identity_consistency · beneficial_ownership · pep · sanctions
party_idsstring[] · PflichtFür diesen Check ausgewählte Beteiligte des Vorgangs.
evidence_idsstring[] · PflichtZum Start berücksichtigte Nachweise desselben Vorgangs; darf bei noch fehlenden Nachweisen leer sein.
source_scopestring · PflichtIm Pilot vereinbarte Quellenabdeckung. Der Wert löst keine unvereinbarte Anbieterabfrage aus.
statusstring · PflichtTechnischer Laufzustand. 202 bestätigt nur die Annahme des Auftrags.queued · running · completed · failed
result_statestring · PflichtErgebnis innerhalb der dokumentierten Abdeckung. unknown ist nie gleich no_match.unknown · no_match · potential_match · inconclusive
source_coverageSourceCoverage · PflichtStrukturiertes Objekt; vollständige Felder im OpenAPI-Download.
findingsFinding[] · PflichtPrüfhinweise. Ein leeres Array ist ohne result_state und Quellenabdeckung nicht auswertbar.
created_atstring · PflichtServerseitiger Annahmezeitpunkt.
Vorgeschlagenes Request-Beispielführt keine Anfrage aus

cURL

curl --request POST \
  "${GECO_BASE_URL}/workspaces/ws_demo/cases/cas_demo/checks" \
  --header "Authorization: Bearer ${GECO_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: createCheck_demo_01" \
  --data '{
  "kind": "beneficial_ownership",
  "party_ids": [
    "pty_demo"
  ],
  "evidence_ids": [
    "evd_demo"
  ],
  "source_scope": "agreed_pilot_sources"
}'

JavaScript · Node.js

const response = await fetch(
  `${process.env.GECO_BASE_URL}/workspaces/ws_demo/cases/cas_demo/checks`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GECO_TOKEN}`,
      "Content-Type": "application/json",
      "Idempotency-Key": "createCheck_demo_01"
    },
    body: JSON.stringify({
      "kind": "beneficial_ownership",
      "party_ids": [
        "pty_demo"
      ],
      "evidence_ids": [
        "evd_demo"
      ],
      "source_scope": "agreed_pilot_sources"
    })
  }
);
const body = await response.json();
if (!response.ok) throw new Error(body.code);
console.log(body);

Python · Standardbibliothek

import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

payload = json.loads('''{
  "kind": "beneficial_ownership",
  "party_ids": [
    "pty_demo"
  ],
  "evidence_ids": [
    "evd_demo"
  ],
  "source_scope": "agreed_pilot_sources"
}''')
headers = {
    "Authorization": "Bearer " + os.environ["GECO_TOKEN"],
    "Content-Type": "application/json",
    "Idempotency-Key": "createCheck_demo_01"
}
request = Request(
    os.environ["GECO_BASE_URL"] + "/workspaces/ws_demo/cases/cas_demo/checks",
    headers=headers,
    method="POST",
    data=json.dumps(payload).encode("utf-8")
)
try:
    with urlopen(request, timeout=30) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))

Vorgeschlagene Antwort202
{
  "id": "chk_demo",
  "workspace_id": "ws_demo",
  "case_id": "cas_demo",
  "kind": "beneficial_ownership",
  "party_ids": [
    "pty_demo"
  ],
  "evidence_ids": [
    "evd_demo"
  ],
  "source_scope": "agreed_pilot_sources",
  "status": "queued",
  "result_state": "unknown",
  "source_coverage": {
    "scope": "agreed_pilot_sources",
    "as_of": null,
    "limitations": [
      "Noch keine Auswertung abgeschlossen."
    ]
  },
  "findings": [],
  "created_at": "2026-10-28T09:03:00Z"
}

Fiktive Beispieldaten · kein Live-Ergebnis

Checks

Check und Grenzen lesen

GET/workspaces/{workspace_id}/checks/{check_id}

Lesen Sie Laufstatus, Ergebniszustand, Quellenabdeckung und Hinweise gemeinsam. Im fiktiven Beispiel fehlt eine Beteiligungsebene: Der technische Lauf ist beendet, das Ergebnis bleibt inconclusive.

Ein potential_match ist ein Prüfhinweis. Ein no_match gilt nur für die ausgewiesene Abdeckung und den dokumentierten Stand. Beides ersetzt keine verantwortete Entscheidung.

Antwortfelder · Check

Antwort-Felder

Antwort-Felder: Check
Feld / TypBedeutung
idstring · PflichtServerseitige Ressourcen-ID.
workspace_idstring · PflichtZugehöriger, im Pilot eingerichteter Arbeitsbereich.
case_idstring · PflichtZugehöriger Vorgang.
kindstring · PflichtGetrennte Prüfaufgabe. PEP- und Sanktionshinweise bleiben fachlich unterschiedliche Fragen.identity_consistency · beneficial_ownership · pep · sanctions
party_idsstring[] · PflichtFür diesen Check ausgewählte Beteiligte des Vorgangs.
evidence_idsstring[] · PflichtZum Start berücksichtigte Nachweise desselben Vorgangs; darf bei noch fehlenden Nachweisen leer sein.
source_scopestring · PflichtIm Pilot vereinbarte Quellenabdeckung. Der Wert löst keine unvereinbarte Anbieterabfrage aus.
statusstring · PflichtTechnischer Laufzustand. 202 bestätigt nur die Annahme des Auftrags.queued · running · completed · failed
result_statestring · PflichtErgebnis innerhalb der dokumentierten Abdeckung. unknown ist nie gleich no_match.unknown · no_match · potential_match · inconclusive
source_coverageSourceCoverage · PflichtStrukturiertes Objekt; vollständige Felder im OpenAPI-Download.
findingsFinding[] · PflichtPrüfhinweise. Ein leeres Array ist ohne result_state und Quellenabdeckung nicht auswertbar.
created_atstring · PflichtServerseitiger Annahmezeitpunkt.
Vorgeschlagenes Request-Beispielführt keine Anfrage aus

cURL

curl --request GET \
  "${GECO_BASE_URL}/workspaces/ws_demo/checks/chk_demo" \
  --header "Authorization: Bearer ${GECO_TOKEN}"

JavaScript · Node.js

const response = await fetch(
  `${process.env.GECO_BASE_URL}/workspaces/ws_demo/checks/chk_demo`,
  {
    method: "GET",
    headers: {
      Authorization: `Bearer ${process.env.GECO_TOKEN}`
    }
  }
);
const body = await response.json();
if (!response.ok) throw new Error(body.code);
console.log(body);

Python · Standardbibliothek

import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

headers = {
    "Authorization": "Bearer " + os.environ["GECO_TOKEN"]
}
request = Request(
    os.environ["GECO_BASE_URL"] + "/workspaces/ws_demo/checks/chk_demo",
    headers=headers,
    method="GET"
)
try:
    with urlopen(request, timeout=30) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))

Vorgeschlagene Antwort200
{
  "id": "chk_demo",
  "workspace_id": "ws_demo",
  "case_id": "cas_demo",
  "kind": "beneficial_ownership",
  "party_ids": [
    "pty_demo"
  ],
  "evidence_ids": [
    "evd_demo"
  ],
  "source_scope": "agreed_pilot_sources",
  "status": "completed",
  "result_state": "inconclusive",
  "source_coverage": {
    "scope": "agreed_pilot_sources",
    "as_of": "2026-10-28T09:03:00Z",
    "limitations": [
      "Weitere Beteiligungsebene fehlt."
    ]
  },
  "findings": [
    {
      "party_id": "pty_demo",
      "summary": "Die mittelbare Kontrollgrundlage bleibt offen.",
      "evidence_ids": [
        "evd_demo"
      ]
    }
  ],
  "created_at": "2026-10-28T09:03:00Z"
}

Fiktive Beispieldaten · kein Live-Ergebnis

Nachweise

Nachweis referenzieren

POST/workspaces/{workspace_id}/cases/{case_id}/evidence

Halten Sie Quelle, Eingangszeitpunkt, bekannten Inhaltsstand und den Bezug zur Originaldatei fest. Dokumentenablage, Aufbewahrung und Zugriffsrechte sind Teil der Pilotvereinbarung; dieser Endpunkt nimmt nur Metadaten entgegen.

Unbekannter Inhaltsstand bleibt null. Ein neuer Nachweis ersetzt keine alte Quelle stillschweigend. Der Hash unterstützt die Zuordnung der Bytes und beweist nicht die Richtigkeit der Quelle.

Request-Felder

Request-Felder: EvidenceCreate
Feld / TypBedeutung
kindstring · PflichtArt des referenzierten Nachweises.register_extract · client_document · review_note
labelstring · PflichtFür Bearbeitende lesbarer Dokumenttitel.
source_namestring · PflichtHerkunft des Nachweises, einschließlich manueller Beschaffung.
captured_atstring · PflichtZeitpunkt der Beschaffung oder des Eingangs; nicht automatisch der inhaltliche Gültigkeitsstand.
effective_atstring | null · optionalBekannter inhaltlicher Stand; null bedeutet ausdrücklich unbekannt.
document_referencestring · PflichtReferenz auf das im Pilot vereinbarte Dokumentenlager. Dieser Vertrag lädt keine Datei hoch und ruft keine URL ab.
media_typestring · PflichtMedientyp der Originaldatei.
sha256string · PflichtSHA-256 der Originalbytes zur späteren Zuordnung. Der Hash beweist weder Herkunft noch inhaltliche Richtigkeit.
Antwortfelder · Evidence

Antwort-Felder

Antwort-Felder: Evidence
Feld / TypBedeutung
idstring · PflichtServerseitige Ressourcen-ID.
workspace_idstring · PflichtZugehöriger, im Pilot eingerichteter Arbeitsbereich.
case_idstring · PflichtZugehöriger Vorgang.
kindstring · PflichtArt des referenzierten Nachweises.register_extract · client_document · review_note
labelstring · PflichtFür Bearbeitende lesbarer Dokumenttitel.
source_namestring · PflichtHerkunft des Nachweises, einschließlich manueller Beschaffung.
captured_atstring · PflichtZeitpunkt der Beschaffung oder des Eingangs; nicht automatisch der inhaltliche Gültigkeitsstand.
effective_atstring | null · PflichtBekannter inhaltlicher Stand; null bedeutet ausdrücklich unbekannt.
document_referencestring · PflichtReferenz auf das im Pilot vereinbarte Dokumentenlager. Dieser Vertrag lädt keine Datei hoch und ruft keine URL ab.
media_typestring · PflichtMedientyp der Originaldatei.
sha256string · PflichtSHA-256 der Originalbytes zur späteren Zuordnung. Der Hash beweist weder Herkunft noch inhaltliche Richtigkeit.
recorded_atstring · PflichtServerseitiger Referenzierungszeitpunkt.
Vorgeschlagenes Request-Beispielführt keine Anfrage aus

cURL

curl --request POST \
  "${GECO_BASE_URL}/workspaces/ws_demo/cases/cas_demo/evidence" \
  --header "Authorization: Bearer ${GECO_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: recordEvidence_demo_01" \
  --data '{
  "kind": "client_document",
  "label": "Fiktive Gesellschafterliste",
  "source_name": "Fiktive Mandantenunterlage",
  "captured_at": "2026-10-28T09:00:00Z",
  "effective_at": null,
  "document_reference": "doc_demo_01",
  "media_type": "application/pdf",
  "sha256": "3ce3aca1d1a0791250b6ad07f3de0c093c32ba1c7d86425091fcb67d3233ab73"
}'

JavaScript · Node.js

const response = await fetch(
  `${process.env.GECO_BASE_URL}/workspaces/ws_demo/cases/cas_demo/evidence`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GECO_TOKEN}`,
      "Content-Type": "application/json",
      "Idempotency-Key": "recordEvidence_demo_01"
    },
    body: JSON.stringify({
      "kind": "client_document",
      "label": "Fiktive Gesellschafterliste",
      "source_name": "Fiktive Mandantenunterlage",
      "captured_at": "2026-10-28T09:00:00Z",
      "effective_at": null,
      "document_reference": "doc_demo_01",
      "media_type": "application/pdf",
      "sha256": "3ce3aca1d1a0791250b6ad07f3de0c093c32ba1c7d86425091fcb67d3233ab73"
    })
  }
);
const body = await response.json();
if (!response.ok) throw new Error(body.code);
console.log(body);

Python · Standardbibliothek

import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

payload = json.loads('''{
  "kind": "client_document",
  "label": "Fiktive Gesellschafterliste",
  "source_name": "Fiktive Mandantenunterlage",
  "captured_at": "2026-10-28T09:00:00Z",
  "effective_at": null,
  "document_reference": "doc_demo_01",
  "media_type": "application/pdf",
  "sha256": "3ce3aca1d1a0791250b6ad07f3de0c093c32ba1c7d86425091fcb67d3233ab73"
}''')
headers = {
    "Authorization": "Bearer " + os.environ["GECO_TOKEN"],
    "Content-Type": "application/json",
    "Idempotency-Key": "recordEvidence_demo_01"
}
request = Request(
    os.environ["GECO_BASE_URL"] + "/workspaces/ws_demo/cases/cas_demo/evidence",
    headers=headers,
    method="POST",
    data=json.dumps(payload).encode("utf-8")
)
try:
    with urlopen(request, timeout=30) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))

Vorgeschlagene Antwort201
{
  "id": "evd_demo",
  "workspace_id": "ws_demo",
  "case_id": "cas_demo",
  "kind": "client_document",
  "label": "Fiktive Gesellschafterliste",
  "source_name": "Fiktive Mandantenunterlage",
  "captured_at": "2026-10-28T09:00:00Z",
  "effective_at": null,
  "document_reference": "doc_demo_01",
  "media_type": "application/pdf",
  "sha256": "3ce3aca1d1a0791250b6ad07f3de0c093c32ba1c7d86425091fcb67d3233ab73",
  "recorded_at": "2026-10-28T09:02:30Z"
}

Fiktive Beispieldaten · kein Live-Ergebnis

Entscheidungen

Menschliche Entscheidung festhalten

POST/workspaces/{workspace_id}/cases/{case_id}/decisions

Eine berechtigte menschliche Prüferrolle dokumentiert den nächsten Schritt und dessen Begründung. Die API bindet die Identität serverseitig an die authentisierte Person; ein Maschinenkonto kann sich nicht durch ein frei gesetztes actor_id zum Reviewer machen.

Vorgangsversion, Zugehörigkeit der Referenzen und Prüferrolle werden atomar geprüft. Bei 409 version_conflict zuerst den aktuellen Vorgang lesen und erneut beurteilen. KI-Ausgaben und Matchwerte erzeugen keine Entscheidung.

Request-Felder

Request-Felder: DecisionCreate
Feld / TypBedeutung
expected_case_versioninteger · PflichtZuletzt gelesene Vorgangsversion. Ein veralteter Stand führt zu 409 version_conflict.
outcomestring · PflichtVerantworteter nächster Schritt; keine automatische rechtliche Freigabe oder Meldung.request_information · continue_relationship · escalate · end_relationship
rationalestring · PflichtMenschlich verfasste fachliche Begründung einschließlich offener Fragen.
evidence_idsstring[] · PflichtNachweise, auf die sich die Entscheidung konkret stützt.
check_idsstring[] · PflichtBerücksichtigte Checks. Unbekannte oder widersprüchliche Ergebnisse bleiben im Review erkennbar.
Antwortfelder · Decision

Antwort-Felder

Antwort-Felder: Decision
Feld / TypBedeutung
idstring · PflichtServerseitige Ressourcen-ID.
workspace_idstring · PflichtZugehöriger, im Pilot eingerichteter Arbeitsbereich.
case_idstring · PflichtZugehöriger Vorgang.
expected_case_versioninteger · PflichtZuletzt gelesene Vorgangsversion. Ein veralteter Stand führt zu 409 version_conflict.
outcomestring · PflichtVerantworteter nächster Schritt; keine automatische rechtliche Freigabe oder Meldung.request_information · continue_relationship · escalate · end_relationship
rationalestring · PflichtMenschlich verfasste fachliche Begründung einschließlich offener Fragen.
evidence_idsstring[] · PflichtNachweise, auf die sich die Entscheidung konkret stützt.
check_idsstring[] · PflichtBerücksichtigte Checks. Unbekannte oder widersprüchliche Ergebnisse bleiben im Review erkennbar.
actor_typestring · PflichtDie Entscheidung stammt aus dem menschlichen Review. human
actor_idstring · PflichtServerseitig aus der authentisierten Prüferidentität ermittelt; kein frei gesetzter Benutzername.
resulting_case_versioninteger · PflichtNeue Vorgangsversion nach der atomar gespeicherten Entscheidung.
recorded_atstring · PflichtServerseitiger Entscheidungszeitpunkt.
Vorgeschlagenes Request-Beispielführt keine Anfrage aus

cURL

curl --request POST \
  "${GECO_BASE_URL}/workspaces/ws_demo/cases/cas_demo/decisions" \
  --header "Authorization: Bearer ${GECO_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: recordHumanDecision_demo_01" \
  --data '{
  "expected_case_version": 4,
  "outcome": "request_information",
  "rationale": "Die weitere Beteiligungsebene ist nicht belegt. Das Mandatsteam fordert den fehlenden Strukturnachweis an.",
  "evidence_ids": [
    "evd_demo"
  ],
  "check_ids": [
    "chk_demo"
  ]
}'

JavaScript · Node.js

const response = await fetch(
  `${process.env.GECO_BASE_URL}/workspaces/ws_demo/cases/cas_demo/decisions`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GECO_TOKEN}`,
      "Content-Type": "application/json",
      "Idempotency-Key": "recordHumanDecision_demo_01"
    },
    body: JSON.stringify({
      "expected_case_version": 4,
      "outcome": "request_information",
      "rationale": "Die weitere Beteiligungsebene ist nicht belegt. Das Mandatsteam fordert den fehlenden Strukturnachweis an.",
      "evidence_ids": [
        "evd_demo"
      ],
      "check_ids": [
        "chk_demo"
      ]
    })
  }
);
const body = await response.json();
if (!response.ok) throw new Error(body.code);
console.log(body);

Python · Standardbibliothek

import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

payload = json.loads('''{
  "expected_case_version": 4,
  "outcome": "request_information",
  "rationale": "Die weitere Beteiligungsebene ist nicht belegt. Das Mandatsteam fordert den fehlenden Strukturnachweis an.",
  "evidence_ids": [
    "evd_demo"
  ],
  "check_ids": [
    "chk_demo"
  ]
}''')
headers = {
    "Authorization": "Bearer " + os.environ["GECO_TOKEN"],
    "Content-Type": "application/json",
    "Idempotency-Key": "recordHumanDecision_demo_01"
}
request = Request(
    os.environ["GECO_BASE_URL"] + "/workspaces/ws_demo/cases/cas_demo/decisions",
    headers=headers,
    method="POST",
    data=json.dumps(payload).encode("utf-8")
)
try:
    with urlopen(request, timeout=30) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))

Vorgeschlagene Antwort201
{
  "id": "dec_demo",
  "workspace_id": "ws_demo",
  "case_id": "cas_demo",
  "expected_case_version": 4,
  "outcome": "request_information",
  "rationale": "Die weitere Beteiligungsebene ist nicht belegt. Das Mandatsteam fordert den fehlenden Strukturnachweis an.",
  "evidence_ids": [
    "evd_demo"
  ],
  "check_ids": [
    "chk_demo"
  ],
  "actor_type": "human",
  "actor_id": "usr_reviewer_demo",
  "resulting_case_version": 5,
  "recorded_at": "2026-10-28T09:05:00Z"
}

Fiktive Beispieldaten · kein Live-Ergebnis

Events

Änderungen dauerhaft nachführen

GET/workspaces/{workspace_id}/events

Lesen Sie den fortsetzbaren Eventstrom eines Workspaces in aufsteigender sequence-Reihenfolge. Nutzen Sie nach dem ersten Abruf den opaken next_cursor als after-Parameter. Ein technischer Ausfall darf den fachlichen Übergang nicht unsichtbar machen.

Speichern Sie den Cursor erst nach dauerhafter Verarbeitung aller Events der Seite. Wiederholte Zustellung ist vorgesehen; deduplizieren Sie nach workspace_id und Event-ID, nicht nach Zeitstempel.

Query-Parameter

after ist optional und übernimmt den letzten bestätigten next_cursor. limit: 1–100, Standard 25. Ohne after beginnt der vereinbarte verfügbare Eventbestand; Aufbewahrungsgrenzen werden im Pilot festgelegt.

Antwortfelder · EventList

Antwort-Felder

Antwort-Felder: EventList
Feld / TypBedeutung
dataEvent[] · PflichtEvents in aufsteigender sequence-Reihenfolge.
has_moreboolean · PflichtWeitere Events sind bereits verfügbar.
next_cursorstring | null · PflichtOpaker Fortsetzungscursor; erst nach dauerhafter Verarbeitung speichern.
Vorgeschlagenes Request-Beispielführt keine Anfrage aus

cURL

curl --request GET \
  "${GECO_BASE_URL}/workspaces/ws_demo/events?limit=25" \
  --header "Authorization: Bearer ${GECO_TOKEN}"

JavaScript · Node.js

const response = await fetch(
  `${process.env.GECO_BASE_URL}/workspaces/ws_demo/events?limit=25`,
  {
    method: "GET",
    headers: {
      Authorization: `Bearer ${process.env.GECO_TOKEN}`
    }
  }
);
const body = await response.json();
if (!response.ok) throw new Error(body.code);
console.log(body);

Python · Standardbibliothek

import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

headers = {
    "Authorization": "Bearer " + os.environ["GECO_TOKEN"]
}
request = Request(
    os.environ["GECO_BASE_URL"] + "/workspaces/ws_demo/events?limit=25",
    headers=headers,
    method="GET"
)
try:
    with urlopen(request, timeout=30) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))

Vorgeschlagene Antwort200
{
  "data": [
    {
      "id": "evt_demo",
      "workspace_id": "ws_demo",
      "sequence": 12,
      "type": "decision.recorded",
      "schema_version": "0.1",
      "case_id": "cas_demo",
      "resource": {
        "kind": "decision",
        "id": "dec_demo",
        "version": 5
      },
      "occurred_at": "2026-10-28T09:05:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": "cursor_demo_12"
}

Fiktive Beispieldaten · kein Live-Ergebnis

Keine verkürzten Ergebnisse

Laufstatus, Ergebnis und Entscheidung.

Lesen Sie drei Ebenen getrennt. Der technische Lauf kann beendet sein, obwohl die Tatsachengrundlage offen bleibt. Eine fachliche Entscheidung wird erst durch einen berechtigten menschlichen Review dokumentiert.

queuedrunningcompletedoderfailed

queued, running und failed tragen result_state = unknown. Ein abgeschlossener Lauf liefert no_match, potential_match oder inconclusive, immer zusammen mit seiner Quellenabdeckung.

Vorgeschlagene Ergebniszustände
result_stateBedeutung im Workflow
unknownNoch kein belastbares Ergebnis

Ein Check ist noch nicht abgeschlossen oder ist fehlgeschlagen. Fehlende Abdeckung wird nicht als negatives Ergebnis ausgegeben.

no_matchKein Hinweis in der benannten Abdeckung

Gilt nur für diese Aufgabe, die dokumentierten Quellen und deren Stand. Keine allgemeine Freigabe und kein Nachweis vollständiger Prüfung.

potential_matchHinweis zur menschlichen Einordnung

Ähnliche Merkmale oder ein möglicher Bezug müssen geprüft werden. Ein Hinweis bestätigt weder Personenidentität noch rechtliche Konsequenzen.

inconclusiveDie Grundlage reicht nicht aus

Unvollständige Merkmale oder widersprüchliche Quellen erlauben kein belastbares Ergebnis. Der nächste Informationsbedarf bleibt sichtbar.

Vorgangszustand

gathering hält fehlende Informationen offen. in_review bezeichnet die Bearbeitung durch eine verantwortliche Rolle. decision_recorded dokumentiert einen menschlich begründeten Schritt. closed ist ein ausdrücklich vereinbarter organisatorischer Abschluss. Keiner dieser Zustände bestätigt für sich die Erfüllung gesetzlicher Pflichten.

Neue Informationen können einen weiteren Review auslösen. Eine Entscheidung request_information hält den Vorgang in gathering; ein dokumentierter Schritt kann also existieren, während die Sache offen bleibt. Übergangsregeln und Abschlussrechte werden mit dem fachlichen Ablauf vereinbart.

Wiederholungen ohne Doppelanlage

Ein Auftrag. Ein stabiler Schlüssel.

Der Vorschlag verlangt bei jedem POST einen Idempotency-Key. Er bezeichnet einen beabsichtigten Auftrag, enthält keine personenbezogenen Angaben und bleibt bei einem technischen Retry unverändert.

  1. Scope: Workspace + HTTP-Methode + Pfad + Schlüssel. Ein Schlüssel für eine Entscheidung gilt nicht automatisch für einen anderen Vorgang.
  2. Gleicher Auftrag: Innerhalb des vereinbarten Speicherfensters werden bei gleichem normalisiertem JSON-Body ursprünglicher Status und ursprünglicher Body erneut geliefert. Ressourcenanlage, Event und Idempotenzresultat müssen atomar gesichert werden.
  3. Abweichender Auftrag: Gleicher Schlüssel mit anderem Body führt zu 409 idempotency_conflict. Eine noch laufende erste Anfrage führt zu 409 request_in_progress.
  4. Aufbewahrung: Vorschlag v0.1: mindestens 24 Stunden. Verbindliche Dauer und Wiederanlauf werden im Pilot vereinbart. Nach Ablauf des Speicherfensters oder weiter unklarem Ausgang keinen neuen Schreibauftrag auslösen. Klären Sie den Auftrag und seine Referenzen mit dem vereinbarten Pilotbetrieb. Diese Vorschau unterstützt keinen allgemeinen Lookup über externe Referenzen.
  5. Veralteter Review: expected_case_version schützt zusätzlich den gelesenen Stand. Bei Versionskonflikt aktuellen Vorgang prüfen; erst eine bewusst neu bestätigte Entscheidung erhält einen neuen Schlüssel.

Eine HTTP-Wiederholung und ein fachlich neuer Auftrag sind unterschiedliche Handlungen. Technische Idempotenz ersetzt keine fachliche Prüfung eines geänderten Sachverhalts.

Konkrete Fehlerbehandlung

Fehler zeigen den nächsten Schritt.

Behandeln Sie Status und maschinenlesbaren code gemeinsam. Der request_id dient der technischen Rückfrage; Begründungen und Logmeldungen sollen weder Zugangsdaten noch Dokumentinhalte wiederholen.

Vorgeschlagene Fehler und Behandlung
HTTP / codeIhre Reaktion
400 / 422invalid_request / validation_failedJSON und benannte Felder korrigieren. Bei 422 precondition_failed auch Mandatszuordnung, Nachweisbezug und fachliche Vorbedingungen prüfen. Nicht unverändert wiederholen.
401 / 403unauthenticated / forbiddenAuthentisierung, Workspace-Bindung und benötigte Rolle prüfen. Ein neuer Idempotenzschlüssel löst kein Berechtigungsproblem.
404not_foundRessourcen-ID und Workspace-Kontext abgleichen. Keine Rückschlüsse auf fremde Workspaces ziehen.
409idempotency_conflictDer Schlüssel wurde mit einem anderen Body verwendet. Ursprünglichen Auftrag abgleichen; einen geänderten Auftrag bewusst mit neuem Schlüssel beginnen.
409request_in_progressDie erste Anfrage wird noch verarbeitet. Mit begrenztem Backoff denselben Auftrag und Schlüssel wiederholen.
409version_conflictVorgang neu lesen und neue Informationen fachlich prüfen. Nach bestätigtem neuem Review einen neuen Schlüssel und die aktuelle Version verwenden.
429rate_limitedRetry-After beachten, Anfragerate begrenzen und Wiederholungen entzerren. Keine enge Polling-Schleife.
500 / 503internal_error / source_unavailableInnerhalb des vereinbarten Idempotenzfensters begrenzt mit Backoff wiederholen; Body und Schlüssel beibehalten. Nach Ablauf oder weiter unklarem Ausgang keinen neuen Schreibauftrag auslösen und mit dem vereinbarten Pilotbetrieb klären. Ein Quellenausfall bleibt unbekannt.
Vorgeschlagenes Fehlerbeispiel409
{
  "type": "urn:geco:aml:error:version_conflict",
  "title": "Vorgang wurde geändert",
  "status": 409,
  "code": "version_conflict",
  "detail": "Aktuellen Vorgang lesen und den Review vor einer erneuten Entscheidung prüfen.",
  "request_id": "req_demo_01"
}

Transport-Timeouts lassen den Ausgang offen. Wiederholen Sie einen bereits begonnenen Schreibvorgang innerhalb des vereinbarten Idempotenzfensters begrenzt mit demselben Body und Schlüssel. Danach oder bei weiter unklarem Ausgang stoppen Sie neue Schreibaufträge und klären den Zustand mit dem vereinbarten Pilotbetrieb. Technische Fehler liefern niemals ersatzweise no_match.

Dauerhafte Ereignisse

Events als Protokoll.
Webhooks als Zustellung.

Der Eventstrom ist die Grundlage für Wiederanlauf und Abgleich. Ein Webhook ist im vorgeschlagenen Vertrag eine zusätzliche Zustellform für denselben Event-Umschlag. Empfangsadresse, Schlüssel, Wiederholungsfenster und Betrieb werden im Pilot vereinbart; diese Website registriert keine Webhooks.

  1. Atomare Entstehung: Die Ressourcenänderung und das zugehörige Event werden gemeinsam dauerhaft geschrieben. Eine nachträgliche, flüchtige Benachrichtigung reicht als Auditspur nicht aus.
  2. Mindestens einmal: Duplikate und abweichende Zustellreihenfolge sind möglich. Deduplizieren Sie nach workspace_id + id. Den aktuellen Stand können Sie für Vorgänge und Checks über die vorhandenen GET-Verträge nachladen.
  3. Signatur prüfen: Vorschlag: X-GECO-Signature enthält v1= + HMAC-SHA256 über X-GECO-Timestamp + Punkt + unveränderte Requestbytes. Verwenden Sie den getrennt vereinbarten Empfangsschlüssel und einen Vergleich mit konstanter Laufzeit.
  4. Replay begrenzen: Prüfen Sie einen Zustellzeitstempel im vorgeschlagenen Fenster von ±300 Sekunden, die Event-ID im Header gegen den Body und die Workspace-Bindung. Bei jeder Wiederholung wird die Zustellung neu signiert; die fachliche Event-ID bleibt gleich.
  5. Dauerhaft annehmen: Bestätigen Sie erst nach dem Speichern in einer eigenen Inbox mit 2xx. Fachliche Verarbeitung läuft danach; doppelte Zustellung bestätigt die bereits gespeicherte ID.
  6. Lücken schließen: Bei 5xx, Timeout oder Verarbeitungsabbruch begrenzte Wiederholungen mit Backoff vorsehen. Nach Ausfall den Eventstrom über GET events und den zuletzt sicher gespeicherten Cursor nachführen. Aufbewahrung, Replay und Alarmierung gehören zu den Abnahmekriterien.

Für Mandate, Beteiligte, Nachweise und Entscheidungen enthält diese Vorschau noch keinen eigenen Lese- oder Suchvertrag. Deren Events enthalten Referenzen, keine vollständig abrufbare Prüfmappe. Fehlende Lese- und Wiederanlaufverträge müssen vor einer produktiven Integration vereinbart werden; offene Zustände werden bis dahin mit dem vereinbarten Pilotbetrieb geklärt.

Ein Event meldet einen dokumentierten Übergang. check.completed ist keine Freigabe. decision.recorded belegt einen Review-Eintrag und ist keine behördliche Einreichungsbestätigung.

Rollen, Daten und fachliche Verantwortung

Die Übergabe bleibt nachvollziehbar.

Ihre Anwendung
Erfasst den Anlass, begrenzt Daten und Zugriffe, stellt offene Fragen verständlich dar und führt Aufgaben sowie Eventverarbeitung dauerhaft nach.
Quellen und Nachweise
Werden hinsichtlich Zweck, Berechtigung, Abdeckung, Aktualität und Lagerung vereinbart. Fehlende oder widersprüchliche Angaben bleiben erkennbar. Originaldatei und abgeleiteter Hinweis sind verschieden.
Menschlicher Review
Bewertet die Tatsachengrundlage, begründet den nächsten Schritt und übernimmt die vereinbarte fachliche Verantwortung. Ein KI-Vorschlag oder Matchwert erzeugt keinen Freigabevermerk.
Optionale Unterstützung
DOMUS Fragen ist ein gesondert vereinbartes Modul. Lawyer in the Loop kann durch DOMUS Recht Rechtsanwaltsgesellschaft mbH oder eine andere Kanzlei aus unserem Partnernetzwerk gesondert beauftragt werden. Kanzlei, professionelles Mandat und Leistungsumfang werden konkret vereinbart.
Export und Einreichung
Ein Export bereitet eine Datei oder einen Arbeitsstand vor. Die Entscheidung über eine Meldung, der Übermittlungsschritt und ein tatsächlicher Empfangsnachweis sind eigenständige Vorgänge. Diese API-Vorschau behauptet keine automatische Behördenanbindung.
Datenschutz und Betrieb
Vor einem Pilot: Zwecke, Verantwortlichkeiten, Auftragsverarbeitung, Speicherorte, Lösch- und Aufbewahrungsvorgaben sowie Rollenrechte klären. Logs und Events enthalten nur benötigte Referenzen; die Beispiele hier sind vollständig fiktiv.

Der nächste Schritt

Vom Entwurf zu Ihrem Pilotumfang.

Besprechen wir einen konkreten Prüfanlass, das führende System, Ihre Rollen und die erste messbare Abnahme: ein nachvollziehbarer Vorgang mit Nachweisen, menschlichem Review und verlässlichem Wiederanlauf.

Die Anfrage öffnet die bestehende E-Mail-Vorbereitung. Sie richtet keinen API-Zugang ein und übermittelt keine Akte.