Rate limits
The Hub enforces per-party rate limits on high-traffic modules:
| Module | Limit |
|---|---|
| Token authorization | 100 requests / minute |
| Commands | 50 requests / minute |
| Location list | 200 requests / minute |
When exceeded, the Hub returns HTTP 429 with OCPI status_code: 2901 (Hub rate-limit code in the custom 29xx range).
Implement exponential backoff and respect Retry-After if provided.
OCPI status codes
All Hub responses use the standard OCPI envelope. Check status_code in every response:
| Code | Name | Meaning |
|---|---|---|
1000 | Success | Request completed successfully |
2000 | Generic client error | Includes auth failures (HTTP 401); check status_message |
2001 | Invalid parameters | Missing/invalid query or body fields |
2002 | Not enough information | e.g. authorize without required context |
2003 | Unknown Location | Location (or related resource) not found |
2004 | Unknown Token | Realtime authorize for unknown token |
2901 | Rate limit (Hub) | Too many requests; back off and retry |
3002 | Unsupported version | Unknown /ocpi/{version} |
4001 | Hub unknown receiver | OCPI-to peer unknown |
4002 | Hub timeout | Forwarded request timed out |
4003 | Hub connection | Circuit open / unavailable |
HTTP status codes
| HTTP | Typical cause |
|---|---|
200 | OCPI success (status_code: 1000) or OCPI error in body |
401 | Missing/invalid token or suspended party (status_code: 2000) |
403 | Forbidden (e.g. command "Not routed") |
404 | Endpoint or resource not found |
429 | Rate limit (status_code: 2901) |
502 | Partner unavailable / Hub forward failure |
504 | Partner timeout on authorize |
Parse HTTP and envelope together
Authorize Hub-side failures return HTTP 504/502 with OCPI 4002/4003 and usually data.allowed: UNKNOWN. Unknown token from the eMSP returns HTTP 404 with OCPI 2004. Always read HTTP status, status_code, payload fields, and status_message.
Lifecycle-specific Hub messages
| Condition | HTTP | OCPI | Payload / status_message | Hub retry? |
|---|---|---|---|---|
| Authorize not routed / unknown CPO | 200 | 1000 | allowed: NOT_ALLOWED | No |
| Authorize unknown token (eMSP) | 404 | 2004 | no data / "Unknown Token" | No |
| Authorize timeout | 504 | 4002 | allowed: UNKNOWN, "CPO authorize timeout" | No |
| Authorize unavailable / circuit | 502 | 4003 | allowed: UNKNOWN + class message | No |
Authorize unknown OCPI-to peer | 404 | 4001 | party not found | No |
| Command not routed | 403 | 2000 | "Not routed" | No |
| Command unknown location / session | 404 | 2003 | "Location not found" | No |
| Command forward timeout | 502 | 4002 | "CPO command forward timed out" | No |
| Command circuit / unavailable | 502 | 4003 | "CPO command forward unavailable" | No |
| Callback → eMSP failed | 502 | 2000 | "Failed to forward command callback to eMSP" (+ timeout variant) | No |
| Async session/CDR forward failed | — | — | Not returned on CPO PUT/POST | Transient only |
Sync vs async retry
Hub does not retry sync authorize/commands to the CPO. Hub does retry async pushes to eMSP receivers for timeout/unavailable only; permanent partner errors are not retried. See Session Lifecycle and Async Delivery.
Common integration errors
| Error / symptom | Likely cause | Resolution |
|---|---|---|
2000 + HTTP 401 on all requests | Invalid or revoked token | Re-check credentials; see Token Rotation |
| Empty location list | No routing rules | Enable routing |
Authorize NOT_ALLOWED (expected routed pair) | No routing rule or unknown CPO | Enable routing; not the same as command "Not routed" |
Authorize UNKNOWN + HTTP 504 | CPO authorize timeout | Check CPO; eMSP may retry |
Authorize UNKNOWN + HTTP 502 | CPO unavailable / circuit / incomplete | Connection Health |
Command "Not routed" | No routing rule | Enable routing |
Command "CPO command forward timed out" / "... unavailable" | CPO down or slow | Fix CPO; eMSP may re-issue (Hub does not retry) |
Command REJECTED | EVSE busy, invalid target, or CPO rejection | Verify location/EVSE IDs; resolve eligibility |
| Session not delivered | Missing cdr_token | CPO must set eMSP identity on session |
| Async delivery failure | eMSP receiver down or permanent error | Fix receiver; pull backfill; support re-drive if needed |
Invalid CountryCode & PartyId combination (HTTP 400) on eMSP receiver | P2P-style path validation | Accept CPO keys from HubClientInfo + routing; see Hub Receiver Identity (eMSP) |
Role enforcement
The Hub enforces party roles on outbound calls partners make to the Hub:
| Error | Meaning |
|---|---|
| CPO-only endpoint called by eMSP | Wrong role for this operation |
| Party mismatch on Hub API | URL path {country_code}/{party_id} does not match your authenticated party when calling Hub |
Inbound receiver validation is different
When Hub pushes to your eMSP receivers, path {country_code}/{party_id} identifies the owning CPO, not your authenticated party and not Hub (CIH). Do not apply the party-mismatch rule from outbound Hub calls to inbound async pushes. See Hub Receiver Identity (eMSP).
Logging for support
Include these in support requests:
X-Request-IDandX-Correlation-IDfrom request/response headers- Timestamp (UTC)
- Endpoint and HTTP method
- Request and response bodies (redact tokens)