Skip to main content
EVPanda attributes every message to something in your network — a charge point, or a roaming partner. That attribution is what makes the dashboard useful: it is how a message becomes “this charger”, how an issue becomes “this partner’s fault”, and how traffic splits per tenant. Identity is per message, not global configuration. One process can serve thousands of chargers or dozens of roaming partners, so the SDK asks who a message belongs to at the moment you capture it, not at the moment you start the client.

The two shapes

A charge point is identified by a charger ID: whatever your CSMS already uses to name a charge point.OCPP identity is known at connect time — you resolve the charge point during the WebSocket handshake, before any frame arrives — so you supply it once per connection and the session handle carries it for every frame.

Tenants

tenantId and tenantName are optional, and all-or-nothing: supply both or neither. A half-set pair fails validation and the message is dropped. Use tenants when one deployment serves several distinct operators — a CPO platform hosting sub-operators, a white-label CSMS, a hub carrying several parties. The dashboard uses them to filter chargers, platforms, messages, and issues, and to report per-tenant activity.
If you have a single operator, leave them out entirely. You can start sending them later; tenants are discovered from traffic like everything else.
OCPP is the exception today. The SDKs treat the tenant pair as optional for both protocols, but the ingestion API currently requires it on OCPP messages and rejects those that omit it — server-side, after a successful delivery, so nothing in the SDK reports it.Until that is relaxed, send a tenant pair on OCPP even in a single-tenant CSMS. A constant value such as your own operator name is fine. See Getting started.

Choosing good identifiers

A charger ID should be the same string your CSMS, your support tooling, and your field team all say out loud. Usually that’s the OCPP identity from the WebSocket URL path. Don’t mint an EVPanda-specific ID — you’ll spend the rest of the year translating between them.
platformId and tenantId group your data over time, so they must not change for the same entity. platformName and tenantName are display strings, and can be updated freely; EVPanda shows the most recent one it has seen.
Identity is stored and shown in the dashboard. It should identify a partner or a charger, not authenticate one. Never pass a token, a Token B, or a client certificate fingerprint as an ID.
The ingestion API rejects a message whose tenantName exceeds 32 characters, or whose other identity fields exceed 64. Long partner names get truncated at the source, not in the dashboard — trim them before you pass them in.

What happens to an unattributable message

The SDK validates identity at capture, before anything is buffered. A message that fails validation is dropped silently — it is not queued, not sent, and never raises an error into your code. An identity is invalid when:
  • A required field is empty, missing, or whitespace only.
  • Exactly one of tenantId / tenantName is set.
Dropping is deliberate: a message EVPanda can’t attribute would arrive as an orphan that nobody can search for or act on. But because the drop is silent, it is also the most common reason for “the SDK isn’t sending anything”. Every SDK counts it. In Go, read panda.Stats().DroppedInvalid. In Node and Python, turn on debug. See Getting started.
The HTTP adapters treat “no identity” as “don’t capture”, not as an error. A request the adapter can’t attribute is served exactly as it would have been — your partners never see a difference.