Quickstart
1. Authentifizierung — ein PAT ausstellen
Abschnitt betitelt „1. Authentifizierung — ein PAT ausstellen“Alle Aufrufe unter /api/v1 verwenden Bearer-Authentifizierung mit einem PAT (Personal Access Token). Ausgestellt wird es über die Konsole oder per API aus einer eingeloggten Session (JWT).
curl -X POST https://d2b.dev/api/v1/me/tokens \ -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" \ -d '{"name": "my-agent", "scopes": ["workbooks:read", "workbooks:write"]}'# → {"token": "d2b_pat_...", ...} (the token is shown in plaintext only in this response)- Scopes sind Ressource×Aktion:
workbooks:read/write/delete,cloud-files:read(Auflisten / Importieren aus Drive / OneDrive — bei Logins standardmäßig, bei PATs explizit),governance:configure,workspaces:read/create/configure/delete,keys:read/mint/revoke,account:read,billing:manage. Implikation nur innerhalb einer Ressource (write ⊃ read); Workbook löschen, Snapshot-Restore und Version-Revert erfordernworkbooks:delete - Ein Token ist immer an genau ein Konto gebunden (ein Token = ein Konto). Aus einer angemeldeten Sitzung ausgestellte Token gehören zum Standardkonto; mit
account_idlässt sich stattdessen eines Ihrer Entwicklerkonten wählen.GET /api/v1/memeldetaccount_id/account_name resourceschränkt die Reichweite ein:workbook:<id>(nur dieses Workbook — empfohlen, wenn das Token an einen Agenten geht) oderworkspace:<id>(nur die Workbooks dieses Workspace; auch neue landen dort). Der Standardaccountist alles unterhalb des Kontos. Die Reichweite bestimmt alleinresource; Scopes legen fest, was der Key darf — ein Key ohneworkspaces:readlegt mitaccount-Pin trotzdem in jedem Workspace seines Kontos an. Ein Workspace außerhalb der Reichweite inworkspace_idergibt 403, beim Auflisten wie beim AnlegenGET /api/v1/me/workspaceslistet die erreichbaren Workspaces mit Namen (is_default= Ziel, wennworkspace_idweggelassen wird)./meund die Workbook-Liste tragen ebenfallsworkspace_name- Workspace-Provisionierung ist
workspaces:create, Schlüsselausgabekeys:mint, Abrechnungsaktionenbilling:manage— Berechtigungen sind unabhängige Ressource×Aktion-Scopes ohne Umbrella-Scope; prägen Sie Schlüssel mit genau dem, was sie brauchen (wie GitHub fine-grained PATs) - Ein Create ohne
workspace_idlandet im ältesten Workspace des Token-Kontos (beim Standardkonto: der persönliche Workspace). Ein Entwicklerkonto ohne Workspace liefert 409 — zuerst in der Konsole (Workspaces) oder mit einemworkspaces:create-Schlüssel (POST /api/control/workspaces) einen anlegen
2. 5 Minuten mit Python
Abschnitt betitelt „2. 5 Minuten mit Python“pip install d2b-sdkfrom d2b import D2BClient
client = D2BClient(api_key="d2b_pat_...", base_url="https://d2b.dev")
# 1) A workbook is the working containerwb = client.workbooks.create(title="monthly-sales")["id"]
# 2) Throw the messy Excel at it. wait=True has the SDK babysit the 202+job.# After extraction and structuring you get clean, typed tablesresult = client.sources.upload(wb, "sales_2026-06.xlsx", wait=True)
# 3) See what landed (the basic agent move)for t in client.tables.list(wb): print(t["name"], t["row_count"])schema = client.tables.schema(wb, "sales")
# 4) Analyse with SQL (governance applied, read-only)out = client.query.sql(wb, 'SELECT product, sum(amount) FROM "sales" GROUP BY 1')
# 5) Derived tables are transforms (lineage is preserved)client.transforms.create( wb, name="agg/monthly", kind="sql", template='CREATE OR REPLACE TABLE "{{ artifact_name }}" AS ' 'SELECT product, sum(amount) AS revenue FROM "{{ src }}" GROUP BY 1', artifact_name="product_sales", args={"src": "sales"},)
# 6) Back to humansxlsx = client.export.tables(wb, tables=["product_sales"]) # formatted xlsxoriginal = client.sources.render_template(wb, "sales_2026-06.xlsx") # original formatting, values refreshed
# 7) Pin a versionclient.versions.commit(wb, "2026-06")3. Dasselbe mit curl
Abschnitt betitelt „3. Dasselbe mit curl“BASE=https://d2b.dev; H="Authorization: Bearer $D2B_PAT"WB=$(curl -s -X POST $BASE/api/v1/workbooks -H "$H" -H "Content-Type: application/json" \ -d '{"title": "monthly"}' | jq -r .id)curl -s -X POST $BASE/api/v1/workbooks/$WB/sources -H "$H" -F file=@sales.xlsx -F mode=auto -F async=true# → {"job_id": ...} → poll GET $BASE/api/v1/jobs/{job_id}curl -s $BASE/api/v1/workbooks/$WB/tables -H "$H"curl -s -X POST $BASE/api/v1/workbooks/$WB/query -H "$H" -H "Content-Type: application/json" \ -d '{"sql": "SELECT count(*) FROM \"sales\""}'4. Mit der CLI
Abschnitt betitelt „4. Mit der CLI“pipx install d2b-sdk # or uvx --from d2b-sdk d2b …d2b logind2b workbooks create --title monthlyd2b upload sales.xlsx --workbook WB --waitd2b query 'SELECT count(*) FROM "sales"' --workbook WBWeiter: Kernkonzepte, Über MCP verbinden, Workbooks mit git verwalten.
Unaufgeräumtes Excel — wann auto, wann staged
Abschnitt betitelt „Unaufgeräumtes Excel — wann auto, wann staged“Zuerst mit dem Standard mode=auto (D2B schneidet jedes Blatt in seine Tabellen und liest verbundene Kopfzeilen, Einheitenzeilen, Zwischensummen und die Hierarchie, um sie zu formen). Nur wenn Extraktion oder Strukturierung danebenlagen, auf staged wechseln:
- Dieselbe Datei mit
mode=stagederneut hochladen (nur Bytes, null Interpretation) POST .../sources/{name}/analyze→ das zurückgegebene Parse-Spec prüfen und korrigieren (Kopfzeile, Datenbereich, Typen)POST .../sources/{name}/materializezum Festschreiben
Der Entscheidungsfluss: auto → Ergebnis ansehen → bei Abweichung das Parse-Spec via staged selbst übernehmen. Das auto-Ergebnis bleibt unter eigenem Namen erhalten — man kann beim Korrigieren vergleichen.
Das Feld structuring der Upload-Antwort nennt das Ergebnis: structured, skipped (mit structuring=skip angefordert — nur die Raw-Tabellen), deferred (mit structuring=defer angefordert — wird später eingetauscht), raw_fallback (Strukturierung angefordert, aber die Raw-Tabellen kamen zurück; structuring_reason nennt den Grund — no_credits, building (erneut hochladen), failed:… — oder auf staged wechseln) oder off (Strukturierung ist auf diesem Server deaktiviert). Die CLI gibt bei raw_fallback eine Warnung auf stderr aus.
Uploads über API / CLI / SDK / MCP werden standardmäßig von D2B strukturiert (structuring=auto): jedes Blatt wird in seine Tabellen und die Titel und Hinweise um sie herum (<Blatt>_補足情報) aufgeteilt, und die herausgeschnittenen Tabellen bleiben so erhalten, wie sie auf dem Blatt angeordnet sind. Daraus werden Tabellen mit Perioden in den Spalten ins Langformat gebracht, und Berichtstabellen mit Zwischen- und Gesamtsummen werden in je eine Tabelle pro Ebene ihrer Hierarchie (<Tabelle>_階層1, <Tabelle>_階層2 …; Summen und Differenzen, die aus Zeilen derselben Ebene berechnet werden, kommen in <Tabelle>_階層1_計算項目 usw.) und ihren Kontenbaum (<Tabelle>_科目) aufgeteilt. Ein Blatt, das nur aus einer Tabelle ohne etwas darum herum besteht, wird nicht aufgeteilt; seine geformte Tabelle übernimmt den Dateinamen. Das Originalblatt bleibt in der Lineage. Die Strukturierung verbraucht die Credits der Arbeitsmappe (derselbe Inhalt wird beim erneuten Hochladen aus dem Cache geliefert, ohne Strukturierungskosten). Um die Raw-Tabellen stattdessen mit Ihrem eigenen LLM und add_transform umzuformen, --no-structuring angeben (API: structuring=skip): jedes Blatt landet unverändert, in ~1s und kostenlos. --defer-structuring (structuring=defer) liefert die Raw-Tabellen sofort, strukturiert im Hintergrund und tauscht die strukturierten Tabellen ein, sobald sie fertig sind (artifact.updated feuert beim Tausch).