Roam OCPI FAQ
About Roam OCPI
Read a summary about Roam OCPI: About Roam OCPI →
What is Roam OCPI?
Roam OCPI is Plugsurfing’s OCPI-based roaming interface designed to share the entire Plugsurfing network to EMPs via a single OCPI integration. It includes managed roaming (agreements, communication and invoicing handled by Plugsurfing).
What does “managed roaming” include?
Managed roaming means Plugsurfing handles the roaming network operations: CPO relationships, commercial negotiation, technical onboarding, quality assurance, price/tariff management, support, invoice processing, reconciliation, CDR validation, and CPO dispute handling.
Which OCPI version is used?
Roam OCPI is exposed to EMPs as an OCPI 2.2.1 integration. Some underlying CPO integrations may still use OCPI 2.1.1 or other protocols, which can affect edge cases such as token/CDR attribution.
What are the main deviations from standard OCPI?
The deviations to OCPI 2.2.1 are lined out under each module.
Which OCPI modules are supported (pull/push)?
How is Roam OCPI different from Drive API?
Roam OCPI is a separate product from Drive API. Use Roam OCPI for managed roaming through OCPI 2.2.1. Do not mix Drive API endpoints, user flows, payment flows, charging-key ordering, AI tooling, or proprietary session flows with Roam OCPI module documentation.
Access and limits
Read the details of how to access the API here: Accessing the API →
How do we authenticate / is IP filtering used?
Plugsurfing does not currently use IP filtering to access the API. Access control is based on the API key exchanged during the Credentials module handshake.
Are IDs unique across all CPOs exposed via Roam OCPI?
Yes — the following IDs are unique across all CPOs exposed via the API: Location id, EVSE uid, Connector id, Tariff id, Session id, CDR id.
Are rate-limit backoff headers returned?
If the limit is reached, Plugsurfing returns HTTP 429. Currently, no rate-limiting headers such as Retry-After are returned. Location pull is allowed up to once per minute, excluding pagination.
Rate limiting / fair usage
Per-minute limit: A maximum of 3,000 requests per clock minute (e.g., from 12:07:00 to 12:07:59). Per-day limit: A maximum of 1,000,000 requests per calendar day (from 00:00 to 23:59 UTC). Soft limit for Roam OCPI Location pull: up to once per minute (pagination excluded).
Related documentation: Fair usage policy →
Credentials
Read the details of the Credentials module deviations and specifications here: Credentials module →
What do we receive during the Credentials handshake?
During the Credentials handshake, Plugsurfing assumes the CPO role with business name Plugsurfing, country_code = DE, and party_id = 8PS. The roles list contains only this Plugsurfing CPO role. Plugsurfing does not use HubClientInfo. The actual CPO/operator is communicated through Locations using country_code, party_id, and the operator field.
How do we know which operators are part of the solution?
Operators are identified through the Locations feed, not through the Credentials roles list. During the Credentials handshake, Plugsurfing is shared as the CPO role with country_code = DE and party_id = 8PS. The actual CPO/operator information is communicated in each Location object using the connection owner’s country_code + party_id and the operator field. There might be several operators linked to one country_code + party_id combination. If a CPO is removed, its Locations will no longer appear in Location pulls.
How are new CPOs added after go-live? Do partners need a new handshake?
For standard Roam OCPI setups using the Plugsurfing role DE*8PS, partners do not need a new handshake when CPOs are added or removed. New CPOs are reflected through new locations becoming available in the Location pulls. If a CPO is removed, its locations will no longer be part of the Location pull.
Retrieving locations
Read the details of the Locations module deviations and specifications here: Locations module →
Can we connect to specific CPOs, or do we subscribe by country?
Production setup is country-based: all locations within your selected countries are available to you. You cannot select only a subset of CPOs to include, but you can request specific CPOs to be filtered out (blocked). Newly added CPOs within your supported countries are available by default.
How do full and delta pulls work?
Locations are pulled by the EMP; Plugsurfing does not push Locations, EVSEs, or connectors. A full pull using GET /locations builds or reconciles the complete cache. A full pull is recommended e.g. once per 24h so that you can remove locations that are no longer available. Delta pulls using date_from / date_to return locations where location data or inlined tariff data has changed during the specified time period. Delta pulls can be performed up to once per minute.
How often should partners pull Locations?
For status and tariff freshness, partners should use delta pulls. We recommend every 1–5 minutes depending on the partner’s use case and traffic profile.
How does Location pagination work?
Maximum page size is 250 locations. Plugsurfing does not use deep pagination; partners should follow the next-page URL in the Link response header. The Link header contains a smart_paging parameter. Parallel pulling of Locations is not supported because smart pagination is used.
How are removed Locations handled?
Removed locations are detected through a full pull: if a previously available location is absent from the full pull, it should be removed from the partner’s system. A nightly full pull is recommended.
Can a Location be delivered without a name?
The name field (display name of the location) is optional in OCPI 2.2.1, so some locations can be delivered without a name.
Which EVSE capabilities are supported?
The following capabilities are supported, and they will be returned from the EVSEs the API: CHIP_CARD_SUPPORT, CONTACTLESS_CARD_SUPPORT, CREDIT_CARD_PAYABLE, DEBIT_CARD_PAYABLE , PED_TERMINAL, REMOTE_START_STOP_CAPABLE, RFID_READER, START_SESSION_CONNECTOR_REQUIRED. The following capabilities are not supported, and they will be stripped from the EVSEs returned via the API: CHARGING_PROFILE_CAPABLE, CHARGING_PREFERENCES_CAPABLE, RESERVABLE, TOKEN_GROUP_CAPABLE, UNLOCK_CAPABLE.
Does Plugsurfing support OCPI routing headers?
Plugsurfing currently does not support routing headers like OCPI-to-country-code, OCPI-to-party-id, OCPI-from-country-code, OCPI-from-party-id.
How are tariffs represented?
The relevant tariffs are inlined on the connector, via the locations module.
When a CPO updates tariffs, will `last_updated` change on Locations?
Tariff updates are exposed through the Locations module because tariffs are inlined on connectors. Delta pulls using date_from / date_to return Locations where either Location data or inlined tariff data has changed. Partners should process the returned Location and inlined tariff object, including the tariff’s own last_updated.
How should partners treat tariff IDs?
Treat tariff IDs as stable identifiers. Tariffs are immutable, which means that the tariff content associated with a specific tariff_id will not change after it has been issued.
Tokens and authorization
Read the details of the Tokens module deviations and specifications here: Tokens module →
What do partners need to send?
Token pull is not supported; EMPs must push new or updated tokens to Plugsurfing. Tokens must be pushed before remote start is initiated. By default, tokens are shared with CPOs using issuer DE*8PS.
Are all token types supported?
AD_HOC_USER is not supported.
How do whitelist types work?
Roam OCPI accepts OCPI whitelist types. NEVER and ALLOWED_OFFLINE are forwarded to CPOs. ALWAYS and ALLOWED are overwritten to ALLOWED_OFFLINE when shared with CPOs. Token whitelist type controls behavior between Plugsurfing and the CPO; real-time authorization between Plugsurfing and the EMP is controlled by an organization setting in Plugsurfing Power Portal.
How does real-time authorization work?
Real-time authorization can be configured per organization by Plugsurfing. If enabled, Plugsurfing performs primary checks first, including whether the Location is within supported countries based on an existing Location reference and whether the key is enabled. If those checks pass, Plugsurfing forwards the authorization request to the EMP. Timeout is configurable from 1–10 seconds, and timeout/malformed-response behavior can be configured to accept or deny.
Can partners block charging attempts for unknown or unsupported locations?
They can get tighter control by using whitelist=NEVER, enabling external real-time authorization, and denying authorizations when the location reference is missing or unknown. This improves control but can negatively affect driver experience because not all CPOs do real-time authorization for all sessions and not all authorization requests include a resolvable location reference.
Can multiple tokens share one `contract_id`?
Yes, if configured. By default, one key is supported per contract_id, but an organization can be configured to support multiple keys per contract_id. A maximum of 25 tokens per contract_id applies. If an older CPO integration only provides the contract_id in a local-start CDR, Plugsurfing may not be able to identify the exact charging key and will pick the first key matching that contract_id. The X-Original-Protocol header on outgoing Session/CDR requests can help identify when this limitation may apply.
What happens if multiple tokens share one `contract_id` and an old CDR arrives later?
When multiple tokens share the same contract_id, some upstream protocols may not identify the exact key used in a CDR. In those cases, Plugsurfing matches the CDR to the first token with that contract_id. The X-Original-Protocol header can be used to understand when this limitation may apply.
What is `X-Original-Protocol`?
X-Original-Protocol is a header available on outgoing Session and CDR requests in cases where there may be uncertainty about the exact charging key used. This can happen when multiple tokens share the same contract_id and an older upstream protocol only provides the contract_id in the CDR. The header contains <protocol>-<version>, for example OCPI-2.1.1, OCPI-2.2, OCPI-2.2.1, or OICP-2.3.
Can `contract_id` be changed after a token has been pushed?
Allow change of contract_id is based on an organization setting, please create a support ticket to learn about or update the setting for your organization.
Why does `contract_id` come back in a different format (with dashes)?
Plugsurfing normalizes incoming contract_id to a consistent format for downstream partners, and the original formatting is not preserved. You may see the normalized version in sessions/CDRs. Example: DE8PSABCDEFGHI1 becomes DE-8PS-ABCDEFGHI-1
Can partners have multiple `contract_id` prefixes?
Multiple prefixes are allowed for contract_id. Plugsurfing needs a list of the contract_id prefixes before tokens are pushed, as those have to be registered in the Plugsurfing portal as well as with some CPO partners before you can roam with them.
Why would a Location reference be missing in authorization?
The location reference is optional in OCPI. Hence, some real-time authorization requests may not include a usable Location reference. This depends on the CPO and originating protocol. Plugsurfing can check whether a Location is within the supported countries when a resolvable Location reference is provided, but partners should not assume that location_id is always available in the authorization flows.
Can charging be restricted by supported countries?
Plugsurfing can restrict charging to specific countries via the EMP's Supported Countries list, and deny starts when the CPO sends online authorization with a resolvable location reference. Limitations: if a station/CPO does offline starts / no online authorization, we can't fully guarantee blocking. To tighten this, set field whitelist=NEVER (vs default ALLOWED_OFFLINE). By requiring real-time auth with whitelist = never and denying real-time auth request where the location reference is missing or unknown, you have full control.
Commands
Read the details of the Commands module deviations and specifications here: Commands module →
Which remote commands are supported?
START_SESSION and STOP_SESSION are supported. RESERVE_NOW, CANCEL_RESERVATION, and UNLOCK_CONNECTOR are not supported. If an unsupported command is sent, an OCPI response with result NOT_SUPPORTED is returned.
Sessions
Read the details of the Sessions module deviations and specifications here: Sessions module →
How are Sessions delivered, and are pull/PATCH updates supported?
Sessions are push-only. Plugsurfing pushes Sessions to the EMP; Session pull is not supported. For generic payload examples, refer to the OCPI 2.2.1 Sessions module examples. We support PATCH updates for incremental kWh data during an ongoing session, but not for charging periods.
CDRs
Read the details of the CDRs module deviations and specifications here: CDRs module →
When and how are CDRs delivered?
CDRs are pushed by Plugsurfing to the partner once they are received by the CPO and fully processed. You should expect one CDR per completed charging transaction
Can CDRs be delayed?
CDR timing depends on when the CPO provides the CDR and whether processing, validation, or dispute handling is needed. Some CDRs may be delivered shortly after the session, while others can be delayed.
What is the retry behavior of CDRs?
If the EMP does not respond with HTTP 200, the CDR will be resent nightly for up to 7 days.
Are credit CDRs supported?
No, credit CDRs are not supported.
Is the CDR ID always the same as the Session ID?
When there is a Session ID, the CDR ID is always the same as the Session ID.
Can a CDR be sent without a Session ID?
Yes. Not all CPOs behind Roam OCPI support the Sessions module. There may also be very short sessions where the CDR is created before the session event is delivered.
Is cost breakdown always populated?
Yes. Even when the CPO does not provide cost breakdown per tariff element, Plugsurfing populates it in the CDR shared with the EMP.
Can anything be missing from CDRs?
Offline/semi-offline sessions can occur without authorization; later session messages may have no authorization_reference. Downstream OCPI 2.1.1 integrations don’t have the authorization_reference field.
Stage testing and support
What should partners test in stage?
Credentials handshake; Location full pull; Location delta pull; token push; token disable/update; remote start/stop; local-start simulation with agreed test token/location; real-time auth accept/deny and timeout/failure behavior if enabled.
What information should partners include when raising support issues?
Environment, timestamp, token UID or contract ID, CPO, EVSE ID, and Session ID when session specific. When necessary, request URL/method, request/response body, OCPI status_code/status_message, X-Original-Protocol if present, and whether issue is CPO-specific or global.
Where can partners monitor platform status?
Operational status of the Plugsurfing platform. Consider subscribing to be directly notified to get updates directly via email.
Related documentation: Plugsurfing status page →