Session Lifecycle

End-to-end charging session flow through ChargeIndia Hub.

This page is the integrator contract for the via-Hub session path: authorize → commands → sessions → CDRs. Role-specific endpoints: CPO, eMSP.

Always parse HTTP status, OCPI status_code, and payload fields (data.allowed, data.result, status_message) together. Authorize Hub-side failures often return OCPI status_code: 4002/4003 with data.allowed: UNKNOWN and HTTP 504 or 502.

RFID and Autocharge use the same Token module: realtime AUTH_REQUEST (CPO→Hub→eMSP authorize) or WHITELIST (eMSP token push). Remote app start remains COMMAND. Dedicated guide: RFID & Autocharge.

Sequence diagram

RFID / Autocharge at charger

See RFID & Autocharge for conventions, online authorize, whitelist sync, and partner checklists.

Whitelist path: eMSP PUT Token → Hub store-and-forward to CPO → local authorize → session with auth_method: WHITELIST.

Command failure branches

Step-by-step

1. Token authorization

CPO → eMSP (RFID / Autocharge at charger) — OCPI 2.2.1 Tokens Sender POST …/authorize:

CPO → Hub: POST /ocpi/2.2.1/tokens/{token_uid}/authorize?type=RFID
           Headers: OCPI-to-country-code / OCPI-to-party-id = token-owning eMSP
           Body: optional LocationReferences
Hub → eMSP: POST {emsp_tokens_sender_url}/{token_uid}/authorize?type=RFID

OCPI-To is required. type defaults to RFID when omitted. Hub returns full AuthorizationInfo (allowed, optional token, location, authorization_reference, info).

App / remote start uses Commands (START_SESSION), not Tokens authorize.

On Hub-side failure to reach or interpret the peer, Hub returns OCPI 4002/4003 with data.allowed: UNKNOWN and sets HTTP 504 (timeout) or 502 (unavailable / other) plus status_message.

2. Start session

eMSP → Hub: POST /ocpi/2.2.1/commands/START_SESSION
Hub → CPO:  POST /ocpi/2.2.1/commands/START_SESSION

Required fields:

  • response_url — eMSP async CommandResult URL (Hub rewrites the URL sent to the CPO to a Hub callback)
  • token — driver token object
  • location_id, evse_uid, connector_id — target charge point

Hub→CPO HTTP timeout for commands is 20 seconds. Immediate data.timeout (default 30) is the OCPI async-result window for the eMSP, not the Hub→CPO HTTP timeout.

3. Session becomes active

CPO → Hub: PUT /ocpi/2.2.1/sessions/{cpo_cc}/{cpo_pid}/{session_id}

You must set cdr_token.country_code and cdr_token.party_id to the eMSP. Hub enqueues async forward:

Hub → eMSP: PUT /ocpi/2.2.1/sessions/{cpo_cc}/{cpo_pid}/{session_id}

4. Stop session

eMSP → Hub: POST /ocpi/2.2.1/commands/STOP_SESSION

Include session_id in the body. Hub resolves the owning CPO from the stored session.

5. Session completed

CPO PUTs COMPLETED; Hub forwards to eMSP asynchronously.

6. CDR delivery

CPO → Hub: POST /ocpi/2.2.1/cdrs
Hub → eMSP: POST /ocpi/2.2.1/cdrs (async)

Required fields summary

FieldSet byPurpose
cdr_token.country_codeCPO on session/CDRRoutes async delivery to eMSP
cdr_token.party_idCPO on session/CDRRoutes async delivery to eMSP
response_urleMSP on commandAsync CommandResult delivery
session_idCPO / command flowLinks stop command to active session

Timing expectations

PathTypeContract
Token authorizeSyncHub waits on CPO; Hub does not retry
CommandsSync + asyncImmediate result; async via authenticated CPO callback → eMSP response_url; Hub→CPO HTTP timeout 20s
Sessions / CDRsAsync pushp95 < 5s Hub → eMSP; retries only for transient partner failures

See Async Delivery.

Ownership and responsibilities

ArtifactSet byHub uses forVisible to
Session path {cc}/{pid}CPOOwning CPO identity; eMSP receiver pathCPO; eMSP (as CPO key)
session.idCPOStorage key; stop routingCPO; routed eMSP
cdr_token.{country_code,party_id}CPOAsync target; eMSP GET /sessions scopeTarget eMSP only
Command response_urleMSPRewritten to Hub callback, then forwardedeMSP
X-Request-ID / X-Correlation-IDCallers / HubSupport correlationBoth

RACI

  • CPO — authorize decision, immediate command result, authenticated async CommandResult callback, session/CDR pushes with correct cdr_token. On charger/CSMS reconnect, finalize open transactions and push COMPLETED + CDR (including abort/power-loss).
  • eMSP — tokens and commands; honor data.timeout when the CPO is silent; idempotent receivers; soft-close UX locally when sessions look stuck (Hub does not push provisional session status).
  • Hub — routing, store-and-forward, callback rewrite, credentialed forward to eMSP. May pull CPO sessions/CDRs to heal a stale Hub store (orphan reconcile). Does not invent sessions, final CommandResults, COMPLETED, or CDRs.

Orphan / stale ACTIVE sessions

If a charger never stops (power loss, missed stop, CSMS gap), Hub may flag an orphan case for ops and pull the CPO for truth. After STOP is ACCEPTED/COMPLETED, Hub waits a 2 minute grace (ORPHAN_STOP_GRACE_MS) before stop_without_complete can open (swept about every 5 minutes). Hub still does not invent COMPLETED, CommandResult TIMEOUT, or CDRs, and does not auto-send another STOP_SESSION. eMSPs should still implement their own soft-close timers and customer messaging. Catch-up: GET /sessions and GET /cdrs. See the ops runbook docs/runbooks/orphan-sessions.md.

Sync vs async retry

Sync (authorize, commands to CPO): Hub does not retry. You may re-issue with your own backoff.

Async (session/CDR/catalog to eMSP): Hub retries timeout and unavailable only. Permanent failures (auth_error, not_found, client_error, invalid_response) are recorded and not retried. Domain write + outbox are durable; queue delivery is best-effort after commit.

Failure scenarios

Each card: Scenario → Hub Response → Retry → Expected Outcome → Owner.

CPO unreachable or timed out (command)

  • Scenario: START_SESSION (or other command); CPO commands endpoint does not answer within 20s, is unreachable, or Hub short-circuits because the circuit is open. Party OFFLINE does not short-circuit the command.
  • Hub Response: HTTP 502, OCPI status_code 2000, status_message one of:
    • "CPO command forward timed out"
    • "CPO command forward unavailable" (circuit or generic unavailable)
    • "CPO command forward unauthorized" / "CPO command forward not found" / "CPO command rejected" / "CPO command forward failed"
    • Command record → REJECTED. Hub does not leave the command pending for later CPO recovery.
  • Retry: No (Hub). eMSP may re-issue after checking Connection Health.
  • Expected Outcome: Treat start as failed unless a later re-issue succeeds.
  • Owner: CPO (availability) + eMSP (retry policy).

Invalid token or authorization / command rejected by CPO

  • Scenario: CPO blocks the token or rejects the command.
  • Hub Response:
    • Authorize: data.allowed = BLOCKED or NOT_ALLOWED (HTTP 200, OCPI 1000) when the CPO responds.
    • Commands: data.result = REJECTED (HTTP 200, OCPI 1000) when the CPO responds.
  • Retry: No (until eligibility changes).
  • Expected Outcome: Resolve token/eligibility before retrying.
  • Owner: eMSP / driver.

Command ACCEPTED, charger never starts

  • Scenario: Immediate ACCEPTED, but no session PUT and no CommandResult callback.
  • Hub Response: Immediate data.result: ACCEPTED and data.timeout (often 30). Hub does not synthesize async TIMEOUT / REJECTED.
  • Retry: No (Hub).
  • Expected Outcome: No session exists on Hub until CPO PUTs one. eMSP must treat silence past timeout as failure unless a callback or session arrives. CPO must POST /commands/callback/{command_id} with final CommandResult when start fails after accept.
  • Owner: CPO (callback + session) + eMSP (timeout handling).

Authorize: not routed or unknown CPO

  • Scenario: No routing rule, or CPO party unknown.
  • Hub Response: HTTP 200, OCPI 1000, data.allowed: NOT_ALLOWED. This is not "Not routed" (that string is for commands/locations).
  • Retry: No until routing is enabled.
  • Expected Outcome: Do not start charging for that pair.
  • Owner: Routing configuration.

Authorize: CPO timeout

  • Scenario: Hub aborts the authorize call to the CPO (timeout).
  • Hub Response: HTTP 504, OCPI 4002, data.allowed: UNKNOWN, status_message: "CPO authorize timeout".
  • Retry: No (Hub). eMSP may retry.
  • Expected Outcome: Do not treat as a definitive token rejection.
  • Owner: CPO + eMSP.

Authorize: CPO unavailable, circuit, or incomplete response

  • Scenario: Open circuit, missing tokens endpoint, network/5xx/TLS failure, or unusable authorize payload. Party OFFLINE does not short-circuit authorize.
  • Hub Response: HTTP 502, OCPI 4003, data.allowed: UNKNOWN, status_message one of:
    • "CPO authorize unavailable"
    • "CPO tokens endpoint not configured"
    • "CPO authorize unauthorized" / "CPO authorize not found" / "CPO authorize rejected" / "CPO authorize response incomplete"
  • Retry: No (Hub). eMSP may retry after health recovers.
  • Expected Outcome: Same as timeout — not a definitive NOT_ALLOWED.
  • Owner: CPO + eMSP.

Command not routed

  • Scenario: No routing rule for the eMSP↔CPO pair.
  • Hub Response: HTTP 403, OCPI 2000, status_message: "Not routed". CPO is not called.
  • Retry: No until routing is enabled.
  • Expected Outcome: Command fails at Hub.
  • Owner: Routing configuration.

Unknown location or session on command

  • Scenario: Unknown location_id on start/reserve, or unknown session_id on stop.
  • Hub Response: HTTP 404, OCPI 2003, status_message: "Location not found".
  • Retry: No (fix IDs first).
  • Expected Outcome: Command not forwarded.
  • Owner: eMSP (IDs) or CPO (publish location / push session first).

Missing or wrong cdr_token on session or CDR

  • Scenario: CPO push omits eMSP identity or sets the wrong party. A common migration mistake is setting cdr_token to Hub (IN / CIH) instead of the eMSP from the START_SESSION token.
  • Hub Response: HTTP 200, OCPI 1000 to the CPO. Hub stores but does not enqueue to Hub (CIH).
    • COMPATIBILITY (active grace): Hub may rewrite the forward target from a matching START_SESSION (authorization_reference, else cdr_token.uid ↔ command token.uid) and deliver to that eMSP. Stored OCPI payload cdr_token is left unchanged; routing columns use the resolved eMSP. CDRs can also inherit a previously rewritten session eMSP.
    • COMPLIANT or expired COMPATIBILITY / no matching START_SESSION: No forward is enqueued. Pull scoping also will not list the session under the real eMSP.
  • Retry: Re-PUT / re-POST with correct cdr_token (eMSP country_code / party_id from the command token). COMPATIBILITY rewrite is a migration aid, not a substitute for correct identity.
  • Expected Outcome: With a correct cdr_token (or successful COMPATIBILITY rewrite), the target eMSP receives the push. Otherwise the eMSP never receives it.
  • Owner: CPO.

eMSP receiver down (async session or CDR)

  • Scenario: CPO push already succeeded; Hub worker cannot deliver to the eMSP receiver.
  • Hub Response: Not returned on the CPO's original call. Transient failures: Hub retries with backoff (may DLQ). Permanent partner errors: recorded and not retried (outbox DEAD).
  • Retry: Yes (Hub) for timeout/unavailable only.
  • Expected Outcome: Eventually delivered, or eMSP backfills via GET /sessions / GET /cdrs, or support re-drive.
  • Owner: eMSP (receiver) + Hub support if stuck.

Wrong party GET session

  • Scenario: Caller requests a session outside ownership / cdr_token scope.
  • Hub Response: HTTP 404, OCPI 2003, status_message: "Not found" (no ownership leak).
  • Retry: No.
  • Expected Outcome: Use the correct party scope.
  • Owner: Requesting party.

Command callback auth or eMSP forward failure

  • Scenario: CPO posts async CommandResult, or Hub cannot reach eMSP response_url.
  • Hub Response:
    • Missing/wrong CPO token or CPO does not own the command → HTTP 401, OCPI 2000.
    • eMSP forward failure → HTTP 502, "Failed to forward command callback to eMSP" or "... (timeout)".
  • Retry: No automatic Hub retry of the callback forward. CPO may retry the callback; keep response_url healthy.
  • Expected Outcome: eMSP may miss async result; correlate with session push.
  • Owner: CPO (auth + retry callback) + eMSP (response_url).

Symptom index: Troubleshooting.

Hub response catalog

ConditionHTTPOCPI status_codePayload / status_messageHub retry?
Authorize not routed / unknown CPO2001000allowed: NOT_ALLOWEDNo
Authorize timeout5044002allowed: UNKNOWN, "CPO authorize timeout"No
Authorize unavailable / circuit / incomplete5024003allowed: UNKNOWN + class messageNo
Authorize CPO ALLOWED / BLOCKED / NOT_ALLOWED2001000allowed as returnedNo
Command not routed4032000"Not routed"No
Command unknown location / session4042003"Location not found"No
Command circuit5022000"CPO command forward unavailable"No
Command forward timeout5022000"CPO command forward timed out"No
Command forward other partner failure5022000Class-specific command messageNo
Command CPO ACCEPTED / REJECTED2001000data.result (+ timeout)No
Callback unauthenticated / wrong CPO4012000Invalid tokenNo
Callback → eMSP failed5022000Failed to forward… (timeout) when applicableNo
Session / CDR stored (even missing cdr_token)2001000StoredN/A on CPO call
Async forward to eMSP failed——Not on CPO responseTransient only
Wrong party GET session4042003"Not found"No
Rate limit4292901"Rate limited"Caller backs off

Do not assume eMSP delivery from CPO success

Async delivery failures are not returned on the CPO's original PUT / POST. Use correlation IDs, pull backfill, and support re-drive when needed.

Role-specific next steps

RoleWhat to implement
CPOSessions · CDRs · Tokens · Commands · Hub Receiver Identity
eMSPTokens · Commands · Sessions · CDRs · Hub Receiver Identity · Async Delivery