# SDKs
Source: https://www.desktopaccountingapi.com/docs/sdks/

> Official Desktop Accounting API SDKs for TypeScript, Python, C# / .NET and Java, and what each one handles for you.

Four official SDKs, generated from the same OpenAPI document as the [API reference](https://www.desktopaccountingapi.com/docs/api/reference/) and released together with the API:

| Language | Package | Install | Requires |
| --- | --- | --- | --- |
| [TypeScript / Node.js](https://www.desktopaccountingapi.com/docs/sdks/typescript/) | `@desktopaccountingapi/quickbooks-desktop` | `npm install @desktopaccountingapi/quickbooks-desktop` | Node.js 20 |
| [Python](https://www.desktopaccountingapi.com/docs/sdks/python/) | `desktopaccountingapi-quickbooks-desktop` | `pip install desktopaccountingapi-quickbooks-desktop` | Python 3.9 |
| [C# / .NET](https://www.desktopaccountingapi.com/docs/sdks/dotnet/) | `DesktopAccountingAPI.QuickBooksDesktop` | `dotnet add package DesktopAccountingAPI.QuickBooksDesktop` | .NET 8 or .NET Standard 2.0 |
| [Java](https://www.desktopaccountingapi.com/docs/sdks/java/) | `com.desktopaccountingapi:quickbooks-desktop` | Maven or Gradle | Java 11 |

## What every SDK does for you

The SDKs are thin over the REST API, but they implement the rules that are easy to get wrong by hand:

- **Same resource tree in every language.** `client.qbd.invoices.list(...)`, `client.endUsers.create(...)`, `client.requests.retrieve(...)`, with each language's naming style. Method names follow the operation IDs in the reference.
- **End-user scoping.** Pass the end user per call, or create a scoped client with `forEndUser("eu_...")`.
- **Idempotency keys.** Every write gets an `Idempotency-Key`, reused across that write's retries.
- **Safe retries.** Network errors before a response, `429`, and `5xx` responses marked retryable are retried with exponential backoff (0.5 to 8 seconds, honoring `Retry-After`), two retries by default. A response with `outcome` `pending` or `unknown` is never retried.
- **Pending requests.** When a sync call times out after QuickBooks received it (`504 QBD_REQUEST_TIMEOUT`), the SDK waits for the result through the request resource instead of resending.
- **Typed errors.** One error class per error type, with every field (`code`, `userFacingMessage`, `requestId`, `retryable`, `outcome`, `fixes`) available directly.
- **Auto-pagination** that requests the next page only when your loop needs it (a loop that stops early runs no extra QuickBooks query), reads ahead for slow loops to stay within QuickBooks' cursor window, a page-by-page mode, and a typed cursor-expired error that never restarts silently.
- **Exact money.** Amounts are decimal types in Python (`Decimal`), C# (`decimal`) and Java (`BigDecimal`), and decimal strings in TypeScript.
- **Key checks.** A mistyped key fails locally, before a network call, thanks to the checksum in every secret key.
- **Webhook verification** helpers for [signed webhooks](https://www.desktopaccountingapi.com/docs/guides/webhooks/).

## Configuration

| Option | Environment variable | Default |
| --- | --- | --- |
| API key | `DAAPI_SECRET_KEY` | none |
| Base URL | `DAAPI_BASE_URL` | `https://api.desktopaccountingapi.com` (a trailing `/v1` is accepted) |
| Timeout | | 100 seconds per HTTP attempt (the server's 90-second default plus 10) |
| Total timeout | | none; caps a whole call, retries and waiting included |
| Max retries | | 2 |
| Default headers | | none |
| End user | | none; set per call or with `forEndUser` |

## Porting from Conductor

Code written for Conductor's Node.js and Python SDKs runs on ours with two edits, the import and the API key: the resource tree, parameter names and response fields match, and the TypeScript and Python SDKs accept Conductor's `conductorEndUserId` / `conductor_end_user_id`, client option names and error class names. Each SDK page has a "Porting from Conductor" section, and [Migrating from Conductor](https://www.desktopaccountingapi.com/docs/get-started/migrating-from-conductor/) lists the API-level differences.

## Other languages

Any language with an HTTP client works with the REST API. You can also generate a client from the [OpenAPI document](https://www.desktopaccountingapi.com/docs/openapi.json). Generated clients do not implement the retry, idempotency and pagination rules above, so follow [Idempotency](https://www.desktopaccountingapi.com/docs/guides/idempotency/) and [Pagination](https://www.desktopaccountingapi.com/docs/guides/pagination/) when you write your own.
