Authentication
How to authenticate with the Data API
The Data API uses OAuth2 Authorization Code Flow (PKCE optional, recommended) and refresh tokens. Every request (except the initial browser redirect to the authorization server) must carry a Bearer access token as an Authorization header.
You first create an OAuth2 client in the management UI at Manage clients. Then you run the flow in your app. Tokens represent the end user (resource owner) and are scoped by the permissions (scopes) they consented to.
Flow summary
See Quick start for a step-by-step guide.
Authorization
Redirect user to Tibber authorization endpoint with
response_type=codeclient_idredirect_uriscopelist- (add PKCE params if you choose to use PKCE)
User consent
User logs in and reviews consent screen (new scopes only)
Redirect back
User is redirected back to your redirect_uri with
code(short-lived)state(if you sent one)
Token exchange
Your backend exchanges the code (plus code_verifier if you used PKCE) and client credentials for access + refresh tokens
Exchange code for tokens (POST to token endpoint with)
grant_type=authorization_codecoderedirect_uriclient_idclient_secret(omit if using PKCE)- (include
code_verifierif using PKCE) Response includes access_token(short-lived, ~1 hour)refresh_token(long-lived, ~30 days, store securely server-side)
API requests
Use access_token in Authorization header; store refresh_token securely server‑side (never expose to frontend)
Token refresh
When access_token expires, use refresh_token to get a new access_token (and often a new refresh_token)
Refresh tokens are long‑lived (~30 days) but may be one‑time use only (rotate after use)
Refresh request (POST to token endpoint with)
grant_type=refresh_tokenrefresh_tokenclient_idclient_secret(omit if using PKCE) Response includes- new
access_token - often a new
refresh_token(rotate securely server-side)
Endpoints (authorization server)
- Authorization:
GET https://thewall.tibber.com/connect/authorize - Token:
POST https://thewall.tibber.com/connect/token
Required baseline scopes
Always request the standard OpenID scopes you need plus at least the user + category scopes relevant to your queries. Minimal useful set for listing homes & devices:
openid profile email offline_access data-api-user-read data-api-homes-readAdd device category scopes like data-api-vehicles-read, data-api-chargers-read, etc. See Scopes.
Access tokens
- Format: JWT (opaque to you; treat as bearer)
- Lifetime: ~1 hour (do not rely on exact value; best to store and check
expires_infrom response, or react to401 Unauthorized) - Present via header:
Authorization: Bearer <token>
Refresh tokens
- Long‑lived (rotating / one‑time usage policy may apply)
- Store securely; rotate after use if you get a new one back
- Do not embed in mobile app binaries or ship to browsers
Revoking access
Deleting a client in the UI (Manage clients) invalidates future refresh operations; existing access tokens naturally expire.
Personal access tokens
While the older GraphQL API supports personal access tokens (PATs) for historical reasons, the Data API does not, and we have no plans to support them.
PKCE (optional, recommended)
PKCE adds protection for public or semi‑public clients by binding the code to a one‑time verifier. It is optional for this API, but recommend using it unless you have a strictly confidential server‑only integration.
Implementation outline:
- Generate a high‑entropy
code_verifier(43–128 chars) - Compute S256
code_challenge=BASE64URL(SHA256(code_verifier)) - Add
code_challenge+code_challenge_method=S256to the authorize URL - Include the original
code_verifierin the token request
If you skip PKCE: just omit the challenge parameters. All other steps are unchanged.
Error handling
| Scenario | HTTP | Notes |
|---|---|---|
| Expired access token | 401 | Refresh then retry once |
| Invalid scope | 403 | Token lacks required category scope |
| Missing token | 401 | Add header |
Further guidance
See operational guidance in:
Next
Continue with the Quick start or review Managing clients.
