Authenticating your application
The Application Marketplace is under active development and may change without long deprecation windows. See the Application Marketplace overview.
Authentication is standard OpenID Connect: Authorisation Code flow with PKCE (S256). There is nothing Road-specific to implement, so you can use an off-the-shelf OAuth/OIDC client library. The authorize step happens on the provider dashboard (so the customer consents in their familiar branded environment); the token, userinfo and JWKS endpoints live on the Road API.
Public vs confidential clients
- Confidential clients hold a
client_secret(provider installations and templates). The secret is presented at the token endpoint. Keep it on a server you control; never ship it to a browser or mobile binary. - Public clients have no secret (dynamic registrations, and any client that can not keep one). Single-page apps, browser extensions, mobile and desktop apps are all public clients. Do not embed or display a secret in the browser.
If your application runs in the browser, it is a public client. Register it as one and rely on PKCE.
PKCE is required for all clients
Per OAuth 2.1, PKCE with S256 is mandatory for every client, public and confidential alike. On each authorisation you generate a random code_verifier, send its S256 challenge on the authorize request, and present the verifier on the token exchange. A missing or mismatched verifier fails the exchange.
Discovery
GET https://api.road.io/1/oauth/road/.well-known/openid-configuration
Returns a standard discovery document. Key fields:
authorization_endpointpoints at the provider dashboard. Open it in the user's browser; do not call it from a back channel.token_endpoint,userinfo_endpoint,jwks_urilive on the Road API.registration_endpointis present only when dynamic registration is enabled for the provider.scopes_supportedlists the scopes Road recognises.response_types_supported: ["code"],grant_types_supported: ["authorization_code", "refresh_token"],code_challenge_methods_supported: ["S256"],token_endpoint_auth_methods_supported: ["client_secret_post", "none"].
ID tokens are signed RS256; verify them against jwks_uri.
The flow
Consent grants scopes only. For applications that request a data scope, the customer also chooses which resources to share; that step is handled separately from the protocol. See Consent, grants and data sharing.
Authorisation request
The application redirects the user to:
{authorization_endpoint}?
client_id={client_id}&
redirect_uri={your_callback}&
response_type=code&
scope=openid+offline_access+sessions:read+chargers:read&
state={csrf_token}&
code_challenge={base64url_sha256(verifier)}&
code_challenge_method=S256&
nonce={random}
The redirect_uri must be registered on the client; unregistered URIs are rejected.
Forcing or skipping the consent UI (prompt)
The standard OIDC prompt parameter is honoured:
prompt | Behaviour |
|---|---|
| (omitted) | Show consent only if needed. If an active grant already covers the requested scopes, auto-approve and redirect immediately. |
consent | Always show consent; never auto-approve. Useful to let the user adjust their data sharing. |
none | Never show UI. Either a code is returned, or a standard error redirect: ?error=login_required, consent_required, or interaction_required. Use in a hidden iframe for silent refresh. |
Token exchange
POST {token_endpoint}
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code={code}&
client_id={client_id}&
client_secret={client_secret}&
redirect_uri={your_callback}&
code_verifier={pkce_verifier}
Confidential clients include client_secret. Public clients omit it: PKCE alone authenticates the exchange. The response is the standard OIDC token envelope:
{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "...",
"refresh_token": "..."
}
For refreshing tokens and calling the API, see Using the API.
Grants are scoped to the user
A grant authorises one application for one user. It records the scopes that user approved. Different users of the same application each have their own grant, and each token acts only for the user it was issued to. Revoking a grant disconnects the application for that user only.
Verifying the ID token
Verify iss, aud (your client_id), exp, and the signature against the JWKS at {issuer}/.well-known/jwks.json. The kid header indicates which JWKS entry to use. Pass a CSRF-resistant state on the authorize request and check it on the callback; Road round-trips state faithfully on success and error redirects.