# Conductor Docs

## Docs

- [Create an AuthSession](https://docs.conductor.is/apis/auth-sessions/create): To launch the authentication flow, create an AuthSession and pass the returned session’s `authFlowUrl` to the client for your end-user to visit in their browser.
- [The AuthSession object](https://docs.conductor.is/apis/auth-sessions/object): An AuthSession is the secure way to programmatically launch the client-side Conductor authentication flow that lets your users connect their accounts to your integration.
- [Retrieve an AuthSession](https://docs.conductor.is/apis/auth-sessions/retrieve): Retrieves the details of an AuthSession that has previously been created.
- [Authentication](https://docs.conductor.is/apis/authentication)
- [Create an EndUser](https://docs.conductor.is/apis/end-users/create): Creates an EndUser.
- [Delete an EndUser](https://docs.conductor.is/apis/end-users/delete): Permanently deletes an EndUser object and all of its connections.
- [List all EndUsers](https://docs.conductor.is/apis/end-users/list): Returns a list of your EndUsers.
- [The EndUser object](https://docs.conductor.is/apis/end-users/object): An EndUser represents a user of your application. Use it to connect integrations.
- [Ping an EndUser's connection](https://docs.conductor.is/apis/end-users/ping): Checks whether the specified IntegrationConnection can connect and process requests end-to-end. This is useful for showing a "connection status" indicator in your app.
- [Send a request to an EndUser's integration connection](https://docs.conductor.is/apis/end-users/request): Sends a request to the specified integration connection (e.g. QuickBooks Desktop) on behalf of the end-user.
- [Retrieve an EndUser](https://docs.conductor.is/apis/end-users/retrieve): Retrieves an EndUser object.
- [The ConductorError object](https://docs.conductor.is/apis/errors/object)
- [Request IDs](https://docs.conductor.is/apis/request-ids)
- [Timeouts](https://docs.conductor.is/apis/timeouts)
- [How to fix: "Your QuickBooks Desktop connection is not active"](https://docs.conductor.is/help/connection-errors/connection-not-active)
- [How to fix: "Could not start QuickBooks"](https://docs.conductor.is/help/connection-errors/could-not-start-quickbooks)
- [How to fix: "Do you want to allow this app to make changes to your device?"](https://docs.conductor.is/help/connection-errors/do-you-want-to-allow-this-app-to-make-changes-to-your-device)
- [How to fix: "QBWC1085: There was a problem with the log file"](https://docs.conductor.is/help/connection-errors/there-was-a-problem-with-the-log-file)
- [How to fix: "Unable to cast COM object of type System.__ComObject..."](https://docs.conductor.is/help/connection-errors/unable-to-cast-com-object)
- [How to fix: "QBWC1039: Unique OwnerID/FileID pair value required"](https://docs.conductor.is/help/connection-errors/unique-owner-id-file-id-pair-required)
- [QuickBooks Desktop FAQ for end-users](https://docs.conductor.is/help/faq/end-user-faq): An FAQ guide written for the end-users of Conductor's QuickBooks Desktop integration.
- [How to disable the QuickBooks Desktop connection](https://docs.conductor.is/help/guides/disable-connection): Learn how to disable the QuickBooks Desktop connection in the QuickBooks Web Connector.
- [Ensure only one version of QuickBooks Desktop is installed](https://docs.conductor.is/help/guides/ensure-only-one-version-installed): Conductor will not function properly if multiple versions of QuickBooks Desktop are installed on the same computer.
- [Ensure the QuickBooks Web Connector opens at startup](https://docs.conductor.is/help/guides/ensure-web-connector-opens-at-startup): Set up the QuickBooks Web Connector to automatically launch and run in the background whenever you start your computer.
- [Move your QuickBooks Desktop connection to a different computer](https://docs.conductor.is/help/guides/move-computers): Learn how to transfer your QuickBooks Desktop connection to a different computer for the same company file.
- [Connect to multiple company files on a single computer](https://docs.conductor.is/help/guides/multiple-connections-one-computer): How to connect to multiple QuickBooks Desktop company files on a single computer.
- [Rebuild and verify Data in QuickBooks Desktop](https://docs.conductor.is/help/guides/rebuild-verify-data): Learn how to use the Rebuild and Verify Data utilities to fix and identify data issues in your QuickBooks Desktop company file.
- [Connecting to Rightworks](https://docs.conductor.is/help/guides/rightworks): How to set up the QuickBooks Web Connector to connect to QuickBooks Desktop when using Rightworks.
- [Upgrade the QuickBooks Web Connector](https://docs.conductor.is/help/guides/upgrade-web-connector): Learn how to upgrade the QuickBooks Web Connector to ensure compatibility with Conductor.
- [FAQ](https://docs.conductor.is/overview/faq): The fundamentals of Conductor.
- [Get started with Conductor](https://docs.conductor.is/overview/get-started): The best QuickBooks Desktop integration on the planet.
- [Quickstart](https://docs.conductor.is/overview/quickstart): Create your first EndUser and connect to QuickBooks Desktop in 5 minutes.
- [Security and data retention](https://docs.conductor.is/overview/security): Conductor's security and data retention policies.
- [Terminology](https://docs.conductor.is/overview/terminology): The key concepts you should know to use Conductor.
- [Create an account](https://docs.conductor.is/qbd-api/accounts/create): Creates a new financial account.
- [List all accounts](https://docs.conductor.is/qbd-api/accounts/list): Returns a list of accounts.
- [The Account object](https://docs.conductor.is/qbd-api/accounts/object): An account represents a financial account, allowing customization like sub-accounting, account numbering, and initial balance setting.
- [Retrieve an account](https://docs.conductor.is/qbd-api/accounts/retrieve): Retrieves an account by ID.
- [Update an account](https://docs.conductor.is/qbd-api/accounts/update): Updates a financial account.
- [Create a bill payment check](https://docs.conductor.is/qbd-api/bill-payment-checks/create): Creates a new bill payment check.
- [List all bill payment checks](https://docs.conductor.is/qbd-api/bill-payment-checks/list): Returns a list of bill payment checks.
- [The Bill Payment Check object](https://docs.conductor.is/qbd-api/bill-payment-checks/object): A bill payment check is a transaction that represents a payment by check for a bill.
- [Retrieve a bill payment check](https://docs.conductor.is/qbd-api/bill-payment-checks/retrieve): Retrieves a bill payment check by ID.
- [Update a bill payment check](https://docs.conductor.is/qbd-api/bill-payment-checks/update): Updates an existing bill payment check.
- [Create a bill payment credit card](https://docs.conductor.is/qbd-api/bill-payment-credit-cards/create): Creates a new bill payment credit card.
- [List all bill payment credit cards](https://docs.conductor.is/qbd-api/bill-payment-credit-cards/list): Returns a list of bill payment credit cards.
- [The Bill Payment Credit Card object](https://docs.conductor.is/qbd-api/bill-payment-credit-cards/object): A bill payment credit card is a transaction that represents a payment by credit card for a bill.
- [Retrieve a bill payment credit card](https://docs.conductor.is/qbd-api/bill-payment-credit-cards/retrieve): Retrieves a bill payment credit card by ID.
- [Create a bill](https://docs.conductor.is/qbd-api/bills/create): Creates a new bill.
- [List all bills](https://docs.conductor.is/qbd-api/bills/list): Returns a list of bills.
- [The Bill object](https://docs.conductor.is/qbd-api/bills/object): A bill is a transaction that represents a request-for-payment from a vendor for goods or services that it has provided.
- [Retrieve a bill](https://docs.conductor.is/qbd-api/bills/retrieve): Retrieves a bill by ID.
- [Update a bill](https://docs.conductor.is/qbd-api/bills/update): Updates an existing bill.
- [Create a check](https://docs.conductor.is/qbd-api/checks/create): Creates a new check.
- [List all checks](https://docs.conductor.is/qbd-api/checks/list): Returns a list of checks.
- [The Check object](https://docs.conductor.is/qbd-api/checks/object): A check is a transaction that represents a paper check.
- [Retrieve a check](https://docs.conductor.is/qbd-api/checks/retrieve): Retrieves a check by ID.
- [Update a check](https://docs.conductor.is/qbd-api/checks/update): Updates an existing check.
- [Create a class](https://docs.conductor.is/qbd-api/classes/create): Creates a new class.
- [List all classes](https://docs.conductor.is/qbd-api/classes/list): Returns a list of classes.
- [The Class object](https://docs.conductor.is/qbd-api/classes/object): A class is a category used to group QuickBooks objects into meaningful categories. For example, classes can be used to classify transactions by department, location, or type of work.
- [Retrieve a class](https://docs.conductor.is/qbd-api/classes/retrieve): Retrieves a class by ID.
- [Update a class](https://docs.conductor.is/qbd-api/classes/update): Updates an existing class.
- [Create a credit card charge](https://docs.conductor.is/qbd-api/credit-card-charges/create): Creates a new credit card charge for the specified account.
- [List all credit card charges](https://docs.conductor.is/qbd-api/credit-card-charges/list): Returns a list of credit card charges.
- [The Credit Card Charge object](https://docs.conductor.is/qbd-api/credit-card-charges/object): A credit card charge is a general charge incurred when a QuickBooks user makes a purchase using a credit card. Credit card charges for purchases can be tracked as expenses (in expense accounts) or as items.
- [Retrieve a credit card charge](https://docs.conductor.is/qbd-api/credit-card-charges/retrieve): Retrieves a credit card charge by ID.
- [Update a credit card charge](https://docs.conductor.is/qbd-api/credit-card-charges/update): Updates an existing credit card charge.
- [Create a credit card credit](https://docs.conductor.is/qbd-api/credit-card-credits/create): Creates a new credit card credit for the specified account.
- [List all credit card credits](https://docs.conductor.is/qbd-api/credit-card-credits/list): Returns a list of credit card credits.
- [The Credit Card Credit object](https://docs.conductor.is/qbd-api/credit-card-credits/object): A credit card credit is a credit card refund issued to a customer.
- [Retrieve a credit card credit](https://docs.conductor.is/qbd-api/credit-card-credits/retrieve): Retrieves a credit card credit by ID.
- [Update a credit card credit](https://docs.conductor.is/qbd-api/credit-card-credits/update): Updates an existing credit card credit.
- [Create a customer](https://docs.conductor.is/qbd-api/customers/create): Creates a new customer.
- [List all customers](https://docs.conductor.is/qbd-api/customers/list): Returns a list of customers.
- [The Customer object](https://docs.conductor.is/qbd-api/customers/object): A customer can refer to either one of the QuickBooks user's customers or an individual job that is being performed for a customer.
- [Retrieve a customer](https://docs.conductor.is/qbd-api/customers/retrieve): Retrieves a customer by ID.
- [Update a customer](https://docs.conductor.is/qbd-api/customers/update): Updates an existing customer.
- [Create a date-driven term](https://docs.conductor.is/qbd-api/date-driven-terms/create): Creates a new date-driven term.
- [List all date-driven terms](https://docs.conductor.is/qbd-api/date-driven-terms/list): Returns a list of date-driven terms.
- [The Date-Driven Term object](https://docs.conductor.is/qbd-api/date-driven-terms/object): A date-driven term shows the day of the month by which payment is due and can include a discount for early payment.
- [Retrieve a date-driven term](https://docs.conductor.is/qbd-api/date-driven-terms/retrieve): Retrieves a date-driven term by ID.
- [Welcome to Conductor's new QuickBooks Desktop API (alpha)](https://docs.conductor.is/qbd-api/intro): Conductor's new QuickBooks Desktop API is a massive leap forward and sets the foundation for future integrations.
- [Create an inventory assembly item](https://docs.conductor.is/qbd-api/inventory-assembly-items/create): Creates a new inventory assembly item.
- [List all inventory assembly items](https://docs.conductor.is/qbd-api/inventory-assembly-items/list): Returns a list of inventory assembly items.
- [The Inventory Assembly Item object](https://docs.conductor.is/qbd-api/inventory-assembly-items/object): An inventory assembly item is an item that is assembled or manufactured from inventory items. The items and/or assemblies that make up the assembly are called components.
- [Retrieve an inventory assembly item](https://docs.conductor.is/qbd-api/inventory-assembly-items/retrieve): Retrieves an inventory assembly item by ID.
- [Update an inventory assembly item](https://docs.conductor.is/qbd-api/inventory-assembly-items/update): Updates an existing inventory assembly item.
- [Create an inventory item](https://docs.conductor.is/qbd-api/inventory-items/create): Creates a new inventory item.
- [List all inventory items](https://docs.conductor.is/qbd-api/inventory-items/list): Returns a list of inventory items.
- [The Inventory Item object](https://docs.conductor.is/qbd-api/inventory-items/object): An inventory item is any merchandise or part that a business purchases, tracks as inventory, and then resells.
- [Retrieve an inventory item](https://docs.conductor.is/qbd-api/inventory-items/retrieve): Retrieves an inventory item by ID.
- [Update an inventory item](https://docs.conductor.is/qbd-api/inventory-items/update): Updates an existing inventory item.
- [Create an inventory site](https://docs.conductor.is/qbd-api/inventory-sites/create): Creates a new inventory site.
- [List all inventory sites](https://docs.conductor.is/qbd-api/inventory-sites/list): Returns a list of inventory sites.
- [The Inventory Site object](https://docs.conductor.is/qbd-api/inventory-sites/object): An inventory site is a location where inventory is stored. For example, a company might have a warehouse, a stockroom, and a showroom, each of which is an inventory site. NOTE: Inventory sites require QuickBooks Enterprise with an Advanced Inventory subscription.
- [Retrieve an inventory site](https://docs.conductor.is/qbd-api/inventory-sites/retrieve): Retrieves an inventory site by ID.
- [Update an inventory site](https://docs.conductor.is/qbd-api/inventory-sites/update): Updates an existing inventory site.
- [Create an invoice](https://docs.conductor.is/qbd-api/invoices/create): Creates a new invoice.
- [List all invoices](https://docs.conductor.is/qbd-api/invoices/list): Returns a list of invoices.
- [The Invoice object](https://docs.conductor.is/qbd-api/invoices/object): An invoice records the amount owed by a customer who purchased goods or services but did not pay in full at the time of the sale.
- [Retrieve an invoice](https://docs.conductor.is/qbd-api/invoices/retrieve): Retrieves an invoice by ID.
- [Update an invoice](https://docs.conductor.is/qbd-api/invoices/update): Updates an existing invoice.
- [Create a non-inventory item](https://docs.conductor.is/qbd-api/non-inventory-items/create): Creates a new non-inventory item.
- [List all non-inventory items](https://docs.conductor.is/qbd-api/non-inventory-items/list): Returns a list of non-inventory items.
- [The Non-Inventory Item object](https://docs.conductor.is/qbd-api/non-inventory-items/object): A non-inventory item is any material or part that a business buys but does not keep on hand as inventory.
There are two types of non-inventory items: 1. Materials or parts that are part of the business’s overhead (for example, office supplies) 2. Materials or parts that the business buys to finish a specific job and then charges back to the customer.
- [Retrieve a non-inventory item](https://docs.conductor.is/qbd-api/non-inventory-items/retrieve): Retrieves a non-inventory item by ID.
- [Update a non-inventory item](https://docs.conductor.is/qbd-api/non-inventory-items/update): Updates an existing non-inventory item.
- [Create a sales order](https://docs.conductor.is/qbd-api/sales-orders/create): Creates a new sales order.
- [List all sales orders](https://docs.conductor.is/qbd-api/sales-orders/list): Returns a list of sales orders.
- [The Sales Order object](https://docs.conductor.is/qbd-api/sales-orders/object): A sales order tracks inventory that is on back order for a customer. In QuickBooks, sales orders and invoices use similar fields, and a sales order can be “converted” into an invoice (by linking the invoice to the sales order) once the inventory is in stock.
- [Retrieve a sales order](https://docs.conductor.is/qbd-api/sales-orders/retrieve): Retrieves a sales order by ID.
- [Update a sales order](https://docs.conductor.is/qbd-api/sales-orders/update): Updates an existing sales order.
- [Create a sales-tax code](https://docs.conductor.is/qbd-api/sales-tax-codes/create): Creates a new sales-tax code.
- [List all sales-tax codes](https://docs.conductor.is/qbd-api/sales-tax-codes/list): Returns a list of sales-tax codes.
- [The Sales-Tax Code object](https://docs.conductor.is/qbd-api/sales-tax-codes/object): A sales tax code helps categorize items on a sales form as taxable or non-taxable, detailing reasons and associating tax codes with customers, items, or transactions.
- [Retrieve a sales-tax code](https://docs.conductor.is/qbd-api/sales-tax-codes/retrieve): Retrieves a sales-tax code by ID.
- [Update a sales-tax code](https://docs.conductor.is/qbd-api/sales-tax-codes/update): Updates an existing sales-tax code.
- [Create a sales-tax item](https://docs.conductor.is/qbd-api/sales-tax-items/create): Creates a new sales-tax item.
- [List all sales-tax items](https://docs.conductor.is/qbd-api/sales-tax-items/list): Returns a list of sales-tax items.
- [The Sales-Tax Item object](https://docs.conductor.is/qbd-api/sales-tax-items/object): A sales-tax item is an item used to calculate a single sales tax that is collected at a specified rate and paid to a single agency.
- [Retrieve a sales-tax item](https://docs.conductor.is/qbd-api/sales-tax-items/retrieve): Retrieves a sales-tax item by ID.
- [Update a sales-tax item](https://docs.conductor.is/qbd-api/sales-tax-items/update): Updates an existing sales-tax item.
- [Create a service item](https://docs.conductor.is/qbd-api/service-items/create): Creates a new service item.
- [List all service items](https://docs.conductor.is/qbd-api/service-items/list): Returns a list of service items.
- [The Service Item object](https://docs.conductor.is/qbd-api/service-items/object): A service item is an item that refers to services that a business charges for or purchases. Examples include specialized labor, consulting hours, and professional fees.
- [Retrieve a service item](https://docs.conductor.is/qbd-api/service-items/retrieve): Retrieves a service item by ID.
- [Update a service item](https://docs.conductor.is/qbd-api/service-items/update): Updates an existing service item.
- [Create a standard term](https://docs.conductor.is/qbd-api/standard-terms/create): Creates a new standard term.
- [List all standard terms](https://docs.conductor.is/qbd-api/standard-terms/list): Returns a list of standard terms.
- [The Standard Term object](https://docs.conductor.is/qbd-api/standard-terms/object): A standard term is a payment term that shows the number of days within which payment is due and can include a discount for early payment.
- [Retrieve a standard term](https://docs.conductor.is/qbd-api/standard-terms/retrieve): Retrieves a standard term by ID.
- [Create a transfer](https://docs.conductor.is/qbd-api/transfers/create): Creates a new transfer.
- [List all transfers](https://docs.conductor.is/qbd-api/transfers/list): Returns a list of transfers.
- [The Transfer object](https://docs.conductor.is/qbd-api/transfers/object): A transfer is a transaction that moves money from one account to another account.
- [Retrieve a transfer](https://docs.conductor.is/qbd-api/transfers/retrieve): Retrieves a transfer by ID.
- [Update a transfer](https://docs.conductor.is/qbd-api/transfers/update): Updates an existing transfer.
- [Create a vendor](https://docs.conductor.is/qbd-api/vendors/create): Creates a new vendor.
- [List all vendors](https://docs.conductor.is/qbd-api/vendors/list): Returns a list of vendors.
- [The Vendor object](https://docs.conductor.is/qbd-api/vendors/object): A vendor is any person or company from whom a small business owner buys goods and services. (Banks and tax agencies usually are included on the vendor list.) A company’s vendor list contains information such as account balance and contact information about each vendor.
- [Retrieve a vendor](https://docs.conductor.is/qbd-api/vendors/retrieve): Retrieves a vendor by ID.
- [Update a vendor](https://docs.conductor.is/qbd-api/vendors/update): Updates an existing vendor.
- [Accounts](https://docs.conductor.is/qbd-examples/accounts)
- [Bills](https://docs.conductor.is/qbd-examples/bills)
- [Inventory items](https://docs.conductor.is/qbd-examples/inventory)
- [Invoices](https://docs.conductor.is/qbd-examples/invoices)
- [Jobs and customers](https://docs.conductor.is/qbd-examples/jobs-and-customers): Understanding the relationship between customers and jobs in QuickBooks Desktop.
- [Request more examples!](https://docs.conductor.is/qbd-examples/more): Conductor supports read, create, and update for *every* QuickBooks Desktop object type.
- [Refunds](https://docs.conductor.is/qbd-examples/refunds)
- [Sales receipts](https://docs.conductor.is/qbd-examples/sales-receipts)
- [Vendors](https://docs.conductor.is/qbd-examples/vendors)
- [Node.js / TypeScript for QuickBooks Desktop](https://docs.conductor.is/qbd/api): Execute real-time requests for *any* QuickBooks Desktop object type with fully-typed requests and responses.
- [Get a free QuickBooks Desktop developer license](https://docs.conductor.is/qbd/dev-license): Obtain a free Not-For-Resale (NFR) license to use QuickBooks Desktop indefinitely for development and testing with Conductor. Takes 2 minutes.
- [Mapping your app's objects to QuickBooks Desktop](https://docs.conductor.is/qbd/mapping-objects): How to handle syncing your application's data objects with QuickBooks Desktop objects.
- [Pagination](https://docs.conductor.is/qbd/pagination): Split your requests into smaller chunks to avoid overwhelming QuickBooks Desktop
- [REST API for QuickBooks Desktop](https://docs.conductor.is/qbd/rest): If your backend does not use Node.js, you can use the REST API to interface with QuickBooks Desktop directly.
- [Create a QuickBooks Desktop test instance](https://docs.conductor.is/qbd/test-instance): Create your own QuickBooks Desktop test instance with an AWS WorkSpace.
- [Connect your users via the auth flow](https://docs.conductor.is/usage/auth-flow): Enable your users to securely connect their QuickBooks Desktop to your application.
- [Autocomplete](https://docs.conductor.is/usage/autocomplete): Use Conductor's built-in autocomplete to discover all available APIs, requests parameters, and response fields.
- [Check an EndUser's connection status](https://docs.conductor.is/usage/connection-status)
- [Error handling](https://docs.conductor.is/usage/error-handling): Catch and respond to connection errors, invalid requests, data problems, and more.
- [API keys](https://docs.conductor.is/usage/keys): Use API keys to authenticate API requests.


# Create an AuthSession

POST /auth-sessions
To launch the authentication flow, create an AuthSession and pass the returned session’s `authFlowUrl` to the client for your end-user to visit in their browser.



# The AuthSession object

An AuthSession is the secure way to programmatically launch the client-side Conductor authentication flow that lets your users connect their accounts to your integration.



# Retrieve an AuthSession

GET /auth-sessions/{id}
Retrieves the details of an AuthSession that has previously been created.



# Authentication



The Conductor API uses [API keys](/usage/keys) to authenticate requests.

Your secret API keys carry many privileges, so be sure to keep them secure. Do not share your secret API keys in publicly accessible areas such as Git, client-side code, or a public website.

You must make all API calls over HTTPS. Calls that you make over plain HTTP will fail. API requests without authentication will also fail.

<Tabs>
  <Tab title="cURL">
    Authentication to the API is performed with bearer auth. Provide your API key in the `Authorization` header.

    ```sh Example authenticated request
    curl -X GET https://api.conductor.is/v1/end-users \
         -H "Authorization: Bearer {{YOUR_SECRET_KEY}}"
    ```
  </Tab>

  <Tab title="Node.js">
    Use your API key by setting it in the initial configuration of Conductor. The Node.js library then automatically sends this key in each request.

    ```ts Example authenticated request
    import Conductor from "conductor-node";
    const conductor = new Conductor("{{YOUR_SECRET_KEY}}");

    const endUsers = await conductor.endUsers.list();
    ```
  </Tab>
</Tabs>


# Create an EndUser

POST /end-users
Creates an EndUser.



# Delete an EndUser

DELETE /end-users/{id}
Permanently deletes an EndUser object and all of its connections.



# List all EndUsers

GET /end-users
Returns a list of your EndUsers.



# The EndUser object

An EndUser represents a user of your application. Use it to connect integrations.



# Ping an EndUser's connection

GET /end-users/{id}/ping/{integrationSlug}
Checks whether the specified IntegrationConnection can connect and process requests end-to-end. This is useful for showing a "connection status" indicator in your app.



# Send a request to an EndUser's integration connection

POST /end-users/{id}/request/{integrationSlug}
Sends a request to the specified integration connection (e.g. QuickBooks Desktop) on behalf of the end-user.



# Retrieve an EndUser

GET /end-users/{id}
Retrieves an EndUser object.



# The ConductorError object



Every error returned by the Conductor API takes the form of a `ConductorError` object.

### Attributes

<ParamField body="message" type="string">
  The developer error message for your logs.
</ParamField>

<ParamField body="userFacingMessage" type="string">
  The user-friendly error message, written specifically for displaying to your end-users in your app's UI.

  This value exists for *every* error. E.g., for a QBD connection error, it might recommend the end-user to confirm their QuickBooks Desktop is open and that they're logged in. But if a Conductor API key is expired, e.g., this message will just say *"An internal server error occurred. Please try again later."*.
</ParamField>

<ParamField body="type" type="string">
  Categorizes the error. See the possible [error types](/usage/error-handling#error-types).

  This value is the same as the subclass name. E.g., `"ConductorIntegrationError"` or `"ConductorInvalidRequestError"`.
</ParamField>

<ParamField body="code" type="string">
  The unique error code from Conductor, which is useful for adding special handling for specific errors. E.g., `"RESOURCE_MISSING"`, `"API_KEY_INVALID"`, or `"QBD_REQUEST_ERROR"`.

  In contrast, `type` is more general and categorizes the error.
</ParamField>

<ParamField body="httpStatusCode" type="number or undefined">
  The HTTP status code of the response that included the error.
</ParamField>

<ParamField body="integrationCode" type="string or undefined">
  The unique error code supplied by the third-party integration for errors returned by the integration (i.e., `ConductorIntegrationError`) or integration connector (i.e., `ConductorIntegrationConnectorError`). This is useful for adding special handling for specific errors from the third-party integration or connector.

  The integration's corresponding error message for this code is in `error.message`.

  The third-party integrations' error codes are not standardized, so you should not rely on this code to be the same across integrations.
</ParamField>

<ParamField body="requestId" type="string or undefined">
  The unique identifier for the request that caused the error.

  If you need to contact us about a specific request, providing the request identifier will ensure the fastest possible resolution.
</ParamField>

<RequestExample>
  ```json Example ConductorError object
  {
    "error": {
      "message": "QBD Connection Error (0x80040420): The QuickBooks user
        has denied access.",
      "userFacingMessage": "We could not connect to QuickBooks Desktop
        because we must re-authorize our connection. To fix this, open
        QuickBooks Desktop, log in as Admin, navigate to 'Edit >
        Preferences > Integrated Applications', click 'Company Preferences',
        select our app, click 'Properties...', ensure 'Allow this
        application to log in automatically' is checked, then click 'OK'.
        Then try again.",
      "type": "INTEGRATION_CONNECTION_ERROR",
      "code": "QBD_CONNECTION_ERROR",
      "httpStatusCode": 502,
      "integrationCode": "0x80040420",
      "requestId": "req_1234567890"
    }
  }
  ```
</RequestExample>


# Request IDs



Each API request has an associated unique identifier. This identifier is returned in the response headers as `Conductor-Request-Id`. You can use this identifier to track the request in the logs. If you need to contact us about a specific request, providing the request identifier will ensure the fastest possible resolution.


# Timeouts



When you send a request to QuickBooks Desktop through Conductor, Conductor will wait up to four minutes for QuickBooks Desktop to process the request and return a response. While the four-minute timeout might seem long, it is necessary for the following reasons:

1.  **Large Data Requests:** Without paginating your requests (via the `MaxReturned` or other range-based parameters), you may unintentionally request tens of thousands of records in a single call. Processing such a large volume of data can take several minutes in QuickBooks Desktop.

2.  **Sequential Processing:** QuickBooks Desktop can only process one request at a time. If multiple requests are sent concurrently, they are placed in a queue and processed sequentially, requiring sufficient time for each request to complete before the next one can begin.

3.  **Potential Program Startup:** If QuickBooks Desktop is not open but the user’s computer is on, Conductor will automatically launch the program when a request is made. Given that QuickBooks Desktop can take at least 30 seconds to start, adding considerably to the response time.

If you prefer a different timeout period, you can customize it by setting the `Conductor-Timeout-Seconds` request header to your desired value.

**NOTE:** If QuickBooks Desktop is already offline when you send the request, Conductor will immediately return an error without initiating the timeout period.


# How to fix: "Your QuickBooks Desktop connection is not active"



export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

If Conductor is unable to sync your QuickBooks Desktop data, you may see the following error:

```
Your QuickBooks Desktop connection is not active. It was last active...
```

This error indicates that Conductor cannot establish a connection with the QuickBooks Web Connector on your computer. The Web Connector is an essential component that comes pre-installed with QuickBooks Desktop. It runs silently in the background, facilitating secure synchronization of your QuickBooks Desktop data with Conductor.

Follow these troubleshooting steps to resolve the issue:

## Troubleshooting your connection

<Steps>
  <Step title="Ensure your computer is on">
    The Web Connector requires your computer to be powered on and connected to the internet. If your computer is off, turn it on and ensure it has an active internet connection before attempting to sync again.

    If the error persists, proceed to the next step.
  </Step>

  <Step title="Ensure the Web Connector is running">
    The Web Connector should always be running in the background on your computer. If it's not, launch the program by following these steps:

    1.  Open QuickBooks Desktop with the company file you want to sync.
    2.  In the top menu bar, click "**File**" > "**App Management**" > "**Update Web Services**" to launch the QuickBooks Web Connector.
    3.  In the window that appears, click "**Hide**" in the bottom-right corner to keep the Web Connector running in the background.

    After completing these steps, attempt to sync your QuickBooks Desktop data again.

    If the error persists, continue to the next step.

    <Note>
      If the Web Connector doesn't start automatically with your computer, Conductor may face difficulties in reliably syncing your QuickBooks Desktop data. To ensure automatic startup, [follow this guide](/help/guides/ensure-web-connector-opens-at-startup).
    </Note>
  </Step>

  <Step title="Confirm Auto-Run is enabled for your connection">
    Reopen the Web Connector (following the steps in Step 2) and **confirm that the Auto-Run checkbox next to your connection is ticked**. This setting is required for Conductor to connect to your QuickBooks Desktop.

    If the Auto-Run checkbox is not ticked, tick it and click "**Hide**" in the bottom-right corner.

    After enabling Auto-Run, attempt to sync your QuickBooks Desktop data once more.

    <Image src="/images/help/connection-errors/connection-not-active/web-connector-enable-auto-run.jpg" alt="Ensure auto-run is enabled for your connection in the Web Connector" />
  </Step>
</Steps>

If you continue to receive the "Your QuickBooks Desktop connection is not active" error after completing these steps, please contact our support team at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Connection%20Issue).


# How to fix: "Could not start QuickBooks"



export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

If you were directed to this page, it was likely because you encountered the following error attempting to sync with your QuickBooks Desktop:

```
We could not connect to your QuickBooks Desktop because either QuickBooks
Desktop is closed and we could not start it, or an error popped up on your
Windows computer.
```

Alternatively, you might have been directed to this page for the following error *(which is the exact same error; the message above is merely Conductor's user-friendly version)*:

```
(0x80040408): Could not start QuickBooks.
```

## Solution

### 1. Ensure only one version of QuickBooks Desktop is installed

Having multiple versions of QuickBooks Desktop installed on your Windows computer can cause the error above and several other issues. Please [complete this guide to ensure](/help/guides/ensure-only-one-version-installed) only one version of QuickBooks Desktop is installed on your computer. Then, try syncing with QuickBooks Desktop again.

### 2. Do you encounter any of these errors when syncing QuickBooks Desktop?

The first common culprit for the error above is if QuickBooks Desktop is unable to properly open. If QuickBooks Desktop is not open, please open it and try syncing with Conductor again.

If you still see the same error, check if any of the following errors pop up on your Windows computer while attempting to sync with QuickBooks Desktop:

<Steps>
  <Step title="&#x22;Do you want to allow this app to make changes to your device?&#x22;">
    If when syncing with QuickBooks Desktop, a dialog box opens on your Windows computer saying, *"Do you want to allow this app to make changes to your device?"*, then please [complete this guide to resolve that issue](/help/connection-errors/do-you-want-to-allow-this-app-to-make-changes-to-your-device). Then, try syncing with QuickBooks Desktop again.

    <Image src="/images/help/connection-errors/do-you-want-to-allow-this-app-to-make-changes-to-your-device/do-you-want-to-allow-this-app-to-make-changes-to-your-device.jpg" alt="QuickBooks Desktop - Do you want to allow this app to make changes to your device" width="400" />
  </Step>

  <Step title="&#x22;There was a problem with the log file&#x22;">
    If when syncing with QuickBooks Desktop, the error shown below popped up on your Windows computer saying, "There was a problem with the log file", then please [complete this guide to resolve that error](/help/connection-errors/there-was-a-problem-with-the-log-file). Then, try syncing with QuickBooks Desktop again.

    <Image src="/images/help/connection-errors/there-was-a-problem-with-the-log-file/there-was-a-problem-with-the-log-file.jpg" alt="QuickBooks Web Connector error - There was a problem with the log file. QuickBooks Web Connector will continue without a log file" width="375" />
  </Step>
</Steps>

If either no error appeared on your Windows computer or some other error not listed above appeared, please email us at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Help). We want to help you resolve this issue and use your experience to improve this guide for others.


# How to fix: "Do you want to allow this app to make changes to your device?"



export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

If you ever see the Windows prompt shown below whenever you attempt to sync with QuickBooks Desktop, it is preventing Conductor from syncing with QuickBooks Desktop. To resolve this issue, you must configure QuickBooks Desktop and the QuickBooks Web Connector to run as an administrator. Please follow all of the steps in this guide to resolve this issue.

<Image src="/images/help/connection-errors/do-you-want-to-allow-this-app-to-make-changes-to-your-device/do-you-want-to-allow-this-app-to-make-changes-to-your-device.jpg" alt="QuickBooks Desktop - Do you want to allow this app to make changes to your device" width="425" />

{/* NOTE: The following solution is identical to `there-was-a-problem-with-the-log-file.mdx` */}

## Solution

To prevent Windows from showing you the prompt above, which blocks Conductor from syncing QuickBooks Desktop, you must configure QuickBooks Desktop and the QuickBooks Web Connector to run as an administrator. To do so, follow the steps below:

### 1. Run QuickBooks Desktop as an administrator

<Steps>
  <Step title="Locate the QuickBooks Desktop shortcut">
    Using Windows search (usually located in the bottom-left corner of your
    screen), type "**QuickBooks Desktop**", right-click on the QuickBooks
    Desktop result, and select "**Open file location**". If you have QuickBooks
    Desktop pinned to your taskbar or on your desktop, you can right-click on
    the icon there instead.
  </Step>

  <Step title="Access properties">
    In the folder that opens, right-click on the QuickBooks Desktop icon and
    select "**Properties**" to open the Properties window.
  </Step>

  <Step title="Navigate to the Compatibility tab">
    In the Properties window, navigate to the "**Compatibility**" tab.
  </Step>

  <Step title="Set to run as administrator">
    Check the box labeled "**Run this program as an administrator**" under the
    Settings section.
  </Step>

  <Step title="Apply and OK">
    Click "**Apply**" to save the changes, then click "**OK**" to close the
    Properties window.
  </Step>

  <Step title="Restart QuickBooks Desktop">
    If QuickBooks Desktop is currently open, close it completely and then
    re-open it.
  </Step>
</Steps>

### 2. Run the QuickBooks Web Connector as an administrator

<Steps>
  <Step title="Locate the Web Connector shortcut">
    Using Windows search (usually located in the bottom-left corner of your
    screen), type "**Web Connector**", right-click on the Web Connector result,
    and select "**Open file location**".
  </Step>

  <Step title="Access properties">
    In the folder that opens, right-click on the Web Connector icon and select
    "**Properties**" to open the Properties window.
  </Step>

  <Step title="Navigate to the Compatibility tab">
    In the Properties window, navigate to the "**Compatibility**" tab.
  </Step>

  <Step title="Set to run as administrator">
    Check the box labeled "**Run this program as an administrator**" under the
    Settings section.
  </Step>

  <Step title="Apply and OK">
    Click "**Apply**" to save the changes, then click "**OK**" to close the
    Properties window.
  </Step>

  <Step title="Restart your computer">
    Restart your computer to ensure the changes take effect.
  </Step>
</Steps>

By following these steps, QuickBooks Desktop and the Web Connector will always run with administrator privileges, preventing the error from occurring.

If you're still encountering the error after completing all the steps in this guide, please email us at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Help) for further assistance.


# How to fix: "QBWC1085: There was a problem with the log file"



export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

When connecting to QuickBooks Desktop with Conductor, you might encounter the error shown below, which prevents syncing your QuickBooks Desktop data with Conductor. This guide outlines two possible solutions to resolve this issue.

<Image src="/images/help/connection-errors/there-was-a-problem-with-the-log-file/there-was-a-problem-with-the-log-file.jpg" alt="QuickBooks Web Connector error - QBWC1085: There was a problem with the log file. QuickBooks Web Connector will continue without a log file" width="375" />

## Solution 1: Delete the QuickBooks Web Connector log file

A corrupted QuickBooks Web Connector log file can cause this error. Deleting the log file will force the Web Connector to generate a new one. To do so, follow these steps:

<Steps>
  <Step title="Close QuickBooks Desktop">
    Ensure QuickBooks Desktop is completely closed.
  </Step>

  <Step title="Terminate the QuickBooks Web Connector">
    Terminate the QuickBooks Web Connector process to ensure it is not running in the background:

    1.  Open the Windows Task Manager by searching for "Task Manager" in the Windows search bar (usually located in the bottom-left corner of your screen).
    2.  In the Task Manager, find "QuickBooks Web Connector", right-click it, and select "**End Task**". You may need to click "**More details**" at the bottom of the Task Manager window to see all running processes.
    3.  Close the Task Manager.
  </Step>

  <Step title="Navigate to the QuickBooks Web Connector log directory">
    Open File Explorer and navigate to the QuickBooks Web Connector log directory by copying and pasting the following path into the address bar:

    ```
    C:\ProgramData\Intuit\QBWebConnector\log
    ```
  </Step>

  <Step title="Delete the log file">
    In the log directory, locate the file named `QWCLog.txt`, right-click on it, and select "**Delete**".
  </Step>

  <Step title="Restart QuickBooks Desktop and the Web Connector">
    Restart QuickBooks Desktop and the QuickBooks Web Connector to generate a new log file:

    1.  Open QuickBooks Desktop with the company file you want to sync.
    2.  In the top menu bar, click "**File**" > "**App Management**" > "**Update Web Services**" to launch the QuickBooks Web Connector.
    3.  In the window that appears, click "**Hide**" in the bottom-right corner to keep the Web Connector running in the background.
  </Step>
</Steps>

After completing these steps, attempt to sync your QuickBooks Desktop data again. If the error persists, proceed to Solution 2.

{/* NOTE: The following solution is identical to `do-you-want-to-allow-this-app-to-make-changes-to-your-device.mdx` */}

## Solution 2: Run QuickBooks Desktop and Web Connector as administrator

If the error persists after completing Solution 1, it may be due to QuickBooks Desktop or the QuickBooks Web Connector lacking permission to write to the log file. Running both as an administrator will grant the necessary permissions. To do so, follow these steps:

### 2.1 Run QuickBooks Desktop as an administrator

<Steps>
  <Step title="Locate the QuickBooks Desktop shortcut">
    Using Windows search (usually located in the bottom-left corner of your
    screen), type "**QuickBooks Desktop**", right-click on the QuickBooks
    Desktop result, and select "**Open file location**". If you have QuickBooks
    Desktop pinned to your taskbar or on your desktop, you can right-click on
    the icon there instead.
  </Step>

  <Step title="Access properties">
    In the folder that opens, right-click on the QuickBooks Desktop icon and
    select "**Properties**" to open the Properties window.
  </Step>

  <Step title="Navigate to the Compatibility tab">
    In the Properties window, navigate to the "Compatibility" tab.
  </Step>

  <Step title="Set to run as administrator">
    Check the box labeled "**Run this program as an administrator**" under the
    Settings section.
  </Step>

  <Step title="Apply and OK">
    Click "**Apply**" to save the changes, then click "**OK**" to close the
    Properties window.
  </Step>

  <Step title="Restart QuickBooks Desktop">
    If QuickBooks Desktop is currently open, close it completely and then
    re-open it.
  </Step>
</Steps>

### 2.2 Run the QuickBooks Web Connector as an administrator

<Steps>
  <Step title="Locate the Web Connector shortcut">
    Using Windows search (usually located in the bottom-left corner of your
    screen), type "**Web Connector**", right-click on the Web Connector result,
    and select "**Open file location**".
  </Step>

  <Step title="Access properties">
    In the folder that opens, right-click on the Web Connector icon and select
    "Properties" to open the Properties window.
  </Step>

  <Step title="Navigate to the Compatibility tab">
    In the Properties window, navigate to the "Compatibility" tab.
  </Step>

  <Step title="Set to run as administrator">
    Check the box labeled "**Run this program as an administrator**" under the
    Settings section.
  </Step>

  <Step title="Apply and OK">
    Click "**Apply**" to save the changes, then click "**OK**" to close the
    Properties window.
  </Step>

  <Step title="Restart your computer">
    Restart your computer to ensure the changes take effect.
  </Step>
</Steps>

By following these steps, QuickBooks Desktop and the Web Connector will always run with administrator privileges, preventing the error from occurring.

If you're still encountering the error after completing all the steps in this guide, please email us at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Help) for further assistance.


# How to fix: "Unable to cast COM object of type System.__ComObject..."



export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

If a Conductor error message directed you to this page, it's because we encountered the following error when attempting to connect to QuickBooks Desktop on your computer:

```
Unable to cast COM object of type 'System.__ComObject' to interface type
'Interop.QBXMLRP2.RequestProcessor2'. This operation failed because the
QueryInterface call on the COM component for the interface with IID
'{8DB91B17-D5A2-41DB-80A7-CC6F1E449A05}' failed due to the following error:
No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
```

## Solution

Complete the following steps to re-register the QuickBooks Desktop components to resolve this issue:

<Steps>
  <Step title="Close QuickBooks Desktop">
    Ensure QuickBooks Desktop is completely closed.
  </Step>

  <Step title="Open the Windows PowerShell as an administrator">
    Using Windows search (usually located in the bottom-left corner of your screen), type "**cmd**", right-click on the "**Command Prompt**" result, and select "**Run as administrator**".

    <Image src="/images/help/connection-errors/unable-to-cast-com-object/run-command-prompt-as-admin.jpg" alt="Run Windows PowerShell as administrator" width="550" />
  </Step>

  <Step title="Run the command to re-register QuickBooks components">
    In the PowerShell window, paste the following command and press Enter:

    ```shell
    regsvr32 "C:\Program Files (x86)\Common Files\Intuit\QuickBooks\QBXMLRP2.dll"
    ```

    <Image src="/images/help/connection-errors/unable-to-cast-com-object/command-prompt-reregister.jpg" alt="Re-register QuickBooks components via Windows Command Prompt" />
  </Step>

  <Step title="Restart your computer">
    If the command was successful, restart your computer to ensure the changes take effect. After restarting, try connecting to QuickBooks Desktop again.
  </Step>
</Steps>

If you're still encountering the same error after following these steps, please email us at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Help).


# How to fix: "QBWC1039: Unique OwnerID/FileID pair value required"



export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

This guide will walk you through resolving the following error that occurs when attempting to add a connection to the QuickBooks Web Connector:

<Image src="/images/help/connection-errors/unique-owner-id-file-id-pair-required/qbwc-unique-owner-id-file-id-required-error.jpg" alt="QuickBooks Web Connector error - QBWC1039: Unique OwnerID/FileID pair value required" width="400" />

This error typically occurs when:

*   You previously added a connection to the QuickBooks Web Connector, removed it, and are now attempting to add it again for the same QuickBooks company file.

*   You previously added the connection to the QuickBooks Web Connector *on another computer* for the same QuickBooks company file, removed it, and are now attempting to add it *on a different computer*.

#### If you are also getting the "Unhandled exception has occurred" error

In addition to the error above, some users also encounter the following error *at the same time:*

<Image src="/images/help/connection-errors/unique-owner-id-file-id-pair-required/qbwc-unhandled-exception.jpg" alt="QuickBooks Web Connector error - Unhandled exception has occurred in a component in your application. If you click Continue, the application will ignore this error and attempt to continue. Index (zero based) must be greater than or equal to zero and less than the size of the argument list." width="450" />

If you are encountering this error as well, we must first force-quit the QuickBooks Web Connector before we can fix the other error at the top of this page. To do this, follow the steps below.

1.  Open the Windows Task Manager by searching for "Task Manager" in the Windows search bar (usually located in the bottom-left corner of your screen).

2.  In the Task Manager, find the QuickBooks Web Connector, right-click it, and select "**End Task**". You may need to click "**More details**" at the bottom of the Task Manager window to see all running processes.

After force-quitting the QuickBooks Web Connector, continue to the next section to fix the original error for *"Unique OwnerID/FileID pair value required"*.

## Solution

Complete the following steps to fix the error shown above for *"Unique OwnerID/FileID pair value required"*.

<Steps>
  <Step title="Open QuickBooks Desktop" />

  <Step title="Download and run the QBWC CP3 Tool">
    Download the [QBWC CP3 tool](https://http-download.intuit.com/http.intuit/CP3Tool/QBWC_CP3Tool.exe?_ga=2.67283025.1765810068.1652776906-1422200743.1652776904), created by Intuit (the makers of QuickBooks Desktop), to address this issue. Open the program ("QBWC\_CP3Tool.exe") from your downloads folder.
  </Step>

  <Step title="Select the QWC file">
    In the window that opens, as shown below, click "**Select File**", locate the QWC file that you attempted to open earlier which resulted in the error, and click "**Open**". This file is often found in your downloads folder.

    <Image src="/images/help/connection-errors/unique-owner-id-file-id-pair-required/qbwc-cp3tool.jpg" alt="QuickBooks Web Connector - QBWC1039: Unique OwnerID/FileID pair value required" width="475" />
  </Step>

  <Step title="Click &#x22;Remove Stamp&#x22;" />

  <Step title="Grant permission to the CP3 tool">
    QuickBooks Desktop will prompt you to grant permission to the CP3 Tool to make the necessary changes:

    1.  In the QuickBooks Application Certificate window that appears, click "**Yes**", then "**Continue**".

    2.  On the Access Confirmation window, select "**Done**".

    3.  Follow the instructions, then select "**OK**".
  </Step>

  <Step title="Close the CP3 tool">
    You should receive a confirmation that the Owner ID was removed. Select "**OK**" and close the CP3 tool.
  </Step>

  <Step title="Retry adding the connection">
    Attempt to open the same QWC file you tried opening earlier. This time, it should work without any errors, and you should see the connection added to the QuickBooks Web Connector.
  </Step>
</Steps>

If you continue to encounter the error after completing these steps or have trouble with any step, please email us at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Help) for further assistance.


# QuickBooks Desktop FAQ for end-users

An FAQ guide written for the end-users of Conductor's QuickBooks Desktop integration.

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

This FAQ is designed to answer any questions you may have about your QuickBooks Desktop connection and Conductor, the technology provider that powers it.

### Who is Conductor?

Conductor is a technology provider that powers the QuickBooks Desktop integration for the software you're using. We specialize in creating secure, reliable connections between different software platforms, ensuring your data flows smoothly and safely from QuickBooks Desktop to your business application.

### Customer support -- we're here to help!

Conductor works hand-in-hand with your software provider to ensure your QuickBooks Desktop integration is set up correctly. If you need assistance, please contact your software provider or [email our support team](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Integration%20help\&body=Please%20describe%20the%20issues%20you%20are%20encountering%20setting%20up%20the%20QuickBooks%20Desktop%20integration:%20). We are happy to help any way we can.

### Does Conductor store my QuickBooks Desktop data?

**No, Conductor does not store any of your data.** We act as a secure conduit, facilitating the transfer of information between your QuickBooks Desktop and the software you are using, without retaining any of that information on our systems.

### How does the integration connect with QuickBooks Desktop?

The integration uses the QuickBooks Web Connector, an inbuilt feature of QuickBooks Desktop designed for secure data synchronization. This method is officially recommended by QuickBooks and involves robust user authentication and SSL (Secure Socket Layer) encryption. This ensures that your data is encrypted during transmission, protecting it from unauthorized access.

### What is the QuickBooks Desktop Web Connector?

The QuickBooks Web Connector is a program that comes preinstalled with QuickBooks Desktop that the integration uses to securely sync your data. This program always runs invisibly in the background on your computer and starts automatically whenever you start your computer. If it does not start automatically, the integration cannot reliably sync your data. The only time you should ever see the Web Connector is when you first set up your QuickBooks Desktop connection with the integration; other than that, it should be invisible.

### Is it a problem if the Web Connector says "Update postponed by application"?

No, there is no problem at all if you see this message. It means that things are working correctly. This message indicates that the Web Connector has checked for updates, but no sync is necessary at the moment.

### Does the integration impact the speed or performance of QuickBooks Desktop?

No, the integration does not slow down QuickBooks Desktop. Here's why:

*   The integration is powered by QuickBooks Desktop's built-in Web Connector. When the Web Connector is running in the background, it operates independently of QuickBooks Desktop, much like any other Windows program. In this idle state, it simply waits for new requests without interacting with QuickBooks Desktop.
*   Even when processing a request, QuickBooks Desktop's performance would only be impacted if more than 5,000 records were being retrieved at once, however, we prevent this by limiting requests to 500 records at a time.
*   The Web Connector is lightweight and only checks for new requests every 10 seconds, making it unlikely to slow down the Windows system as a whole.
*   We have never observed or received reports of the integration affecting system performance.

### What security measures does Conductor implement to secure data?

Conductor adheres to the industry's top security practices, including:

*   **SSL Encryption:** For secure data transmission.
*   **Encrypted API Keys:** Unique keys that ensure only authorized software can access your data.
*   **Zero Data Storage Policy:** We don't store your QuickBooks data, maintaining your privacy.
*   **Continuous Monitoring:** Our systems are monitored continuously for any unusual activity to prevent unauthorized access.

### Which data from QuickBooks Desktop can the integration access?

The integration can read and write most data types in your QuickBooks Desktop, ***excluding* sensitive personal information like Social Security Numbers and customer credit card details**. This broad access is necessary because the QuickBooks Web Connector does not support limited permissions for selective data access.

### Does my computer need to be powered on to sync my QuickBooks Desktop data?

Yes, your computer must be powered on to sync your QuickBooks Desktop data.

### Does QuickBooks Desktop need to be open to sync my data?

No, we can sync your QuickBooks Desktop data even if QuickBooks Desktop is not open. However, if QuickBooks Desktop is open to a different company file, we will return an error.

### Does my computer need to sign in as the Admin user to sync my data?

No, signing in as the Admin user is only required for the initial setup process. After the setup is complete, you can switch back to your regular QuickBooks Desktop user.

### Does the integration work with Rightworks (formerly called Right Networks)?

Yes, the integration fully supports QuickBooks Desktop when hosted on Rightworks. For setup instructions, please see our [Connecting to Rightworks guide](/help/guides/rightworks).

### How often does the integration access my QuickBooks data?

The frequency of data access is determined by the software you are using, not Conductor. Typically, data syncs occur when you initiate them (e.g., clicking a "sync" button in your software). For specifics, please contact your software provider.

### How can I disable the QuickBooks Desktop connection?

Please follow [this guide](/help/guides/disable-connection) to disable the QuickBooks Desktop connection.

### Any other questions?

If you have any other questions, please email us at [support@conductor.is](mailto:support@conductor.is).


# How to disable the QuickBooks Desktop connection

Learn how to disable the QuickBooks Desktop connection in the QuickBooks Web Connector.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

Follow the steps below to disable a QuickBooks Desktop connection in the QuickBooks Web Connector.

<Steps>
  <Step title="Open the QuickBooks Web Connector">
    1.  Open QuickBooks Desktop.
    2.  In the top menu bar, click "**File**" > "**App Management**" > "**Update Web Services**" to launch the QuickBooks Web Connector.
  </Step>

  <Step title="Disable the connection">
    In the Web Connector window that opens, find the connection for the product or service you want to disconnect, and uncheck the box in the "**Auto-Run**" column for that connection.

    <Image src="/images/help/guides/disable-connection/web-connector-disable-auto-run.jpg" alt="Disable Auto-Run for the Web Connector connection on your old computer" />

    <Note>
      We recommend disabling "Auto-Run" instead of clicking "Remove" because the "Remove" button is known to cause issues. Plus, it is convenient to save the old connection's configuration in case you want to restore this connection later.
    </Note>
  </Step>

  <Step title="Close the QuickBooks Web Connector">
    Finally, click "**Hide**" in the bottom-right corner of the window to close the Web Connector.

    <Image src="/images/help/guides/disable-connection/web-connector-hide.jpg" alt="Close the QuickBooks Web Connector" />
  </Step>
</Steps>

Conductor's QuickBooks Desktop connection will no longer run on your computer.

If you encountered any unexpected issues while following these steps, please email us at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Help).


# Ensure only one version of QuickBooks Desktop is installed

Conductor will not function properly if multiple versions of QuickBooks Desktop are installed on the same computer.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

Having multiple versions of QuickBooks Desktop installed on the same computer can cause issues with Conductor. Often, this prevents the QuickBooks Web Connector from connecting to QuickBooks Desktop or causes it to crash. Please follow the steps below to ensure only one version of QuickBooks Desktop is installed on your computer.

<Steps>
  <Step title="Open the Windows Control Panel">
    Using Windows search (usually located in the bottom-left corner of your screen), search for "Control Panel", and open it.
  </Step>

  <Step title="Click on Programs and Features">
    In the Control Panel, click on "**Programs and Features**" or "**Uninstall a program**" (exact wording may vary depending on your version of Windows).
  </Step>

  <Step title="Check for multiple versions of QuickBooks Desktop">
    In the list of installed programs, look for any versions of QuickBooks Desktop. If you see multiple versions, such as in the example below, continue to the next step. If you only see one version, you can stop here.

    <Image src="/images/help/guides/ensure-only-one-version-installed/multiple-versions-installed.jpg" alt="Multiple versions of QuickBooks Desktop installed" width={550} shadow={false} />
  </Step>

  <Step title="Close QuickBooks Desktop">
    Before uninstalling any versions of QuickBooks Desktop, make sure QuickBooks Desktop is completely closed.
  </Step>

  <Step title="Uninstall the older version(s) of QuickBooks Desktop">
    Back in the Control Panel window, right-click on the older version(s) of QuickBooks Desktop in the list of installed programs and click "**Uninstall**". Follow the prompts to uninstall the program. For example:

    <Image src="/images/help/guides/ensure-only-one-version-installed/uninstall-old-quickbooks-desktop.jpg" alt="Uninstall older version of QuickBooks Desktop" width={550} shadow={false} />
  </Step>

  <Step title="Reopen QuickBooks Desktop">
    After uninstalling the older version(s), reopen QuickBooks Desktop and follow any prompts for updates.

    1.  If QuickBooks Desktop asks you to fix the installation, click "**Continue**".

    <Image src="/images/help/guides/ensure-only-one-version-installed/fix-quickbooks-desktop-after-uninstalling-old-version.jpg" alt="Fix QuickBooks Desktop after uninstalling old version" width={500} shadow={false} />

    2.  If QuickBooks Desktop asks you to reboot after fixing the installation, click "**OK**".

    <Image src="/images/help/guides/ensure-only-one-version-installed/reboot-required-after-fixing-quickbooks-desktop.jpg" alt="Reboot required after fixing QuickBooks Desktop" width={400} shadow={false} />
  </Step>
</Steps>

By following these steps, you can ensure only one version of QuickBooks Desktop is installed on your computer, which will help prevent issues with Conductor.


# Ensure the QuickBooks Web Connector opens at startup

Set up the QuickBooks Web Connector to automatically launch and run in the background whenever you start your computer.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

The QuickBooks Web Connector is a program that comes preinstalled with QuickBooks Desktop that Conductor uses to securely sync your data. This program always runs invisibly in the background on your computer and starts automatically whenever you start your computer. If it does not start automatically, Conductor cannot reliably sync your data.

If you are having trouble syncing your data, please follow the steps below to ensure that the Web Connector starts automatically when you start your computer. If we discover it does not, we will configure the Windows Task Scheduler to start the Web Connector automatically.

## 1. Check if the Web Connector starts automatically when you start your computer

First, let's check whether the Web Connector starts automatically when you start your computer:

<Steps>
  <Step title="Restart your computer">
    Restart your computer so we can check in the next step whether the Web Connector automatically starts when your computer starts.
  </Step>

  <Step title="Check the Task Manager for the Web Connector">
    After your computer finishes booting up, the Web Connector should automatically start invisibly in the background. Let's check if it is running:

    1.  Open the Windows Task Manager by searching for "Task Manager" in the Windows search bar (usually located in the bottom-left corner of your screen).

    2.  If you see a "More details" button in the bottom-left corner of the Task Manager window, click it to expand the Task Manager.

    3.  Navigate to the "Details" tab and scroll down until you see the "QBWebConnector.exe" process which should look like the screenshot below. **If you see it, you can skip the rest of this guide. Otherwise, continue to the section below.**

        <Image src="/images/help/guides/ensure-web-connector-opens-at-startup/task-scheduler/qbwc-task-manager.jpg" alt="The Web Connector running in the Task Manager" shadow={false} />
  </Step>
</Steps>

## 2. Configure the Web Connector to start automatically using the Windows Task Scheduler

After confirming that the Web Connector does not start automatically when you start your computer in the previous section, we will now configure the Windows Task Scheduler to start the Web Connector automatically.

<Steps>
  <Step title="Open Windows Task Scheduler">
    Open the Windows Task Scheduler by searching for "Task Scheduler" in the Windows search bar (usually located in the bottom-left corner of your screen).
  </Step>

  <Step title="Create a new task">
    In the Task Scheduler, go to the "Action" menu and select "**Create Task**".

    <Image src="/images/help/guides/ensure-web-connector-opens-at-startup/task-scheduler/create-task.jpg" alt="Task Scheduler create task" width={300} shadow={false} />
  </Step>

  <Step title="General tab">
    In the "General" tab of the new task window:

    1.  Enter any name for your task, such as "Open QuickBooks Web Connector".

    2.  Check the option "**Run with highest privileges**" near the bottom to ensure the task runs with administrator rights.

    <Image src="/images/help/guides/ensure-web-connector-opens-at-startup/task-scheduler/general-tab.jpg" alt="Task Scheduler general tab" shadow={false} />
  </Step>

  <Step title="Set trigger for startup">
    Go to the "**Triggers**" tab and click "**New**".

    1.  Under "Begin the task", select "**At startup**" from the dropdown menu.

    2.  Set a delay for 1 minute by checking "Delay task for" and choose "1 minute".

    Finally, click "**OK**".

    <Image src="/images/help/guides/ensure-web-connector-opens-at-startup/task-scheduler/new-trigger.jpg" alt="Task Scheduler new trigger" shadow={false} />
  </Step>

  <Step title="Get the file path for the Web Connector">
    1.  Using Windows search (usually located in the bottom-left corner of your screen), type "**Web Connector**", right-click on the Web Connector result, and select "**Open file location**".

    2.  In the folder that opens, you should see a shortcut for the Web Connector. Right-click on the Web Connector icon and select "**Properties**" from the context menu to open the Properties window.

    3.  In the Properties window, as shown below, copy the file path in the "**Target**" field. You can do this by selecting the text and pressing `Ctrl + C` on your keyboard. Then click "**Cancel**" to close the Properties window.

        <Image src="/images/help/guides/ensure-web-connector-opens-at-startup/task-scheduler/qbwc-file-path.jpg" alt="Copy the Web Connector file path" width={550} shadow={false} />
  </Step>

  <Step title="Set action to start QuickBooks Web Connector">
    Go back to the Task Scheduler window and go to the "Actions" tab. Click "**New**" and paste the file path you copied in the previous step into the "**Program/script**" field by right-clicking and selecting "**Paste**" from the context menu. Then click "**OK**".

    <Image src="/images/help/guides/ensure-web-connector-opens-at-startup/task-scheduler/new-action.jpg" alt="Task Scheduler new action" shadow={false} />
  </Step>

  <Step title="Configure settings to retry">
    In the "Settings" tab, check the option "**If the task fails, restart every**" and set the value to "**1 minute**" and the "**Attempt to restart up to**" value to "**3 times**". Then click "**OK**".

    <Image src="/images/help/guides/ensure-web-connector-opens-at-startup/task-scheduler/settings-tab.jpg" alt="Task Scheduler settings tab" shadow={false} />
  </Step>

  <Step title="Save and exit">
    Click "**OK**" to save your new task. You might be prompted to enter an administrator password at this point.
  </Step>

  <Step title="Test the task">
    Finally, test your task by restarting your computer, waiting one minute, and confirming that the QuickBooks Web Connector opened automatically after startup using [the same steps as in the first section of this guide](/help/guides/ensure-web-connector-opens-at-startup#1-check-if-the-web-connector-starts-automatically-when-you-start-your-computer).
  </Step>
</Steps>

By following these steps, the QuickBooks Web Connector will now always start automatically whenever you start your computer.

If you're still having trouble after completing all steps, please email us at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Help).


# Move your QuickBooks Desktop connection to a different computer

Learn how to transfer your QuickBooks Desktop connection to a different computer for the same company file.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

<Steps>
  <Step title="Disable the connection on your current computer">
    Before setting up the new connection, follow [this guide to disable the existing connection](/help/guides/disable-connection) on your **current** computer.

    <Warning>
      It is essential that you complete this step first to avoid synchronization conflicts with your new computer's connection.
    </Warning>
  </Step>

  <Step title="Prepare QuickBooks Desktop on the new computer">
    1.  Launch QuickBooks Desktop on your **new** computer.
    2.  Open the company file you want to connect.
    3.  Log in using your QuickBooks **Admin** user credentials.

    <Warning>
      Ensure you're using the exact same company file as before. The file path can be different, but it must be the same QuickBooks company file.
    </Warning>
  </Step>

  <Step title="Install the new connection">
    Return to the setup guide, click **"Download config file"**, and then the downloaded configuration file.

    <Info>
      QuickBooks Desktop might *not* show the permissions prompt when adding the new connection because you previously authorized access to this company file on your old computer. This is normal and doesn't indicate any problem with the setup.
    </Info>
  </Step>

  <Step title="Complete the connection setup">
    Follow the remaining steps in the setup guide. When complete, the final step of the guide will confirm that the connection is successful.
  </Step>
</Steps>

You have now successfully moved your connection to a different computer.

If you encountered any unexpected issues while following these steps, please email us at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Help).


# Connect to multiple company files on a single computer

How to connect to multiple QuickBooks Desktop company files on a single computer.

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

In QuickBooks Desktop, a **company file** is the primary local file that stores all financial data for a specific company. While most QuickBooks Desktop users have only one company file, some users, such as accounting firms managing finances for multiple clients, work with several company files on a single computer. This guide will walk you through connecting Conductor (which powers your integration) to multiple company files on a single computer, as well as best practices and performance considerations.

## Important requirement

<Warning>
  **QuickBooks Desktop must always remain open *without* any company file loaded
  when connecting to multiple company files on a single computer.** This setup
  allows the Web Connector to open the correct company file when it receives a
  request from your QuickBooks Desktop integration.
</Warning>

### Why is this necessary?

The [QuickBooks Web Connector](/help/faq/end-user-faq#what-is-the-quickbooks-desktop-web-connector) has certain limitations when working with multiple company files on a single computer:

1.  It can only communicate with one company file at a time.
2.  It can only communicate with the company file that is currently open in QuickBooks Desktop.
3.  It cannot switch between company files if QuickBooks Desktop already has a different company file open (to avoid disrupting an active user).

Despite these limitations, **the Web Connector can open a specified company file if no other company file is currently open, fulfill the request, and then close the company file** without fully closing QuickBooks Desktop. Therefore, keeping QuickBooks Desktop open without any company file loaded allows the Web Connector to open and process requests for the correct company file as needed.

### How to close a company file

To ensure QuickBooks Desktop is open without any company file loaded:

1.  Open **QuickBooks Desktop**.
2.  Go to the "**File**" menu.
3.  Select "**Close Company**".

<Frame caption="QuickBooks Desktop must always be open without any company file loaded, as shown here, to receive requests for any company file on the computer.">
  ![QuickBooks Desktop without any company file
  loaded](https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/help/guides/multiple-connections-one-computer/qbd-no-company-open.jpg)
</Frame>

If you or someone else opens a company file *on this machine* without returning QuickBooks Desktop to this state, you may encounter an error stating that the wrong company file is open.

## How to set up connections to multiple company files

To connect to multiple company files on one computer, you must complete the setup process **for each company file**, as each requires its own connection and authentication.

1.  Open **QuickBooks Desktop**.
2.  Open the company file you wish to connect.
3.  Sign in as the **Admin** user.
4.  Complete the setup guide *while* the corresponding company file is open.
5.  Repeat steps 1-4 for each company file.

Once complete, each company file will have a separate connection in the Web Connector, resembling the state shown below:

<Frame caption="QuickBooks Web Connector with multiple connections for separate company files.">
  ![QuickBooks Web Connector with multiple
  connections](https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/help/guides/multiple-connections-one-computer/web-connector-multiple-connections.jpg)
</Frame>

## Best practices

*   **Use a dedicated virtual machine (optional):** Many users managing multiple company files on a single computer set up an always-on virtual machine dedicated to fulfilling Conductor requests. This dedicated instance allows QuickBooks Desktop to remain open without a company file loaded, ready to receive requests and open the correct company file. This setup is preferable to sharing a personal computer used for other tasks, where the Web Connector cannot fulfill requests if the wrong company file is open.

*   **Add QuickBooks Desktop to Windows startup:** Adding QuickBooks Desktop to the computer's startup programs ensures it is always open and ready to receive requests whenever you restart the computer. The Web Connector already automatically starts in the background when the computer boots up and can open QuickBooks Desktop if it receives a request from Conductor while QuickBooks Desktop is closed; however, doing so will delay the request because QuickBooks Desktop takes a while to launch.

## Performance considerations

*   **Increased request time:** Keeping QuickBooks Desktop open without a company file loaded adds 20–30 seconds to each request due to the time it takes to load a company file. However, when you send numerous Conductor requests for the same company file in quick succession, the Web Connector will resolve the sequence rapidly because Conductor keeps the company file open between these requests.

*   **Serial processing:** The Web Connector can only process requests for one company file at a time because it can only communicate with QuickBooks Desktop when one company file is loaded. Therefore, Conductor manages your requests in a queue, ensuring that the Web Connector processes them serially, opening and closing the appropriate company file for each request.


# Rebuild and verify Data in QuickBooks Desktop

Learn how to use the Rebuild and Verify Data utilities to fix and identify data issues in your QuickBooks Desktop company file.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

Over time, your QuickBooks Desktop company file may accumulate data issues that can lead to unexpected behavior or errors. QuickBooks provides built-in tools—**Rebuild Data** and **Verify Data**—to help fix and identify these issues. This guide will walk you through the steps to rebuild and verify your company file to ensure data integrity.

<Info>
  **When to use these utilities:** Use the **Rebuild Data** utility if you
  experience symptoms like missing transactions, program crashes, balance sheet
  discrepancies, or other unexpected behaviors. After rebuilding your data, use
  the **Verify Data** utility to confirm that all issues have been resolved.
</Info>

<Steps>
  <Step title="Run the Rebuild Data utility">
    Use the Rebuild Data utility to fix data issues in your company file:

    1.  Open QuickBooks Desktop.
    2.  Go to the "**File**" menu, hover over "**Utilities**", and select "**Rebuild Data**".

    <Image src="/images/help/guides/rebuild-verify-data/select-rebuild-data.jpg" alt="Accessing the Rebuild Data utility in QuickBooks Desktop" width={500} />

    3.  When prompted to back up your company file, click "**OK**". QuickBooks will ask you to create a backup before rebuilding to prevent data loss.
    4.  Choose a location to save the backup, then click "**OK**".
    5.  QuickBooks will begin rebuilding your data. This may take some time, depending on the size of your company file.

    <Image src="/images/help/guides/rebuild-verify-data/rebuilding-data.jpg" alt="Rebuilding your data" width={350} />

    6.  Once the rebuild is complete, click "**OK**" when you see the message "Rebuild has completed".
  </Step>

  <Step title="Run the Verify Data utility">
    After rebuilding your data, use the Verify Data utility to confirm that all issues have been resolved:

    1.  Go to the "**File**" menu, hover over "**Utilities**", and select "**Verify Data**".

    <Image src="/images/help/guides/rebuild-verify-data/select-verify-data.jpg" alt="Accessing the Verify Data utility in QuickBooks Desktop" width={500} />

    2.  QuickBooks will begin scanning your company file. This may take a few minutes.

    <Image src="/images/help/guides/rebuild-verify-data/verifying-data.jpg" alt="Verifying your data" width={350} />
  </Step>

  <Step title="Review the results of Verify Data">
    After the verification process completes, QuickBooks will display a message:

    *   **If you see "QuickBooks detected no problem with your data":** Your company file is now repaired and in good shape.
    *   **If you see "Your data has lost integrity":** Data issues still exist, repeat the rebuild process.
    *   **If you see a specific error message or code:** Note the details as they may be helpful if you need to contact support.

    <Info>
      **Note:** If errors continue after rebuilding your data multiple times, your company file may be damaged beyond repair through these utilities. Please contact Intuit support for further assistance.
    </Info>
  </Step>
</Steps>

By following these steps, you've ensured that your QuickBooks Desktop company file is free of data issues. If you encounter any problems during this process or need additional assistance, please contact our support team at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Help).


# Connecting to Rightworks

How to set up the QuickBooks Web Connector to connect to QuickBooks Desktop when using Rightworks.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

Rightworks (formerly called Right Networks) is a hosting provider for QuickBooks Desktop, offering remote access to a QuickBooks Desktop instance. We fully support connecting to Rightworks; however, there is **one important limitation you must remember**:

<Warning>
  **Important:** To sync data with your QuickBooks Desktop, you must be actively
  connected to your Rightworks remote desktop session with QuickBooks Desktop
  open. This requirement is due to Rightworks preventing programs from running
  in the background after you disconnect.
</Warning>

**One more requirement:** You must also configure your Rightworks account to allow the QuickBooks Web Connector (a built-in program we use to connect to QuickBooks Desktop) to start automatically whenever you connect to Rightworks. Please follow the steps below to configure this.

## Required: Enable the Web Connector to start automatically

Follow the steps below to configure the Web Connector to start automatically when you log into Rightworks.

<Info>
  If this guide does not work for you, please [contact
  us](mailto:support@conductor.is?subject=Rightworks%20Help) so we can continue
  to improve it. There are many different versions of Rightworks, and there
  might be steps missing that we would like to add.
</Info>

<Steps>
  <Step title="Contact Rightworks support">
    Setting up the Web Connector to start automatically requires assistance from Rightworks support. This cannot be done on your own.Visit the [Rightworks Support](https://helpdesk.rightnetworks.com) page to get started.

    Rightworks support is available Monday - Friday, 8:00 AM - 8:00 PM ET.
  </Step>

  <Step title="Start a live support chat">
    On the Rightworks support page, click the yellow "Chat" bubble in the bottom-right corner to start a live chat (there is no email or phone support available for this task).

    <Image src="/images/help/guides/rightworks/rightworks-support-chat-bubble.jpg" alt="Rightworks support chat bubble" width={270} />
  </Step>

  <Step title="Provide your account information">
    In the chat window, **provide the full name and email address** associated with your Rightworks account. This is typically the information for the person at your company who set up your Rightworks account.

    <Image src="/images/help/guides/rightworks/rightworks-support-chat-name-email.jpg" alt="Rightworks support chat name and email" width={450} />
  </Step>

  <Step title="Request to add the Web Connector to your startup programs">
    **Copy and send** the entire message below to the Rightworks support agent:

    ```
    Hello! Could you please configure our Rightworks account to ensure
    that BOTH of the following applications are added to our startup
    items and automatically launch in the background every time we sign
    into our Rightworks instance?

    1. QuickBooks Web Connector
    2. QuickBooks Desktop

    We need BOTH applications to launch automatically.

    Please apply this setting for ALL USERS on our Rightworks account.
    ```

    <Image src="/images/help/guides/rightworks/rightworks-support-chat-startup-request.jpg" alt="Rightworks support chat startup request" width={400} />
  </Step>

  <Step title="Confirm the changes with the support agent">
    1.  Wait for the support agent to confirm that the Web Connector has been added to your startup programs.
    2.  Sign out and sign back into your Rightworks desktop session for the changes to take effect.
  </Step>
</Steps>

That's it! From now on, the QuickBooks Web Connector will automatically start every time you connect to Rightworks, ensuring a stable connection to your QuickBooks Desktop company file.


# Upgrade the QuickBooks Web Connector

Learn how to upgrade the QuickBooks Web Connector to ensure compatibility with Conductor.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Info>
  This guide is provided by Conductor, the service that powers the QuickBooks
  Desktop integration for many business tools, including the one that sent you
  here.
</Info>

The QuickBooks Web Connector is a vital component that comes pre-installed with QuickBooks Desktop. Conductor uses this tool to securely sync your data. To use Conductor, you must have at least **version 2.3.0.20** of the QuickBooks Web Connector installed. In our experience, fewer than 1% of users have an older version. If you're using an outdated version, you might see an error message like this:

<Image src="/images/help/guides/upgrade-web-connector/upgrade-web-connector-error.jpg" alt="Error message indicating an outdated QuickBooks Web Connector version" width="500" />

Follow these steps to upgrade the QuickBooks Web Connector to the latest version:

<Steps>
  <Step title="Close QuickBooks Desktop">
    Ensure that QuickBooks Desktop is completely closed before proceeding.
  </Step>

  <Step title="Terminate the QuickBooks Web Connector">
    Close the QuickBooks Web Connector process to ensure it's not running in the background:

    1.  Open the Windows Task Manager by pressing `Ctrl + Shift + Esc` or by searching for "Task Manager" in the Windows search bar.
    2.  In the Task Manager, locate "QuickBooks Web Connector". Right-click it and select "**End Task**". If you don't see it, click "**More details**" at the bottom of the Task Manager window to view all running processes.
    3.  Close the Task Manager.
  </Step>

  <Step title="Delete the current QuickBooks Web Connector installation">
    To upgrade, you must first delete the current installation:

    1.  Open File Explorer and navigate to `C:\Program Files (x86)\Common Files\Intuit\QuickBooks`.
    2.  Delete the folder named `QBWebConnector` and, if present, the folder named `QBWebConnector3.0`.
  </Step>

  <Step title="Download the latest QuickBooks Web Connector">
    Visit Intuit's [official download page](https://developer.intuit.com/app/developer/qbdesktop/docs/get-started/get-started-with-quickbooks-web-connector#download-and-install-the-quickbooks-web-connector) to get the latest version of the QuickBooks Web Connector. Always download the most recent version, even if you're using an older version of QuickBooks Desktop.

    <Image src="/images/help/guides/upgrade-web-connector/download-web-connector.jpg" alt="QuickBooks Web Connector download page on Intuit's website" />
  </Step>

  <Step title="Install the QuickBooks Web Connector">
    Once the download is complete, open the downloaded file and follow the installation wizard's instructions.
  </Step>

  <Step title="Relaunch the QuickBooks Web Connector">
    1.  Open QuickBooks Desktop.
    2.  In the top menu bar, click "**File**" > "**App Management**" > "**Update Web Services**" to launch the QuickBooks Web Connector.
    3.  In the window that appears, click "**Hide**" in the bottom-right corner to keep the Web Connector running in the background.
  </Step>
</Steps>

You have now successfully upgraded to the latest version of the QuickBooks Web Connector and can proceed with setting up your connection to Conductor. If you encounter any issues during this process, please don't hesitate to contact our support team at [support@conductor.is](mailto:support@conductor.is?subject=QuickBooks%20Desktop%20Help).


# FAQ

The fundamentals of Conductor.

## Conductor basics

<AccordionGroup>
  <Accordion title="How does Conductor work?">
    Conductor is a web service that securely connects your app to one or more QuickBooks Desktop instances. It provides a RESTful API and fully-typed client libraries that you can use to read and write data to/from QuickBooks Desktop.

    Behind the scenes, Conductor uses the QuickBooks Web Connector, which is a Windows SOAP-based program that comes preinstalled with QuickBooks Desktop on your end-users' computers. This program always runs invisibly in the background, waiting for requests from Conductor. When you send a request to Conductor, it forwards the request to the Web Connector, which then forwards the request to QuickBooks Desktop. The response follows the same path in reverse. Between each of those steps, there are many layers of error handling, validation, and data transformation.

    Conductor abstracts away all of the complexity, idiosyncrasies, and fragility of working with QuickBooks Desktop so that interfacing with this criminally outdated technology is as easy and wonderful as using Stripe's API.
  </Accordion>

  <Accordion title="How do users set up the QuickBooks Desktop integration with Conductor?">
    Conductor leverages a program called QuickBooks Web Connector, which comes preinstalled with all versions of QuickBooks Desktop and runs invisibly in the background on the Windows computer to maintain the connection. To connect, the QuickBooks Desktop users will step through Conductor's [authentication flow](/usage/auth-flow), which has them download a config file that Conductor generates, open it in the Web Connector, authenticate, and connect to Conductor (and thereby to your application). Here is a [demo of the auth flow](https://connect.conductor.is/qbd/demo).
  </Accordion>

  <Accordion title="Pricing: How much does Conductor cost?">
    Conductor is priced at **\$49 month for each active QuickBooks Desktop company file connection**. A connection is considered active if *both* of the following conditions are met within the same monthly billing period:

    1.  Conductor receives a heartbeat from the QuickBooks Desktop instance.
    2.  Your application makes a Conductor API call to that connection.

    NOTE: Connections used for testing and development are free. Connections using data from an active production environment are not.

    Volume discounts are available for enterprises requiring a large number of connections.
  </Accordion>

  <Accordion title="Should I use Conductor or build the integration from scratch?">
    Integrating with QuickBooks Desktop from scratch is a painful nightmare. It's a decades-old API that hasn't been modernized and is riddled with edge cases, idiosyncrasies, and bugs that are incredibly difficult to work with. Conductor solves all of these problems and takes only a fraction of the time to implement with none of the maintenance headaches. We have obsessed over the edge cases and performance. Beyond the significant time savings, **Conductor preserves your team's mental well-being**.
  </Accordion>
</AccordionGroup>

## Data handling and security

<AccordionGroup>
  <Accordion title="Does Conductor use a cache layer between me and my end-users' QuickBooks Desktop?">
    No, every Conductor API call is a real-time direct request to/from QuickBooks Desktop. If you make a request when the end-user's computer is off or QuickBooks Desktop is inaccessible, Conductor will return an error message with instructions for how the end-user can resolve the issue.

    By design, Conductor has no cache layer because it causes all sorts of problems when data is out-of-sync. E.g., you modify data on one end that has already been removed on the other.

    Ideally, the computer running QuickBooks Desktop is always on and accessible. If that is not possible for some end-users, this design has still worked well because if such an end-user triggers a sync while using your app, they likely did so from the same computer as where QuickBooks Desktop is already running.
  </Accordion>

  <Accordion title="Does Conductor store any of my end-users' QuickBooks Desktop data?">
    No, Conductor does not retain any of your end-users' QuickBooks Desktop data on a permanent basis. For operational purposes, API request logs, which includes QuickBooks Desktop data, are temporarily, securely stored in a SOC 2 and GDPR-compliant log manager for 14 days before permanent deletion. Access to these logs is strictly limited to authorized Conductor engineers, who use them solely for debugging, offering customer support, and product improvement purposes. This approach ensures both the confidentiality of your data and compliance with the highest standards of data protection.
  </Accordion>

  <Accordion title="Does Conductor support batch processing?">
    No, Conductor's APIs currently only support working with a single object at a time because QuickBooks Desktop itself only resolves requests serially. If you want to create 50 invoices, for example, you will need to call the create-invoice API 50 times. However, you can send multiple requests in parallel; for example, you can use `await Promise.all([ ... ])` in JavaScript with multiple requests, but you cannot send multiple requests in a single HTTPS request.
  </Accordion>
</AccordionGroup>

## QuickBooks Desktop and Web Connector

<AccordionGroup>
  <Accordion title="What is the QuickBooks Web Connector?">
    The QuickBooks Web Connector is a Windows program that comes preinstalled with QuickBooks Desktop that Conductor uses to securely communicate with QuickBooks Desktop. This program runs invisibly in the background on the end-user's computer, waiting for requests from Conductor. The only time your end-user should see the Web Connector is when they first set up their QuickBooks Desktop connection with Conductor; other than that, it should be invisible to them.
  </Accordion>

  <Accordion title="What is a QuickBooks Desktop &#x22;company file&#x22;?">
    In the world of QuickBooks Desktop, a "company file" is the main local file for all the financial data for a specific company. Typically, a QuickBooks Desktop user will have only one company file: the one they use to manage their business. However, some users manage multiple company files on one computer and actively switch between them. For example, an accounting firm might manage the books for multiple clients, each with their own QuickBooks Desktop company file.

    Each Conductor connection is tied to a specific company file. If you need to connect to multiple company files, you will need to create multiple EndUsers in Conductor, each with their own connection. See this [guide](/help/guides/multiple-connections-one-computer) for more information.
  </Accordion>

  <Accordion title="What versions of QuickBooks Desktop does Conductor support?">
    Conductor supports every version, variant, and edition of QuickBooks Desktop since 2018, including:

    *   **QuickBooks Enterprise Solutions - any version or year**
        *   Any edition: Accountant, Contractor, Manufacturing and Wholesale, Nonprofit, Professional Services, Retail.
    *   **QuickBooks Premier (Plus) - 2018 or later**
        *   Any edition: Accountant, Contractor, Manufacturing and Wholesale, Nonprofit, Professional Services, Retail.
    *   **QuickBooks Desktop Pro (Plus) - 2018 or later**
    *   **QuickBooks Accountant Desktop (Plus) - 2018 or later**
  </Accordion>

  <Accordion title="Is QuickBooks Desktop being discontinued?">
    No, QuickBooks Desktop is not being discontinued.

    1.  **Ongoing Support:** Intuit continues to support all existing versions of QuickBooks Desktop for current customers.
    2.  **Continued Sales:** Intuit is still actively selling "QuickBooks Enterprise", the main version of QuickBooks Desktop tailored for medium to large businesses, to new customers.
    3.  **Product Changes:** Intuit will soon cease sales of "QuickBooks Desktop Pro/Premier Plus" – a less popular variant primarily used by small family businesses – to *new* customers (existing customers will still be supported).

    While Intuit has encouraged users to migrate to QuickBooks Online, Desktop users consistently tell us that it doesn't fully meet their business needs. Consequently, the base of existing QuickBooks Desktop users, including both "Enterprise" and "Pro/Premier" versions, remains robust. Conductor continues to support these users and their ongoing reliance on QuickBooks Desktop.
  </Accordion>
</AccordionGroup>

## Compatibility and connectivity

<AccordionGroup>
  <Accordion title="Does Conductor support multiple Web Connector connections across different computers to the same QuickBooks Desktop company file?">
    Yes, you can set up Web Connector connections on multiple computers for the same QuickBooks Desktop company file. This is applicable if your company shares the same company file across multiple computers on your office network. This setup can serve as a backup in case one computer is offline. However, we haven't seen any Conductor users needing this approach so far, but we have confirmed that it works.
  </Accordion>

  <Accordion title="Can Conductor access QuickBooks Desktop instances when the user's computer is off?">
    No, there is no way to access QuickBooks Desktop instances when the user's computer is off because QuickBooks Desktop data is not stored online. Instead, QuickBooks Desktop is a local application that runs on a user's computer. As a result, this means an active Conductor connection is always direct and real-time. Conductor intentionally avoids using a cache layer to prevent potential data conflicts when data is out-of-sync.

    While this may seem limiting to many developers, we find that typical QuickBooks Desktop users do not mind:

    1.  **User Availability:** When a user is interacting with your application that syncs data with QuickBooks Desktop, they are typically at their computer anyway, which means that QuickBooks Desktop is accessible.

    2.  **User Control:** Many QuickBooks Desktop users are protective of their data and prefer to manually initiate data syncs rather than rely on automatic background processes. This approach gives them greater control over their data and ensures that no syncs occur without their explicit consent.
  </Accordion>

  <Accordion title="Does QuickBooks Desktop need to be open for Conductor to connect?">
    No, QuickBooks Desktop does not need to be actively open. As long as the computer itself is powered on, Conductor can send a request to QuickBooks Desktop, which will then automatically launch in the background, process the request, and close itself once completed.

    **Important Note:** Launching QuickBooks Desktop in the background adds approximately 30 seconds to the request processing time due to the software's startup process. For optimal faster response times, we recommend keeping QuickBooks Desktop open while using Conductor.
  </Accordion>

  <Accordion title="Does Conductor support connections to multiple QuickBooks Desktop company files on the same computer?">
    Yes, please see this [guide](/help/guides/multiple-connections-one-computer) for more information.
  </Accordion>

  <Accordion title="Does Conductor work with Rightworks (previously called Right Networks)?">
    Yes, Conductor is fully compatible with Rightworks. Users can establish the connection just as they would with a typical Windows instance running QuickBooks Desktop.

    However, there is an important consideration: Rightworks users must sign in to their remote desktop session each time they wish to sync with QuickBooks Desktop. This requirement exists because Rightworks terminates inactive instances once the connection is closed, preventing background processes from running when the user is signed out. Despite this, most users find this process manageable because signing in to Rightworks is a routine part of their workflow. It is worth noting that, based on our experience, remote QuickBooks Desktop hosts like Rightworks account for fewer than 2% of all QuickBooks Desktop companies.

    Please see [this guide](/help/guides/rightworks) for setting up a Conductor connection with a Rightworks QuickBooks Desktop instance.
  </Accordion>
</AccordionGroup>


# Get started with Conductor

The best QuickBooks Desktop integration on the planet.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

<Image src="/images/get-started/autocomplete.jpg" alt="QuickBooks Desktop autocomplete" border={false} />

## What is Conductor?

Conductor is a real-time, fully-typed API for QuickBooks Desktop (sometimes called QuickBooks Enterprise), available via Python, Node.js, TypeScript, and REST. In just a few lines, get real-time access to fetch, create, or update [*any* QuickBooks Desktop object type](/qbd/api#supported-object-types) and receive a fully-typed response. Check out the documentation below to get started.

Conductor, the company, is building a data integration platform for vertical SaaS companies, starting with QuickBooks Desktop. Our team has spent over a decade building companies, scaling vast software systems, and obsessing over quality.

## Key features

*   **Any data type:** Query, create, or update any QuickBooks Desktop data type.
*   **Real-time**: Get real-time updates on your QuickBooks Desktop data. No queues, no polling.
*   **Modern API:** JSON-based REST API, replacing the old XML-based SOAP model.
*   **Typed client libraries:** Fully typed libraries in Node.js and Python with autocomplete, inline docs, and type validation for endpoints, parameters, and responses.
*   **Request handling:** Invisibly manages queues, timeouts, retries, and pagination.
*   **Multi-company support:** Connects to multiple QuickBooks Desktop company files.
*   **Validation:** Sanitizes and validates all inputs and outputs.
*   **Unified error handling:** Streamlines error handling across the QuickBooks stack.
*   **Authentication flow UI:** Simple UI for securely connecting QuickBooks Desktop accounts.
*   **Dashboard**: UI to monitor and manage your QuickBooks Desktop connections and data.
*   **Error resolution:** Detailed guides and instructions for resolving errors and handling edge cases.

## Explore the documentation

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/overview/quickstart">
    Create your first EndUser and connect to QuickBooks Desktop in 5 minutes.
  </Card>

  <Card title="Terminology" icon="book" href="/overview/terminology">
    The key concepts you must know to use Conductor.
  </Card>

  <Card title="Node.js / TypeScript API" icon="code" href="/qbd/api">
    Execute any QuickBooks Desktop API through fully-typed async TypeScript.
  </Card>

  <Card title="REST API" icon="globe" href="/qbd/rest">
    Access Conductor's REST API to connect to QuickBooks Desktop from any
    language.
  </Card>

  <Card title="Error handling" icon="circle-exclamation" href="/usage/error-handling">
    Catch and respond to connection errors, invalid requests, data problems, and
    more.
  </Card>
</CardGroup>


# Quickstart

Create your first EndUser and connect to QuickBooks Desktop in 5 minutes.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

The following server-side walkthrough will guide you through connecting a QuickBooks Desktop instance to your Conductor account. In just a few minutes, you'll be able to create, read, and update data in your QuickBooks Desktop instance.

#### Requirements

1.  A Conductor API key pair: one secret key, one publishable key. To obtain these, please [join our private beta](https://73a5v9t55ed.typeform.com/to/VRX7rfrN).
2.  A QuickBooks Desktop instance for testing. If you do not have one, you can [create a free test instance](/qbd/test-instance).

## Create your first EndUser and IntegrationConnection

<Steps titleSize="h3">
  <Step title="Install Conductor">
    <Tabs>
      <Tab title="Node.js">
        <CodeGroup>
          ```sh npm
          npm install conductor-node
          ```

          ```sh yarn
          yarn add conductor-node
          ```

          ```sh pnpm
          pnpm add conductor-node
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Python">
        ```sh
        pip install --pre conductor-py
        ```
      </Tab>

      <Tab title="cURL">
        Continue to the next step to access our REST API directly via `curl`.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Create an EndUser and save its ID to your database">
    An EndUser is a user of *your* application for whom we are creating an IntegrationConnection. Each EndUser can represent an individual or an entire company/organization of multiple users within your application. You can attach one or more IntegrationConnections to this EndUser.

    <Warning>
      After you create your EndUser, you must save the EndUser's `id` to your database for sending requests to their IntegrationConnections in the future.

      For example, if your database has a `users` table, you can store the `id` in a column like `conductor_end_user_id`.
    </Warning>

    Either create the EndUser via the web dashboard or use the following code on your server to create an EndUser programmatically:

    <CodeGroup>
      ```ts Node.js
      import Conductor from "conductor-node";
      const conductor = new Conductor("{{YOUR_SECRET_KEY}}");

      // Replace these placeholders with your own values.
      const endUser = await conductor.endUsers.create({
        // Your end-user's company name shown elsewhere in Conductor.
        companyName: "{{END_USER_COMPANY_NAME}}",
        // Your end-user's unique ID from _your_ database. Must be distinct from
        // your other EndUsers. Can be anything you want if you are just testing.
        sourceId: "{{UNIQUE_ID_FROM_YOUR_DB}}",
        // Your end-user's email address for identification purposes.
        email: "{{END_USER_EMAIL}}",
      });
      console.log("Save this EndUser ID to auth future requests:", endUser.id);
      ```

      ```py Python
      from conductor import Conductor
      conductor = Conductor(api_key="{{YOUR_SECRET_KEY}}")

      # Replace these placeholders with your own values.
      end_user = conductor.end_users.create(
        # Your end-user's company name shown elsewhere in Conductor.
        company_name="{{END_USER_COMPANY_NAME}}",
        # Your end-user's unique ID from _your_ database. Must be distinct from
        # your other EndUsers. Can be anything you want if you are just testing.
        source_id="{{UNIQUE_ID_FROM_YOUR_DB}}",
        # Your end-user's email address for identification purposes.
        email="{{END_USER_EMAIL}}"
      )
      print("Save this EndUser ID to auth future requests:", end_user.id)
      ```

      ```sh cURL
      curl -X POST https://api.conductor.is/v1/end-users \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer {{YOUR_SECRET_KEY}}" \
        -d '{
              "companyName": "{{END_USER_COMPANY_NAME}}",
              "sourceId": "{{UNIQUE_ID_FROM_YOUR_DB}}",
              "email": "{{END_USER_EMAIL}}"
            }'
      ```
    </CodeGroup>

    This API call will return the newly created EndUser object, for example:

    ```json Example EndUser response {2-3}
    {
      // ❗❗ Save this `id` to your database!
      "id": "end_usr_1234567abcdefg",
      "objectType": "end_user",
      "createdAt": "2022-11-16 23:51:08.996+00",
      "companyName": "Big Construction Co.",
      "sourceId": "12345678-abcd-abcd-example-1234567890ab",
      "email": "bob@bigconstruction.com",
      "integrationConnections": []
    }
    ```
  </Step>

  <Step title="Create an AuthSession">
    Before you can read/write data to/from an EndUser's IntegrationConnection, your EndUser must complete the connection authentication flow. The following operation creates a session and returns a URL to redirect your end-user.

    <CodeGroup>
      ```ts Node.js
      // ... continued from above

      const authSession = await conductor.authSessions.create({
        publishableKey: "{{YOUR_PUBLISHABLE_KEY}}",
        // Use `endUser.id` from above.
        endUserId: endUser.id,
      });
      console.log("Complete the QuickBooks Desktop auth flow:", authSession.authFlowUrl);
      ```

      ```py Python
      # ... continued from above

      auth_session = conductor.auth_sessions.create(
        publishable_key="{{YOUR_PUBLISHABLE_KEY}}",
        end_user_id=end_user.id
      )
      print("Complete the QuickBooks Desktop auth flow:", auth_session.auth_flow_url)
      ```

      ```sh cURL
      curl -X POST https://api.conductor.is/v1/auth-sessions \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer {{YOUR_SECRET_KEY}}" \
        -d '{
              "publishableKey": "{{YOUR_PUBLISHABLE_KEY}}",
              "endUserId": "{{END_USER_ID_FROM_ABOVE}}"
            }'
      ```
    </CodeGroup>

    ```json Example AuthSession response {6-7}
    {
      "id": "auth_sess_1234567abcdefg",
      "endUserId": "end_usr_1234567abcdefg",
      "clientSecret": "auth_sess_client_secret_1234567abcdefg",
      "expiresAt": "2022-11-16 23:51:08.996+00",
      // 👇 Visit this URL from the response to launch the authentication flow.
      "authFlowUrl": "https://connect.conductor.is/qbd/auth_sess_client_secret_1234567abcdefg?key={{YOUR_PUBLISHABLE_KEY}}"
    }
    ```
  </Step>

  <Step title="Complete the authentication flow">
    Visit the returned `authSession.authFlowUrl` in your browser on the same computer or instance as your QuickBooks Desktop installation. This authentication flow will guide you through connecting your QuickBooks Desktop instance to Conductor.

    <Image src="/images/quickstart/auth-flow.jpg" alt="Conductor authentication flow for QuickBooks Desktop" width="600" border={false} />
  </Step>

  <Step title="You're done!">
    After completing the authentication flow, you can access your QuickBooks Desktop instance through the Conductor library. The following example fetches a list of invoices from your QuickBooks Desktop instance.

    <CodeGroup>
      ```ts Node.js
      // ... continued from above

      const qbdInvoices = await conductor.qbd.invoice.query(endUser.id, {
        MaxReturned: 10,
      });
      console.log("QBD invoices:", qbdInvoices);
      ```

      ```py Python
      # ... continued from above

      qbd_invoices = conductor.qbd.invoices.list(
        conductor_end_user_id=end_user.id,
        limit=10,
      )
      print("QBD invoices:", qbd_invoices)
      ```

      ```sh cURL
      curl --request GET \
        --url 'https://api.conductor.is/v1/quickbooks-desktop/invoices?limit=10' \
        --header 'Authorization: Bearer {{YOUR_SECRET_KEY}}' \
        --header 'Conductor-End-User-Id: {{END_USER_ID_FROM_ABOVE}}'
      ```
    </CodeGroup>

    ```json Example QBD response
    {
      "objectType": "list",
      "url": "/v1/quickbooks-desktop/invoices",
      "data": [
        {
          "id": "123ABC-1234567890",
          "objectType": "qbd_invoice",
          "createdAt": "2021-10-01T17:34:56.000Z",
          "updatedAt": "2021-10-01T20:45:30.000Z",
          "revisionNumber": "1721172183",
          "customer": {
            "id": "80000001-1234567890",
            "fullName": "Acme Corporation"
          },
          "invoiceLines": [
            {
              "id": "456DEF-1234567890",
              "objectType": "qbd_invoice_line",
              "item": {
                "id": "80000010-1234567890",
                "fullName": "Widget A"
              },
              "description": "High-quality widget with custom engraving",
              "quantity": 5,
              "amount": "1000.00",
              // ... more fields omitted
            }
          ],
          // ... more fields omitted
        },
        // ... more invoices omitted
      ],
      "nextCursor": "12345678-abcd-abcd-example-1234567890ab",
      "remainingCount": 10,
      "hasMore": true
    }
    ```
  </Step>
</Steps>


# Security and data retention

Conductor's security and data retention policies.

### Temporary data storage

*   **Conductor does not permanently retain your end-user data (such as QuickBooks Desktop data).**
*   **For operational purposes, API request logs, which include end-user data, are temporarily stored securely in a SOC 2 compliant log manager for 14 days before permanent deletion.**
*   The logs are encrypted at rest using AES-256 and in transit using HTTPS/TLS.
*   The logs are stored in certified data centers located in Germany and Finland within the EU.
*   Access to these logs is strictly limited to authorized Conductor engineers, who use them solely for debugging, customer support, and product improvement.

### Permanent data storage

*   The only data Conductor stores permanently pertains to managing and authenticating your Conductor account, connections, end-users, API keys, and projects. This does not include any end-user data.
*   This data is stored in a centralized SOC 2 compliant database hosted by AWS in the US West (Oregon) region. There is no physical or logical separation of customer data within the database.
*   The database is encrypted at rest and requires SSL/TLS encryption for all connections.
*   Access to the database is strictly limited to authorized Conductor engineers.

### API request security

*   All API requests to Conductor are authenticated using an API key and restricted to HTTPS.
*   Data in transit is encrypted, and requests are processed through our SOC 2 compliant backend hosted by AWS in the US West (Oregon) region.

### Security and compliance

*   **SOC 2:** Conductor is actively working toward achieving its SOC 2 certification, implementing and monitoring the necessary measures to meet the Security, Availability, and Confidentiality Trust Service Criteria. We have engaged an independent AICPA-accredited auditor to formally assess and report on Conductor's controls.
*   Conductor's [Trust Center](https://trust.conductor.is) monitors our progress toward SOC 2 compliance.
*   Conductor's [Privacy Policy](https://conductor.is/privacy) outlines our data handling practices.

{/* We remove the section below because it's mostly redundant with the above. */}

{/* ### Sensitive data handling */}

{/* Based on Conductor's recommended API configuration, the QuickBooks Desktop data accessible via Conductor's API typically would not include highly sensitive personal data, such as Social Security Numbers, customer credit card details, or bank account numbers. However, depending on the specific data the customer chooses to request, some sensitive data transferred may still include: */}

{/* - Payroll and benefits information for employees and contractors, without direct identifiers such as Social Security Numbers. */}

{/* - Confidential revenue, expense, and profitability data for end-users' businesses. */}

{/* - Proprietary vendor and supplier details, contracts, and transaction terms. */}

{/* Conductor applies the following safeguards to protect this sensitive data: */}

{/* - **Strict purpose limitation:** Sensitive data is only used for the specific purposes of enabling end-user integrations (e.g., QuickBooks Desktop) via Conductor's API, and never for any other purposes. */}

{/* - **Encryption:** All sensitive data is encrypted in transit (HTTPS/TLS) and at rest (AES-256) using industry-standard encryption protocols. */}

{/* - **Onward transfer restrictions:** Conductor does not transfer any sensitive data to third parties or subprocessors without prior consent from the customer, and any approved transfers are governed by contracts ensuring the same level of data protection. */}

{/* - **Retention limitations:** Conductor does not retain any end-user data on a permanent basis. For operational purposes, API request logs that include end-user data are temporarily stored securely in a log manager for 14 days before permanent deletion. */}

{/* - **Access restrictions:** Access to sensitive customer and end-user data is restricted to only the necessary Conductor staff who have undergone specialized privacy and security training. */}

## Data subprocessors

Conductor subprocessors are third-party entities authorized to process data to support Conductor services in accordance with our service agreements. Conductor requires each subprocessor to meet specific contractual obligations to ensure they enforce security controls and comply with data protection regulations.

| **Subprocessor** | **Function**                                                                                                                                                                                              | **Location**                   |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| **Better Stack** | Logging manager for ingesting, parsing, and querying API request logs for debugging, offering customer support, and product improvement purposes. Retains end-user data for 14 days before deletion.      | Germany, Finland               |
| **Neon**         | Postgres database hosting (using AWS underneath) for managing customer data, such as for authentication, connections, and account management. Does not store any end-user data.                           | Oregon - US West (AWS)         |
| **Render**       | Compute instance hosting (using AWS underneath) for running Conductor's core API services. Processes and transmits end-user data as needed to authenticate, process, and fulfill customers' API requests. | Oregon - US West (AWS)         |
| **Sentry**       | Application monitoring and error tracking. Captures diagnostic data and metadata around application errors and performance issues. May include limited customer data if present in error contexts.        | Iowa, U.S.; Frankfurt, Germany |
| **Vercel**       | Web app hosting for Conductor's web user interfaces. Does not directly process or store customer and end-user data.                                                                                       | N. California - US West (AWS)  |


# Terminology

The key concepts you should know to use Conductor.

Familiarize yourself with the terms below that we use throughout the documentation and APIs.

| Term                                                          | Definition                                                                                                                                                                                                   |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [EndUser](/apis/end-users/object)                             | A user of *your* application for whom you will connect integrations through Conductor. Each EndUser can represent an individual or an entire company/organization of multiple users within your application. |
| Integration                                                   | A third-party service you want to connect to your application. For example, QuickBooks Desktop.                                                                                                              |
| [IntegrationConnection](/apis/integration-connections/object) | A connection for a specific EndUser to a specific integration. For example, a connection for the company "ABC Company" to their QuickBooks Desktop instance.                                                 |
| [Authentication flow](/usage/auth-flow)                       | The UI walkthrough that guides your users through securely connecting their QuickBooks Desktop to your Conductor account.                                                                                    |


# Create an account

POST /quickbooks-desktop/accounts
Creates a new financial account.



# List all accounts

GET /quickbooks-desktop/accounts
Returns a list of accounts.



# The Account object

An account represents a financial account, allowing customization like sub-accounting, account numbering, and initial balance setting.



# Retrieve an account

GET /quickbooks-desktop/accounts/{id}
Retrieves an account by ID.



# Update an account

POST /quickbooks-desktop/accounts/{id}
Updates a financial account.



# Create a bill payment check

POST /quickbooks-desktop/bill-payment-checks
Creates a new bill payment check.



# List all bill payment checks

GET /quickbooks-desktop/bill-payment-checks
Returns a list of bill payment checks.



# The Bill Payment Check object

A bill payment check is a transaction that represents a payment by check for a bill.



# Retrieve a bill payment check

GET /quickbooks-desktop/bill-payment-checks/{id}
Retrieves a bill payment check by ID.



# Update a bill payment check

POST /quickbooks-desktop/bill-payment-checks/{id}
Updates an existing bill payment check.



# Create a bill payment credit card

POST /quickbooks-desktop/bill-payment-credit-cards
Creates a new bill payment credit card.



# List all bill payment credit cards

GET /quickbooks-desktop/bill-payment-credit-cards
Returns a list of bill payment credit cards.



# The Bill Payment Credit Card object

A bill payment credit card is a transaction that represents a payment by credit card for a bill.



# Retrieve a bill payment credit card

GET /quickbooks-desktop/bill-payment-credit-cards/{id}
Retrieves a bill payment credit card by ID.



# Create a bill

POST /quickbooks-desktop/bills
Creates a new bill.



# List all bills

GET /quickbooks-desktop/bills
Returns a list of bills.



# The Bill object

A bill is a transaction that represents a request-for-payment from a vendor for goods or services that it has provided.



# Retrieve a bill

GET /quickbooks-desktop/bills/{id}
Retrieves a bill by ID.



# Update a bill

POST /quickbooks-desktop/bills/{id}
Updates an existing bill.



# Create a check

POST /quickbooks-desktop/checks
Creates a new check.



# List all checks

GET /quickbooks-desktop/checks
Returns a list of checks.



# The Check object

A check is a transaction that represents a paper check.



# Retrieve a check

GET /quickbooks-desktop/checks/{id}
Retrieves a check by ID.



# Update a check

POST /quickbooks-desktop/checks/{id}
Updates an existing check.



# Create a class

POST /quickbooks-desktop/classes
Creates a new class.



# List all classes

GET /quickbooks-desktop/classes
Returns a list of classes.



# The Class object

A class is a category used to group QuickBooks objects into meaningful categories. For example, classes can be used to classify transactions by department, location, or type of work.



# Retrieve a class

GET /quickbooks-desktop/classes/{id}
Retrieves a class by ID.



# Update a class

POST /quickbooks-desktop/classes/{id}
Updates an existing class.



# Create a credit card charge

POST /quickbooks-desktop/credit-card-charges
Creates a new credit card charge for the specified account.



# List all credit card charges

GET /quickbooks-desktop/credit-card-charges
Returns a list of credit card charges.



# The Credit Card Charge object

A credit card charge is a general charge incurred when a QuickBooks user makes a purchase using a credit card. Credit card charges for purchases can be tracked as expenses (in expense accounts) or as items.



# Retrieve a credit card charge

GET /quickbooks-desktop/credit-card-charges/{id}
Retrieves a credit card charge by ID.



# Update a credit card charge

POST /quickbooks-desktop/credit-card-charges/{id}
Updates an existing credit card charge.



# Create a credit card credit

POST /quickbooks-desktop/credit-card-credits
Creates a new credit card credit for the specified account.



# List all credit card credits

GET /quickbooks-desktop/credit-card-credits
Returns a list of credit card credits.



# The Credit Card Credit object

A credit card credit is a credit card refund issued to a customer.



# Retrieve a credit card credit

GET /quickbooks-desktop/credit-card-credits/{id}
Retrieves a credit card credit by ID.



# Update a credit card credit

POST /quickbooks-desktop/credit-card-credits/{id}
Updates an existing credit card credit.



# Create a customer

POST /quickbooks-desktop/customers
Creates a new customer.



# List all customers

GET /quickbooks-desktop/customers
Returns a list of customers.



# The Customer object

A customer can refer to either one of the QuickBooks user's customers or an individual job that is being performed for a customer.



# Retrieve a customer

GET /quickbooks-desktop/customers/{id}
Retrieves a customer by ID.



# Update a customer

POST /quickbooks-desktop/customers/{id}
Updates an existing customer.



# Create a date-driven term

POST /quickbooks-desktop/date-driven-terms
Creates a new date-driven term.



# List all date-driven terms

GET /quickbooks-desktop/date-driven-terms
Returns a list of date-driven terms.



# The Date-Driven Term object

A date-driven term shows the day of the month by which payment is due and can include a discount for early payment.



# Retrieve a date-driven term

GET /quickbooks-desktop/date-driven-terms/{id}
Retrieves a date-driven term by ID.



# Welcome to Conductor's new QuickBooks Desktop API (alpha)

Conductor's new QuickBooks Desktop API is a massive leap forward and sets the foundation for future integrations.

<Warning>
  This new API is **neither stable nor ready for use**. We are iterating
  rapidly. Expect changes to the API and documentation every single day.
</Warning>

Welcome to Conductor's new QuickBooks Desktop API. It brings the following improvements over the current generation:

1.  Proper HTTP methods: `GET` for reading, `POST` for creating or updating. No more `POST` for everything.
2.  Cleaner URL endpoints: `/quickbooks_desktop/invoices` instead of `/end-users/{id}/request/quickbooks_desktop` with `InvoiceQueryRq` in the body.
3.  An OpenAPI spec for the entire API.
4.  Full online documentation of all fields and their types.
5.  API playground in the documentation to test requests and see responses.
6.  Always returns all response fields. Uses `null` for undefined fields instead of omitting them.
7.  Consistently returns arrays for any nested fields that previously returned a single object for one item and an array for multiple items.
    *   Returns an empty array instead of `null` for empty lists.
8.  Clean response bodies: No more unwrapping outer objects; e.g., no more `InvoiceQueryRs.InvoiceRet`.
9.  Proper object wrapper for all list responses: Previously, we returned an array of objects. Now, we return an object with a `data` field that contains the array of objects.
10. Pagination for all list endpoints.
11. Better parameter names instead of QuickBooks Desktop's unconventional naming. For example:
    *   `MaxReturned` → `limit`
    *   `TimeModified` → `updatedAt`
    *   `DataExtRet` → `customFields`
12. Uses `camelCase` for input and output field names instead of `PascalCase`.
13. Simplified request structure. For example:
    *   `refNumberStartsWith: "REF"` instead of `RefNumberFilter: { MatchCriterion: "StartsWith", RefNumber: "REF" }`
    *   `accountId: "123"` instead of `AccountRef: { ListID: "123" }`
14. Correct types for obscure fields: Previously, we inferred types from XML. Now, we define the type of every field to ensure it is always correct.
15. Better field descriptions: we are using our own descriptions instead of QuickBooks' descriptions.
16. Field-specific coercions: better handling of dates and money amounts.
17. Enforced upper bound on `limit` of 1000 items to prevent overloading QuickBooks Desktop instances.
18. Better defaults. For example:
    *   `includeLineItems` is `true` by default because who wants an empty invoice?
    *   `ownerId` is 0 by default to always include your end-users' custom fields.

## Feedback

We value your input! If you have suggestions or requests for improvements, changes, field names, documentation, or anything else, [please let us know](mailto:support@conductor.is?subject=Conductor%20QuickBooks%20Desktop%20API%20Feedback).


# Create an inventory assembly item

POST /quickbooks-desktop/inventory-assembly-items
Creates a new inventory assembly item.



# List all inventory assembly items

GET /quickbooks-desktop/inventory-assembly-items
Returns a list of inventory assembly items.



# The Inventory Assembly Item object

An inventory assembly item is an item that is assembled or manufactured from inventory items. The items and/or assemblies that make up the assembly are called components.



# Retrieve an inventory assembly item

GET /quickbooks-desktop/inventory-assembly-items/{id}
Retrieves an inventory assembly item by ID.



# Update an inventory assembly item

POST /quickbooks-desktop/inventory-assembly-items/{id}
Updates an existing inventory assembly item.



# Create an inventory item

POST /quickbooks-desktop/inventory-items
Creates a new inventory item.



# List all inventory items

GET /quickbooks-desktop/inventory-items
Returns a list of inventory items.



# The Inventory Item object

An inventory item is any merchandise or part that a business purchases, tracks as inventory, and then resells.



# Retrieve an inventory item

GET /quickbooks-desktop/inventory-items/{id}
Retrieves an inventory item by ID.



# Update an inventory item

POST /quickbooks-desktop/inventory-items/{id}
Updates an existing inventory item.



# Create an inventory site

POST /quickbooks-desktop/inventory-sites
Creates a new inventory site.



# List all inventory sites

GET /quickbooks-desktop/inventory-sites
Returns a list of inventory sites.



# The Inventory Site object

An inventory site is a location where inventory is stored. For example, a company might have a warehouse, a stockroom, and a showroom, each of which is an inventory site. NOTE: Inventory sites require QuickBooks Enterprise with an Advanced Inventory subscription.



# Retrieve an inventory site

GET /quickbooks-desktop/inventory-sites/{id}
Retrieves an inventory site by ID.



# Update an inventory site

POST /quickbooks-desktop/inventory-sites/{id}
Updates an existing inventory site.



# Create an invoice

POST /quickbooks-desktop/invoices
Creates a new invoice.



# List all invoices

GET /quickbooks-desktop/invoices
Returns a list of invoices.



# The Invoice object

An invoice records the amount owed by a customer who purchased goods or services but did not pay in full at the time of the sale.



# Retrieve an invoice

GET /quickbooks-desktop/invoices/{id}
Retrieves an invoice by ID.



# Update an invoice

POST /quickbooks-desktop/invoices/{id}
Updates an existing invoice.



# Create a non-inventory item

POST /quickbooks-desktop/non-inventory-items
Creates a new non-inventory item.



# List all non-inventory items

GET /quickbooks-desktop/non-inventory-items
Returns a list of non-inventory items.



# The Non-Inventory Item object

A non-inventory item is any material or part that a business buys but does not keep on hand as inventory.
There are two types of non-inventory items: 1. Materials or parts that are part of the business’s overhead (for example, office supplies) 2. Materials or parts that the business buys to finish a specific job and then charges back to the customer.



# Retrieve a non-inventory item

GET /quickbooks-desktop/non-inventory-items/{id}
Retrieves a non-inventory item by ID.



# Update a non-inventory item

POST /quickbooks-desktop/non-inventory-items/{id}
Updates an existing non-inventory item.



# Create a sales order

POST /quickbooks-desktop/sales-orders
Creates a new sales order.



# List all sales orders

GET /quickbooks-desktop/sales-orders
Returns a list of sales orders.



# The Sales Order object

A sales order tracks inventory that is on back order for a customer. In QuickBooks, sales orders and invoices use similar fields, and a sales order can be “converted” into an invoice (by linking the invoice to the sales order) once the inventory is in stock.



# Retrieve a sales order

GET /quickbooks-desktop/sales-orders/{id}
Retrieves a sales order by ID.



# Update a sales order

POST /quickbooks-desktop/sales-orders/{id}
Updates an existing sales order.



# Create a sales-tax code

POST /quickbooks-desktop/sales-tax-codes
Creates a new sales-tax code.



# List all sales-tax codes

GET /quickbooks-desktop/sales-tax-codes
Returns a list of sales-tax codes.



# The Sales-Tax Code object

A sales tax code helps categorize items on a sales form as taxable or non-taxable, detailing reasons and associating tax codes with customers, items, or transactions.



# Retrieve a sales-tax code

GET /quickbooks-desktop/sales-tax-codes/{id}
Retrieves a sales-tax code by ID.



# Update a sales-tax code

POST /quickbooks-desktop/sales-tax-codes/{id}
Updates an existing sales-tax code.



# Create a sales-tax item

POST /quickbooks-desktop/sales-tax-items
Creates a new sales-tax item.



# List all sales-tax items

GET /quickbooks-desktop/sales-tax-items
Returns a list of sales-tax items.



# The Sales-Tax Item object

A sales-tax item is an item used to calculate a single sales tax that is collected at a specified rate and paid to a single agency.



# Retrieve a sales-tax item

GET /quickbooks-desktop/sales-tax-items/{id}
Retrieves a sales-tax item by ID.



# Update a sales-tax item

POST /quickbooks-desktop/sales-tax-items/{id}
Updates an existing sales-tax item.



# Create a service item

POST /quickbooks-desktop/service-items
Creates a new service item.



# List all service items

GET /quickbooks-desktop/service-items
Returns a list of service items.



# The Service Item object

A service item is an item that refers to services that a business charges for or purchases. Examples include specialized labor, consulting hours, and professional fees.



# Retrieve a service item

GET /quickbooks-desktop/service-items/{id}
Retrieves a service item by ID.



# Update a service item

POST /quickbooks-desktop/service-items/{id}
Updates an existing service item.



# Create a standard term

POST /quickbooks-desktop/standard-terms
Creates a new standard term.



# List all standard terms

GET /quickbooks-desktop/standard-terms
Returns a list of standard terms.



# The Standard Term object

A standard term is a payment term that shows the number of days within which payment is due and can include a discount for early payment.



# Retrieve a standard term

GET /quickbooks-desktop/standard-terms/{id}
Retrieves a standard term by ID.



# Create a transfer

POST /quickbooks-desktop/transfers
Creates a new transfer.



# List all transfers

GET /quickbooks-desktop/transfers
Returns a list of transfers.



# The Transfer object

A transfer is a transaction that moves money from one account to another account.



# Retrieve a transfer

GET /quickbooks-desktop/transfers/{id}
Retrieves a transfer by ID.



# Update a transfer

POST /quickbooks-desktop/transfers/{id}
Updates an existing transfer.



# Create a vendor

POST /quickbooks-desktop/vendors
Creates a new vendor.



# List all vendors

GET /quickbooks-desktop/vendors
Returns a list of vendors.



# The Vendor object

A vendor is any person or company from whom a small business owner buys goods and services. (Banks and tax agencies usually are included on the vendor list.) A company’s vendor list contains information such as account balance and contact information about each vendor.



# Retrieve a vendor

GET /quickbooks-desktop/vendors/{id}
Retrieves a vendor by ID.



# Update a vendor

POST /quickbooks-desktop/vendors/{id}
Updates an existing vendor.



# Accounts



export const pluralObjectName_0 = "accounts"

In QuickBooks Desktop, an **account** is a record that tracks the money coming in and going out of your business. Accounts are organized into a chart of accounts which includes assets, liabilities, income, and expenses. Each account has specific properties and characteristics.

<Info>
  To see all of the **request parameters and response fields** for
  {pluralObjectName_0}, check out our client library's [amazing
  autocomplete](/usage/autocomplete).
</Info>

## Fetching accounts

Fetching accounts in QuickBooks Desktop is straightforward. You can use optional request parameters to filter the results as needed.

```ts Fetching all accounts
const accounts = await conductor.qbd.account.query("{{END_USER_ID}}");
```

```ts Fetching all accounts with a filter
const accounts = await conductor.qbd.account.query("{{END_USER_ID}}", {
  NameFilter: {
    MatchCriterion: "StartsWith",
    Name: "Test Account",
  },
});
```

## Creating accounts

Creating accounts is also straightforward. There are several optional request parameters available, but the only required ones are `Name` and `AccountType`.

```ts Creating an account
const account = await conductor.qbd.account.add("{{END_USER_ID}}", {
  // Create a unique name for testing because QBD requires unique names.
  Name: "Test Account " + Date.now(),
  AccountType: "Expense",
});
```

<RequestExample>
  ```json Example account object from QBD
  {
    "ListID": "80000001-1234567890",
    "TimeCreated": "2022-01-01T09:00:00-07:00",
    "TimeModified": "2024-05-02T14:30:00-07:00",
    "EditSequence": "1234567890",
    "Name": "Test Account",
    "FullName": "Parent Account:Test Account",
    "IsActive": true,
    "ParentRef": {
      "ListID": "80000002-0987654321",
      "FullName": "Parent Account"
    },
    "Sublevel": 1,
    "AccountType": "Expense",
    "SpecialAccountType": "AccountsPayable",
    "IsTaxAccount": true,
    "AccountNumber": "1234",
    "BankNumber": "987654321",
    "Desc": "This is a test account.",
    "Balance": "1000.00",
    "TotalBalance": "1500.00",
    "SalesTaxCodeRef": {
      "ListID": "80000003-2345678901",
      "FullName": "Tax Code"
    },
    "TaxLineInfoRet": {
      "TaxLineID": 1,
      "TaxLineName": "Tax Line Name"
    },
    "CashFlowClassification": "Operating",
    "CurrencyRef": {
      "ListID": "20000000-1234567890",
      "FullName": "USD"
    },
  }
  ```
</RequestExample>


# Bills



export const pluralObjectName_0 = "bills"

A **bill** in QuickBooks Desktop is a record of a transaction that represents a request-for-payment from a [vendor](/qbd-examples/vendors) for goods or services that it has provided. Companies use bills to track the expenses they need to pay but have not yet paid. Bills are also known as payables.

<Info>
  To see all of the **request parameters and response fields** for
  {pluralObjectName_0}, check out our client library's [amazing
  autocomplete](/usage/autocomplete).
</Info>

## Fetching bills

Each bill has one or multiple line items, which are the goods or services that the vendor is requesting payment for. The following example fetches all bills for a given EndUser, including the line items for each bill.

```ts Fetching all bills with line items
const bills = await conductor.qbd.bill.fetchAll("{{END_USER_ID}}", {
  IncludeLineItems: true,
});
```

## Creating bills

To create a bill in QuickBooks Desktop, you either need the identifiers (e.g., `ListID`) of the required associated objects, or you must create the associated objects first.

The following example uses mock data to create a bill in QuickBooks Desktop, which also requires creating a mock vendor, account, and service-item using the `add()` method of each object. The `add()` method returns the created object, which contains the `ListID` identifier to associate the objects with each other.

```ts Creating a bill
const END_USER_ID = "{{END_USER_ID}}";
// Use unique names for mock objects because QBD requires each to be unique.
const UNIQUE_SUFFIX = Math.random().toFixed(6);

const vendor = await conductor.qbd.vendor.add(END_USER_ID, {
  Name: `Test Vendor ${UNIQUE_SUFFIX}`,
});

// A bill cannot be empty, so we must create an item to add to the bill,
// and every item requires an account, which we must create first.
const incomeAccount = await conductor.qbd.account.add(END_USER_ID, {
  Name: `Test Income Account ${UNIQUE_SUFFIX}`,
  AccountType: "Income",
});

// Create a service-item for the invoice with the account we just created.
const serviceItem = await conductor.qbd.itemService.add(END_USER_ID, {
  Name: `Construction Work ${UNIQUE_SUFFIX}`,
  SalesOrPurchase: {
    Price: "100.00",
    AccountRef: {
      ListID: incomeAccount.ListID,
    },
  },
});

const bill = await conductor.qbd.bill.add(END_USER_ID, {
  VendorRef: {
    ListID: vendor.ListID,
  },
  ItemLineAdd: [
    {
      ItemRef: {
        ListID: serviceItem.ListID,
      },
      Amount: "100.00",
      Quantity: 1,
    },
  ],
});
```

<RequestExample>
  ```json Example bill object from QBD
  {
    "TxnID": "ABC-1234567890",
    "TxnNumber": 123,
    "TxnDate": "2024-05-01",
    "DueDate": "2024-05-15",
    "TimeCreated": "2024-05-01T09:30:00+05:30",
    "TimeModified": "2024-05-01T09:30:00+05:30",
    "EditSequence": "9876543210",
    "VendorRef": {
      "ListID": "8000000A-1234567890",
      "FullName": "Acme Inc."
    },
    "APAccountRef": {
      "ListID": "8000000B-1234567890",
      "FullName": "Accounts Payable"
    },
    "LinkedTxn": {
      "TxnID": "XYZ-0987654321",
      "TxnType": "PurchaseOrder",
      "TxnDate": "2024-04-25",
      "RefNumber": "PO-12345",
      "LinkType": "QUANTYPE",
      "Amount": "0.00"
    },
    "AmountDue": "5000.00",
    "OpenAmount": "5000.00",
    "IsPaid": false,
    "ItemLineRet": [
      {
        "TxnLineID": "1A1-1234567890",
        "ItemRef": {
          "ListID": "8000000C-1234567890",
          "FullName": "Widget A"
        },
        "Quantity": 10,
        "Cost": "250.00",
        "Amount": "2500.00"
      },
      {
        "TxnLineID": "1A2-1234567890",
        "ItemRef": {
          "ListID": "8000000D-1234567890",
          "FullName": "Widget B"
        },
        "Quantity": 5,
        "Cost": "300.00",
        "Amount": "1500.00"
      },
      {
        "TxnLineID": "1A3-1234567890",
        "ItemRef": {
          "ListID": "8000000E-1234567890",
          "FullName": "Widget C"
        },
        "Quantity": 2,
        "Cost": "500.00",
        "Amount": "1000.00"
      }
    ]
  }
  ```
</RequestExample>


# Inventory items



export const pluralObjectName_0 = "inventory items"

In QuickBooks Desktop, an inventory item is any merchandise or part that a business purchases, tracks as inventory, and then resells. In QuickBooks, information about an inventory item is grouped into three categories:

1.  **Purchase Information:** `PurchaseDesc`, `PurchaseCost`, `COGSAccountRef`, and `PrefVendorRef`.
2.  **Sales Information:** `SalesDesc`, `SalesPrice`, and `SalesTaxCodeRef`.
3.  **Inventory Information:** `AssetAccountRef`, `ReorderPoint`, `QuantityOnHand`, `TotalValue`, and `InventoryDate`.

<Info>
  To see all of the **request parameters and response fields** for
  {pluralObjectName_0}, check out our client library's [amazing
  autocomplete](/usage/autocomplete).
</Info>

In addition to the inventory item operations documented herein, **Conductor can fetch, create, and update every other inventory-related QuickBooks Desktop data type**:

*   Inventory assembly items
*   Inventory transfers
*   Inventory adjustments
*   Inventory sites

We will document these data types in the future. In the meantime, contact us if you need help with them.

## Fetching inventory items

It is quite simple to fetch inventory items. There are many optional request parameters you can use to filter the results.

```ts Fetching all inventory items
const inventoryItems =
  await conductor.qbd.itemInventory.query("{{END_USER_ID}}");
```

```ts Fetching all inventory items with a filter
const inventoryItems = await conductor.qbd.itemInventory.query(
  "{{END_USER_ID}}",
  {
    NameFilter: {
      MatchCriterion: "StartsWith",
      Name: "Test Inventory Items",
    },
  },
);
```

## Creating inventory items

Creating vendors is also quite simple. There are many optional request parameters available, but the only required one is `Name`.

```ts Creating an inventory item
const END_USER_ID = "{{END_USER_ID}}";
// Use unique names for mock objects because QBD requires each to be unique.
const UNIQUE_SUFFIX = Math.random().toFixed(6);

// An inventory item requires an income account, asset account, and a COGS
// account. These will usually already exist for an end-user, but we create
// mock accounts below for this example:
const incomeAccount = await client.qbd.account.add(END_USER_ID, {
  Name: `Test Income Account ${UNIQUE_SUFFIX}`,
  AccountType: "Income",
});
const assetAccount = await client.qbd.account.add(END_USER_ID, {
  Name: `Test Asset Account ${UNIQUE_SUFFIX}`,
  AccountType: "FixedAsset",
});
const cogsAccount = await client.qbd.account.add(END_USER_ID, {
  Name: `Test COGS Account ${UNIQUE_SUFFIX}`,
  AccountType: "CostOfGoodsSold",
});

const inventoryItem = await client.qbd.itemInventory.add(END_USER_ID, {
  Name: `Test Inventory Item ${UNIQUE_SUFFIX}`,
  IncomeAccountRef: {
    ListID: incomeAccount.ListID,
  },
  AssetAccountRef: {
    ListID: assetAccount.ListID,
  },
  COGSAccountRef: {
    ListID: cogsAccount.ListID,
  },
  PurchaseCost: "50.00",
  SalesPrice: "100.00",
});
```

<RequestExample>
  ```json Example inventory item object from QBD
  {
    "ListID": "800012AB-1234567890",
    "Name": "MS-EX-ITEM",
    "FullName": "MS-EX-ITEM",
    "ManufacturerPartNumber": "EXITEM123",
    "IsActive": true,
    "Sublevel": 0,
    "QuantityOnHand": 100,
    "QuantityOnOrder": 50,
    "QuantityOnSalesOrder": 75,
    "PurchaseCost": "50.00",
    "AverageCost": "48.50",
    "SalesPrice": "99.99",
    "PurchaseDesc": "EXAMPLE ITEM PURCHASE DESCRIPTION",
    "SalesDesc": "EXAMPLE ITEM SALES DESCRIPTION",
    "ClassRef": {
      "ListID": "80000ABC-1234567890",
      "FullName": "EXAMPLE CLASS"
    },
    "UnitOfMeasureSetRef": {
      "ListID": "80000XYZ-1234567890",
      "FullName": "EACH"
    },
    "PrefVendorRef": {
      "ListID": "80000DEF-1234567890",
      "FullName": "EXAMPLE VENDOR"
    },
    "AssetAccountRef": {
      "ListID": "80000JKL-1234567890",
      "FullName": "Inventory Asset"
    },
    "COGSAccountRef": {
      "ListID": "80000MNO-1234567890",
      "FullName": "Cost of Goods Sold"
    },
    "IncomeAccountRef": {
      "ListID": "80000PQR-1234567890",
      "FullName": "Sales"
    },
    "SalesTaxCodeRef": {
      "ListID": "80000GHI-1234567890",
      "FullName": "EXAMPLE TAX CODE"
    },
    "EditSequence": "1234567890",
    "TimeCreated": "2024-05-01T09:30:00-05:00",
    "TimeModified": "2024-05-02T14:45:30-05:00"
  }
  ```
</RequestExample>


# Invoices



export const pluralObjectName_0 = "invoices"

An **invoice** in QuickBooks Desktop records the amount owed by a customer who purchased goods or services but did not pay in full at the time of the sale. If full payment is received at the time of the sale, it is recorded as a [sales receipt](/qbd-examples/sales-receipts), not an invoice.

<Info>
  To see all of the **request parameters and response fields** for
  {pluralObjectName_0}, check out our client library's [amazing
  autocomplete](/usage/autocomplete).
</Info>

## Fetching invoices

Each invoice in QuickBooks Desktop has several line items, which you would typically want to include when fetching invoices. The following example does just that:

```ts Fetching all invoices with line items
const invoices = await conductor.qbd.invoice.query("{{END_USER_ID}}", {
  IncludeLineItems: true,
});
```

Invoices are also assigned to specific jobs under a customer or to the customer directly when not related to a particular job. The following example fetches all invoices for a specific customer:

```ts Fetching all invoices for a specific customer
const invoices = await conductor.qbd.invoice.query("{{END_USER_ID}}", {
  EntityFilter: {
    FullName: "Test customer 1234",
  },
  IncludeLineItems: true,
});
```

Here is an example of fetching invoices modified (or created) after a specific date:

```ts Fetching invoices modified after a specific date
const invoices = await conductor.qbd.invoice.query("{{END_USER_ID}}", {
  ModifiedDateRangeFilter: {
    FromModifiedDate: "2024-04-01",
  },
  IncludeLineItems: true,
});
```

## Creating invoices

An invoice is a complex object with many associated objects. To create an invoice from scratch, you either need the identifiers (e.g., `ListID`) of the required associated objects, or you must create the associated objects first.

The following example uses mock data to create an invoice in QuickBooks Desktop, which also requires creating a mock customer, account, and service-item using the `add()` method of each object. The `add()` method returns the created object, which contains the `ListID` identifier to associate the objects with each other.

<Tabs>
  <Tab title="Node.js">
    ```ts Creating an invoice
    const END_USER_ID = "{{END_USER_ID}}";
    // Use unique names for mock objects because QBD requires each to be unique.
    const UNIQUE_SUFFIX = Math.random().toFixed(6);

    const customer = await conductor.qbd.customer.add(END_USER_ID, {
      Name: `Test customer ${UNIQUE_SUFFIX}`,
    });

    // An invoice cannot be empty, so we must create an item to add to the invoice,
    // and every item requires an account, which we must create first.
    const account = await conductor.qbd.account.add(END_USER_ID, {
      Name: `Test income account ${UNIQUE_SUFFIX}`,
      AccountType: "Income",
    });

    // Create a service-item for the invoice with the account we just created.
    const serviceItem = await conductor.qbd.itemService.add(END_USER_ID, {
      Name: `Construction work ${UNIQUE_SUFFIX}`,
      SalesOrPurchase: {
        Price: "100.00",
        AccountRef: {
          ListID: account.ListID,
        },
      },
    });

    const invoice = await conductor.qbd.invoice.add(END_USER_ID, {
      CustomerRef: {
        ListID: customer.ListID,
      },
      TxnDate: "2021-09-01",
      InvoiceLineAdd: [
        {
          Amount: "100.00",
          ItemRef: {
            ListID: serviceItem.ListID,
          },
        },
      ],
    });
    ```
  </Tab>

  <Tab title="Python">
    We do not yet have a Python client library for our API, but it is coming soon. For now, Python users can use [Conductor's REST API for QuickBooks Desktop](/qbd/rest) and still leverage Conductor's powerful backend.

    The following Python script creates an invoice in QuickBooks Desktop using Conductor's REST API. This script includes several helper functions that are an excellent example for how to use Conductor's REST API for QuickBooks Desktop in Python.

    <Warning>
      We are actively working on a complete rewrite of our REST API for QuickBooks Desktop that is much more powerful and much simpler. Available in Q1 2025.

      In the meantime, use the approach documented below, which will be backward-compatible and easily adaptable to the new REST API when it is released.
    </Warning>

    ```py Creating an invoice
    import json
    import random
    import requests

    API_KEY = "{{YOUR_SECRET_KEY}}"
    END_USER_ID = "{{END_USER_ID}}"


    def create_objects() -> None:
      # Use unique names for mock data because QBD requires each to be unique.
      mock_data_suffix = str(random.random())[:8]

      customer = create_customer(END_USER_ID, f"Test customer {mock_data_suffix}")
      print("New Customer:", json.dumps(customer, indent=4))

      # An invoice cannot be empty, so we must create an item to add to the
      # invoice, and every item requires an account, which we must create first.
      income_account = create_income_account(
        END_USER_ID, f"Test income account {mock_data_suffix}"
      )
      print("\nNew Income Account:", json.dumps(income_account, indent=4))

      # Create a service-item for the invoice with the account we just created.
      service_item = create_service_item(
        END_USER_ID,
        f"Construction work {mock_data_suffix}",
        income_account["ListID"],
      )
      print("\nNew Service Item:", json.dumps(service_item, indent=4))

      # Create an invoice with the customer and service-item we just created.
      invoice = create_invoice(END_USER_ID, customer["ListID"], service_item["ListID"])
      print("\nNew Invoice:", json.dumps(invoice, indent=4))


    def create_customer(end_user_id: str, customer_name: str) -> dict:
      response = send_qbd_request_to_conductor(
        end_user_id,
        {"CustomerAddRq": {"CustomerAdd": {"Name": customer_name}}},
      )
      return extract_return_value(response, "CustomerAddRs", "CustomerRet")


    def create_income_account(end_user_id: str, account_name: str) -> dict:
      response = send_qbd_request_to_conductor(
        end_user_id,
        {
          "AccountAddRq": {
            "AccountAdd": {
              "Name": account_name,
              "AccountType": "Income",
            }
          }
        },
      )
      return extract_return_value(response, "AccountAddRs", "AccountRet")


    def create_service_item(
      end_user_id: str, item_name: str, income_account_list_id: str
    ) -> dict:
      response = send_qbd_request_to_conductor(
        end_user_id,
        {
          "ItemServiceAddRq": {
            "ItemServiceAdd": {
              "Name": item_name,
              "SalesOrPurchase": {
                "Price": "100.00",
                "AccountRef": {
                  "ListID": income_account_list_id,
                },
              },
            }
          },
        },
      )
      return extract_return_value(response, "ItemServiceAddRs", "ItemServiceRet")


    def create_invoice(
      end_user_id: str, customer_list_id: str, service_item_list_id: str
    ) -> dict:
      response = send_qbd_request_to_conductor(
        end_user_id,
        {
          "InvoiceAddRq": {
            "InvoiceAdd": {
              "CustomerRef": {
                "ListID": customer_list_id,
              },
              "TxnDate": "2021-09-01",
              "InvoiceLineAdd": [
                {
                  "Amount": "100.00",
                  "ItemRef": {
                    "ListID": service_item_list_id,
                  },
                }
              ],
            }
          },
        },
      )
      return extract_return_value(response, "InvoiceAddRs", "InvoiceRet")


    def send_qbd_request_to_conductor(end_user_id: str, request_body: dict) -> dict:
      try:
        response = requests.post(
          url=f"https://api.conductor.is/v1/end-users/{end_user_id}/request/quickbooks_desktop",
          json=request_body,
          headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
          },
        )
        response.raise_for_status()
        return response.json()
      except requests.HTTPError:
        print(f"Conductor error: {response.text}")
        raise
      except requests.RequestException as e:
        print(f"Error during requests to {response.url}: {e}")
        raise


    # Helper function to safely extract data from response.
    def extract_return_value(response, *keys):
      for key in keys[:-1]:
        response = response.get(key, {})
      return response.get(keys[-1])


    if __name__ == "__main__":
      create_objects()
    ```
  </Tab>
</Tabs>

## Updating invoices and line-items

To modify existing line-items or add line-items to an invoice, QuickBooks Desktop requires that you include all unmodified line-items in the update request, even the ones you do not want to change. Otherwise, QuickBooks Desktop will remove the line-items you did not include in the update request. Hence, we recommend you first query the invoice you want to update, then update that invoice with the new line-items you want to add or modify while including all the existing line-items returned from the query.

```ts Updating an invoice by adding a new line-item
const END_USER_ID = "{{END_USER_ID}}";

const newInvoice = await conductor.qbd.invoice.add(END_USER_ID, {
  CustomerRef: {
    FullName: "Test Customer",
  },
  Memo: "New invoice",
  InvoiceLineAdd: [
    {
      ItemRef: {
        FullName: "Test Item",
      },
      Desc: "First line item",
      Amount: "100.00",
    },
    {
      ItemRef: {
        FullName: "Test Item",
      },
      Desc: "Second line item",
      Amount: "200.00",
    },
  ],
});

const updatedInvoice = await conductor.qbd.invoice.mod(END_USER_ID, {
  TxnID: newInvoice.TxnID,
  // `EditSequence` from the original object is required to update
  // any QuickBooks Desktop object.
  EditSequence: newInvoice.EditSequence,
  Memo: "Updated invoice",
  InvoiceLineMod: [
    // QuickBooks Desktop requires that you re-include the
    // existing line items in the request. Otherwise, it will
    // remove them from the invoice.
    ...newInvoice.InvoiceLineRet,
    {
      ItemRef: {
        ListID: inventoryItems[0].ListID,
      },
      Desc: "Item 3",
      // Set `TxnLineID` to -1 to add a new line item.
      TxnLineID: "-1",
    },
  ],
});
```

<RequestExample>
  ```json Example invoice object from QBD
  {
    "TxnID": "ABC123-9876543210",
    "TxnNumber": 2345,
    "RefNumber": "INV-2345",
    "TxnDate": "2024-05-01",
    "TimeCreated": "2024-05-01T09:30:00+00:00",
    "TimeModified": "2024-05-01T09:45:00+00:00",
    "EditSequence": "9876543210",
    "CustomerRef": {
      "ListID": "100000-1234567890",
      "FullName": "John Doe"
    },
    "ARAccountRef": {
      "ListID": "200000-1234567890",
      "FullName": "Accounts Receivable"
    },
    "TemplateRef": {
      "ListID": "300000-1234567890",
      "FullName": "Standard Invoice Template"
    },
    "ItemSalesTaxRef": {
      "ListID": "400000-1234567890",
      "FullName": "State Sales Tax"
    },
    "CustomerSalesTaxCodeRef": {
      "ListID": "500000-1234567890",
      "FullName": "Standard Tax Code"
    },
    "ShipMethodRef": {
      "ListID": "600000-1234567890",
      "FullName": "FedEx Ground"
    },
    "Subtotal": "1000.00",
    "SalesTaxTotal": "80.00",
    "SalesTaxPercentage": 8.0,
    "AppliedAmount": "500.00",
    "BalanceRemaining": "580.00",
    "DueDate": "2024-06-01",
    "ShipDate": "2024-05-03",
    "IsPaid": false,
    "IsPending": true,
    "IsFinanceCharge": false,
    "IsToBeEmailed": true,
    "IsToBePrinted": false,
    "InvoiceLineRet": [
      {
        "TxnLineID": "LI1-9876543210",
        "ItemRef": {
          "ListID": "700000-1234567890",
          "FullName": "Product A"
        },
        "Desc": "Product A description",
        "Quantity": 10,
        "Rate": "100.00",
        "Amount": "1000.00",
        "SalesTaxCodeRef": {
          "ListID": "500000-1234567890",
          "FullName": "Standard Tax Code"
        }
      },
      {
        "TxnLineID": "LI2-9876543210",
        "ItemRef": {
          "ListID": "800000-1234567890",
          "FullName": "Discount"
        },
        "Desc": "10% discount",
        "RatePercent": -10,
        "Amount": "-100.00"
      },
      {
        "TxnLineID": "LI3-9876543210",
        "ItemRef": {
          "ListID": "900000-1234567890",
          "FullName": "Subtotal"
        },
        "Desc": "Subtotal",
        "Amount": "900.00"
      }
    ]
  }
  ```
</RequestExample>


# Jobs and customers

Understanding the relationship between customers and jobs in QuickBooks Desktop.

export const pluralObjectName_0 = "customers"

## Overview

In QuickBooks Desktop, both "customers" and "jobs" are represented as `Customer` objects. Jobs are considered a subset of customers and cannot be queried separately. This data model is a quirk of QuickBooks Desktop and is outside of Conductor's control.

## Differences between jobs and customers

A job in QuickBooks Desktop differs from a customer in the following ways:

1.  **ParentRef:** A job has a `ParentRef` property that points to the parent customer.

2.  **FullName:** A job's `FullName` property is the concatenation of the parent customer's `FullName` and the job's Name.

    *   Example: If the parent customer's `FullName` is `"Annie's Alligators"` and the job's Name is `"Swamp"`, the job's `FullName` will be `"Annie's Alligators:Swamp"`.

3.  **Sublevel:** A job has a `Sublevel` property set to `1`, while the parent customer's `Sublevel` property is set to `0`.

## Querying customers and jobs

To fetch all customers and jobs for a given end-user, use the following query:

```ts Fetching all customers and jobs
const customersAndJobs = await conductor.qbd.customer.query("{{END_USER_ID}}");
```

<Tip>
  If you're looking for a specific job in QuickBooks Desktop, you must query for
  the customer and then filter the results to find the job.
</Tip>

<Info>
  To see all of the **request parameters and response fields** for
  {pluralObjectName_0}, check out our client library's [amazing
  autocomplete](/usage/autocomplete).
</Info>

## Fetching objects related to customers' jobs

Some objects in QuickBooks Desktop, such as SalesOrders, are associated with a customer's job instead of directly with the customer. In these cases, querying using the `EntityFilter.ListID` parameter set to a customer's `ListID` will return no results.

To fetch objects related to a customer's jobs, use the `EntityFilter.ListIDWithChildren` parameter with the customer's `ListID`. This will return the objects corresponding to all of the customer's jobs. For example:

```ts Fetching SalesOrders for all jobs of a customer
const salesOrders = await conductor.qbd.salesOrder.query("{{END_USER_ID}}", {
  EntityFilter: {
    // The `ListID` of the customer whose jobs' SalesOrders you want to fetch.
    ListIDWithChildren: "800000AB-1234567890",
  },
});
```

By using the `ListIDWithChildren` parameter, you can effectively query for objects related to a customer's jobs without having to query for each job individually.

<RequestExample>
  ```json Example customer object from QBD
  {
    "ListID": "800000AB-1234567890",
    "Name": "SUNNY GARDENS INC.",
    "FullName": "SUNNY GARDENS INC.",
    "CompanyName": "SUNNY GARDENS INC.",
    "Phone": "555-987-6543",
    "AltPhone": "800-246-1357",
    "Fax": "555-123-4567",
    "Email": "info@sunnygardens.com",
    "IsActive": true,
    "Balance": "5678.92",
    "TotalBalance": "5678.92",
    "TimeCreated": "2021-09-15T14:30:00-05:00",
    "TimeModified": "2023-09-01T09:45:12-05:00",
    "EditSequence": "1987654321",
    "CustomerTypeRef": {
      "ListID": "8000000F-1234567890",
      "FullName": "Wholesale"
    },
    "PriceLevelRef": {
      "ListID": "80000003-1234567890",
      "FullName": "WHOLESALE PRICE LEVEL LIST"
    },
    "SalesTaxCodeRef": {
      "ListID": "80000003-1234567890",
      "FullName": "Taxable"
    },
    "TermsRef": {
      "ListID": "80000007-1234567890",
      "FullName": "Net 60"
    },
    "BillAddress": {
      "Addr1": "SUNNY GARDENS INC.",
      "Addr2": "4321 MAIN STREET",
      "City": "SPRINGFIELD, IL 62701 US, IL 62",
      "State": "IL 62701 US"
    },
    "BillAddressBlock": {
      "Addr1": "SUNNY GARDENS INC.",
      "Addr2": "4321 MAIN STREET",
      "Addr3": "SPRINGFIELD, IL 62701 US, IL 62701"
    },
    "ShipAddress": {
      "Addr1": "SUNNY GARDENS INC.",
      "Addr2": "4321 MAIN STREET",
      "City": "SPRINGFIELD",
      "State": "IL",
      "PostalCode": "62701",
      "Country": "United States"
    },
    "ShipAddressBlock": {
      "Addr1": "SUNNY GARDENS INC.",
      "Addr2": "4321 MAIN STREET",
      "Addr3": "SPRINGFIELD, IL 62701",
      "Addr4": "United States"
    },
    "Sublevel": 0,
    "JobStatus": "None",
    "Notes": "John Smith - Owner\\nMary Smith - Manager"
  }
  ```
</RequestExample>

<ResponseExample>
  ```json Example "job" for the customer above
  {
    "ListID": "8000000D-1987654321",
    "TimeCreated": "2022-03-01T10:15:00-05:00",
    "TimeModified": "2023-09-01T14:30:00-05:00",
    "EditSequence": 1987654322,
    "Name": "Spring Planting",
    // For jobs, `FullName` is the concatenation of the
    // parent customer's `FullName` and the job's `Name`.
    "FullName": "SUNNY GARDENS INC.:Spring Planting",
    "IsActive": true,
    // `ParentRef` only exists for jobs and points to
    // the parent customer object.
    "ParentRef": {
      "ListID": "800000AB-1234567890",
      "FullName": "SUNNY GARDENS INC."
    },
    "Sublevel": 1,
    "Balance": 1234.56,
    "TotalBalance": 1234.56,
    "JobStatus": "In Progress",
    "PreferredDeliveryMethod": "Email",
    "StartDate": "2022-03-15",
    "ProjectedEndDate": "2022-05-31",
    "JobTypeRef": {
      "ListID": "8000000G-1987654321",
      "FullName": "Landscaping"
    },
    "JobDescription": "Annual spring planting and garden setup for Sunny Gardens Inc.",
    "PrimaryContactRef": {
      "ListID": "8000000H-1987654321",
      "FullName": "Mary Smith"
    }
  }
  ```
</ResponseExample>


# Request more examples!

Conductor supports read, create, and update for *every* QuickBooks Desktop object type.

**Conductor has fully-typed APIs for reading, creating, and updating [*any* object in QuickBooks Desktop](/qbd/api#supported-object-types).** If the QuickBooks Desktop UI can do it, then so can Conductor's API.

We have dozens more guides we want to write with code samples and examples. If you have a specific use case you'd like to see, [email us](mailto:support@conductor.is?subject=Conductor%20Docs%20Request\&body=Conductor%20supports%20every%20possible%20QuickBooks%20Desktop%20operation.%20Describe%20below%20what%20you%20are%20trying%20to%20do%2C%20and%20we%27ll%20either%20point%20you%20to%20an%20existing%20document%20or%20create%20one%20ASAP.) and we will publish it within 24 hours.

<Info>
  In the meantime, we recommend using our client library's [awesome autocomplete
  functionality](/usage/autocomplete) to discover all of the available APIs,
  request parameters, and response fields.
</Info>


# Refunds



This guide covers how to implement refunds using Conductor's QuickBooks Desktop API. We'll cover two main scenarios:

1.  Invoice-based refunds (full or partial)
2.  Custom refunds (not linked to any invoice)

## Invoice-based refund

For invoice-based refunds, you will create a credit memo and then apply it to the relevant invoice using a receive payment transaction to reduce the outstanding balance.

### Step 1: Create the credit memo

First, create a credit memo for the customer for the amount you wish to refund. This credit memo can be for the full or partial amount of the invoice.

Here's an example of how to create a credit memo:

```typescript
const creditMemo = await conductor.qbd.creditMemo.add("{{END_USER_ID}}", {
  CustomerRef: {
    ListID: "customer_list_id", // Customer's ListID from the original invoice
  },
  TxnDate: "2024-10-23", // Current date
  RefNumber: "REFUND-123", // Optional: Your reference number
  Memo: "Refund for Invoice INV-001", // Add a memo for reference
  CreditMemoLineAdd: [
    {
      ItemRef: {
        ListID: "item_list_id", // Original item from the invoice
      },
      Desc: "Refund for Invoice #123",
      Quantity: 1, // Quantity being refunded
      Amount: "50.00", // Amount being refunded for the item
    },
  ],
});
```

### Step 2: Apply the credit memo to the invoice

Next, apply the credit memo to the outstanding invoice using a receive payment request. This will reduce the balance of the invoice by the credit amount.

Here's an example of how to apply the credit:

```typescript
const receivePayment = await conductor.qbd.receivePayment.add(
  "{{END_USER_ID}}",
  {
    CustomerRef: {
      ListID: "customer_list_id", // Must match the customer from credit memo
    },
    TotalAmount: "0.00", // No new payment being received
    Memo: "Applying credit memo to invoice",
    AppliedToTxnAdd: {
      TxnID: "original_invoice_txn_id", // Original invoice's TxnID
      PaymentAmount: "0.00", // No payment being made
      SetCredit: {
        CreditTxnID: creditMemo.TxnID, // TxnID from the credit memo we just created
        AppliedAmount: "50.00", // Amount of credit to apply
      },
    },
  },
);
```

## Custom refund (not linked to any invoice)

For a custom refund not linked to any specific invoice, simply create a credit memo to record the amount owed to the customer.

Here's an example of how to create a custom credit memo:

```typescript
const standaloneCreditMemo = await conductor.qbd.creditMemo.add(
  "{{END_USER_ID}}",
  {
    CustomerRef: {
      ListID: "customer_list_id", // Required: Customer's ListID
    },
    TxnDate: "2024-10-23", // Current date
    RefNumber: "REFUND-124", // Optional: Your reference number
    Memo: "Goodwill refund",
    CreditMemoLineAdd: [
      {
        ItemRef: {
          ListID: "refund_item_list_id", // Use a specific item for refunds
        },
        Desc: "Customer satisfaction refund",
        Amount: "75.00", // Refund amount
      },
    ],
  },
);
```

## Common scenarios

### Partial refund

Modify the `CreditMemoLineAdd.Amount` to match the partial refund amount:

```typescript
CreditMemoLineAdd: [
  {
    ItemRef: { ListID: "item_list_id" },
    Desc: "Partial refund - 50%",
    Amount: "25.00", // Half of the original amount
  },
];
```

### Multiple item refund

Use multiple `CreditMemoLineAdd` entries:

```typescript
CreditMemoLineAdd: [
  {
    ItemRef: { ListID: "item1_list_id" },
    Desc: "Refund - Item 1",
    Amount: "30.00",
  },
  {
    ItemRef: { ListID: "item2_list_id" },
    Desc: "Refund - Item 2",
    Amount: "20.00",
  },
];
```


# Sales receipts



export const pluralObjectName_0 = "sales receipts"

A **sales receipt** in QuickBooks Desktop is a record of a sale to a customer, such as a payment by cash, check, or credit card. Each sales receipt has several line items, which are the products or services sold.

<Info>
  To see all of the **request parameters and response fields** for
  {pluralObjectName_0}, check out our client library's [amazing
  autocomplete](/usage/autocomplete).
</Info>

## Fetching sales receipts

The following example fetches all sales receipts for the specified EndUser, including the line items:

```ts Fetching all sales receipts with line items
const salesReceipts = await conductor.qbd.salesReceipt.query(
  "{{END_USER_ID}}",
  { IncludeLineItems: true },
);
```

## Creating sales receipts

To create a sales receipt in QuickBooks Desktop from scratch, you either need the identifiers (e.g., `ListID`) of the required associated objects, or you must create the associated objects first.

The following example uses mock data to create a sales receipt in QuickBooks Desktop, which also requires creating a mock customer, account, and service-item using the `add()` method of each object. The `add()` method returns the created object, which contains the `ListID` identifier to associate the objects with each other.

```ts Creating a sales receipt
const END_USER_ID = "{{END_USER_ID}}";
// Use unique names for mock objects because QBD requires each to be unique.
const UNIQUE_SUFFIX = Math.random().toFixed(6);

const customer = await conductor.qbd.customer.add(END_USER_ID, {
  Name: `Test Customer ${UNIQUE_SUFFIX}`,
});

// A sales receipt cannot be empty, so we must create an item to add to the
// sales receipt, and every item requires an account, which we create first.
const account = await conductor.qbd.account.add(END_USER_ID, {
  Name: `Test Income Account ${UNIQUE_SUFFIX}`,
  AccountType: "Income",
});

// Create a service-item for the sales receipt with the account we just created.
const serviceItem = await conductor.qbd.itemService.add(END_USER_ID, {
  Name: `Construction Work ${UNIQUE_SUFFIX}`,
  SalesOrPurchase: {
    Price: "100.00",
    AccountRef: {
      ListID: account.ListID,
    },
  },
});

const salesReceipt = await conductor.qbd.salesReceipt.add(END_USER_ID, {
  CustomerRef: {
    ListID: customer.ListID,
  },
  SalesReceiptLineAdd: [
    {
      Quantity: 5,
      ItemRef: {
        ListID: serviceItem.ListID,
      },
    },
  ],
});
```

<RequestExample>
  ```json Example sales receipt object from QBD
  {
    "TxnID": "1234-5678901234",
    "TxnNumber": 1000,
    "TxnDate": "2024-05-01",
    "RefNumber": "11",
    "CustomerRef": {
      "ListID": "1234567890",
      "FullName": "John Doe"
    },
    "Subtotal": "1000.00",
    "SalesTaxTotal": "80.00",
    "TotalAmount": "1080.00",
    "DepositToAccountRef": {
      "ListID": "9876543210",
      "FullName": "Checking Account"
    },
    "ClassRef": {
      "ListID": "1122334455",
      "FullName": "Online Sales"
    },
    "TemplateRef": {
      "ListID": "5544332211",
      "FullName": "Standard Sales Receipt"
    },
    "BillAddress": {
      "Addr1": "123 Main St"
    },
    "BillAddressBlock": {
      "Addr1": "123 Main St"
    },
    "ShipDate": "2024-05-02",
    "DueDate": "2024-05-15",
    "SalesTaxPercentage": 8.0,
    "IsPending": false,
    "IsToBeEmailed": true,
    "IsToBePrinted": false,
    "EditSequence": "1683057600",
    "TimeCreated": "2024-05-01T09:30:00-04:00",
    "TimeModified": "2024-05-01T09:45:00-04:00",
    "SalesReceiptLineRet": {
      "TxnLineID": "4E3-1703630162",
      "ItemRef": {
        "ListID": "80000035-1703630156",
        "FullName": "Construction Work"
      },
      "Quantity": 5,
      "Rate": 100,
      "Amount": 500,
      "SalesTaxCodeRef": {
        "ListID": "80000002-1692738438",
        "FullName": "Non"
      }
    }
  }
  ```
</RequestExample>


# Vendors



export const pluralObjectName_0 = "vendors"

A **vendor** in QuickBooks Desktop is an entity that represents a person, company, or business entity from which a business purchases goods or services. (Banks and tax agencies usually are included on the
vendor list.) A company’s vendor list contains information such as account
balance and contact information about each vendor. This entity is crucial for tracking and managing expenses and accounts payable.

<Info>
  To see all of the **request parameters and response fields** for
  {pluralObjectName_0}, check out our client library's [amazing
  autocomplete](/usage/autocomplete).
</Info>

## Fetching vendors

It is quite simple to fetch vendors. There are many optional request parameters you can use to filter the results.

```ts Fetching all vendors
const vendors = await conductor.qbd.vendor.query("{{END_USER_ID}}");
```

```ts Fetching all vendors with a filter
const vendors = await conductor.qbd.vendor.query("{{END_USER_ID}}", {
  NameFilter: {
    MatchCriterion: "StartsWith",
    Name: "Test Vendor",
  },
});
```

## Creating vendors

Creating vendors is also quite simple. There are many optional request parameters available, but the only required one is `Name`.

```ts Creating a vendor
const vendor = await conductor.qbd.vendor.add("{{END_USER_ID}}", {
  // Create a unique name for testing because QBD requires unique names.
  Name: "Test Vendor " + Date.now(),
});
```

<RequestExample>
  ```json Example vendor object from QBD
  {
    "ListID": "9000008D-1234567890",
    "Name": "Acme Inc.",
    "CompanyName": "Acme Inc.",
    "NameOnCheck": "Acme Inc.",
    "IsActive": true,
    "Balance": "1250.00",
    "Phone": "555-123-4567",
    "Fax": "555-987-6543",
    "AdditionalContactRef": [
      {
        "ContactName": "Customer Support",
        "ContactValue": "800-555-1234"
      },
      {
        "ContactName": "Sales",
        "ContactValue": "800-555-5678"
      }
    ],
    "VendorAddress": {
      "Addr1": "Acme Inc.",
      "Addr2": "123 Main St.",
      "City": "Anytown",
      "State": "CA",
      "PostalCode": "12345"
    },
    "VendorAddressBlock": {
      "Addr1": "Acme Inc.",
      "Addr2": "123 Main St.",
      "Addr3": "Anytown, CA 12345"
    },
    "TermsRef": {
      "ListID": "90000007-1234567890",
      "FullName": "Net 60"
    },
    "IsVendorEligibleFor1099": true,
    "TimeCreated": "2022-01-01T09:00:00-07:00",
    "TimeModified": "2024-05-02T14:30:00-07:00",
    "EditSequence": "1234567890"
  }
  ```
</RequestExample>


# Node.js / TypeScript for QuickBooks Desktop

Execute real-time requests for *any* QuickBooks Desktop object type with fully-typed requests and responses.

## Accessing QuickBooks Desktop through Conductor

With Conductor, you can read, create, or update *any* QuickBooks Desktop object type. Every operation is available through a single, consistent interface vis `conductor.qbd.*`.

<Tip>
  We recommend using Conductor's [amazing autocomplete](/usage/autocomplete) to
  discover the available operations, parameters, and responses fields.
</Tip>

For example:

<CodeGroup>
  ```ts Fetch all invoices with line items
  const invoices = await conductor.qbd.invoice.query("{{END_USER_ID}}", {
    IncludeLineItems: true,
  });
  ```

  ```ts Create an invoice
  const newInvoice = await conductor.qbd.invoice.add("{{END_USER_ID}}", {
    CustomerRef: {
      FullName: "Acme Inc.",
    },
    TxnDate: "2024-01-12",
    Memo: "Customer invoice for Jan 1 - 7",
    InvoiceLineAdd: [
      {
        Amount: "100.00",
        ItemRef: {
          FullName: "Consulting",
        },
      },
    ],
  });
  ```

  ```ts Update an invoice
  const updatedInvoice = await conductor.qbd.invoice.mod("{{END_USER_ID}}", {
    TxnID: "1234-ABCD",
    EditSequence: "1234-ABCD",
    DueDate: "2024-01-19",
    InvoiceLineMod: {
      TxnLineID: "1234-ABCD",
      ItemRef: {
        FullName: "Consulting",
      },
      Amount: "200.00",
    },
  });
  ```
</CodeGroup>

### Supported object types

Conductor supports the following QuickBooks Desktop object types and operations. Alternatively, see [QuickBooks Desktop's official API Reference](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop) to explore the operations available for each object type.

| Object                | Read | Create | Update |
| --------------------- | :--: | :----: | :----: |
| Account               |   ✔  |    ✔   |    ✔   |
| AgingReport           |   ✔  |        |        |
| Bill                  |   ✔  |    ✔   |    ✔   |
| BillPaymentCheck      |   ✔  |    ✔   |    ✔   |
| BillPaymentCreditCard |   ✔  |    ✔   |        |
| BillingRate           |   ✔  |    ✔   |        |
| BudgetSummaryReport   |   ✔  |        |        |
| BuildAssembly         |   ✔  |    ✔   |    ✔   |
| Charge                |   ✔  |    ✔   |    ✔   |
| Check                 |   ✔  |    ✔   |    ✔   |
| Class                 |   ✔  |    ✔   |    ✔   |
| Company               |   ✔  |        |        |
| CreditCardCharge      |   ✔  |    ✔   |    ✔   |
| CreditCardCredit      |   ✔  |    ✔   |    ✔   |
| CreditMemo            |   ✔  |    ✔   |    ✔   |
| Currency              |   ✔  |    ✔   |    ✔   |
| CustomDetailReport    |   ✔  |        |        |
| CustomSummaryReport   |   ✔  |        |        |
| Customer              |   ✔  |    ✔   |    ✔   |
| CustomerType          |   ✔  |    ✔   |        |
| DataExt               |      |    ✔   |    ✔   |
| DateDrivenTerms       |   ✔  |    ✔   |        |
| Deposit               |   ✔  |    ✔   |    ✔   |
| Employee              |   ✔  |    ✔   |    ✔   |
| Estimate              |   ✔  |    ✔   |    ✔   |
| GeneralDetailReport   |   ✔  |        |        |
| GeneralSummaryReport  |   ✔  |        |        |
| InventoryAdjustment   |   ✔  |    ✔   |    ✔   |
| InventorySite         |   ✔  |    ✔   |    ✔   |
| Invoice               |   ✔  |    ✔   |    ✔   |
| ItemDiscount          |   ✔  |    ✔   |    ✔   |
| ItemFixedAsset        |   ✔  |    ✔   |    ✔   |
| ItemGroup             |   ✔  |    ✔   |    ✔   |
| ItemInventory         |   ✔  |    ✔   |    ✔   |
| ItemInventoryAssembly |   ✔  |    ✔   |    ✔   |
| ItemNonInventory      |   ✔  |    ✔   |    ✔   |
| ItemOtherCharge       |   ✔  |    ✔   |    ✔   |
| ItemPayment           |   ✔  |    ✔   |    ✔   |
| ItemReceipt           |   ✔  |    ✔   |    ✔   |
| ItemSalesTax          |   ✔  |    ✔   |    ✔   |
| ItemSalesTaxGroup     |   ✔  |    ✔   |    ✔   |
| ItemService           |   ✔  |    ✔   |    ✔   |
| ItemSites             |   ✔  |        |        |
| ItemSubtotal          |   ✔  |    ✔   |    ✔   |
| JobReport             |   ✔  |        |        |
| JobType               |   ✔  |    ✔   |        |
| JournalEntry          |   ✔  |    ✔   |    ✔   |
| Lead                  |   ✔  |    ✔   |    ✔   |
| ListDeleted           |   ✔  |        |        |
| OtherName             |   ✔  |    ✔   |    ✔   |
| PaymentMethod         |   ✔  |    ✔   |        |
| PayrollDetailReport   |   ✔  |        |        |
| PayrollItemWage       |   ✔  |    ✔   |        |
| PayrollSummaryReport  |   ✔  |        |        |
| PriceLevel            |   ✔  |    ✔   |    ✔   |
| PurchaseOrder         |   ✔  |    ✔   |    ✔   |
| ReceivePayment        |   ✔  |    ✔   |    ✔   |
| SalesOrder            |   ✔  |    ✔   |    ✔   |
| SalesReceipt          |   ✔  |    ✔   |    ✔   |
| SalesRep              |   ✔  |    ✔   |    ✔   |
| SalesTaxCode          |   ✔  |    ✔   |    ✔   |
| SalesTaxPaymentCheck  |   ✔  |    ✔   |    ✔   |
| StandardTerms         |   ✔  |    ✔   |        |
| TimeReport            |   ✔  |        |        |
| TimeTracking          |   ✔  |    ✔   |    ✔   |
| Transaction           |   ✔  |        |        |
| Transfer              |   ✔  |    ✔   |    ✔   |
| TransferInventory     |   ✔  |    ✔   |    ✔   |
| TxnDeleted            |   ✔  |        |        |
| Vehicle               |   ✔  |    ✔   |    ✔   |
| VehicleMileage        |   ✔  |    ✔   |        |
| Vendor                |   ✔  |    ✔   |    ✔   |
| VendorCredit          |   ✔  |    ✔   |    ✔   |
| VendorType            |   ✔  |    ✔   |        |
| WorkersCompCode       |   ✔  |    ✔   |    ✔   |

## TypeScript for QuickBooks Desktop

In the Conductor Node.js library, every request parameter and response attribute is fully-typed with inline documentation and will autocomplete in your editor. This makes it easy to explore the API and write code that works the first time.

If you ever need to access the raw QuickBooks Desktop types, you can import them from `conductor-node` like so:

```ts
import { QbdTypes } from "conductor-node";

const accountAddInput: QbdTypes.AccountAdd = {
  Name: "Test Account",
  AccountType: "Bank",
  OpenBalance: "100",
};
```


# Get a free QuickBooks Desktop developer license

Obtain a free Not-For-Resale (NFR) license to use QuickBooks Desktop indefinitely for development and testing with Conductor. Takes 2 minutes.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

To develop and test integrations with Conductor, you need your own QuickBooks Desktop instance. If you don't have an existing instance, you can [install the QuickBooks Desktop free trial](/qbd/test-instance.mdx). The trial includes all features of the full version but expires after 30 days. To continue using QuickBooks Desktop for development beyond this period, you'll need a free Not-For-Resale (NFR) license. Follow these steps to obtain one:

<Steps>
  <Step title="Install QuickBooks Desktop trial">
    If you haven't already, follow our guide for [installing the QuickBooks Desktop free trial](/qbd/test-instance.mdx).
  </Step>

  <Step title="Create an Intuit developer account">
    [Sign up for an Intuit developer account](https://accounts.intuit.com/app/sign-in?start_screen_hint=SignUp) if you don't have one. This account is required to request the NFR license.
  </Step>

  <Step title="Create a support ticket">
    1.  Go to [Intuit's developer support page](https://help.developer.intuit.com/s/contactsupport).
    2.  Choose the following options:
        *   **Product:** QuickBooks Desktop
        *   **Category:** NFR License
    3.  Click "Next" to proceed.

    <Frame>
      ![Support ticket creation page with 'QuickBooks Desktop' selected as the
      Product and 'NFR License' selected as the
      Category](https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/dev-license/create-ticket-1.jpg)
    </Frame>
  </Step>

  <Step title="Provide version details">
    On the next page, specify:

    *   **Product Year:** 2024 (or the latest available)
    *   **Product Country:** US
    *   **Product Version:** QuickBooks Enterprise v24 (or the latest version)
        <Info>
          Conductor works identically with all QuickBooks Desktop versions and editions. We recommend the Enterprise edition for development to avoid potential limitations in user count and dataset size.
        </Info>
    *   **Enable Advanced Inventory?** Yes (Allows testing with the full feature set)

    After filling out these details, click "Create Support Ticket".

    <Frame>
      ![Support ticket creation page with the specified options selected](https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/dev-license/create-ticket-2.jpg)
    </Frame>
  </Step>

  <Step title="Wait for the license key via email">
    After you click "Create Support Ticket", Intuit will send you a confirmation email. Intuit will send you another email within 24-48 hours with your license key.
  </Step>

  <Step title="Activate your license once you receive it">
    Once you have the license key:

    1.  Open your existing QuickBooks Desktop trial installation.
    2.  Go to Help > Manage My License > Change Product License.
    3.  Enter the NFR license key when prompted.
    4.  Follow any additional on-screen instructions to complete activation.

    Your QuickBooks Desktop is now licensed for indefinite use in development and testing with Conductor.
  </Step>
</Steps>


# Mapping your app's objects to QuickBooks Desktop

How to handle syncing your application's data objects with QuickBooks Desktop objects.

Most complex QuickBooks Desktop (QBD) object types, such as [invoices](/qbd-examples/invoices) and [sales receipts](/qbd-examples/sales-receipts), interact with various related objects. For instance, an invoice may contain multiple line items, with each item linked to a specific QBD inventory item via an ID. **When creating these objects in QBD, you must ensure that all related objects are correctly linked.**

For effective integration, depending on the data type of these related objects and you application requirements, you can either:

1.  **Create new QBD objects** and store their IDs in your application's database for future reference.
2.  **Map existing QBD objects to corresponding objects in your application** through manual configurations made by users within your application's UI. Consider the following example for inventory items:
    1.  Fetch all existing QBD inventory items using Conductor's API (e.g., `await conductor.qbd.itemInventory.query()`).
    2.  Display these QBD items alongside items from your application in the UI.
    3.  Users can then specify mappings, or opt to create new items in QBD.
    4.  Record the corresponding QBD item ID in your application's database (e.g., add a **`qbd_item_id`** column to the **`items`** table).

<Tip>
  **Important:** The need to map or create objects may vary based on object type
  (e.g., some users might prefer mapping existing QBD objects for certain types
  while creating new ones for others). Regardless, it is crucial for your
  application to store these QBD IDs in its database for all future
  interactions, ensuring no duplicate objects are created.
</Tip>


# Pagination

Split your requests into smaller chunks to avoid overwhelming QuickBooks Desktop

Some QuickBooks Desktop users have unexpectedly large amounts of data. In addition, QuickBooks Desktop is slow and memory-intensive. Without proper limits or pagination, a request might inadvertently retrieve tens of thousands of rows, which can take many minutes to return. To avoid overwhelming QuickBooks Desktop, you may need to split your requests into smaller chunks. This process is called **pagination**.

## Pagination via the Node.js client library

Cursor-based pagination is not yet supported in the Node.js client library. Instead, we recommend batching your requests by date range and concatenating the results. This will avoid overwhelming QuickBooks Desktop by requesting only a subset of the data at a time.

For example, the following fetches all invoices from the provided date range in yearly batches:

```ts Fetch invoices in yearly batches
import Conductor, { QbdTypes } from "conductor-node";

async function getQbdInvoices(
  endUserId: string,
  startDate: string,
): Promise<QbdTypes.InvoiceRet[]> {
  const conductor = new Conductor("{{YOUR_SECRET_KEY}}");

  const startYear = new Date(startDate).getFullYear();
  const endYear = new Date().getFullYear();

  // Fetch invoices in yearly batches to avoid overwhelming QuickBooks Desktop
  // because some users have tens of thousands of invoices.
  const allInvoices: QbdTypes.InvoiceRet[] = [];
  for (let year = startYear; year <= endYear; year++) {
    const yearStartDate = year === startYear ? startDate : `${year}-01-01`;
    const yearEndDate = `${year}-12-31`;

    const yearInvoices = await conductor.qbd.invoice.query(endUserId, {
      TxnDateRangeFilter: {
        FromTxnDate: yearStartDate,
        ToTxnDate: yearEndDate,
      },
    });

    allInvoices.push(...yearInvoices);
  }
  return allInvoices;
}
```

## Pagination via the REST API

If you are using the REST API directly, you can paginate requests by following the instructions below.

### Initiating pagination

To paginate a QuickBooks Desktop query, include the `MaxReturned` parameter in your request body, specifying the maximum number of records you want to receive in a single response. If the total number of records exceeds `MaxReturned`, the response will include two additional fields:

1.  `IteratorID`: A unique identifier for the current query.
2.  `IteratorRemainingCount`: The number of records remaining to be fetched.

Here's an example of a pagination request:

```sh Start pagination request with MaxReturned
curl -X POST https://api.conductor.is/v1/end-users/{{END_USER_ID}}/request/quickbooks_desktop \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer {{YOUR_SECRET_KEY}}" \
  -d '{
    "InvoiceQueryRq": {
      "MaxReturned": 2
    }
  }'
```

And here's an example of a pagination response:

```json Example pagination response with IteratorID and IteratorRemainingCount
{
  "InvoiceQueryRs": {
    "IteratorID": "fce6b40f-9700-435b-949c-f2587af31536",
    "IteratorRemainingCount": 0,
    "InvoiceRet": [
      {
        "TxnID": "4E4-1703631996",
        "TimeCreated": "2021-01-01T00:00:00Z",
        "CustomerRef": {
          "ListID": "80000020-1703631977",
          "FullName": "Alice"
        },
        "RefNumber": "INV-1",
        "IsPaid": true,
        "TotalAmount": 100
      },
      {
        "TxnID": "4E4-1703631997",
        "TimeCreated": "2021-01-02T00:00:00Z",
        "CustomerRef": {
          "ListID": "80000020-1703631978",
          "FullName": "Bob"
        },
        "RefNumber": "INV-2",
        "IsPaid": false,
        "TotalAmount": 200
      }
    ]
  }
}
```

### Continuing pagination

**If `IteratorRemainingCount` is greater than 0**, send another request with the same request body as the previous request, but include the `IteratorID` parameter on the root level of the request body, set to the value from the previous response.

<Note>
  The parameter `IteratorID` goes on the root level of the request body, not
  inside the query object.
</Note>

```sh Continue pagination request with IteratorID
curl -X POST https://api.conductor.is/v1/end-users/{{END_USER_ID}}/request/quickbooks_desktop \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer {{YOUR_SECRET_KEY}}" \
  -d '{
    // ❗ `IteratorID` is at root level of the request body
    "IteratorID": "fce6b40f-9700-435b-949c-f2587af31536",
    "InvoiceQueryRq": {
      "MaxReturned": 1000
    }
  }'
```

### Considerations

*   **The iterator can only be used within the same QuickBooks Web Connector session, which we keep open for 10 seconds.** If the iterator is not used within that time, you will receive an error. Therefore, you must implement the pagination logic programmatically in your backend to ensure that the iterator is used within the 3-second window.
    *   The short expiry is due to how the QuickBooks Web Connector handles pagination. Upon the initial request, the QuickBooks Web Connector requests the entire result set from QuickBooks Desktop, stores it in local memory, and returns only the first batch. As a result, the first request will take longer because QBD must process and assemble the entire result set. Subsequent requests will return immediately.
*   If you attempt to use the iterator after the previous request returned `IteratorRemainingCount` of `0`, you will receive an error.


# REST API for QuickBooks Desktop

If your backend does not use Node.js, you can use the REST API to interface with QuickBooks Desktop directly.

If your backend is not in Node.js, you can use the REST API that powers our Node.js library to send requests to QuickBooks Desktop. To do so, we *strongly* recommend following the guide below to **set up Node.js and TypeScript locally to *test* Conductor, and enable verbose logging to see the REST API request format**, which you can then copy and paste to your backend. This approach enables you to easily determine the APIs and parameters you need by leveraging the client library's type-safety, autocomplete, and inline docs.

Skip to Step 10 below to see the REST API request format.

<Warning>
  We are actively working on a complete rewrite of our REST API for QuickBooks Desktop that is much more powerful and much simpler. Available in Q1 2025.

  In the meantime, use the approach documented below, which will be backward-compatible and easily adaptable to the new REST API when it is released.
</Warning>

<Tip>
  Check out this [Python example for creating an
  invoice](/qbd-examples/invoices#creating-invoices) in QuickBooks Desktop using
  Conductor's REST API.
</Tip>

## Build your REST API requests with Node.js locally and Conductor

This guide will show you how to easily generate the REST API request format for QuickBooks Desktop using Node.js and Conductor in your local environment. You can then replicate the REST API request format in your backend.

<Steps>
  <Step title="Install Node.js locally if you do not have it already">
    If you are on a Mac:

    ```sh
    brew install node
    ```
  </Step>

  <Step title="Create a new directory">
    ```sh
    mkdir conductor-test
    cd conductor-test
    ```
  </Step>

  <Step title="Initialize a new Node.js project">
    ```sh
    npm init -y
    ```
  </Step>

  <Step title="Install TypeScript and Conductor's Node.js library">
    ```sh
    npm install conductor-node typescript @types/node
    ```
  </Step>

  <Step title="Create a new TypeScript file">
    ```sh
    touch index.ts
    ```
  </Step>

  <Step title="Follow our quickstart guide if you haven't yet">
    If you haven't already, follow our [quickstart guide](/overview/quickstart) to create an EndUser with an authorized connection to a QuickBooks Desktop instance.
  </Step>

  <Step title="Add the following code to your `index.ts` file">
    ```typescript
    import Conductor from "conductor-node";

    const conductor = new Conductor("{{YOUR_SECRET_KEY}}", {
      // ❗ Enable logging to see the REST API request format.
      verbose: true,
    });

    async function main() {
      // ❗ Replace `{{END_USER_ID}}` below with the ID of the EndUser
      // you created in the Quickstart guide.
      const invoices = await conductor.qbd.invoice.query("{{END_USER_ID}}", {
        IncludeLineItems: true,
        MaxReturned: 5,
      });
    };

    main();
    ```
  </Step>

  <Step title="Run the code">
    ```sh
    npx ts-node index.ts
    ```
  </Step>

  <Step title="Review the output">
    You will see the complete REST API request format in the output. For example:

    ```ts
    Conductor request: {
      method: 'POST',
      url: 'https://api.conductor.is/v1/end-users/{{END_USER_ID}}/request/quickbooks_desktop',
      headers: {
        'Content-Type': 'application/json',
        Authorization: 'Bearer sk_live_************',
      },
      body: {
        InvoiceQueryRq: {
          IncludeLineItems: true,
          MaxReturned: 3
        }
      }
    }
    ```
  </Step>

  <Step title="Replicate the REST API request format in your backend">
    For example, with `curl`:

    ```sh
    curl -X POST https://api.conductor.is/v1/end-users/{{END_USER_ID}}/request/quickbooks_desktop \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer {{YOUR_SECRET_KEY}}" \
      -d '{
        "InvoiceQueryRq": {
          "IncludeLineItems": true,
          "MaxReturned": 3
        }
      }'
    ```
  </Step>
</Steps>


# Create a QuickBooks Desktop test instance

Create your own QuickBooks Desktop test instance with an AWS WorkSpace.

export const Image = ({src, alt, width, shadow = true, border = true}) => <img src={`https://mintlify.s3-us-west-1.amazonaws.com/conductor${src}`} alt={alt} width={width} className={`mx-auto rounded-xl ${border ? "border border-gray-200 dark:border-0" : ""} ${shadow ? "shadow-md dark:shadow-none" : ""}`} />;

To develop and test integrations with Conductor, you need your own QuickBooks Desktop instance to send and receive data. If you don't have an existing instance, this guide outlines a one possible approach for setting up a dedicated QuickBooks Desktop test environment. We will guide you through the process of creating a virtual Windows instance using AWS WorkSpaces and installing the QuickBooks Desktop free trial. Once set up, you can connect your local development environment to this test instance via Conductor, enabling you to validate your integration without impacting production data.

## 1. Set up a virtual Windows environment

<AccordionGroup>
  <Accordion title="1. Create an Amazon Workspace">
    Create a new Amazon WorkSpace at [https://us-west-2.console.aws.amazon.com/workspaces/v2/workspaces](https://us-west-2.console.aws.amazon.com/workspaces/v2/workspaces).

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/1.1.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="2. Create a new Directory">
    Either select the directory in the list or click `Create a new Directory` if there are none:

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/1.2.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="3. Add yourself as a user">
    Add yourself as a user with your email address:

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/1.3.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="4. Select the bundle">
    Select the bundle `Standard with Windows 10 (Server 2019 based) (PCoIP)`:

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/1.4.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="5. Select AlwaysOn">
    Select `AlwaysOn`:

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/1.5.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="6. Skip the Customization step">
    Skip the Customization step, then review the final page and click the button `Create` in the bottom-right corner:

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/1.6.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="7. Set a password">
    After 20-30 minutes, look for an email from Amazon WorkSpaces with a link to set a password.
  </Accordion>

  <Accordion title="8. Download Amazon WorkSpaces">
    Download Amazon WorkSpaces on your local computer:

    ```sh
    brew install amazon-workspaces
    ```
  </Accordion>

  <Accordion title="9. Open the WorkSpaces app">
    Open the WorkSpaces app, enter the registration key from the email, and sign in using the username and password you set via the reset link in the email. You must enter this password every time you open WorkSpaces, so best to save it to your local password manager.

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/1.7.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="10. Connect to your new Windows desktop instance">
    After it loads, you will see your new Windows desktop instance!

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/1.8.jpg" style={{ width: "600px" }} />
  </Accordion>
</AccordionGroup>

## 2. Disable IE Enhanced Security Configuration

By default, you will see the following warning whenever you open QuickBooks Desktop. If you do not resolve this issue, this warning will freeze QuickBooks Desktop whenever the QuickBooks Web Connector opens QuickBooks Desktop when it is closed.

<Image src="/images/qbd/test-instance/2.1.jpg" alt="Windows error - Internet security levels are set too high" width="500" />

To prevent this error, follow these steps:

<AccordionGroup>
  <Accordion title="1. Open the Server Manager">
    Search for and open Server Manager:

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/2.2.jpg" style={{ width: "300px" }} />

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/2.3.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="2. Choose Local Server">
    Choose `Local Server` from the left navigation pane:

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/2.4.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="3. Open settings for IE Enhanced Security Configuration">
    For `IE Enhanced Security Configuration`, click the button that says `On`:

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/2.5.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="4. Turn off IE Enhanced Security Configuration">
    For Administrators, select `Off`. For Users, select `Off`. Choose `OK`. Then
    you are done!

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/2.6.jpg" style={{ width: "600px" }} />
  </Accordion>
</AccordionGroup>

## 3. Install QuickBooks Desktop

<AccordionGroup>
  <Accordion title="1. Download the QuickBooks Desktop Enterprise trial">
    From the Windows instance, open Firefox and download the QuickBooks Desktop
    Enterprise trial:
    [https://quickbooks.intuit.com/learn-support/en-us/new-subscriptions/download-a-trial-of-quickbooks-desktop/00/185974](https://quickbooks.intuit.com/learn-support/en-us/new-subscriptions/download-a-trial-of-quickbooks-desktop/00/185974)
  </Accordion>

  <Accordion title="2. Open the installer">
    Navigate to the "Downloads" directory in the Windows File Explorer, and
    launch the application named `QuickBooksEnterprise23Trial.exe`. Then, walk
    through the installation.

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/3.1.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="3. Install QuickBooks Desktop">
    After that installation finishes, another installer should launch
    automatically. Walk through that installer, too. This can take 20-30 minutes
    to finish.

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/3.2.jpg" style={{ width: "600px" }} />

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/3.3.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="4. Select the correct variant">
    Next, the following window will appear. Select the variant `QuickBooks
            Desktop Enterprise General Business`:

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/3.4.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="5. Create a mock company file">
    Click "I want to see a Sample company file", which will provide a mock
    dataset for you to use with QuickBooks Desktop. If this option does not
    work, which sometimes happens, then click "I'm ready to create my own
    company file" to create a new, empty company file.

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/3.5.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="6. Sign in to your Intuit developer account">
    If prompted, sign in to your Intuit developer account in QuickBooks Desktop.
    If you do not have one, [you can create account
    here](https://accounts.intuit.com/app/sign-in?start_screen_hint=SignUp).

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/3.6.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="7. Open the company file">
    When you are done, you will see the QuickBooks Desktop interface:

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/3.7.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="8. Create a password for the company file">
    At some point, QuickBooks Desktop might ask you to create a password.
    Conductor will not ask for this password; it is internal to QuickBooks
    Desktop.

    <img src="https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/qbd/test-instance/3.8.jpg" style={{ width: "600px" }} />
  </Accordion>

  <Accordion title="9. Get a free developer (NFR) license">
    The trial installation will work for 30 days, after which you will need a
    developer (NFR) license, which you can [get for free by following our
    guide](/qbd/dev-license.mdx). After completing that guide, you can continue
    to use the trial version while you wait for your NFR license to arrive.
  </Accordion>
</AccordionGroup>

## 4. Connect Conductor to your QuickBooks Desktop instance

Now that you have your own QuickBooks Desktop test instance, you can return to the [Quickstart](/overview/quickstart) guide to connect it to Conductor. Don't worry; this part is much easier.


# Connect your users via the auth flow

Enable your users to securely connect their QuickBooks Desktop to your application.

The authentication flow in Conductor is a user interface walkthrough that allows your users to securely connect their QuickBooks Desktop installation to their Conductor account. For an example, check out this [demo of the auth flow](https://connect.conductor.is/qbd/demo).

There are two main approaches to integrating the auth flow with your application:

1.  Integrate the auth flow with your backend to manage multiple users and connections.
2.  Generate shareable auth links for getting started quickly or one-off connections.

## Integrate the auth flow with your backend

If you are building a multi-user service where each user needs to connect their QuickBooks Desktop account to your application, you'll want to integrate Conductor's QuickBooks Desktop auth flow into your backend.

<Steps>
  <Step title="Create an EndUser">
    Consider you have an end-user of your application who needs to connect their QuickBooks Desktop to your application. Begin by creating an EndUser for that user and saving their `id` to your database. You will use this `id` to match your users to their corresponding QuickBooks Desktop connection in Conductor.

    <Tip>
      If your database has a `users` table, consider creating a column called `conductor_end_user_id`.
    </Tip>

    ```ts Create an EndUser
    import Conductor from "conductor-node";
    const conductor = new Conductor("{{YOUR_SECRET_KEY}}");

    // Replace the placeholders with your actual data.
    const endUser = await conductor.endUsers.create({
      companyName: "{{END_USER_COMPANY_NAME}}",
      sourceId: "{{UNIQUE_ID_FROM_YOUR_DB}}",
      email: "{{END_USER_EMAIL}}",
    });

    // Save the EndUser ID to your database.
    await db.users.update({
      conductorEndUserId: endUser.id,
    });
    ```
  </Step>

  <Step title="Check if the EndUser has an active QuickBooks Desktop connection">
    The next step is to initiate an AuthSession for your user to connect their QuickBooks Desktop. However, what if they already has an active connection? Or, what if they previously started the auth flow but didn't complete it?

    Imagine your application has a web app where your users configure the integrations with their application. If you create a section for the QuickBooks Desktop integration, you can use the following approach to track whether an active connection already exists:

    ```ts Check the connection status
    try {
      // Ping to check the connection status.
      await conductor.endUsers.ping("{{END_USER_ID}}", "quickbooks_desktop");
      updateUI("QuickBooks Desktop is successfully connected!");
    } catch (error) {
      if (error instanceof ConductorIntegrationConnectionError) {
        if (error.code === "INTEGRATION_CONNECTION_NOT_SET_UP") {
          // Initiate an AuthSession if the user never started or completed the auth flow.
          const authSession = await conductor.authSessions.create({
            publishableKey: "{{YOUR_PUBLISHABLE_KEY}}",
            endUserId: "{{END_USER_ID}}",
          });
          updateUI("Set up your QuickBooks Desktop connection: " + authSession.authFlowUrl);
        } else {
          // Display connection errors for your user to resolve.
          updateUI("An error occurred: " + error.userFacingMessage);
        }
      } else {
        throw error;
      }
    }
    ```

    ***Note:** Replace `updateUI()` with your actual code that updates your application's UI based on the status or errors received.*
  </Step>
</Steps>

## Create a shareable auth flow link

For a quick start, particularly useful for pilot deployments or small-scale operations, generate a secure, shareable link for the QuickBooks Desktop auth flow:

<Steps>
  <Step title="Create an EndUser">
    If you haven't already done so, create an EndUser and save their `id`. You will use this `id` to authenticate future requests.

    <CodeGroup>
      ```ts Node.js
      import Conductor from "conductor-node";
      const conductor = new Conductor("{{YOUR_SECRET_KEY}}");

      // Replace these placeholders with your own values.
      const endUser = await conductor.endUsers.create({
        companyName: "{{END_USER_COMPANY_NAME}}",
        sourceId: "{{UNIQUE_ID_FROM_YOUR_DB}}",
        email: "{{END_USER_EMAIL}}",
      });
      console.log("Save this EndUser ID to auth future requests:", endUser.id);
      ```

      ```sh cURL
      curl -X POST https://api.conductor.is/v1/end-users \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer {{YOUR_SECRET_KEY}}" \
        -d '{
              "companyName": "{{END_USER_COMPANY_NAME}}",
              "sourceId": "{{UNIQUE_ID_FROM_YOUR_DB}}",
              "email": "{{END_USER_EMAIL}}"
            }'
      ```
    </CodeGroup>
  </Step>

  <Step title="Create an AuthSession">
    Using the EndUser ID, create an AuthSession with an extended link expiry time if needed:

    <CodeGroup>
      ```ts Node.js
      import Conductor from "conductor-node";
      const conductor = new Conductor("{{YOUR_SECRET_KEY}}");

      const authSession = await conductor.authSessions.create({
        publishableKey: "{{YOUR_PUBLISHABLE_KEY}}",
        endUserId: "{{END_USER_ID}}",
        linkExpiryMins: 60 * 24, // 24 hours
      });
      console.log("Send this link to your customer to complete the auth flow:", authSession.authFlowUrl);
      ```

      ```sh cURL
      curl -X POST https://api.conductor.is/v1/auth-sessions \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer {{YOUR_SECRET_KEY}}" \
        -d '{
              "publishableKey": "{{YOUR_PUBLISHABLE_KEY}}",
              "endUserId": "{{END_USER_ID}}",
              "linkExpiryMins": 1440
            }'
      ```
    </CodeGroup>
  </Step>

  <Step title="Share the auth flow link">
    Share the generated `authFlowUrl` with your end-user to direct them to the auth flow to connect their QuickBooks Desktop instance to your application.

    The link will resemble this mock example:

    ```
    https://connect.conductor.is/qbd/auth_sess_client_secret_1234567abcdefg?key={{YOUR_PUBLISHABLE_KEY}}
    ```
  </Step>
</Steps>


# Autocomplete

Use Conductor's built-in autocomplete to discover all available APIs, requests parameters, and response fields.

We highly recommend using [Conductor's client library](https://github.com/conductor-is/quickbooks-desktop-api) because it has built-in autocomplete and documentation for every API, request parameter, and response field. This feature is especially helpful for working with the QuickBooks Desktop API.

The following examples show the autocomplete in action in VS Code, though this works in any modern editor.

#### QuickBooks Desktop object types

<Frame caption="Use autocomplete to see the available QuickBooks Desktop object types (e.g. `customer`, `invoice`, `account`, etc.).">
  ![Conductor autocomplete for QuickBooks Desktop object
  types](https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/usage/autocomplete/qbd-object-types.jpg)
</Frame>

#### Request parameters

<Frame caption="Use autocomplete to see each method's request parameters.">
  ![Conductor autocomplete for QuickBooks Desktop request
  parameters](https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/usage/autocomplete/qbd-request-parameters.jpg)
</Frame>

#### Response fields

<Frame caption="Use autocomplete to see each method's response fields.">
  ![Conductor autocomplete for QuickBooks Desktop response
  fields](https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/usage/autocomplete/qbd-response-fields.jpg)
</Frame>

#### Enum values

<Frame caption="Use autocomplete to see the available enum values for each request parameter.">
  ![Conductor autocomplete for QuickBooks Desktop enum
  values](https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/usage/autocomplete/qbd-enum-values.jpg)
</Frame>

#### Inline documentation for request parameters

<Frame caption="Hover over each QuickBooks Desktop request parameter to see its description.">
  ![Conductor inline documentation for QuickBooks Desktop request
  parameters](https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/usage/autocomplete/qbd-docs-request-parameters.jpg)
</Frame>

#### Inline documentation for response fields

<Frame caption="Hover over each QuickBooks Desktop request parameter or response field to see its description.">
  ![Conductor inline documentation for QuickBooks Desktop response
  fields](https://mintlify.s3-us-west-1.amazonaws.com/conductor/images/usage/autocomplete/qbd-docs-response-fields.jpg)
</Frame>


# Check an EndUser's connection status



Sometimes, it is useful to check whether an EndUser's IntegrationConnection is working. For example, you might want to display a "connection status" indicator in your app's UI.

To do this, you can use the [method `conductor.endUsers.ping()`](/apis/end-users/ping) to check whether the specified IntegrationConnection can connect and process requests end-to-end. If an error occurs, we strongly recommend displaying [the property `error.userFacingMessage`](/usage/error-handling#user-facing-error-messages) to your EndUser in your app's UI because it contains instructions for how your EndUser can resolve the error.

<CodeGroup>
  ```ts Node.js
  try {
    await conductor.endUsers.ping(endUserId, "quickbooks_desktop");
  } catch (error) {
    if (error instanceof ConductorError) {
      // Update your app's UI to display `error.userFacingMessage`, which explains
      // that the connection is failing and how to resolve the error.
    }
    // ...
  }
  ```

  ```sh cURL
  curl -X GET https://api.conductor.is/v1/end-users/{{END_USER_ID}}/ping/quickbooks_desktop \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer {{YOUR_SECRET_KEY}}"
  ```
</CodeGroup>


# Error handling

Catch and respond to connection errors, invalid requests, data problems, and more.

One of the most complicated aspects of QuickBooks Desktops is its error handling. QuickBooks's errors are often cryptic and unhelpful, and they can arise from several sources (e.g., Web Connector, QB request processor, QuickBooks Desktop itself), each using a different format and mechanism. Sometimes, their errors do not even describe what went wrong when they could! **Conductor unifies and simplifies these errors into a single, consistent error format and augments each with our own user-friendly language that describes how to resolve the issue.**

With Conductor, every error is an instance of [ConductorError](/apis/errors/object), each with plenty of useful information.

## Error types

Any error object you receive will be an instance of one of the following error types:

| Name                                  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ConductorIntegrationError`           | Raised when the third-party integration encounters an error while processing the end-user's request. This often results from an issue with the request or data handling that requires your attention to resolve.<br /><br />E.g., a `ListID` you provided was not found in QuickBooks Desktop, or an accounting value you supplied did not adhere to the integration's accounting rules.<br /><br />Refer to `error.integrationCode` for the error code returned by the integration, if available.                                                                                                                                                                                                                |
| `ConductorIntegrationConnectionError` | Raised when a connection error occurs with the third-party integration on the end-user's side. This typically indicates an issue with the end-user's IntegrationConnection or configuration, which they must resolve. In other words, you cannot take action to fix these errors.<br /><br />E.g., QuickBooks Web Connector (QBWC) failed to connect to QuickBooks Desktop on the end-user's computer.<br /><br />Refer to `error.integrationCode` for the error code returned by the integration connector, if available.<br /><br />❗ We recommend *not* triggering alerts for these errors because only the end-user can fix them. See [Global error handling](#global-error-handling) for an example of this. |
| `ConductorInvalidRequestError`        | Raised when you make an API call with the wrong parameters, in the wrong state, or in an invalid way.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `ConductorAuthenticationError`        | Raised when Conductor cannot authenticate you with the credentials you provided. E.g., an incorrect API key.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `ConductorPermissionError`            | Raised when you attempt to access a resource that is not allowed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `ConductorConnectionError`            | Raised when there was a network problem between the client (on your server) and Conductor's servers. E.g., a downed network or a bad TLS certificate.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `ConductorInternalError`              | Raised when something went wrong on Conductor's end. (These are rare.)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |

## User-facing error messages

Every [ConductorError](/apis/errors/object) includes two error messages, and you should use both:

1.  `error.message`: The technical error message that you should log for debugging.
2.  `error.userFacingMessage`: The descriptive user-friendly error message explicitly written for the end-user that often contains instructions helping the end-user resolve the issue.

<Note>
  Your app's UI should display `error.userFacingMessage` to your end-users for
  every `ConductorError` while logging the full `error` object for your
  debugging purposes.
</Note>

For example, see the `message` and `userFacingMessage` in the following QBD connection error:

```ts Example ConductorError
{
  // The developer-facing error message, which includes the QBD-provided
  // error code and the QBD-provided error message.
  message: `QBD Connection Error (0x80040420): The QuickBooks user has
    denied access.`,
  // The user-facing error message with instructions for the end-user to
  // resolve the issue.
  userFacingMessage: `We could not connect to QuickBooks Desktop because
    we must re-authorize our connection. To fix this, open QuickBooks
    Desktop, log in as Admin, navigate to "Edit > Preferences >
    Integrated Applications", click "Company Preferences", select our
    app, click "Properties...", ensure "Allow this application to log in
    automatically" is checked, then click "OK". Then try again.`,
  ...
  // Other properties omitted for example.
}
```

## Specific error handling

If you need special handling for specific errors, you can wrap individual API calls, as shown below.

Using `async`/`await`:

```ts
try {
  const newAccount = await conductor.qbd.account.add(endUserId, {
    Name: "Test Account",
    AccountType: "Bank",
    OpenBalance: "100",
  });
} catch (error) {
  if (error instanceof ConductorError) {
    // Check `error.code`, `error.integrationCode`, etc., for special handling.
  } else {
    // ...
  }
}
```

Or in the form of a rejected promise:

```ts
conductor.qbd.account
  .add(endUserId, {
    Name: "Test Account",
    AccountType: "Bank",
    OpenBalance: "100",
  })
  .then((newAccount) => {
    // ...
  })
  .catch((error) => {
    if (error instanceof ConductorError) {
      // Check `error.code`, `error.integrationCode`, etc., for special handling.
    } else {
      // ...
    }
  });
```

## Global error handling

It is unnecessary to wrap each API call individually, as demonstrated in the examples above. Instead, we suggest implementing a global error handler for your server, such as [`app.use((error, ...) => { ... })` in Express](https://expressjs.com/en/guide/error-handling.html#writing-error-handlers) or [`formatError` in Apollo Server](https://apollographql.com/docs/apollo-server/data/errors/#for-client-responses). Within this handler, perform the following actions:

1.  For any `ConductorError` instance, display the `error.userFacingMessage` property to the end-user in your app's UI while logging the complete error object.
2.  For all `ConductorError` instances, transmit the full error object to your error-tracking service (e.g., Sentry):
    *   Send a **warning** for instances of `ConductorIntegrationConnectionError`, which are not actionable by you and can only be resolved by the end-user; for example, failure to connect to QuickBooks Desktop on the end-user's computer.
    *   Send an **error** for all other `ConductorError` instances, such as an invalid API key.

For example, using an [Express error handler](https://expressjs.com/en/guide/error-handling.html#writing-error-handlers):

```ts
import * as Sentry from "@sentry/node";
import {
  ConductorError,
  ConductorIntegrationConnectionError,
} from "conductor-node";

app.use((error, req, res, next) => {
  if (error instanceof ConductorError) {
    Sentry.captureException(error, {
      level:
        error instanceof ConductorIntegrationConnectionError
          ? "warning"
          : "error",
    });
    // Return a different error message for your end-user to see in your
    // app's UI.
    res.status(500).send({ error: { message: error.userFacingMessage } });
  } else {
    // ...
  }
});
```

Or using [Apollo Server's error handler](https://apollographql.com/docs/apollo-server/data/errors/#for-client-responses):

```ts
import { ApolloServer } from "@apollo/server";
import { unwrapResolverError } from "@apollo/server/errors";
import * as Sentry from "@sentry/node";
import {
  ConductorError,
  ConductorIntegrationConnectionError,
} from "conductor-node";

const server = new ApolloServer({
  // ...
  formatError: (formattedError, error) => {
    const origError = unwrapResolverError(error);
    if (origError instanceof ConductorError) {
      Sentry.captureException(origError, {
        level:
          origError instanceof ConductorIntegrationConnectionError
            ? "warning"
            : "error",
      });
      return {
        ...formattedError,
        // Return a different error message for your end-user to see in
        // your app's UI.
        message: origError.userFacingMessage,
      };
    }
    // ...
    return formattedError;
  },
});
```


# API keys

Use API keys to authenticate API requests.

Conductor authenticates your API requests using your account's API keys. If a request does not include a valid key, Conductor returns an invalid request error.

## Secret and publishable keys

Every Conductor account has two API keys:

1.  **Secret key:** Use this key to authenticate requests to Conductor's API from your server-side code. It is highly sensitive and should be deleted if leaked. Store this key securely in your server, such as in an environment variable or a credential management system. Do not store this key in Git, include it in client-side code, or expose it on a website.

2.  **Publishable key:** Use this key when [creating an AuthSession](/apis/auth-sessions/create), which generates the unique [auth flow](/usage/auth-flow) URL for your end-user. Unlike the secret key, the publishable key can be safely shared, stored in Git, or included in client-side code.