Rate limits
MimicBot rate-limits the public chat endpoint on four independent axes, plus a separate limit on action result submissions. A request is rejected as soon as any single axis is saturated.
Chat endpoint limits
The four limits below are enforced on every POST /v1/public/chat request, in order:
| Scope | Limit | Window |
|---|---|---|
| Per visitor, per bot | 30 messages | 1 hour (sliding) |
| Per IP, per bot | 60 messages | 1 hour (sliding) |
| Per bot | 10,000 messages | 1 day (sliding) |
| Per agency | 50,000 messages | 1 day (sliding) |
The constants live in apps/api/src/routes/public/chat.ts as VISITOR_LIMIT, IP_LIMIT, DAILY_LIMIT, and AGENCY_DAILY_LIMIT.
Action result limits
Submitting a widget-side action result to POST /v1/public/actions/:executionId/result is rate-limited on one axis:
| Scope | Limit | Window |
|---|---|---|
| Per visitor, per bot | 5 results | 1 hour (sliding) |
Defined as VISITOR_RATE_LIMIT in apps/api/src/routes/public/actions.ts.
How the counters work
All windows are sliding, not fixed. The limiter in apps/api/src/rate-limit.ts counts rows inserted within the last windowSeconds against the bucket's key — so two requests spaced 59 minutes 59 seconds apart count against different windows, and the counter never "resets on the hour".
What happens on 429
When any limit is exceeded, the server responds:
HTTP/1.1 429 Too Many Requests
Retry-After: <windowSeconds>
Content-Type: application/json
{
"error": {
"code": "RATE_LIMITED"
}
}
Retry-After is the full window length for the axis that tripped — 3600 seconds for the hourly visitor and IP windows, 86400 seconds for the daily bot and agency windows. This is an upper bound: a sliding-window counter may free up a slot sooner as older requests age out, but waiting the full window is always guaranteed to succeed.
Honor Retry-After. Retrying sooner just burns another counter slot on both sides.
Raising the limits
Bot and agency daily limits are tied to your plan. Upgrade via the MimicBot dashboard. Visitor and IP hourly limits are fixed and not raised on request — they exist to protect your agency quota from a single abusive visitor.
See Errors for non-429 error responses.