Authenticate API requests with an OAuth 2.0 access token issued by your Wallboard server.
| Application | Flow | Client authentication |
|---|---|---|
| Browser app or CLI | Authorization code with S256 PKCE | Public client ID and code verifier; no secret |
| Server-side application | Authorization code | Confidential client ID and secret sent as token-request form fields, or the configured private-key method |
| Machine-to-machine integration | Password | Built-in default client and a user explicitly enabled as a Service Account; include TOTP if enabled |
For authorization-code flows, configure a client with the integration's callback URI and required grant types. Public clients cannot keep a secret; use PKCE.
GET /oauth/authorize with your
client_id, redirect_uri, response_type=code, scope=FULL_ACCESS and a random state.
Public clients must also send code_challenge=BASE64URL(SHA256(code_verifier)).state, then exchange the callback's code at POST /oauth/token
using application/x-www-form-urlencoded. Send the same redirect URI and client ID,
plus the PKCE verifier or confidential client credentials as appropriate.Authorization: Bearer <access_token> with subsequent API requests.The authorization-code exchange does not read HTTP Basic credentials. For a client using a secret,
send client_id and client_secret in the form body. Password and refresh grants also accept Basic
authentication. Keep confidential integration secrets in server-side applications.
Enable Service Account in the user's settings, then use the built-in client:
| Property | Value |
|---|---|
| client_id | default-client |
| client_secret | 76211db5d8ea |
| Basic Auth | Basic ZGVmYXVsdC1jbGllbnQ6NzYyMTFkYjVkOGVh |
This client supports password and refresh grants. Send grant_type=password, the service account's
username and password, and totp when 2FA is enabled. Authenticate the client with the Basic header
above or the two client form fields. The shared client credentials do not replace user authentication.
| Token | Omitted kmsi or kmsi=true |
kmsi=false |
|---|---|---|
| Access token | 30 minutes | 30 minutes |
| Refresh token | 30 days | 1 hour |
Send kmsi on the token request. It is evaluated on code exchange and every refresh,
so repeat kmsi=false when the one-hour lifetime is required.
To renew a session, send grant_type=refresh_token, the current refresh_token and client authentication
to /oauth/token. Each successful refresh consumes the old refresh token. Persist the replacement
and serialize refresh attempts for that session. HTTP 400 with error=invalid_grant can indicate an
expired, invalid or already-consumed refresh token; start a new authorization flow when renewal fails.
API requests with an expired access token return 401; insufficient permissions return 403.
OAuth-capable clients can inspect /.well-known/oauth-authorization-server for server capabilities
and /.well-known/oauth-protected-resource/mcp for the MCP resource. Registration, HTTPS Client ID
Metadata Documents and private-key authentication depend on server policy and version.
When resource is supplied during authorization and code exchange, its values must match.
Exchange an authorization code, refresh a session, or authenticate an enabled service account. Each successful refresh consumes the old refresh token and returns a replacement; serialize refresh attempts and persist the replacement. kmsi applies to each token request and defaults to true (30 days); false gives one hour. Clients must handle HTTP 400 invalid_grant for expired or already-consumed refresh tokens.
| Authorization | string Example: Basic <base64-client-id-and-secret> Client Basic authentication where supported. Confidential code exchange should send client_id and client_secret as form fields; public PKCE clients do not send a secret. |
| grant_type required | string Enum: "authorization_code" "refresh_token" "password" OAuth2 grant type |
| code | string Authorization code (for authorization_code grant) |
| code_verifier | string PKCE code verifier (for authorization_code grant with PKCE) |
| redirect_uri | string <uri> Redirect URI (must match authorization request) |
| refresh_token | string Refresh token (for refresh_token grant) |
| username | string <email> Service account email (for password grant) |
| password | string <password> Service account password (for password grant) |
| totp | string TOTP code for 2FA (if enabled on service account) |
| client_id | string Client ID. Send as a form field for authorization-code exchange; password and refresh grants also accept Basic authentication. |
| client_secret | string Confidential client secret. Send as a form field for authorization-code exchange; omit for public PKCE clients. Password and refresh grants also accept Basic authentication. |
| kmsi | boolean Default: true Refresh-token lifetime: true or omitted = 30 days; false = one hour. Evaluated on code exchange and every refresh. |
| resource | string <uri> OAuth resource binding; must agree with the authorization request when supplied. |
| client_assertion_type | string Client assertion type for a client configured for private_key_jwt. |
| client_assertion | string Signed client assertion for private_key_jwt authentication. |
curl -X POST 'https://{server}/oauth/token' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=authorization_code' \ -d 'code=AUTH_CODE_FROM_CALLBACK' \ -d 'code_verifier=YOUR_CODE_VERIFIER' \ -d 'client_id=your-client-id' \ -d 'redirect_uri=https://your-app.com/callback'
{- "access_token": "<access-token>",
- "token_type": "bearer",
- "expires_in": 1800,
- "refresh_token": "a5fc1f68-8f7d-43b7-937c-68729b3b4f17",
- "refresh_total_validity_seconds": 2592000,
- "customerId": 0,
- "readOnly": false
}