Developer Guide

Rate Limits & Errors

The PollsLive API uses per-key rate limits and returns consistent JSON error objects with machine-readable codes.

Rate limits

Limits are enforced per API key (or per OAuth client) using a Redis fixed-window counter. Exceeding the limit returns 429 Too Many Requests.

Endpoint groupLimitWindow
All /api/v1/ endpoints120 requests1 minute
POST /api/v1/media30 requests1 minute
POST /api/oauth/token10 requests1 minute per client_id

Enterprise plan customers can request higher limits. Contact our team.

Rate limit headers

Every API response includes rate limit metadata headers:

Response headers
X-RateLimit-Limit: 120
X-RateLimit-Window: 60s

Exceeding the limit returns 429 with the rate_limited error code. The window is a fixed 60-second bucket - wait for it to reset before retrying.

Error response format

All API errors return a JSON body with a nested error object containing a machine-readable code and a human-readable message:

Standard error
HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "error": {
    "code": "not_found",
    "message": "Poll not found."
  }
}

Validation errors return 422 with a details field inside the error object:

Validation error
{
  "error": {
    "code": "validation_failed",
    "message": "Request validation failed.",
    "details": {
      "fieldErrors": { "title": ["String must contain at least 1 character(s)"] },
      "formErrors": []
    }
  }
}

OAuth token errors follow RFC 6749 §5.2 format instead:

OAuth error
{
  "error": "invalid_client",
  "error_description": "Invalid client credentials."
}

Error codes

HTTP statuscodeMeaning
400invalid_jsonRequest body is not valid JSON
401missing_authorizationNo Bearer token provided
401invalid_api_keyUnknown or incorrect API key
401revoked_api_keyKey was revoked
401expired_api_keyKey expired after rotation
401invalid_oauth_tokenOAuth token is invalid or expired
402upgrade_requiredAction requires Pro/Enterprise plan
403insufficient_scopeCredential lacks the scope this endpoint requires
404not_foundResource not found
409already_respondedThis voter already answered the slide/poll
422validation_failedRequest body failed schema validation
429rate_limitedToo many requests - retry after the 60s window resets
500internal_errorUnexpected server error

Retries & backoff

We recommend an exponential backoff with jitter strategy for production integrations:

Retry with backoff (JavaScript)
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const res = await fetch(url, options);

    if (res.status === 429) {
      // PollsLive uses a fixed 60s window and does not send Retry-After,
      // so back off exponentially (capped at the window length).
      const backoff = Math.min(1000 * 2 ** attempt + Math.random() * 500, 60000);
      await new Promise((r) => setTimeout(r, backoff));
      continue;
    }
    if (res.status >= 500 && attempt < maxRetries) {
      const backoff = Math.min(1000 * 2 ** attempt + Math.random() * 500, 30000);
      await new Promise((r) => setTimeout(r, backoff));
      continue;
    }
    return res;
  }
  throw new Error("Max retries exceeded");
}

Do not retry on 4xx errors (other than 429) - they indicate a problem with your request that won't resolve with retrying.

OAuth error format

The token endpoint (POST /api/oauth/token) returns errors in RFC 6749 format:

errorMeaning
invalid_requestMissing or malformed parameters
invalid_clientUnknown client_id or wrong client_secret
access_deniedClient is revoked or rate-limited
unsupported_grant_typeOnly client_credentials is supported

Still have questions?

Our team is happy to help.

Contact us
Rate Limits & Errors - PollsLive Developer Docs | PollsLive