---
url: /guides/use-the-quarzo-sdk.md
---
# Use the Quarzo SDK

Use this guide to call Quarzo from a Broker backend with the Quarzo SDK.
The SDK is a TypeScript client. It has one typed method for each Quarzo endpoint.

## Prerequisites

* Node.js 24 or later. Deno and Bun also work.
* A working token request, as [Call Quarzo from a Broker backend](/guides/call-quarzo-from-a-broker-backend) shows.
  The SDK does not get access tokens. Your backend gets them and gives them to the SDK.
* The API base URL of your environment. See [Environments](/topics/environments).

## 1. Install the SDK

The SDK is on JSR with the name `@quarzo-life/sdk`.

```bash
# npm
npx jsr add @quarzo-life/sdk

# pnpm
pnpm dlx jsr add @quarzo-life/sdk

# Deno
deno add jsr:@quarzo-life/sdk
```

## 2. Create a client

Put the token request of [Call Quarzo from a Broker backend](/guides/call-quarzo-from-a-broker-backend#_2-get-an-access-token) in a function `getAccessToken`.
The function returns the JSON body of the token response: `access_token` and `expires_in`.

Then create the client with the token:

```js
import { QuarzoSdk } from "@quarzo-life/sdk";

const createQuarzo = (accessToken) =>
  new QuarzoSdk({
    accessToken,
    baseURL: process.env.QUARZO_API_BASE_URL,
    version: "v1",
  });
```

The client sends `Authorization: Bearer <access_token>` with each request.
Each request has a timeout of 10 seconds. To change it, add `timeout` in milliseconds.

## 3. Renew the access token

A client keeps the token that you give it. It does not renew the token.
Before the token expires, get a new token and create a new client:

```js
let current;

const getQuarzo = async () => {
  if (!current || Date.now() >= current.renewAt) {
    const token = await getAccessToken();
    current = {
      quarzo: createQuarzo(token.access_token),
      // Renew one minute before the expiration.
      renewAt: Date.now() + (token.expires_in - 60) * 1000,
    };
  }
  return current.quarzo;
};
```

Use `getQuarzo()` before each call. Do not get a new token for each request.

## 4. Call an endpoint

The client has one module for each area of the API, for example `quarzo.authentication`, `quarzo.premiumScheduling` or `quarzo.brokerNotifications`.
Each module has one method for each endpoint. The [API reference](/api/) gives the endpoints and their request formats.

As a first call, read the current identity. This is the same check as `GET /v1/authentication/me`:

```js
const quarzo = await getQuarzo();
const me = await quarzo.authentication.getCurrentUser();

console.log(me.kind); // "brokerMachine"
```

### Commands and idempotency keys

A method that creates or changes data can have an `idempotencyKey` parameter.
Make the key before the first attempt, and keep it.
If the call fails because of a timeout or a network error, send the same call again with the same key.
Use a new key only for a new operation. See [Idempotent requests](/topics/idempotent-requests).

```js
import { randomUUID } from "node:crypto";

const idempotencyKey = randomUUID();
// Save the key with your operation, then call the method with it.
```

## 5. Handle errors

When Quarzo returns a status that is not `2XX`, the SDK throws a `QuarzoApiError`.
The error has the HTTP `status` and a list of `issues`. Each issue has a `code`, a `message` and a `doc_url`.

```js
import { QuarzoApiError } from "@quarzo-life/sdk";

try {
  await quarzo.authentication.getCurrentUser();
} catch (error) {
  if (error instanceof QuarzoApiError) {
    console.error(
      error.status,
      error.issues.map((issue) => issue.code),
    );
  } else {
    throw error;
  }
}
```

The `doc_url` of an issue opens the page of its error code. The [API reference](/api/) gives the errors of each endpoint.

| Status | Cause                                                                           |
| ------ | ------------------------------------------------------------------------------- |
| `401`  | The access token is missing, expired or not valid. Get a new token.             |
| `403`  | The token does not have the permission for this operation.                      |
| `409`  | For `IDEMPOTENCY_KEY_CONFLICT`: the same key was used with a different request. |

If a timeout occurs, the SDK throws an `Error` with the message `Request timeout after <ms>ms`. Send the same call again with the same idempotency key.

Do not log the access token or the private key. When you ask Quarzo for help, send the status, the `code` of each issue and the time of the request.

## Next steps

* [API reference](/api/): the endpoints and their request formats.
* [Webhooks](/topics/webhooks): receive the events of your Broker.
* [Idempotent requests](/topics/idempotent-requests): retry commands safely.
