npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nxus-qbd

v0.6.2

Published

Official TypeScript SDK for the Nxus QuickBooks Desktop API. Runs on Node.js 18+ and Bun 1.0+.

Readme

nxus-qbd

Official TypeScript SDK for the Nxus QuickBooks Desktop API.

Runtime Support

Runs on Node.js 18+ and Bun 1.0+. The SDK uses native fetch and AbortController with no Node-specific dependencies.

Installation

npm install nxus-qbd
pnpm add nxus-qbd
bun add nxus-qbd

Environments

The SDK targets https://api.nx-us.net/ by default.

Use environment: NxusEnvironment.DEVELOPMENT to target https://localhost:7242/, or pass an explicit baseUrl override when you need a custom endpoint.

import { NxusClient, NxusEnvironment } from "nxus-qbd";

const nxus = new NxusClient({
  apiKey: "sk_live_...",
  environment: NxusEnvironment.DEVELOPMENT,
});

Timeouts

The SDK defaults to a 100_000ms client timeout so normal callers can still receive the API's structured timeout responses for heavier QuickBooks operations.

Advanced callers can override this globally or per request:

import { NxusClient } from "nxus-qbd";

const nxus = new NxusClient({
  apiKey: "sk_live_...",
  timeout: 120_000,
});

const page = await nxus.transactions.list({
  connectionId: "your-connection-id",
  limit: 100,
  DetailLevel: "all",
  timeout: 30_000,
});

Paginated/list requests can also send a backend timeout hint without changing the SDK's local abort timer:

const page = await nxus.transactions.list({
  connectionId: "your-connection-id",
  limit: 100,
  DetailLevel: "all",
  timeout: 30_000,
  timeoutSeconds: 45,
});

When timeoutSeconds is provided on a .list() call, the SDK sends it as the X-Nxus-Timeout-Seconds request header and keeps reusing that header for manual getNextPage() calls and for await auto-pagination. It is not added to the query string.

Automatic Retries

The SDK automatically retries transient failures up to 2 additional times (3 total attempts) with exponential backoff and jitter.

The x-should-retry response header from the API is the primary signal:

  • true → retry, even for statuses that wouldn't normally retry.
  • false → don't retry, even for statuses that normally would.

When the header is absent (older backend, infrastructure-level error), the SDK falls back to retrying:

  • Network errors (fetch threw before receiving a response)
  • HTTP 408 (Request Timeout) and 429 (Too Many Requests)
  • HTTP 5xx

409 is not in the fallback retry set: the API overloads 409 for both retryable lock contention (ObjectInUse, LockFailed) and terminal business-rule violations (OutdatedEditSequence, NameNotUnique). Without x-should-retry to disambiguate, the safe default is to surface the error to the caller. Servers that emit x-should-retry: true opt the retryable 409s back in.

For backoff, the standard Retry-After response header (seconds or HTTP-date) is honored when present, with error.retryAfter (seconds) in the JSON body as a fallback. Local timeouts (the SDK's abort timer) are treated as cancellations and are not retried.

Configure globally or per-request:

const nxus = new NxusClient({
  apiKey: "sk_live_...",
  maxRetries: 3, // default is 2; set to 0 to disable
});

// Disable retries for one call
const created = await nxus.invoices.create({
  customerRefListId: "...",
  invoiceLineAdds: [{ itemRefListId: "...", amount: 100 }],
  connectionId: "...",
  maxRetries: 0,
});

Verbose Logging

Set verbose: true to emit structured logs for every request, response, retry, and error. Sensitive headers (Authorization, Cookie, Set-Cookie, X-Api-Key, Proxy-Authorization) are automatically redacted.

const nxus = new NxusClient({
  apiKey: "sk_live_...",
  verbose: true,                     // logs to console
});

Plug in your own logger (winston, pino, etc.) by providing any object that implements { debug, info, warn, error }:

import type { NxusLogger } from "nxus-qbd";

const logger: NxusLogger = {
  debug: (m, c) => myLogger.debug({ event: m, ...c }),
  info:  (m, c) => myLogger.info({ event: m, ...c }),
  warn:  (m, c) => myLogger.warn({ event: m, ...c }),
  error: (m, c) => myLogger.error({ event: m, ...c }),
};

const nxus = new NxusClient({ apiKey: "sk_live_...", logger });

Providing a logger implies verbose: true. You can also opt-in on a single call via { verbose: true } in request options.

Proxy Support

Route traffic through an outbound HTTP/HTTPS proxy by passing proxy:

const nxus = new NxusClient({
  apiKey: "sk_live_...",
  proxy: "http://proxy.corp:8080",
});

On Node, the SDK lazily loads undici.ProxyAgent (shipped with Node 18+) and wires it via fetchOptions.dispatcher. On Bun, the URL is passed through as the native proxy fetch option. For advanced cases — custom TLS, mTLS, per-request dispatchers — use the fetchOptions escape hatch:

import { ProxyAgent } from "undici";

const nxus = new NxusClient({
  apiKey: "sk_live_...",
  fetchOptions: {
    dispatcher: new ProxyAgent({
      uri: "http://proxy.corp:8080",
      token: `Basic ${Buffer.from("user:pass").toString("base64")}`,
    }),
  },
});

fetchOptions may also be supplied per request to override the client default.

Raw HTTP Access

When you need direct access to the underlying Response — headers, streaming bodies, custom status handling — use transport.raw(). Authentication, default headers, the timeout, and retries are still applied; only JSON parsing and the typed error mapping are bypassed.

import { NxusClient } from "nxus-qbd";

const nxus = new NxusClient({ apiKey: "sk_live_..." });

const res = await (nxus as unknown as { transport: { raw: (path: string, init?: RequestInit) => Promise<Response> } })
  .transport.raw("/api/v1/vendors", { method: "GET" });

console.log(res.status, res.headers.get("x-request-id"));
const stream = res.body; // ReadableStream for large downloads

Non-2xx responses are returned, not thrown — the caller is responsible for checking response.ok. Use this only for cases the typed resource methods can't model (binary downloads, response-header inspection, custom error semantics).

Quick Start

import { NxusClient } from "nxus-qbd";

const nxus = new NxusClient({ apiKey: "sk_live_..." });

// List vendors
const page = await nxus.vendors.list({ limit: 50, connectionId: "your-connection-id" });

for (const vendor of page.data) {
  console.log(vendor.name);
}

// Retrieve a single customer by QuickBooks ListID
const customer = await nxus.customers.retrieve("80000001-1234567890", {
  connectionId: "your-connection-id",
});

// Create an invoice (flat params)
const invoice = await nxus.invoices.create({
  customerRefListId: "80000001-1234567890",
  invoiceLineAdds: [
    { itemRefListId: "80000002-1234567890", amount: 150.0 },
  ],
  connectionId: "your-connection-id",
});

// Update a vendor (ID first, flat fields)
const updated = await nxus.vendors.update("80000001-1234567890", {
  name: "Acme (Updated)",
  revisionNumber: vendor.revisionNumber,
  connectionId: "your-connection-id",
});

// Delete
await nxus.vendors.delete("80000001-1234567890", {
  connectionId: "your-connection-id",
});

Connection Scoping

Every request requires a connectionId to identify which QuickBooks Desktop company file to target. You can set it per-request or globally via the constructor:

// Per-request
const page = await nxus.vendors.list({ limit: 10, connectionId: "your-connection-id" });
const vendor = await nxus.vendors.retrieve("id", { connectionId: "your-connection-id" });

// Global default
const nxus = new NxusClient({
  apiKey: "sk_live_...",
  headers: { "X-Connection-Id": "your-connection-id" },
});

Auto-Pagination

List methods return an AutoPaginationPromise that supports both manual page navigation and for await iteration:

// Auto-paginate through all records
for await (const vendor of nxus.vendors.list({ limit: 100, timeoutSeconds: 45 })) {
  console.log(vendor.name);
}

// Manual page-by-page navigation
let page = await nxus.vendors.list({ limit: 50, timeoutSeconds: 45 });
while (page.hasNextPage()) {
  page = await page.getNextPage();
}

[!IMPORTANT] Processing Constraints: Each paginated request must either complete or be cancelled before the subsequent request can be processed by the backend.

  • Async API (Primary): The Async API is the recommended way to handle these requests as it allows for better lifecycle management.
  • Sync Wrappers: While sync wrappers are provided for convenience, you may need to increase your client-side timeouts to ensure large paginated sets complete successfully.

Examples

Runnable examples live in examples/:

| Example | Description | |---|---| | basic-crud.ts | Create, retrieve, update, list, and delete a vendor | | authSetup.ts | Create a connection, generate a hosted QWC auth flow URL, and check auth status | | auto-pagination.ts | Auto-iteration across pages plus manual page navigation | | connection-scoped.ts | Multi-company isolation with connectionId | | error-handling.ts | Error categorization and typed SDK errors | | pagination-walkthrough.ts | Cursor handling walkthrough | | reports.ts | Aging, general detail, and general summary reports | | timeout-tuning.ts | Default timeout behavior, client-wide overrides, and per-request timeout tuning |

Error Handling

All methods throw NxusApiError on non-2xx responses:

import { NxusClient, NxusApiError } from "nxus-qbd";

try {
  await nxus.vendors.retrieve("non-existent-id");
} catch (err) {
  if (err instanceof NxusApiError) {
    console.log(err.status);          // 404
    console.log(err.userMessage);     // User-safe message
    console.log(err.isNotFound);      // true
    console.log(err.isAuthError);     // false
    console.log(err.isRateLimited);   // false
  }
}

Resources

All QuickBooks Desktop resources are available as namespaced properties:

| Category | Resources | |---|---| | Transactions | invoices, bills, checks, deposits, estimates, creditMemos, purchaseOrders, salesReceipts, journalEntries, receivePayments, vendorCredits, creditCardCharges, creditCardBills, creditCardCredits, charges, buildAssemblies, arRefundCreditCards, salesTaxPaymentChecks, itemReceipts, CheckBillPayments, timeTrackings, transactions | | Lists | accounts, customers, vendors, employees, otherNames, currencies, terms, dateDrivenTerms, paymentMethods, shipMethods, salesTaxCodes, priceLevels, qbdClasses, customerTypes, vendorTypes, billingRates, inventorySites, barCodes, accountTaxLineInfos, unitOfMeasureSets, specialItems | | Read-only | billToPay | | Items | items, inventoryItems, itemDiscounts, itemFixedAssets, itemGroups, itemInventoryAssemblies, itemNonInventory, itemOtherCharges, itemPayments, itemSalesTax, itemSalesTaxGroups, serviceItems, itemSubtotals | | Payroll | payrollItemNonWages, payrollItemWages, workersCompCodes | | Reports | reports.retrieveAging(), reports.retrieveGeneralDetail(), reports.retrieveGeneralSummary(), reports.retrieveBudgetSummary(), reports.retrieveJob(), reports.retrieveTime(), reports.retrieveCustomDetail(), reports.retrieveCustomSummary(), reports.retrievePayrollDetail() | | Platform | authSessions, connections |

License

MIT