Personyze Personyze developer docs
Open Personyze
REST API

Errors, limits and retries

Status codes, error messages, query limits and when to retry.

Personyze developer documentation Questions: support@personyze.com

For information about how REST API works, see rest main page.

Every endpoint uses the same status codes, the same error body format and the same query limits. This page describes them once.

Status codes

Status Meaning What to do
200 OK The request succeeded. The body is JSON.
400 Bad Request Your request was rejected — an unknown column, a malformed where, a missing mandatory field, a query the object doesn't support, or a rate limit. The body explains which. Fix the request. Retrying the same request will fail again.
401 Unauthorized The API key is wrong or revoked, or the request wasn't sent over HTTPS. Check the key, and check you are using https://.
500 Server Error Something failed on our side. The body contains a description. Retry once; if it persists, send us the response body.
503 Service Unavailable A temporary database condition. Wait a few seconds and retry. Safe to retry automatically with backoff.

Error bodies are plain text, not JSON — only successful responses are JSON. So when a client fails to parse a response as JSON, the status code is the thing to look at.

Common error messages

These come back with 400:

  • Unknown column: {name} / No such column in table: {name} / Requested column doesn't exist: {name} — the column you asked for in columns, where or the request body isn't exposed by that object. Each object's page lists its columns.
  • Column "{name}" is mandatory — a required field was missing from a POST body.
  • Column {name} is read-only — that field can be read but not written.
  • Couldn't interpret "where" / Error in "where" / Error in "where": columns count doesn't match values count — the path parameter syntax is malformed.
  • Couldn't interpret "limit"limit was not a number, or not offset,limit.
  • Only can select up to 1000 rows — see Query limits below.
  • Cannot do this operation on whole table… / Queries to this object must use indices… / Such query to this object is not supported — see Query limits below.
  • Row not found — a PUT or DELETE addressed a record id that doesn't exist.
  • Couldn't parse input application/json or application/x-www-form-urlencoded — the request body wasn't valid JSON, and the Content-Type wasn't form-encoded either.
  • Too many simultaneous requests — writes to users are serialized per account and arrived too fast. Retry with backoff.

Query limits

At most 1000 rows per request. /limit/1000 is the maximum. Use /limit/{OFFSET},{LIMIT} to page through more.

Large tables must be queried by an index. Objects backed by big tables (users, sessions, interactions) won't run a query that would scan the whole table. In practice:

  • Selecting by an indexed column (for users: user_id, internal_id, email, fb_id, data_last_modified) is fast and unrestricted.
  • Selecting by a non-indexed column (for example a user's first name) is a full scan. Personyze will either refuse the query, or serve only the first 50 rows of it.
  • When a query is refused, the error message names the columns that do have indices — use one of them in where or order_by.

Small catalog-style objects (user_lists, placeholders, conditions, users_columns) have no such restriction — you can read them whole.

Writing safely

  • POST to users merges into an existing profile when an identifier matches, so re-sending the same record is safe and won't create duplicates.
  • PUT and DELETE apply to every row matched by the path parameters. A DELETE with no where is not silently interpreted as "nothing" — always send an explicit condition.
  • PUT and DELETE return the number of affected rows, so 0 means your condition matched nothing.

Retrying

503, and 500 on a write, are the only statuses worth retrying automatically. Use exponential backoff starting around one second. Because writes to users merge rather than duplicate, a retry after an ambiguous failure is safe.