SDKs (Python / TypeScript) and REST
The SDKs are a thin skin over REST (every method maps to one endpoint). Shared behaviour:
- Every mutating call carries an automatic
Idempotency-Key(retry-safe) - 429 / 5xx retry with exponential backoff. 409 (optimistic lock) is never retried — re-read and re-apply; that is the contract
- Errors become exceptions carrying the problem+json
suggested_fix(readable by an LLM as-is) - Practical helpers:
jobs.wait()/tables.iter_rows()/webhooks.verify_signature()
Python
Section titled “Python”pip install d2b-sdkfrom d2b import D2BClient, ConflictError
client = D2BClient(api_key="d2b_pat_...", base_url="https://d2b.dev")wb = client.workbooks.create(title="monthly")["id"]client.sources.upload(wb, "sales.xlsx", wait=True)
page = client.tables.rows(wb, "sales")try: client.tables.upsert_rows(wb, "sales", rows=[{"product": "apple", "qty": 3}], expected_version=page["edit_version"])except ConflictError: page = client.tables.rows(wb, "sales") # re-read → re-applyResources: workbooks / sources / tables / query / transforms / versions / jobs / reviews / sheets / charts / export / webhooks.
TypeScript
Section titled “TypeScript”npm install d2b-sdkimport { D2BClient } from "d2b-sdk";
const client = new D2BClient({ apiKey: "d2b_pat_...", baseUrl: "https://d2b.dev" });const wb = (await client.workbooks.create({ title: "monthly" })).id as string;await client.sources.upload(wb, fileBlob, { filename: "sales.xlsx", wait: true });const grid = await client.tables.a1(wb, "sales", "A1:D10"); // read in Excel coordinatesawait client.sheets.put(wb, "summary", [ { kind: "heading", text: "Monthly summary" }, { kind: "table_view", table: "sales" },]);const xlsx = await client.sheets.render(wb, "summary");Where the packages live
Section titled “Where the packages live”| Package | Source and issues | |
|---|---|---|
| Python + CLI | d2b-sdk on PyPI | github.com/600/d2b-sdk (python/) |
| TypeScript | d2b-sdk on npm | github.com/600/d2b-sdk (typescript/) |
The distribution is d2b-sdk on both registries. The Python import package and the command are both d2b (d2b on PyPI is an unrelated project), so with uvx that reads uvx --from d2b-sdk d2b …. The GitHub repository is a read-only mirror (the SDKs are developed in D2B’s main repository): pull requests can’t be merged there, issues are welcome. Each release syncs the same tag (sdk-py-v* / sdk-ts-v*) to the mirror, which publishes to both registries (npm with provenance).
Raw REST
Section titled “Raw REST”- Base URL:
https://d2b.dev(paths under/api/v1/...; tenant management under/api/control/...) - Auth:
Authorization: Bearer <PAT>(/api/v1), Account API key (/api/control) - Mutations accept an
Idempotency-Keyheader (same key + same body replays the first response) - OpenAPI 3.1: openapi.json — the API reference is generated from it