> ## Documentation Index
> Fetch the complete documentation index at: https://docs.conductor.is/llms.txt
> Use this file to discover all available pages before exploring further.

# Upgrading to Conductor's new Node.js SDK

> How to migrate from the old `conductor-node` package to Conductor's new Node.js SDK and QuickBooks Desktop API v2.

We're excited to announce a major update to `conductor-node` that brings full support for Conductor's new QuickBooks Desktop API v2. This new version introduces significant improvements in usability, consistency, and functionality.

<Info>
  Though the old version of `conductor-node` will continue to work, it will not
  receive any further updates. We strongly recommend upgrading to take advantage
  of the new features and improvements.
</Info>

## Key improvements

Our new QuickBooks Desktop API v2 has been completely redesigned from the ground up. We've carefully chosen every field name, parameter, and method description to be significantly more intuitive and clearer than QuickBooks's original documentation. The API structure has been simplified while maintaining full functionality.

Major improvements include:

* **[Automatic pagination](#automatic-pagination) support**
* **Automatic retries** with exponential backoff
* **Configurable timeouts**
* **Improved parameter and fields names**
* Completely **rewritten inline documentation**
* New methods like **`.retrieve()`** and **`.delete()`**
* All fields included in responses
* Consistent array handling

## How to upgrade

<CodeGroup>
  ```bash npm theme={"system"}
  npm install conductor-node@latest
  ```

  ```bash yarn theme={"system"}
  yarn add conductor-node@latest
  ```

  ```bash pnpm theme={"system"}
  pnpm add conductor-node@latest
  ```
</CodeGroup>

## Breaking changes

<Note>
  **No QuickBooks or Conductor business logic has changed!** We've simply made
  the interface simpler, more intuitive, and more robust, while adding new
  features like automatic pagination and retries.
</Note>

### ⚠️ Functional Changes

<AccordionGroup>
  <Accordion title="1. Missing QuickBooks Desktop types">
    <Warning>
      Several *less common* QuickBooks Desktop types/endpoints from the previous version of `conductor-node` are not *yet* available in the new SDK. **If the type is listed in the left sidebar of this page, it is supported in the new SDK.**

      Need a missing QBD type? [Contact us](mailto:support@conductor.is) and we'll add it ASAP.
    </Warning>
  </Accordion>

  <Accordion title="2. Pagination limited to 150 records per page">
    Previously, the API would return all matching records by default. This could lead to performance issues when unintentionally retrieving thousands of records, potentially causing long response times, overloading QuickBooks Desktop, and consuming excessive memory.

    To prevent these issues, **Conductor now limits responses to a maximum of 150 records per page by default**. This limit was carefully determined through extensive testing across different scenarios and system configurations to optimize performance while avoiding timeouts and resource constraints.

    With the new [automatic pagination](https://github.com/conductor-is/quickbooks-desktop-node?tab=readme-ov-file#auto-pagination), you can efficiently retrieve all records when needed, without worrying about these performance concerns.
  </Accordion>
</AccordionGroup>

### ⚠️ Naming and Structure Changes

<AccordionGroup>
  <Accordion title="1. Restructured constructor parameters">
    **Old:**

    ```typescript  theme={"system"}
    import Conductor from "conductor-node";

    const conductor = new Conductor("{{YOUR_SECRET_KEY}}");
    ```

    **New:** You can now automatically load your secret key from the `CONDUCTOR_SECRET_KEY` environment variable (or pass it to the constructor as an argument like before):

    ```typescript  theme={"system"}
    import Conductor from "conductor-node";

    const conductor = new Conductor({
      apiKey: process.env["CONDUCTOR_SECRET_KEY"], // This is the default and can be omitted
    });
    ```
  </Accordion>

  <Accordion title="2. Renamed resources">
    **Old:** Singular resource names.

    ```typescript  theme={"system"}
    await conductor.qbd.bill.*
    await conductor.qbd.invoice.*
    await conductor.qbd.itemInventory.*
    ```

    **New:** Plural resource names and clearer naming.

    ```typescript  theme={"system"}
    await conductor.qbd.bills.*
    await conductor.qbd.invoices.*
    await conductor.qbd.inventoryItems.*
    ```
  </Accordion>

  <Accordion title="3. Renamed methods">
    **Old:** Odd naming conventions.

    ```typescript  theme={"system"}
    await conductor.qbd.bill.query(...)
    await conductor.qbd.bill.add(...)
    await conductor.qbd.bill.mod(...)
    ```

    **New:** Intuitive naming following REST conventions.

    ```typescript  theme={"system"}
    await conductor.qbd.bills.list(...)
    await conductor.qbd.bills.create(...)
    await conductor.qbd.bills.update(...)
    await conductor.qbd.bills.retrieve(...) // New!
    await conductor.qbd.bills.delete(...) // New!
    ```
  </Accordion>

  <Accordion title="4. Moved end-user ID parameter">
    **Old:** Required as its own argument.

    ```typescript  theme={"system"}
    await conductor.qbd.bill.query("end_usr_1234abcd", { ... });
    ```

    **New:** Required as a `conductorEndUserId` parameter in the parameters object.

    ```typescript  theme={"system"}
    await conductor.qbd.bills.list({
      conductorEndUserId: "end_usr_1234abcd",
      // ... other params
    });
    ```
  </Accordion>

  <Accordion title="5. Renamed request parameters">
    <Info>
      All request parameters are now in camelCase and have been renamed for clarity
      and consistency. Most of the changes are straightforward that you can find
      using autocomplete in your IDE or checking the APIs in the sidebar.
    </Info>

    **Old:** Odd naming conventions.

    ```typescript  theme={"system"}
    await conductor.qbd.bill.add("end_usr_1234abcd", {
      VendorRef: { ListID: "..." },
      RefNumber: "...",
      ExpenseLineAdd: [
        {
          Amount: "1.00",
        },
      ],
    });
    ```

    **New:** camelCase and clearer naming.

    ```typescript  theme={"system"}
    await conductor.qbd.bills.create({
      conductorEndUserId: "end_usr_1234abcd",
      vendorId: "...",
      refNumber: "...",
      expenseLines: [
        {
          amount: "1.00",
        },
      ],
    });
    ```
  </Accordion>

  <Accordion title="6. Renamed response fields">
    <Info>
      All output fields are now in camelCase and have been renamed for clarity and
      consistency. Most of the changes are straightforward that you can find using
      autocomplete in your IDE or checking the APIs in the sidebar.
    </Info>

    Here are some key renamed fields:

    * `TxnID` and `ListID` → `id`
    * `TimeCreated` and `TimeModified` → `createdAt` and `updatedAt`
    * `EditSequence` → `revisionNumber`
    * `*Ref` fields (e.g., `CustomerRef`) → simplified (e.g., `customer`)

    **Old:** Odd naming conventions.

    ```typescript  theme={"system"}
    const invoice = await conductor.qbd.invoice.query("end_usr_1234abcd", "...");
    // {
    //   TxnID: "...",
    //   TimeCreated: "...",
    //   TimeModified: "...",
    //   EditSequence: "...",
    //   TxnNumber: "...",
    //   CustomerRef: {
    //     ListID: "...",
    //     FullName: "..."
    //   }
    // }
    ```

    **New:** camelCase and clearer naming.

    ```typescript  theme={"system"}
    const invoice = await conductor.qbd.invoices.retrieve({
      conductorEndUserId: "end_usr_1234abcd",
      id: "...",
    });
    // {
    //   id: "...",
    //   objectType: "qbd_invoice",
    //   createdAt: "...",
    //   updatedAt: "...",
    //   revisionNumber: "...",
    //   transactionNumber: "...",
    //   customer: {
    //     id: "...",
    //     fullName: "..."
    //   }
    // }
    ```
  </Accordion>

  <Accordion title="7. Restructured query/list request parameters">
    **Old:** Odd naming conventions and complex structure.

    ```typescript  theme={"system"}
    const invoices = await conductor.qbd.invoice.query("end_usr_1234abcd", {
      ModifiedDateRangeFilter: {
        FromModifiedDate: "...",
        ToModifiedDate: "...",
      },
      AccountFilter: {
        ListID: "...",
      },
      RefNumberFilter: "...",
      RefNumberRangeFilter: {
        FromRefNumber: "...",
        ToRefNumber: "...",
      },
      MaxReturned: 100,
    });
    ```

    **New:** Significantly simplified structure and clearer naming.

    ```typescript  theme={"system"}
    const invoices = await conductor.qbd.invoices.list({
      conductorEndUserId: "end_usr_1234abcd",
      updatedAfter: "...",
      updatedBefore: "...",
      accountId: "...",
      refNumber: "...",
      refNumberFrom: "...",
      refNumberTo: "...",
      limit: 100,
    });
    ```
  </Accordion>

  <Accordion title="8. Restructured query/list responses">
    To support automatic pagination, the query/list method now returns results in an object wrapper with properties for pagination metadata.

    **Old:** Returns an array of results directly.

    ```typescript  theme={"system"}
    const invoices = await conductor.qbd.invoice.query("end_usr_1234abcd");
    // [
    //   {
    //     TxnID: "...",
    //     TimeCreated: "...",
    //     ...
    //   }
    // ]
    ```

    **New:** Returns results in an object wrapper with properties for pagination metadata.

    ```typescript  theme={"system"}
    const response = await conductor.qbd.invoices.list({
      conductorEndUserId: "end_usr_1234abcd",
    });

    console.log(response);
    // {
    //   nextCursor: "...",
    //   hasMore: true,
    //   remainingCount: 100,
    //   data: [
    //     {
    //       id: "...",
    //       objectType: "qbd_invoice",
    //       createdAt: "...",
    //       ...
    //     }
    //   ]
    // }
    ```
  </Accordion>

  <Accordion title="9. Consistent array responses">
    Fields that can have multiple values are now always arrays, even when there's only one record:

    ```typescript  theme={"system"}
    const response = await conductor.qbd.invoices.list({
      conductorEndUserId: "end_usr_1234abcd",
    });

    // All responses with potential multiple records use arrays consistently
    console.log(response.data[0].lines); // Always an array, even if there's only one line
    ```
  </Accordion>
</AccordionGroup>

## New features

<AccordionGroup>
  <Accordion title="Automatic pagination" icon="arrows-rotate">
    You can now easily paginate through all results. See the [automatic pagination](https://github.com/conductor-is/quickbooks-desktop-node?tab=readme-ov-file#auto-pagination) section of the README for more details.

    ```typescript  theme={"system"}
    async function fetchAllQbdInvoices(params) {
      const allQbdInvoices = [];
      // Automatically fetches more pages as needed
      for await (const invoice of conductor.qbd.invoices.list({
        conductorEndUserId: "{{YOUR_END_USER_ID}}",
        ...params,
      })) {
        allQbdInvoices.push(invoice);
      }
      return allQbdInvoices;
    }
    ```
  </Accordion>

  <Accordion title="Automatic retries with exponential backoff" icon="arrow-rotate-right">
    Intelligently retries requests, but only those requests that can potentially succeed when retried (such as network errors).
  </Accordion>

  <Accordion title="New retrieve and delete methods" icon="code">
    All objects now have a `retrieve` method and all transaction objects have a `delete` method.

    ```typescript  theme={"system"}
    await conductor.qbd.bills.retrieve({ conductorEndUserId: "...", id: "..." });
    await conductor.qbd.bills.delete({ conductorEndUserId: "...", id: "..." });
    ```
  </Accordion>

  <Accordion title="Complete field returns" icon="database">
    The new API now returns a consistent response structure with all possible fields, making it easier to work with the data. Fields that have no value are explicitly set to `null` rather than being omitted, and empty array fields return `[]` instead of being excluded. This means you can reliably access any field without checking if it exists first, and array operations will work consistently without special handling for missing fields.
  </Accordion>
</AccordionGroup>

## More information

For more detailed information about the new Node.js SDK, please check its [GitHub repository](https://github.com/conductor-is/quickbooks-desktop-node).


Built with [Mintlify](https://mintlify.com).