> 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.

# Concepts

OCPPLAB Gateway is a REST API that drives a fleet of OCPP simulators. Every resource lives under a tenant, and every charger points at a CSMS over WebSocket. This page is the mental model you need before writing integration code.

## Tenants

A **tenant** (also called an "organization") is the isolation boundary. Locations, chargers, and OCPI bundles all belong to exactly one tenant.

* **User tokens** are pre-scoped to a single tenant. Your requests only ever see that tenant's data.
* **Admin tokens** can act across tenants and pick one per request via `X-Organization-Id`. See [Authentication](/authentication) — you can ignore this section unless you are an internal integrator.

## Locations

A **location** is a physical site: a charging hub, depot, parking lot, or forecourt. It holds address, coordinates, timezone, and an owner name. Chargers are always deployed into exactly one location.

Location routes live at `/locations` — CRUD plus a few read helpers for listing chargers within a site.

## Chargers

A **charger** is a deployed, simulated charge point. Each one:

* Picks a brand and model from the **catalog** (e.g. `wallbox` / `wallbox-pulsar-plus`)
* Chooses an OCPP version — `OCPP1.6` or `OCPP2.0.1`
* Points at a CSMS WebSocket URL (`ws_url`) — that is the backend you are testing
* Is bound to one location

Once created, the simulator opens a WebSocket to the CSMS and starts emitting OCPP traffic — `BootNotification`, `StatusNotification`, `Heartbeat`, and the rest.

`/chargers/{charger_id}/...` routes target exactly one charger.

`/locations/{location_id}/chargers/...` routes fan out to every charger in the site, or to a subset via `charger_ids`.

## Catalog

The **catalog** is read-only. It lists the brands, models, connector types, and OCPP versions the simulator supports. Always pick a brand and model from the catalog before creating a charger — the backend rejects unknown slugs.

## Commands

**Commands** drive the simulator. They come in two flavors:

* **Lifecycle** — `start-transaction`, `stop-transaction`, `reset`, `unlock-connector`
* **State** — `update-configuration`, `set-local-auth-list`, `inject-fault`, `clear-fault`

Most commands exist on both the single-charger and location-scoped routes. Prefer the location-scoped variant when orchestrating a fleet.

## OCPI bundles

The **OCPI** section is for roaming and integration testing. A CPO bundle provisions:

* A Charge Point Operator identity (country code, party ID)
* One or more locations
* Several chargers per location
* OCPI credentials ready for an eMSP to connect

Bundles are preset-driven — pass a `template` like `small-urban-ac` and the server stamps out the full topology.

## Logs

`GET /chargers/{charger_id}/logs` is the first tool to reach for after a command. Every OCPP message crossing the wire — in either direction — lands here with direction, action, raw message frame, and timestamp. Use it to verify commands landed, diff runs against a baseline, or debug low-level protocol issues.

## Request lifecycle

A typical integration flow:

1. **Read the catalog** — find a brand, model, and OCPP version
2. **Create a location** — save the returned `id`
3. **Create a charger** — bound to the location, pointed at your CSMS
4. **Drive it with commands** — start/stop transactions, inject faults
5. **Read the logs** — verify the CSMS saw what you expected

Every resource id you receive from a list or create response is the canonical value to pass back in later requests. Don't construct ids yourself.

## Next step

Run through the 5-step onboarding flow.

End-to-end examples of the flows most teams need first.