OCPI MODULE · UPDATED 11 AUG 2026

Tokens: who is allowed to charge

Before a charger releases a single watt, someone has to answer: is this driver allowed, and who pays? The Tokens module is that answer — in two flavours, synced ahead of time or asked in the moment, and the choice between them is a trade between speed and control.

PART OF THE OCPI 2.2.1 COMPLETE GUIDE · 15 MODULE & COMMAND GUIDES

IN ONE PARAGRAPH

The eMSP owns its customers' tokens and pushes them to CPOs, so a driver can be authorised even when the CPO cannot reach the eMSP. The whitelist field decides whether the CPO may authorise locally, must ask in real time, or may choose. Getting that field wrong produces either unauthorised charging or drivers stranded at working chargers.

Token anatomy

The eMSP is the Sender here — it owns the customer relationship and therefore the tokens. It pushes them to each CPO it roams with.

FieldMeaning
uidThe physical or logical identifier — what the charger reads from an RFID card
typeRFID, APP_USER, AD_HOC_USER or OTHER
contract_idThe eMI3 contract identifier — who gets billed. Distinct from uid.
issuerThe eMSP's display name, shown on the charger screen
validWhether the token is currently usable at all
whitelistWhether the CPO may authorise locally — see below
group_idGroups tokens that share a limit, such as a fleet
last_updatedOrdering guard for updates
uid and contract_id are not the same thing and must not be conflated. uid identifies the credential presented at the charger; contract_id identifies the billing relationship. One contract may have several tokens — a card, a phone app, a spare card — and replacing a lost card changes the uid while the contract_id stays. Billing keyed on uid breaks the first time a customer loses a card.

The whitelist field is the real decision

ValueMeaningConsequence
ALWAYSCPO must authorise locally; never call the eMSPFastest. No real-time control — revocation only takes effect once the update propagates.
ALLOWEDCPO may authorise locallyCPO chooses. Usually local, falling back to real-time.
ALLOWED_OFFLINELocal authorisation only when the eMSP is unreachableReal-time normally, graceful degradation when the link drops. The usual best default.
NEVERCPO must always ask in real timeMaximum control. Driver is stranded if the eMSP is unreachable.

The trade-off is stark. ALWAYS means a cancelled customer can keep charging until the token update reaches every CPO. NEVER means an eMSP outage stops every one of its customers charging anywhere in the country.

ALLOWED_OFFLINE is the setting that survives contact with production for most consumer use cases: real-time authorisation when everything works, local fallback when it does not. Reserve NEVER for tokens where the financial exposure genuinely justifies stranding a driver — high-value fleet cards, for instance.

Real-time authorisation

When the CPO must ask, it POSTs an authorisation request to the eMSP:

POST /ocpi/2.2.1/tokens/DR-88231/authorize?type=APP_USER
Authorization: Token <base64 token>
OCPI-from-country-code: IN
OCPI-from-party-id: EFI
OCPI-to-country-code: IN
OCPI-to-party-id: EMS

{
  "location_id": "LOC-ND-014",
  "evse_uids": ["EVSE-014-02"]
}

And the eMSP answers:

HTTP/1.1 200 OK

{
  "data": {
    "allowed": "ALLOWED",
    "token": {
      "country_code": "IN", "party_id": "EMS",
      "uid": "DR-88231", "type": "APP_USER",
      "contract_id": "IN-EMS-C0142",
      "issuer": "Example Mobility Services",
      "valid": true, "whitelist": "ALLOWED_OFFLINE",
      "last_updated": "2026-08-11T08:55:00Z"
    },
    "authorization_reference": "auth-4471"
  },
  "status_code": 1000,
  "timestamp": "2026-08-11T09:11:58Z"
}

The allowed values

ValueMeaningWhat the charger shows
ALLOWEDProceedStarting
BLOCKEDToken is blockedCard blocked — contact your provider
EXPIREDToken has expiredCard expired
NO_CREDITInsufficient balanceInsufficient credit
NOT_ALLOWEDNot permitted here — e.g. this network is out of policyNot valid at this location

authorization_reference in the response is the correlation key. A conforming CPO echoes it on the resulting Session and CDR, which is what lets you tie an authorisation decision to the charge and the invoice that followed. Always return one.

Latency is a product constraint

A driver is standing at a charger holding a card. Every second of authorisation latency is a second of them wondering whether it worked.

  • Budget under two seconds end to end. Beyond about five, CPOs commonly time out and fall back to their own policy.
  • Never make authorisation depend on a slow downstream system. If your billing platform is the bottleneck, cache entitlement rather than querying it inline.
  • Fail in a defined direction. Decide deliberately whether a timeout on your side should permit or deny, and make sure the whitelist value you publish matches that intent.
  • Instrument the p99, not the mean. The tail is what strands drivers.

Revocation, and its limits

Revoking a token means setting valid to false and pushing the update to every CPO you roam with. The gap between that push and the last CPO applying it is your exposure window.

  • With whitelist: NEVER, revocation is effectively immediate — the next authorisation call returns BLOCKED.
  • With ALWAYS, it is only as fast as your slowest partner's ingestion, which may be hours.
  • Push revocations before routine updates. If your token sync is a batch job, a blocked card should not wait behind a thousand address changes.
  • Confirm propagation. Pull the token back from the CPO to verify the change landed rather than assuming a 200 meant applied.

Production rules

  • Key billing on contract_id, never on uid. Cards get lost and replaced; contracts persist.
  • Default to ALLOWED_OFFLINE unless there is a specific reason to do otherwise.
  • Always return authorization_reference — it is your only clean link from decision to invoice.
  • Enforce last_updated ordering on token pushes, exactly as with Locations and Sessions.
  • Never log a raw token uid in plaintext at rest. It is a credential and it is regulated personal data in most jurisdictions.
  • Reconcile your token list with each CPO periodically. Divergence accumulates silently, and the symptom is a driver refused at one network and accepted at another.

Frequently asked questions

What does the whitelist field do in OCPI Tokens?

It tells the CPO whether it may authorise a token locally or must ask the eMSP in real time. ALWAYS means authorise locally and never ask; NEVER means always ask; ALLOWED lets the CPO choose; ALLOWED_OFFLINE means ask normally but fall back to local authorisation when the eMSP is unreachable.

What is the difference between uid and contract_id?

uid identifies the credential presented at the charger, such as an RFID card. contract_id identifies the billing relationship. One contract can have several tokens, and replacing a lost card changes the uid while the contract_id stays the same, so billing must be keyed on contract_id.

Which whitelist setting should you use?

ALLOWED_OFFLINE suits most consumer cases: real-time authorisation when systems are healthy, local fallback when the link drops. NEVER gives maximum control but strands drivers during an eMSP outage; ALWAYS is fastest but delays revocation until updates propagate.

What is authorization_reference used for?

It is the correlation key returned in an authorisation response. A conforming CPO echoes it onto the resulting Session and CDR, letting you tie an authorisation decision to the charge and the invoice that followed.

How fast must OCPI real-time authorisation respond?

Budget under two seconds end to end. Beyond roughly five seconds many CPOs time out and fall back to their own policy, so instrument the p99 rather than the mean — the tail is what strands drivers at chargers.