JouloDocs

Authentication

OAuth 2.0 client-credentials (machine-to-machine) with per-scope access.

Authentication

The Integrated API uses OAuth 2.0 client credentials (RFC 6749 §4.4). Your client is a machine identity bound to one CPO partner — there is no end user behind the token.

Get your credentials

Joulo provisions an OAuth client for your partner and gives you a client_id and client_secret, plus the scopes your integration needs. The secret is shown once.

Store the client_secret in a secrets manager. If it leaks, ask Joulo to rotate it • the old secret stops working immediately.

Request a token

POST https://api.joulo.nl/functions/v1/oauth-token

curl -X POST https://api.joulo.nl/functions/v1/oauth-token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "your-client-id",
    "client_secret": "your-client-secret"
  }'
{
  "access_token": "9f456b04e72e749c...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "cpo:accounts:write cpo:mandates:write cpo:sessions:write cpo:chargers:write"
}

The token is valid for one hour. There is no refresh token — for machine-to-machine access you simply request a new token when the old one expires (re-presenting your credentials).

You may narrow a token to a subset of your scopes by passing a space-separated scope parameter; omit it to receive all scopes granted to your client.

Call the API

Send the token as a bearer token on every request:

curl https://api.joulo.nl/functions/v1/api/v1/accounts \
  -H "Authorization: Bearer 9f456b04e72e749c..."

Scopes

Access is fail-closed: an endpoint you lack the scope for returns 403 Insufficient scope, and unknown routes return 404.

ScopeGrants
cpo:accounts:readGET /v1/accounts
cpo:accounts:writePOST /v1/accounts
cpo:mandates:writePOST /v1/mandate-links
cpo:chargers:writePOST /v1/chargers
cpo:sessions:writePOST /v1/sessions:batch

Errors

HTTPerrorMeaning
400unsupported_grant_typegrant_type must be client_credentials
400unauthorized_clientYour client isn't provisioned for client credentials
400invalid_scopeRequested scope exceeds what your client was granted
401invalid_clientUnknown client or wrong secret
403cpo_token_requiredThe /v1 API needs a client-credentials token
403client_not_linkedYour client isn't linked to a partner yet — contact Joulo