Zum Inhalt springen

Quickstart

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).

Terminal-Fenster
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 erfordern workbooks: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_id lässt sich stattdessen eines Ihrer Entwicklerkonten wählen. GET /api/v1/me meldet account_id / account_name
  • resource schränkt die Reichweite ein: workbook:<id> (nur dieses Workbook — empfohlen, wenn das Token an einen Agenten geht) oder workspace:<id> (nur die Workbooks dieses Workspace; auch neue landen dort). Der Standard account ist alles unterhalb des Kontos. Die Reichweite bestimmt allein resource; Scopes legen fest, was der Key darf — ein Key ohne workspaces:read legt mit account-Pin trotzdem in jedem Workspace seines Kontos an. Ein Workspace außerhalb der Reichweite in workspace_id ergibt 403, beim Auflisten wie beim Anlegen
  • GET /api/v1/me/workspaces listet die erreichbaren Workspaces mit Namen (is_default = Ziel, wenn workspace_id weggelassen wird). /me und die Workbook-Liste tragen ebenfalls workspace_name
  • Workspace-Provisionierung ist workspaces:create, Schlüsselausgabe keys:mint, Abrechnungsaktionen billing: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_id landet 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 einem workspaces:create-Schlüssel (POST /api/control/workspaces) einen anlegen
Terminal-Fenster
pip install d2b-sdk
from d2b import D2BClient
client = D2BClient(api_key="d2b_pat_...", base_url="https://d2b.dev")
# 1) A workbook is the working container
wb = 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 tables
result = 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 humans
xlsx = client.export.tables(wb, tables=["product_sales"]) # formatted xlsx
original = client.sources.render_template(wb, "sales_2026-06.xlsx") # original formatting, values refreshed
# 7) Pin a version
client.versions.commit(wb, "2026-06")
Terminal-Fenster
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\""}'
Terminal-Fenster
pipx install d2b-sdk # or uvx --from d2b-sdk d2b …
d2b login
d2b workbooks create --title monthly
d2b upload sales.xlsx --workbook WB --wait
d2b query 'SELECT count(*) FROM "sales"' --workbook WB

Weiter: Kernkonzepte, Über MCP verbinden, Workbooks mit git verwalten.

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:

  1. Dieselbe Datei mit mode=staged erneut hochladen (nur Bytes, null Interpretation)
  2. POST .../sources/{name}/analyze → das zurückgegebene Parse-Spec prüfen und korrigieren (Kopfzeile, Datenbereich, Typen)
  3. POST .../sources/{name}/materialize zum 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).