Developer Guide
OAuth 2.0 Client Credentials
Authenticate server-side integrations without a user session using the industry-standard Client Credentials flow (RFC 6749 §4.4).
Overview
The Client Credentials grant is designed for server-to-server integrations where there is no user present - CI pipelines, cron jobs, backend services, and SaaS platform integrations. Your application exchanges a client_id / client_secret pair for a short-lived Bearer access token.
Token endpoint
POST https://pollslive.com/api/oauth/tokenToken TTL
3600 seconds (1 hour)Plan required
Pro or EnterpriseWhen to use OAuth vs API keys
| Scenario | Recommended credential |
|---|---|
| Personal automation / scripts | API key (plv_live_…) |
| Internal server process, one workspace | API key |
| SaaS product integrating PollsLive for multiple customers | OAuth Client Credentials per customer workspace |
| Zero-trust rotation without downtime | OAuth (tokens expire automatically) or API key rotation |
| Scope-limited third-party access | OAuth with scopes |
1. Create an OAuth client
Go to Studio → Developer API → OAuth 2.0 Clients and click Create OAuth client. Give the client a descriptive name (e.g. My Backend Service) and optionally narrow the scopes.
Alternatively, use the management API:
curl -X POST https://pollslive.com/api/oauth/clients \
-H "Cookie: next-auth.session-token=<your session>" \
-H "Content-Type: application/json" \
-d '{
"name": "My Backend Service",
"scopes": ["polls:read", "polls:write"]
}'
# Response (save clientSecret - shown exactly once):
# {
# "client": { "id": "…", "clientId": "plv_cid_…", "name": "My Backend Service", … },
# "clientSecret": "plv_cs_…"
# }clientSecret immediately. Like an API key, it is shown exactly once and never stored in plaintext.2. Get an access token
Send a POST request to the token endpoint using application/x-www-form-urlencoded (the RFC standard) or application/json (for convenience):
curl -X POST https://pollslive.com/api/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=plv_cid_…&client_secret=plv_cs_…&scope=polls:read polls:write"curl -X POST https://pollslive.com/api/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "plv_cid_…",
"client_secret": "plv_cs_…",
"scope": "polls:read polls:write"
}'{
"access_token": "plv_oauth_…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "polls:read polls:write"
}Errors follow RFC 6749 §5.2 format: { "error": "invalid_client", "error_description": "…" }
3. Use the token
Include the access_token as a Bearer token on every API request - exactly the same as an API key:
curl https://pollslive.com/api/v1/polls \
-H "Authorization: Bearer plv_oauth_…"Your application should cache the token and re-request only when expires_in is approaching (e.g. refresh when less than 5 minutes remain).
Token lifetime & refresh
Tokens are valid for 1 hour (expires_in: 3600). There is no refresh token - simply request a new token with your client credentials when the current one expires. Since this is a server-side flow, the client secret never leaves your backend.
let token = null;
let expiresAt = 0;
async function getToken() {
if (token && Date.now() < expiresAt - 5 * 60 * 1000) return token;
const res = await fetch("https://pollslive.com/api/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "client_credentials",
client_id: process.env.OAUTH_CLIENT_ID,
client_secret: process.env.OAUTH_CLIENT_SECRET,
}),
});
const data = await res.json();
token = data.access_token;
expiresAt = Date.now() + data.expires_in * 1000;
return token;
}Scopes
Scopes let you limit what an OAuth client can do. If you don't specify any scopes when creating the client, it inherits full workspace access (equivalent to an API key).
See the full Scopes Reference for the complete list.
Revoke a client
Revoking a client immediately invalidates all tokens issued for it. Existing in-flight requests using a token will fail with 401 invalid_oauth_token.
curl -X DELETE https://pollslive.com/api/oauth/clients/CLIENT_DB_ID \
-H "Cookie: next-auth.session-token=<your session>"Or go to Studio → Developer API → OAuth 2.0 Clients and click Revoke.
Still have questions?
Our team is happy to help.