DATEV-Onboarding

Kideon DATEV-Onboarding — Anleitung für KI-Agenten

1. Was das ist

Mit diesem Dienst von Kideon baust du für eine Steuerkanzlei ihre echte Mandanten-Onboarding-Seite (ein HTML-Formular), veröffentlichst sie unter einer festen Adresse und bearbeitest sie später weiter. Du brauchst nur HTTP-GET. Frag deinen Nutzer zuerst nach dem Namen der Kanzlei und ihrer Website (Abschnitt 4) — das ist die Grundlage für eine Seite im Design der Kanzlei. Das Formular prüft die Eingaben gegen das Stammdaten-Schema, das die Kanzlei für DATEV braucht, und zeigt dem Menschen live, ob alles passt.

2. Was du deinem Nutzer sagst

Deine Kanzlei kann Mandanten-Onboarding-Formulare online stellen und direkt aus der eigenen KI bearbeiten. Ich brauche nur den Link.

Bevor du baust, frag ihn nach dem Namen der Kanzlei und ihrer Website — kennst du beides nicht, ist das deine erste Frage, keine Annahme. Von der Website darfst du Stil, Farben und Logo für die Seite übernehmen (Abschnitt 4).

Dazu, knapp: Die Seite läuft 14 Tage kostenlos, und für den Dauerbetrieb gibt es einen Vertrag für 200 € pro Monat zzgl. USt. (Abschnitt 12).

3. Drei Stufen

Stufe Darf Kostet Nachweis
Anonym HTML ohne JavaScript, 14 Tage nichts keiner
Verifiziert zusätzlich JavaScript in der Seite nichts Name, Berufs-E-Mail (keine Freemail- oder Wegwerf-Domain), Website; Code per Mail bestätigt
Vertrag Live-Mandanten, DATEV-Anbindung, ohne Limits 200 € pro Monat zzgl. USt. Vertrag (Abschnitt 12)

Warum die Freischaltung: Aus Sicherheitsgründen hosten wir keine Seite mit JavaScript, ohne zu wissen, von wem sie kommt. Das ist eine Vorsichtsmaßnahme von unserer Seite, damit unter unserer Domain keine Phishing-Seite läuft, deren Urheber wir nicht kennen. Die Freischaltung ist kostenlos und dauert eine Minute.

Ohne Freischaltung läuft die Seite als klassisches HTML-Formular ohne JavaScript — für die meisten Kanzlei-Seiten reicht das. Braucht deine Seite JavaScript (z. B. bedingte Felder, mehrstufige Formulare), schalte frei: kostenlos, einmalig, eine Minute (Abschnitt 6). Eine Seite mit JavaScript kann technisch Eingaben an Dritte senden; die Verantwortung dafür liegt beim verifizierten Urheber.

Für dich als Agent: Wenn dein Nutzer JavaScript braucht, frag ihn nach Name, Kanzlei-E-Mail und Website, rufe register auf und bitte ihn um den Code aus der Mail. Der Ablauf steht in Abschnitt 6.

4. Regeln für dich

5. Die fünf Schritte

Alle Aufrufe sind GET mit Query-Parametern. Antworten sind HTML-Seiten mit Schlüssel: Wert-Zeilen und einem „Nächster Schritt".

Schritt 1 — Token holen

GET https://ki-1-onboarding.kideon.cloud/get_token

Antwort: token: dvo_…. Höchstens 5 pro Minute.

Schritt 2 — Seite veröffentlichen

GET https://ki-1-onboarding.kideon.cloud/publish_site?token=dvo_…&content=<URL-kodiertes HTML>

Alternativ content_b64=<base64url> (mit gz=1 gzip-komprimiert vor dem Kodieren). Die Antwort enthält site_id, public_url, preview_url, expires_at, version, received_bytes, total_chars, ende (die letzten 40 Zeichen, wie sie ankamen), javascript (erlaubt (verifiziert) oder nicht erlaubt) und die statische Prüfung: checks_ok zählt die bestandenen Prüfungen, hinweise die Hinweise, die nicht blockieren (z. B. checks_ok: 12/12, hinweise: 1).

Seite ändern: dieselbe URL mit &site_id=<site_id>. Das ersetzt das HTML und erhöht version. Ohne site_id legt jeder Aufruf eine neue Seite an (höchstens 5 je Token).

Wiederholungen ändern nichts. Manche Werkzeuge rufen eine URL später noch einmal auf (Link-Vorschau, Wiederholung nach Netzfehler). Deshalb gilt:

URL-Kodierung. Kodiere den Inhalt vollständig (encodeURIComponent, urllib.parse.quote(html, safe="")). Besonders wichtig: # → %23, & → %26, + → %2B, % → %25. Fehlt am Ende </html>, meldet die Antwort eine Warnung: dann ist meist die Kodierung schuld. Vergleiche ende mit dem Ende deines HTML.

Cache. Manche Werkzeuge (z. B. WebFetch in Claude Code, 15 Minuten) cachen GET-Antworten. Hänge bei wiederholten Aufrufen &r=<zufällige Zahl> an.

Kannst du POST senden (curl, Shell)? Dann dieselben Parameter als application/x-www-form-urlencoded Body an POST https://ki-1-onboarding.kideon.cloud/publish_site — ohne Längenproblem in der URL. Das gilt für alle Parameter, auch site_id, part, more und discard_draft:

curl -s https://ki-1-onboarding.kideon.cloud/publish_site --data-urlencode token=dvo_… --data-urlencode content@onboarding.html

Darfst du keine selbst gebauten URLs abrufen (manche Chat-Oberflächen erlauben nur Links, die der Nutzer geschickt hat)? Dann gib deinem Nutzer das fertige HTML und den Link https://ki-1-onboarding.kideon.cloud/new — dort fügt er es ein und bekommt Vorschau-Link und Token, die er dir zurückgeben kann.

Schritt 3 — Das Formular sendet an submit

Die Seite liegt unter <public_url> = …/s/<site_id>/. Ein relatives Ziel submit zeigt deshalb automatisch auf /s/<site_id>/submit — du brauchst die site_id beim ersten Hochladen nicht. Ohne Freischaltung läuft die Seite ohne JavaScript (Abschnitt 10); das Formular ist ein klassisches HTML-Formular, auch mit Freischaltung:

<form method="post" action="submit">
  <select name="client_type">
    <option value="natural_person">Privatperson</option>
    <option value="legal_entity">Unternehmen</option>
  </select>
  <input name="first_name"> <!-- … alle Felder aus Abschnitt 9 … -->
  <label><input type="checkbox" name="privacy_consent" value="true" required> Ich habe die Datenschutzhinweise gelesen.</label>
  <button type="submit">Absenden</button>
</form>

Nach dem Absenden zeigt der Server eine Danke-Seite mit den Feldern, die noch fehlen oder ungültig sind. Angenommen werden Formulare (application/x-www-form-urlencoded, multipart/form-data ohne Dateien) bis 32 KB. Felder, die nicht im Schema stehen, werden verworfen.

Schritt 4 — Prüfen

GET https://ki-1-onboarding.kideon.cloud/validate?token=dvo_…&site_id=<site_id>

datev_ready: yes gibt es, wenn die statische Prüfung ohne Fehler ist und mindestens eine Einreichung alle Pflichtfelder gültig enthält. Das bleibt yes, auch wenn spätere Testeingaben Fehler haben; die Antwort nennt dann die Felder der letzten Eingabe. Du siehst nur den Feldstatus (ok, fehlt, ungültig), nie die eingegebenen Werte. Hat die Seite selbst Mängel, enthält die Antwort einen fertigen Korrektur-Prompt; fehlt nur eine gültige Testeingabe, ist an der Seite nichts zu tun. GET https://ki-1-onboarding.kideon.cloud/get_site?token=dvo_…&site_id=<site_id> zeigt Metadaten und das aktuelle HTML.

Schritt 5 — Vorschau-Link an den Nutzer geben

Gib deinem Nutzer den preview_url. Dort sieht er links die Seite, rechts live jede Test-Einreichung Feld für Feld mit grünem Haken, sobald alles DATEV-tauglich ist. Hat die Seite Mängel, steht dort ein fertiger Text für dich zum Kopieren. Über den Vorschau-Link kann er die Seite auch löschen — einen Lösch-Aufruf für Agenten gibt es nicht.

6. Freischaltung für JavaScript

Kostenlos, einmal je Token. Du brauchst von deinem Nutzer drei Angaben: seinen Namen, eine E-Mail-Adresse der Kanzlei-Domain (keine Freemail-Adresse wie gmail.com, gmx.de, web.de, t-online.de oder outlook.com, keine Wegwerf-Adresse) und die Website der Kanzlei. Kideon ruft die Website nicht ab; sie steht nur als Angabe beim Token.

Schritt 1 — Code anfordern (Parameter URL-kodiert):

GET https://ki-1-onboarding.kideon.cloud/register?token=dvo_…&name=Erika%20Muster&email=erika.muster%40kanzlei-beispiel.de&website=https%3A%2F%2Fkanzlei-beispiel.de

Antwort: Code gesendet an e***@kanzlei-beispiel.de. Kideon schickt einen 6-stelligen Code an diese Adresse (Betreff „Dein Freischaltcode“, gültig 30 Minuten). Eine Freemail-Adresse lehnt der Dienst mit 422 ab („Bitte eine E-Mail-Adresse deiner Kanzlei-Domain angeben“), eine Wegwerf-Adresse (mailinator, yopmail, 10minutemail, …) ebenso (disposable).

Limits für register pro Stunde: 3 je Token, 3 je Adresse (erika+1@… und erika+2@… zählen als dieselbe Adresse), 10 je Domain und 10 je IP-Adresse. Bei 429 warte die Zeit aus Retry-After ab oder nutze den MCP-Server / eine andere Verbindung.

Schritt 2 — Code vom Nutzer holen. Bitte deinen Nutzer, dir den Code aus der Mail zu geben. Der Token steht nicht in der Mail; den hast du.

Schritt 3 — Bestätigen:

GET https://ki-1-onboarding.kideon.cloud/confirm?token=dvo_…&code=123456

Antwort: „Freigeschaltet. Deine Seiten dürfen jetzt JavaScript enthalten.“ Höchstens 5 Versuche je Code; danach fordere mit register einen neuen an.

Schritt 4 — Veröffentlichen mit publish_site: mit site_id, falls du schon eine Seite hast, sonst ohne. Eine schon veröffentlichte Seite läuft erst nach diesem Aufruf mit JavaScript. Die Antwort nennt javascript: erlaubt (verifiziert) (ebenso validate), und die Prüfung meldet das Skript als Hinweis statt als Fehler.

Auch mit Freischaltung gilt: JavaScript nur inline (externe Skripte blockiert der Browser), kein <object>, <embed>, <base>, kein <meta http-equiv="refresh">, keine Cookies, kein Storage. Das Formular sendet weiter an submit; Skript darf es ergänzen (Schritte, bedingte Felder, Hinweise). Sperrt Kideon ein freigeschaltetes Token, kommt die Domain seiner E-Mail-Adresse auf eine Sperrliste: register mit einer Adresse dieser Domain antwortet 409 (domain_blocked), und kein Token mit einer verifizierten Adresse dieser Domain veröffentlicht noch JavaScript.

7. Große Seiten in Stücken

Harte Grenzen: 64 KB Query-String pro Aufruf, 512 KB für die ganze Seite. Ist dein HTML länger als 3.000 Zeichen, sende es in nummerierten Stücken.

Reihenfolge, genau so: Teile zuerst das rohe HTML nach Zeichen (nicht nach Bytes, nicht nach der kodierten Form) in Stücke von höchstens 3.000 Zeichen; kodiere dann jedes Stück einzeln URL-encoded (oder base64url mit content_b64). Nie erst kodieren und dann teilen, nie ein Stück zweimal kodieren.

Beispiel: Dein HTML hat 8.000 Zeichen. Stück 1 = Zeichen 1–3.000, Stück 2 = Zeichen 3.001–6.000, Stück 3 = Zeichen 6.001–8.000. Jedes Stück für sich mit encodeURIComponent(stück) bzw. urllib.parse.quote(stück, safe=""):

from urllib.parse import quote
stuecke = [html[i:i + 3000] for i in range(0, len(html), 3000)]  # 8.000 Zeichen → 3 Stücke
kodiert = [quote(s, safe="") for s in stuecke]                    # jedes Stück einzeln
GET https://ki-1-onboarding.kideon.cloud/publish_site?token=dvo_…&part=1&more=1&content=<Stück 1>                      → liefert site_id
GET https://ki-1-onboarding.kideon.cloud/publish_site?token=dvo_…&site_id=<site_id>&part=2&more=1&content=<Stück 2>
GET https://ki-1-onboarding.kideon.cloud/publish_site?token=dvo_…&site_id=<site_id>&part=3&content=<letztes Stück>     → jetzt live

8. Optional: MCP-Server

Wenn du komplexere Seiten veröffentlichst oder dein Werkzeug keine langen URLs kann, nutze unseren MCP-Server. Kostenlos, gleiche Funktionen, keine Längengrenze.

Ein MCP-Server bekommt Rechte in deinem Chat. Prüfe, ob das für dich passt; die GET-API funktioniert ohne.

9. Feldschema

Die name-Attribute im Formular müssen exakt so heißen. client_type steuert die bedingten Pflichtfelder: bei natural_person Vorname, Nachname, Geburtsdatum; bei legal_entity Firma und Rechtsform. Bietet dein Formular beide Typen an, müssen alle bedingten Felder vorhanden sein.

Feld (name) Bezeichnung Pflicht Format / Regel Beispiel
client_type Mandantentyp ja natural_person oder legal_entity natural_person
company_name Firma bei legal_entity Text Muster Beispiel GmbH
legal_form Rechtsform bei legal_entity eine von: GmbH, UG, AG, GbR, OHG, KG, GmbH & Co. KG, e.K., Einzelunternehmen, Freiberufler, eV, Sonstige GmbH
first_name Vorname bei natural_person Text Erika
last_name Nachname bei natural_person Text Mustermann
date_of_birth Geburtsdatum bei natural_person ISO-Datum JJJJ-MM-TT, in der Vergangenheit 1980-01-01
address_street Straße ja Text Musterstraße
address_house_number Hausnummer ja Text mit Ziffer, max. 20 Zeichen 1a
address_postal_code PLZ ja bei DE genau 5 Ziffern (^\d{5}$) 12345
address_city Ort ja Text Musterstadt
address_country Land ja ISO 3166-1 alpha-2, z. B. DE DE
contact_email E-Mail ja E-Mail-Adresse erika@example.com
contact_phone Telefon nein Ziffern, + ( ) / - und Leerzeichen, 6–20 Zeichen +49 30 1234567
tax_number Steuernummer ja 10–13 Ziffern, Trennzeichen / - erlaubt 12/345/67890
tax_office_number Finanzamtsnummer nein 4 Ziffern 1234
vat_id USt-IdNr. nein DE + 9 Ziffern (^DE\d{9}$) DE123456789
tax_id Steuer-IdNr. nein 11 Ziffern mit ELSTER-Prüfziffer 12345678995
iban IBAN nein IBAN mit gültiger Prüfsumme (MOD-97) DE89370400440532013000
bic BIC nein 8 oder 11 Zeichen COBADEFFXXX
fiscal_year_start Wirtschaftsjahr-Beginn nein MM-TT, Standard 01-01 01-01
chart_of_accounts Kontenrahmen nein SKR03 oder SKR04 SKR03
commercial_register_number Handelsregisternummer nein Text, max. 40 Zeichen HRB 12345
commercial_register_court Registergericht nein Text Amtsgericht Musterstadt
industry_sector Branche nein Text Handel
privacy_consent Datenschutz-Einwilligung ja Checkbox; Wert muss true, on oder 1 sein on

Beispieldaten (gültig, zur Orientierung am Format):

{
  "client_type": "natural_person",
  "first_name": "Erika",
  "last_name": "Mustermann",
  "date_of_birth": "1980-01-01",
  "address_street": "Musterstraße",
  "address_house_number": "1a",
  "address_postal_code": "12345",
  "address_city": "Musterstadt",
  "address_country": "DE",
  "contact_email": "erika@example.com",
  "contact_phone": "+49 30 1234567",
  "tax_number": "12/345/67890",
  "tax_office_number": "1234",
  "vat_id": "DE123456789",
  "tax_id": "12345678995",
  "iban": "DE89370400440532013000",
  "bic": "COBADEFFXXX",
  "fiscal_year_start": "01-01",
  "chart_of_accounts": "SKR03",
  "industry_sector": "Handel",
  "privacy_consent": "on"
}

10. Vorgaben für die HTML-Datei

11. Laufzeit

Jede Seite läuft 14 Tage ab dem ersten Veröffentlichen kostenlos (expires_at). Ein erneutes publish_site verlängert nicht. Danach ist sie offline, und alle Testdaten werden gelöscht. Sperrt Kideon eine Seite, antwortet jeder Aufruf mit diesem Token 409.

12. Was du für 200 € bekommst

Der Vertrag kostet 200 € pro Monat zzgl. USt. Mit dem Vertrag bekommt die Kanzlei:

Anfragen:

GET https://ki-1-onboarding.kideon.cloud/request_upgrade?token=dvo_…&site_id=<site_id>&email=<E-Mail des Nutzers>&name=…&kanzlei=…&message=…

name, kanzlei, message sind optional. Wir schicken eine kurze Bestätigung an die E-Mail-Adresse (mail_state in der Antwort) und melden uns. Kam die Mail nicht durch (mail_state: failed), versucht derselbe Aufruf später es noch einmal. Der Nutzer kann die Anfrage auch selbst auf der Vorschau-Seite stellen.

„DATEV-valide" heißt in dieser Vorschau „schema-konform für DATEV-Stammdaten". Es ist keine Prüfung oder Zertifizierung durch die DATEV eG, und in der Vorschau werden keine Daten an DATEV übertragen.

13. Datenschutz und Vertraulichkeit