Skip to the content
Menu: Limits and paging

Limits and paging

Rate limits#

Every operation belongs to a class, shown in the reference. Requests are counted per key and per organisation (an organisation's keys share its budget), across all of Zentiq's servers, in one-minute windows:

ClassPer key, a minutePer organisation, a minuteUsed by
read6001,200Reading: lists and single records (59 operations)
write120240Creating, changing and deleting (49 operations)
live3060Starting a live session (2 operations)
heavy2040Work that takes a while: cloning a voice, planning or filling a portal, exports, candidates' interviews (6 operations)
search120240Searching knowledge (2 operations)
address600 a minute from one address, whatever the keyEvery request

Every answer carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds until the window resets), for whichever of your key's or your organisation's limits is closer. Past it, the answer is 429 rate_limited with Retry-After: wait that many seconds. GET /v1/me lists your limits under rateLimits.

Live sessions and minutes#

  • At once: a plan (or an owner, under Plan & billing) can cap how many live sessions run at the same time. Past it, starting one is 429 concurrency_limit; end one first. GET /v1/me shows limits.maxConcurrentSessions and limits.activeSessions.
  • Minutes are prepaid, shared by the console and the API. With none left (or past the organisation's own monthly cap), starting a session is 402 insufficient_minutes. GET /v1/usage shows minutes used and left, and the usage.threshold webhook warns you as they run low.
  • Plan features: a session that needs something the plan doesn't include is 403 feature_not_in_plan; a paused account is 403 account_paused.

Pages#

Lists answer one page at a time:

  • limit: how many items, 1 to 200 (default 50);
  • cursor: the nextCursor of the page before; nextCursor is null on the last page.

A page can hold fewer than limit items and still have a nextCursor: keep going until it is null. Lists are newest first, unless an operation offers order=asc. A cursor belongs to its list and its filters: use it with the same query.

Node
// One page at a time…
const first = await zentiq.listPersonas({ limit: 50 });
if (first.nextCursor) await zentiq.listPersonas({ limit: 50, cursor: first.nextCursor });
// …or every item, fetching pages as you go.
for await (const persona of zentiq.paginate("listPersonas", { limit: 100 })) console.log(persona.id, persona.name);

Syncing what changed#

To keep your own system in step, ask only for what changed since your last run:

  • lists that offer updatedAfter (an ISO time; the reference shows which, results and inbox items among them) give only what changed after it;
  • the event log, GET /v1/events, takes after (an event id) with order=asc, and from / to: every event your webhooks were offered, with the same ids, so you can catch up after an outage.

Editing at the same time#

Subject content is saved as versions. Reading it gives its version (and an ETag); send it back as baseVersion (or If-Match) when you save, and a save made on top of an older version than the current one is refused with 409 version_conflict and details.currentVersion, instead of overwriting someone's work. Without one, the last save wins.

Work that takes a while#

Reading a document into a knowledge pack, or checking that a duo renders before it goes live, takes longer than a request. The operation answers at once (a document's status is processing), and the event says when it is done (knowledge.document.processed); or poll the resource. The SDKs' waitUntilReady does the polling for you.

Sizes#

A request, a file or a field that is too large is 413 too_large (on the 2026-07-08 contract, 413 invalid_request). The reference gives each field's limits.