Create a client session
Says who Link acts for, and what it may reach, for 60 minutes. Call it from the one endpoint your app’s
fetchClientSecret calls and return client_secret to the SDK, or send a browser to web_url (append
&action=…&charger_id=… for an action other than add). Link opens any number of link sessions with it
until it expires, then asks your app for a new one.
Without external_user_id the client session is for your own chargers. With it, it is for one of your
users: the first client session for an external_user_id creates that user, and their first link
session shows them a consent screen with your name and logo. A Plugchoice user calling with their own
token acts for themselves.
The scope (required) is everything its link sessions may reach, so the secret can’t be used on the
rest of your fleet: the chargers to work on, the sites to add chargers to (and work on any charger at
them), one address to add chargers at (location), and whether add may make a new site at an address
the hosted flow asks your user for (new_site). Name at least one (422 scope-required), at most 100 ids
per list. Every id is checked now (404 not-found for one you may not use), so a scope can only narrow
your access; there is no “everything”. What you may name:
| Caller | Chargers and sites | location or new_site |
|---|---|---|
Integration, without external_user_id (your own chargers) | At sites your team owns | Creates a site in your team |
Integration, with external_user_id (one of your users) | At that user’s sites | Reuses the user’s site with the same reference, else creates one in your team |
| Plugchoice user | At sites they have Sensitive access to | Creates a site in their current team |
Once an add link session has made the site of location (when it starts) or a new site (when the
hosted flow has the address), later link sessions of the same client session add to that site.
The other fields are defaults for every link session: the language, the colour scheme, the brand and methods offered, and your label for the charger.
Authorizations
Your integration's client credentials (test or live). The token acts as your integration's team and
lasts 1 hour; request a new one when it expires. Send client_id, client_secret and
grant_type=client_credentials. No OAuth scopes are needed.
- Token URL
- https://app.plugchoice.com/oauth/token
Headers
The API version to answer with (400 unknown-version for one this API does not know). Every response carries the version that answered in the same header.
2026-10-07 Body
Everything the client session's link sessions may reach. At least one of them (422 scope-required); every id must be one
you may use (404 not-found).
Integrations only. For this user of yours; turns on the consent screen. Without it, your own chargers.
1 - 200^[A-Za-z0-9._:@-]+$The kind of device. Only chargers for now; another type is 422 unsupported-device-type.
charger BCP 47 tag for the hosted flow. Unsupported languages fall back to English.
"nl"
light, dark, system A catalog vendor id (for example peblar). Skips the brand picker.
Limit the onboarding methods offered. Default all.
How a charger gets connected:
local_hotspot: the SDK joins the charger's own Wi-Fi and configures it (Peblar).local_lan: the SDK finds the charger on the home network, or joins its setup hotspot, signs in to it over the brand's pinned HTTPS and configures it (Alfen). The identity is read from the charger.manual_ocpp: the user types the identity and configures the charger themselves; any OCPP charger, works in a browser.vendor_cloud: Plugchoice switches the charger over in its brand's cloud after the user signs in there with the charger owner's account (Zaptec); works in a browser.
More may be added.
local_hotspot, local_lan, manual_ocpp, vendor_cloud Integrations only. Your own label for the charger being added; returned as reference.
255Browser only. Where the hosted flow sends your user when a link session is done; it must be on your integration's allow-list (for a Plugchoice user, a Plugchoice or custom domain of theirs). The SDK ignores it and returns to your app.
Response
Created
Hand it to the SDK (your fetchClientSecret returns it). cs_test_ for a test integration,
cs_live_ otherwise, then 32 random bytes base64url. Opaque; never log it.
"cs_live_Hq3k9d0mR2xYw7pLf8sVb1nC4eTgJ6aZuQ5iKoXyM0w"
Link can open link sessions with it until then (60 minutes).
Link in a browser, with the client secret in the fragment (never sent to a server). Append &action=…&charger_id=… for an action other than add.
"https://connect.plugchoice.com/#cs=cs_live_Hq3k9d0mR2xYw7pLf8sVb1nC4eTgJ6aZuQ5iKoXyM0w"