C
Chatty

Rate Limits

Limits

LimitScopeWindow
60 req / minPer API keySliding 60s
120 req / minPer IP address per endpointSliding 60s

Both limits use a sliding window — not a fixed clock minute.

429 response

HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json
{ "detail": "Rate limit exceeded (60/min per key)" }

Handling 429s

Python — exponential backoff
import httpx, time
 
def chat_with_retry(text, session_id, retries=3):
    for attempt in range(retries):
        r = httpx.post(
            "https://api.personaliai.com/api/v1/chat",
            headers={"Authorization": "Bearer chatty_sk_key"},
            json={"text": text, "session_id": session_id},
        )
        if r.status_code == 429:
            wait = int(r.headers.get("retry-after", 60)) * (2 ** attempt)
            time.sleep(wait)
            continue
        r.raise_for_status()
        return r.json()
    raise RuntimeError("Max retries exceeded")
Node.js — exponential backoff
async function chat(text, sessionId, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const res = await fetch("https://api.personaliai.com/api/v1/chat", {
      method: "POST",
      headers: { Authorization: "Bearer chatty_sk_key", "Content-Type": "application/json" },
      body: JSON.stringify({ text, session_id: sessionId }),
    });
    if (res.status === 429) {
      const wait = parseInt(res.headers.get("retry-after") || "60") * 2 ** i;
      await new Promise((r) => setTimeout(r, wait * 1000));
      continue;
    }
    return res.json();
  }
}

Best practices

EndpointAdditional limit
POST /api/v1/knowledge (url)1 crawl per call; takes 2–5s
GET /api/v1/leadsMax 200 per page
Widget (/api/widget/chat)30 msg/60s per visitor IP + bot

The widget rate limit is separate from the API key limit and only applies to embedded chat, not to API key requests.