# Connection status and health checks
Source: https://www.desktopaccountingapi.com/docs/connect/connection-status/

> What each connection status means, how to run a health check before a sync, and how to show connection problems to your customers.

A QuickBooks Desktop connection depends on a computer you do not control. It can be switched off, QuickBooks can be showing a dialog, or someone can open a different company file. Two tools tell you what is going on: the connection `status` on the end user, which costs nothing to read, and the health check, which makes a real round trip to QuickBooks.

## Connection statuses

Read the status from `integrationConnections[0].status` on `GET /v1/end-users/{id}`.

| Status | Meaning | What to do |
| --- | --- | --- |
| `pending_setup` | No Web Connector has finished setup yet. | Send the customer a [setup link](https://www.desktopaccountingapi.com/docs/connect/setup-flow/). |
| `online` | The Web Connector checked in within the last minute and the last QuickBooks session opened successfully. | Nothing. Requests should work. |
| `offline` | No Web Connector check-in for more than 60 seconds. The computer is off or asleep, the Windows user signed out, or the Web Connector was closed. | Ask the customer to follow [Connection not active](https://www.desktopaccountingapi.com/docs/help/connection-errors/connection-not-active/). |
| `quickbooks_unavailable` | The Web Connector checks in, but the last two attempts to open QuickBooks failed, or QuickBooks has not answered an open session for 20 seconds. `statusReason` holds the error code, for example `QBD_CANNOT_START` or `QBD_QUICKBOOKS_NOT_RESPONDING` (usually a dialog open in QuickBooks). | Show the matching help page; see [the error code](https://www.desktopaccountingapi.com/docs/errors/) and [request diagnosis](https://www.desktopaccountingapi.com/docs/troubleshooting/) for the fix. |
| `company_file_mismatch` | QuickBooks opened a company file that is not the one this connection was set up with. | See [Company file mismatch](#company-file-mismatch). |
| `disabled` | You disabled the connection in the dashboard. | Enable it again in the dashboard. |

The list can grow, so treat unknown values like `offline` rather than failing.

`statusReason` is `null` when there is nothing more to say. Besides error codes, it can be `WEB_CONNECTOR_SCHEDULE_CHANGED`: the Web Connector checks in less often than once a minute, which usually means someone typed a number into the **Every-Min** column. Requests still work, but each one can wait minutes for the next check-in. The fix is in [Web Connector settings to keep](https://www.desktopaccountingapi.com/docs/help/guides/change-connection-settings/).

> **Caution:**
> `online` describes the last few seconds, not the next request. A computer can go to sleep between your status read and your call. When it matters, run a health check, or simply make the call and handle the error.

## Health checks

`GET /v1/quickbooks-desktop/health-check` sends a small request through the Web Connector, has QuickBooks open the company file and read company information, and returns:

```json
{
  "status": "ok",
  "duration": 812,
  "quickbooks": {
    "product": "QuickBooks Enterprise Solutions: General Business 24.0",
    "qbxmlVersion": "16.0",
    "companyName": "Acme Supply Co"
  }
}
```

`duration` is the round trip in milliseconds. On failure you get the same structured errors as any QuickBooks call.

**TypeScript**

```ts
import { DesktopAccountingApi, ApiError } from "@desktopaccountingapi/quickbooks-desktop";

const qb = new DesktopAccountingApi().forEndUser("eu_01j9...");

try {
  const health = await qb.qbd.healthCheck();
  console.log(`Connected to ${health.quickbooks.companyName} in ${health.duration} ms`);
} catch (err) {
  if (err instanceof ApiError && err.code === "INTEGRATION_CONNECTION_NOT_SET_UP") {
    // Show the "Connect QuickBooks Desktop" button with a new setup link.
  } else if (err instanceof ApiError) {
    // Show err.userFacingMessage to your customer.
  } else {
    throw err;
  }
}
```

**Python**

```python
from desktopaccountingapi import APIError, DesktopAccountingApi

qb = DesktopAccountingApi().for_end_user("eu_01j9...")

try:
    health = qb.qbd.health_check()
    print(f"Connected to {health.quickbooks.company_name} in {health.duration} ms")
except APIError as err:
    if err.code == "INTEGRATION_CONNECTION_NOT_SET_UP":
        pass  # Show the "Connect QuickBooks Desktop" button with a new setup link.
    else:
        print(err.user_facing_message)  # Show it to your customer.
```

**curl**

```sh
curl https://api.desktopaccountingapi.com/v1/quickbooks-desktop/health-check \
  -H "Authorization: Bearer $DAAPI_SECRET_KEY" \
  -H "Daapi-End-User-Id: eu_01j9..."
```

The health check waits up to 60 seconds by default, because a cold connection may need the next Web Connector check-in and, with "always allow" access, a QuickBooks start. Send `Daapi-Timeout-Seconds` to wait less. When the Web Connector has not checked in recently, the health check fails within a second with `503 INTEGRATION_CONNECTION_NOT_ACTIVE` instead of waiting.

Health checks are free: they never count toward billing, and they keep working when billing blocks production data requests.

### When to run one

- Before a sync that the customer starts with a button, so you can show a clear message instead of a half-finished sync.
- When the customer opens your QuickBooks settings page, to show "Connected to Acme Supply Co" or the problem.
- After the setup flow returns with `status=completed`.

You do not need to run one before every request. A failing request returns the same error a health check would.

## Showing problems to your customers

Connection errors have `type: "INTEGRATION_CONNECTION_ERROR"`. They are about the customer's computer, not your code, so:

- Show `userFacingMessage`. It is written for the person at the QuickBooks computer and says what to do, such as closing a dialog in QuickBooks.
- Link the matching page in our [help center](https://www.desktopaccountingapi.com/docs/help/). Each error code in the [error reference](https://www.desktopaccountingapi.com/docs/errors/) lists its help page.
- Log these errors as warnings. Paging your on-call engineer because a customer's PC is asleep helps nobody.
- Retry later when `retryable` is `true`. Many of these clear on their own, such as `QBD_STARTING` while QuickBooks opens.

## Company file mismatch

Each connection remembers which company it was set up with. When QuickBooks opens a different company file, we stop and report it instead of reading or writing the wrong books:

- `QBD_WRONG_COMPANY_FILE_OPEN` (`503`, retryable): another company file is open in QuickBooks right now. It clears when the right file is open again. Sometimes we infer it: when QuickBooks refuses to open the stored file through the Web Connector (`0x80040408`), the error carries `details.inferred: true`, and the next session checks which file is actually open.
- `QBD_COMPANY_FILE_MISMATCH` (`409`, not retryable): the file at the stored location now reports a different company identity, for example after someone restored a different backup over it.

While the status is `company_file_mismatch`, the end user object and the dashboard show the last file QuickBooks reported, with its name, location and time. To fix it, ask your customer which file is right, have them open it in QuickBooks, then reset the connection:

```sh
curl https://api.desktopaccountingapi.com/v1/end-users/eu_01j9.../reset-company-file \
  -H "Authorization: Bearer $DAAPI_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode":"path","confirm":"reset_company_file"}'
```

- `mode: "path"` forgets the stored file location, for a file that was moved or renamed on disk. The next session uses the file open in QuickBooks, as long as it is the same company.
- `mode: "identity"` also forgets which company the connection belongs to, for a company that was renamed or a customer who deliberately switched files. The next file QuickBooks opens becomes the connected one.
- `confirm` must be `"reset_company_file"`, to show you checked with your customer. Queued requests stay queued.

The dashboard's **Reset company file path** button does the `path` reset, and your customer can do it themselves from a setup link by choosing **The company file moved or was renamed**.

The connection recognizes a company by a private marker it stores in the company file after setup, so moving the file or restoring a recent backup keeps it recognized. See [Custom fields](https://www.desktopaccountingapi.com/docs/quickbooks/custom-fields/#the-field-we-keep).

## Status change events

Subscribe to the [`connection.status_changed`](https://www.desktopaccountingapi.com/docs/guides/webhooks/#event-types) webhook to keep your own copy of the status current without polling. A status must hold for 30 seconds before an `offline` event fires, so a brief network drop does not wake anyone up.
