Skip to content

Limits & concurrency

Each API key has a cap on how many sessions can be active at once. This protects the rendering pipeline (and your bill) from unbounded growth, and is the main limit you’ll design around.

Responses from session endpoints include two headers so you can self-monitor without guessing:

x-twai-concurrent-sessions: 4
x-twai-max-concurrent-sessions: 10

Check these proactively, for example before offering a new conversation to a user, rather than waiting to be throttled.

Once you’re at your cap, POST /v1/sessions returns 429 Too Many Requests with a Retry-After header (in seconds) and the standard error envelope:

{
"error": {
"type": "rate_limit_error",
"code": "concurrent_session_limit_exceeded",
"message": "You have reached your concurrent session limit (10).",
"request_id": "req_9a2c7e1f3b5d"
}
}

Handle it by waiting at least Retry-After seconds before retrying, or by first ending a session you no longer need:

async function createSessionWithBackoff(body) {
const res = await fetch('https://api.2wai.ai/v1/sessions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TWAI_SECRET_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
if (res.status === 429) {
const retryAfter = Number(res.headers.get('retry-after') ?? '5');
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
return createSessionWithBackoff(body);
}
return res.json();
}

The most common cause of hitting the cap isn’t traffic, it’s sessions that were never ended. See the session hygiene checklist: end sessions when a conversation is over (DELETE /v1/sessions/{id}), and consider waiting_state for pauses shorter than a full teardown.

If your default concurrency cap is genuinely too low for your traffic, contact your 2wai account contact. This is a per-account configuration, not something you can change over the API.

  • Sessions for the full lifecycle, including when to end a session versus park it.
  • Errors for the general error envelope.