OCPI 2.2.1 · CPO simulator

A CPO that isn't real.Sessions that are.

Register your eMSP backend against an OCPI 2.2.1 CPO. Connect an EV, start a session, watch the energy accrue, and pull the CDR — in development, in CI, and against production.

  • No partner CPO required
  • No car at a charger
  • Deterministic in CI
$ curl -H "Authorization: Token $TOKEN" \
    https://acme.sandbox.plugbench.dev/ocpi/versions

{ "data": [ { "version": "2.2.1", "url": "…/ocpi/2.2.1" } ],
  "status_code": 1000,
  "timestamp": "2026-08-02T09:14:22Z" }

You cannot test what you cannot talk to.

  • Your integration is blocked on a partner contract.
  • Your test needs a car plugged into a real charger.
  • Your callback bug only happens at 03:00, in production.

How it works

Three steps to a CDR.

  1. 01

    Point at the versions URL

    GET /ocpi/versions with your bootstrap token. Discovery returns absolute module URLs and interface roles, exactly as a real CPO would.

  2. 02

    Complete the handshake

    POST your credentials and get a generated token back. Rotate it with PUT. Deregister with DELETE. Then do it all again.

  3. 03

    Drive it

    Connect an EV, swipe an RFID token or send START_SESSION. Power tapers as the battery fills. One immutable CDR falls out the other end.

What it does

A backend that argues back.

  • Callbacks arrive out of order. On purpose.

    Request order never implies callback order. So you find out today whether you really correlate on response_url — instead of at 03:00 next February.

  • Nine modules, not a stub

    Versions, Credentials, Locations, Tariffs, Sessions, CDRs, Tokens, Commands and Charging Profiles. Real envelopes, real X-Total-Count and Link headers, real four-digit status codes.

  • Break it deliberately

    Force any remote command to be rejected, to stall for up to 60 seconds, to fail — or to never call back at all.

  • Deterministic by design

    Scenarios are JSON. A reset restores byte-equivalent state and the same identifiers. Same test, same result, every run.

  • Charging that behaves

    EV profiles with real battery sizes, AC and DC limits and connector compatibility. Set a starting and a target SOC; power tapers as the battery fills; reaching the target stops delivery.

    The plugbench console showing two electric vehicles charging at once: a Tesla at 24.8% toward an 80% target drawing 250 kW from a CCS high-power charger on the HPC tariff, and a Renault Zoe at 63.4% drawing 22 kW from a Type 2 AC connector on the default tariff.Open full size
  • The handshake, end to end

    Register, rotate, deregister — the part that breaks first, and the part no hand-written mock ever covers.

    The plugbench console showing a registered eMSP peer: announced OCPI endpoints with sender and receiver roles, an empty delivery queue, and the peer token masked until revealed.Open full size
  • Every request, both directions

    Inbound and outbound attempts with exponential-backoff retries, durations and OCPI status codes. Credentials redacted, always.

    The plugbench outbound request journal showing a network error on its third attempt, a ten-second timeout, an HTTP 503 followed by a successful retry, and an HTTP 200 carrying OCPI status 2001.Open full size

Where it runs

Development, CI, and production.

  • In development

    A sandbox endpoint your local stack registers against. No infrastructure to run, no database to babysit.

  • In your pipeline

    Deterministic fixtures behind a reset, so a red build means your code changed — not the world.

  • Against production

    A permanent peer your live stack registers with, for end-to-end synthetic checks on the real path.

Who builds it

Built by an EMP that runs it in production.

EV-Freaks builds ChargEV FleX, a live E-Mobility Provider. plugbench is what we test it with, every day. No customer logos and no testimonials — the protocol either works or it doesn't.

Ready to break something?

Tell us what you're integrating. You get a sandbox endpoint and a bootstrap token.