> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ocpplab.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ocpplab.io/_mcp/server.

# TypeScript SDK

## Install

```bash
npm i ocpplab
```

## Create a client

```typescript
import { OcpplabSDK } from "ocpplab";

const client = new OcpplabSDK({ token: process.env.OCPPLAB_TOKEN! });
```

| Option             | Default                  | Use it to                                                        |
| ------------------ | ------------------------ | ---------------------------------------------------------------- |
| `token`            | —                        | Authenticate. See [Authentication](/get-started/authentication). |
| `baseUrl`          | `https://api.ocpplab.io` | Call another host, such as a local API.                          |
| `timeoutInSeconds` | `60`                     | Fail a request that takes longer.                                |
| `maxRetries`       | `2`                      | Change how often a retryable request is retried.                 |

Every option except `token` can also be set per request as the last argument, for example `{ timeoutInSeconds: 10 }`.

## Call the API

Methods follow the API's domains and are camelCase. Request and response fields keep the API's snake_case names.

```typescript
const brands = await client.evcharger.catalog.listBrands();
for await (const brand of brands) {
    console.log(brand.slug, brand.name);
}

const status = await client.evcharger.commands.getStatus({ command_id: "cmd-123" });
console.log(status.status);
```

Every method, its parameters and a runnable snippet are in the [API Reference](/api-reference): pick **TypeScript** in any code example.

## Pagination

List methods return a pager. Iterate it with `for await` to walk every page, or read one page at a time:

```typescript
const page = await client.evcharger.catalog.listBrands({ limit: 20 });
console.log(page.data);
if (page.hasNextPage()) {
    const next = await page.getNextPage();
}
```

## Types

Request and response types are under `OcpplabSDKTypes`:

```typescript
import { OcpplabSDKTypes } from "ocpplab";

const target: OcpplabSDKTypes.CommandTarget = { identity: "DEMO-CP-001" };
```

## Full example

```typescript title={"quickstart.ts"}
// Put virtual chargers online against your CSMS, then wait until they connect.
//
//     export OCPPLAB_TOKEN="<api-key>"
//     export CSMS_WS_URL="wss://csms.example.com/ocpp"
//     npx tsx examples/quickstart.ts
//
// Creating a location returns 202 at once; the chargers deploy in the background,
// so this polls their deployment stage until every one is online.
import { OcpplabSDK } from "ocpplab";

const IDENTITIES = ["DEMO-CP-001", "DEMO-CP-002"];

async function main(): Promise<void> {
    // Defaults to https://api.ocpplab.io; pass baseUrl for another host.
    const client = new OcpplabSDK({ token: process.env.OCPPLAB_TOKEN! });
    const accepted = await client.evcharger.location.create({
        name: "Demo hub",
        address: "1 Parvis de la Defense",
        city: "Puteaux",
        country: "FRA",
        coordinates: { lat: 48.892, lng: 2.238 },
        chargers: IDENTITIES.map((identity) => ({
            identity,
            brand_slug: "wallbox",
            model: "wallbox-pulsar-plus",
            connector_type: "Type2",
            ws_url: process.env.CSMS_WS_URL!,
        })),
    });
    console.log(`location ${accepted.location_id}: ${accepted.detail}`);

    const deadline = Date.now() + 600_000;
    while (true) {
        const { items: chargers } = await client.evcharger.deploymentRuntimeOps.status({
            identity: IDENTITIES,
        });
        for (const charger of chargers) {
            console.log(charger.identity, charger.stage, charger.outcome, charger.hint ?? "");
        }
        if (chargers.length > 0 && chargers.every((charger) => charger.stage === "online")) {
            return;
        }
        if (chargers.some((charger) => charger.outcome === "failed" || charger.outcome === "stuck")) {
            throw new Error("a charger failed to deploy; see the hint above");
        }
        if (Date.now() > deadline) {
            throw new Error("chargers were not online after 10 minutes");
        }
        await new Promise((resolve) => setTimeout(resolve, 5_000));
    }
}

void main();

```

## Next

* [Errors and retries](/sdks/errors-and-retries)
* [Long-running operations](/get-started/guides/long-running-operations)