REST APIAuthentication, limits and errors

Authentication, limits and errors

How to authenticate Opttab API requests, stay inside the rate limit, page through lists and handle every error code.

HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json

{ "error": "ThrottlerException: Too Many Requests", "code": "RATE_LIMITED" }
{
  "error": "API_KEY_SCOPE",
  "code": "FORBIDDEN"
}
{
  "error": "Validation failed",
  "code": "VALIDATION_ERROR",
  "details": {
    "formErrors": [],
    "fieldErrors": { "pageSize": ["Number must be less than or equal to 100"] }
  }
}

Every Opttab API request carries one API key. This page covers how to send it, the rate limit, paging, and what each error means.

Authenticate

Send your key in the Authorization header as a bearer token:

header
Authorizationstring
Required

Bearer opt_live_…: the word Bearer, one space, then the secret that starts with opt_live_.

curl https://api.opttab.com/v1/external/workspace \
  -H "Authorization: Bearer opt_live_xxxxxxxx"

These do not authenticate:

  • A signed-in Opttab browser session (cookie).
  • An X-API-Key header.
  • An ?api_key= query parameter.

An API key also does not open any other Opttab route. It works only on /v1/external/*.

Keep keys on your server. Never put a key in browser code, a mobile app or a public repository.

The workspace comes from the key

You choose a workspace when you create the key. Every call reads that workspace, and no route takes a workspace id. To read another workspace, create another key.

An id from another workspace behaves as if it does not exist: you get 404.

How a request is checked

Rate limit

Each key can make 60 requests per 60 seconds. The count is per key, not per IP address, so two servers sharing one key share the limit.

Request 61 inside the window gets 429 Too Many Requests with a Retry-After header:

On 429, wait the number of seconds in Retry-After, then retry. If you sync a lot of data, space requests about one second apart, and add exponential backoff with jitter for repeated 429s.

Paging

List routes return one page at a time:

query
pageinteger

Page number, starting at 1. Default 1.

query
pageSizeinteger

Items per page, from 1 to 100. Default 20.

Every list response carries items, page, pageSize and totalCount. Keep asking for the next page until you have totalCount items:

curl "https://api.opttab.com/v1/external/prompts?page=2&pageSize=100" \
  -H "Authorization: Bearer opt_live_xxxxxxxx"

Paged routes: prompts, a prompt's responses, topics and competitors. GET /v1/external/responses/{responseId}/sources returns all sources in one list.

Query parameters are strict. An unknown parameter, such as ?limit=50, is refused with 400.

Error envelope

Every error has the same JSON shape:

FieldWhat it holds
errorA reason code such as API_KEY_SCOPE, or a short message
codeThe HTTP status as a name, such as FORBIDDEN
detailsOptional. Extra detail, for example which field failed validation
requestIdOptional. Quote it when you contact support

Branch on error in your code, not on the message text.

Error reference

StatuserrorMeaningFix
400Validation failedpage, pageSize or period is out of range, or the query has an unknown parameter. details.fieldErrors names the field.Fix the query. pageSize maximum is 100. period is one of 1d, 7d, 30d, 3m, 6m, 1y.
401API_KEY_INVALIDThe key is missing, not in the Bearer opt_live_… form, revoked, expired or otherwise unusable. All cases share this one answer on purpose.Check the header. If it is right, create a new key in Settings › API.
403API_KEY_IP_DENIEDThe caller's IP address is not on the key's Allowed addresses.Add the address or range to the key, or call from an allowed address.
403API_KEY_SCOPEThe key does not have the scope this route needs.Edit the key and tick the scope. See the scope table in the API overview.
404PROMPT_NOT_FOUNDThe prompt id is malformed or not in the key's workspace.Use an id from GET /v1/external/prompts with the same key.
404PROMPT_RESPONSE_NOT_FOUNDThe answer id is malformed or not in the key's workspace.Use an id from GET /v1/external/prompts/{promptId}/responses.
429ThrottlerException: Too Many RequestsMore than 60 requests in 60 seconds with this key.Wait Retry-After seconds, then retry.

Example 400:

FAQ