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

# Quickstart

Follow this guide to make your first successful requests against the OCPPLAB Gateway API.

Create a user token from the [OCPPLAB dashboard](https://app.ocpplab.com) and export it alongside your API host:

```bash
export BASE_URL="https://<your-api-host>"
export ACCESS_TOKEN="<jwt>"
```

Confirm the API is reachable before you go further:

```bash
curl "$BASE_URL/health"
```

You should see a `200` with a small JSON body. If not, stop here and fix connectivity before anything else. The `Authorization: Bearer $ACCESS_TOKEN` header is all a user token needs. See [Authentication](/authentication) for the admin case.

OCPPLAB ships SDKs for Python and Node.js. Pick one — or skip to shell if you prefer raw HTTP.

```bash title="Python"
pip install ocpplab
```

```bash title="Node.js"
npm install ocpplab
```

Initialize the client:

```python title="Python"
import os
from ocpplab import OcpplabSDK

client = OcpplabSDK(
    token=os.environ["ACCESS_TOKEN"],
    base_url=os.environ["BASE_URL"],
)
```

```javascript title="Node.js"
import { OcpplabSDK } from "ocpplab";

const client = new OcpplabSDK({
  token: process.env.ACCESS_TOKEN,
  baseUrl: process.env.BASE_URL,
});
```

The catalog lists every charger brand and model the simulator supports. Pick one before you deploy a charger.

```bash title="Shell"
curl "$BASE_URL/catalog/brands?page=1&limit=20" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

curl "$BASE_URL/catalog/brands/wallbox/models?page=1&limit=50" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

```python title="Python"
brands = client.catalog.list_brands(page=1, limit=20)
models = client.catalog.list_models(brand_slug="wallbox", page=1, limit=50)
```

```javascript title="Node.js"
const brands = await client.catalog.listBrands({ page: 1, limit: 20 });
const models = await client.catalog.listModels("wallbox", { page: 1, limit: 50 });
```

A location groups chargers under one physical site. Save the returned `id` — the next step uses it.

```bash title="Shell"
curl -X POST "$BASE_URL/locations" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "La Defense Charging Hub",
    "address": "14 Rue de la Paix",
    "city": "Paris",
    "country": "FR",
    "coordinates": { "latitude": 48.8566, "longitude": 2.3522 },
    "timezone": "Europe/Paris",
    "owner_name": "VINCI Autoroutes",
    "public": true
  }'
```

```python title="Python"
location = client.locations.create(
    name="La Defense Charging Hub",
    address="14 Rue de la Paix",
    city="Paris",
    country="FR",
    coordinates={"latitude": 48.8566, "longitude": 2.3522},
    timezone="Europe/Paris",
    owner_name="VINCI Autoroutes",
    public=True,
)

print(f"Created location: {location.id}")
```

```javascript title="Node.js"
const location = await client.locations.create({
  name: "La Defense Charging Hub",
  address: "14 Rue de la Paix",
  city: "Paris",
  country: "FR",
  coordinates: { latitude: 48.8566, longitude: 2.3522 },
  timezone: "Europe/Paris",
  owner_name: "VINCI Autoroutes",
  public: true,
});

console.log(`Created location: ${location.id}`);
```

Example response:

```json
{
  "id": "4090477f-a416-4515-a302-97aa344a0a2a",
  "slug": "paris-la-defense-hub-a1b2c3d4",
  "name": "La Defense Charging Hub",
  "status": "active"
}
```

Bind a charger to the location from step 4, pick a model from the catalog, and point it at any CSMS WebSocket. Replace `<LOCATION_ID>` with the `id` returned in step 4.

```bash title="Shell"
curl -X POST "$BASE_URL/chargers" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "identity": "CP-TEST-001",
    "brand_slug": "wallbox",
    "model_slug": "wallbox-pulsar-plus",
    "connector_type": "Type2",
    "ws_url": "wss://ocpp.ocpplab.com",
    "ocpp_version": "OCPP1.6",
    "charge_point_name": "Bay A01",
    "location_id": "<LOCATION_ID>",
    "location_name": "La Defense Charging Hub"
  }'
```

```python title="Python"
charger = client.chargers.create(
    identity="CP-TEST-001",
    brand_slug="wallbox",
    model_slug="wallbox-pulsar-plus",
    connector_type="Type2",
    ws_url="wss://ocpp.ocpplab.com",
    ocpp_version="OCPP1.6",
    charge_point_name="Bay A01",
    location_id=location.id,
    location_name="La Defense Charging Hub",
)
```

```javascript title="Node.js"
const charger = await client.chargers.create({
  identity: "CP-TEST-001",
  brand_slug: "wallbox",
  model_slug: "wallbox-pulsar-plus",
  connector_type: "Type2",
  ws_url: "wss://ocpp.ocpplab.com",
  ocpp_version: "OCPP1.6",
  charge_point_name: "Bay A01",
  location_id: location.id,
  location_name: "La Defense Charging Hub",
});
```

Kick off a transaction on the charger, then read the OCPP traffic it produced.

```bash title="Shell"
curl -X POST "$BASE_URL/chargers/$CHARGER_ID/start-transaction" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id_tag": "TAG-RFID-001", "evse_id": 1, "connector_id": 1}'

curl "$BASE_URL/chargers/$CHARGER_ID/logs?event=Authorize&limit=100&offset=0" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

```python title="Python"
client.commands.start_transaction(
    charger_id=charger.id,
    id_tag="TAG-RFID-001",
    evse_id=1,
    connector_id=1,
)

logs = client.chargers.list_logs(
    charger_id=charger.id,
    event="Authorize",
    limit=100,
    offset=0,
)
```

```javascript title="Node.js"
await client.commands.startTransaction(charger.id, {
  id_tag: "TAG-RFID-001",
  evse_id: 1,
  connector_id: 1,
});

const logs = await client.chargers.listLogs(charger.id, {
  event: "Authorize",
  limit: 100,
  offset: 0,
});
```

You now have a live charger replaying OCPP messages against your CSMS. Keep going:

Bulk-provision chargers, spin up CPO bundles, inject faults.

How tenants, locations, chargers, and OCPI fit together.

Every endpoint with shell, Python, and Node samples.

Sync and async clients, retries, timeouts.