Skip to content

Node.js client

If you already have a QuickBooks Online integration, you don't need a client library — swap the base URL and your existing stack keeps working. For new Node.js code, @tenkeybridge/client is the supported client: a thin, zero-dependency, typed wrapper over the REST surface with OAuth token management built in.

sh
npm install @tenkeybridge/client

Requires Node 18.17+. Ships ESM and CJS, no runtime dependencies.

Connect and read

ts
import { TenkeyBridgeClient } from "@tenkeybridge/client";

const client = new TenkeyBridgeClient({
  realmId: process.env.TKB_REALM_ID!,
  auth: {
    clientId: process.env.TKB_CLIENT_ID!,
    clientSecret: process.env.TKB_CLIENT_SECRET!,
    refreshToken: process.env.TKB_REFRESH_TOKEN!,
    onTokensRefreshed: async (tokens) => saveTokens(tokens),
  },
});

const { entities } = await client.customer.query({ maxResults: 10 });
const invoice = await client.invoice.get("2FBE8-1071508936");

The auth block accepts a static { accessToken }, the client-credentials + refresh-token shape above, or a TokenManager you construct yourself. With a refresh token, the client refreshes ahead of expiry, single-flights concurrent refreshes, and calls onTokensRefreshed whenever the pair rotates — persist it there. Rotation is soft: the previous refresh token keeps working for a short grace window, and the manager uses that to recover from concurrent-refresh races automatically.

Writes

Same JSON as QuickBooks Online. Updates are always sparse — send Id plus the fields you're changing:

ts
const created = await client.invoice.create({
  CustomerRef: { value: "80000001-1234" },
  Line: [{
    DetailType: "SalesItemLineDetail",
    Amount: 100,
    SalesItemLineDetail: { ItemRef: { value: "42" }, Qty: 2 },
  }],
});

await client.invoice.update({ Id: created.Id!, DocNumber: "INV-1042" });
await client.invoice.delete({ Id: created.Id! });

Typed against the matrix

The per-entity helpers and TypeScript types are generated from the same compatibility catalog that gates the gateway, so the client can't promise more than the API delivers:

  • Only the 31 live entities get accessors (client.customer, client.salesReceipt, …).
  • Read-only entities (Item, Employee, Preferences, TaxRate, …) expose get/query but no create/update/delete — it's a compile error, not a runtime 400.
  • Entity types carry only the fields the matrix marks supported; anything Desktop can't honor is absent, so TypeScript flags it before the API has to.

Field-level notes — the exact fix for anything marked partial — live in the entity matrix.

Queries and pagination

ts
const page = await client.query("Invoice", {
  where: "TxnDate >= '2026-01-01'",
  maxResults: 100,
  startPosition: 1,
});

// Auto-pagination
for await (const c of client.customer.queryAll()) {
  console.log(c.DisplayName);
}

// Raw QBO query strings work too
await client.rawQuery("select * from Customer maxresults 5");

The query language is the documented QBO subset — see IDs, SyncToken & sparse updates for what's accepted.

Errors

API failures throw TenkeyBridgeApiError carrying the QBO Fault plus TenkeyBridge's tkb hint block — stable error code, causes, fixes, and a docs link:

ts
try {
  await client.invoice.create(inv);
} catch (err) {
  if (err instanceof TenkeyBridgeApiError) {
    console.error(err.code, err.tkb?.fixes, err.tkb?.docsUrl);
  }
}

OAuth failures (expired refresh token, bad credentials) throw TenkeyBridgeOAuthError with the OAuth error code (invalid_grant, …).

Where to go next

  1. Authentication — getting credentials and the OAuth flow.
  2. Entity matrix — what's live, field by field.
  3. Error codes — every stable code and its fix.

TenkeyBridge is an independent product, not affiliated with, endorsed by, or sponsored by Intuit Inc. QuickBooks, QuickBooks Online, and QuickBooks Desktop are trademarks of Intuit Inc., used only to describe compatibility.

TenkeyBridge is an independent product, not affiliated with, endorsed by, or sponsored by Intuit Inc. QuickBooks, QuickBooks Online, and QuickBooks Desktop are trademarks of Intuit Inc., used only to describe compatibility.