Rate limits
Each API key can make a set number of requests a minute, shared between the REST API and the platform MCP server. Past it, wait for Retry-After.
Limits protect your account and the AI receptionist from a runaway integration. They are counted per API key, per minute.
Limits
| What | Limit |
|---|---|
| Requests per API key | 120 a minute, shared by the REST API and the platform MCP server |
Live chat replies (POST /chats/{chat}/messages) |
30 a minute per key, within the overall limit |
| Requests with a missing or invalid key | 30 a minute per IP address |
Public MCP servers (/mcp/site, /mcp/docs) |
60 requests a minute per IP address each |
Need more for a real use case? Contact us and tell us what you are building.
Headers
Responses carry the state of the per-key limit:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Requests allowed per minute. |
X-RateLimit-Remaining |
Requests left in the current minute. |
Retry-After |
On a 429, seconds to wait before trying again. |
Handling 429
Over the limit, the API answers 429 Too Many Requests. Wait for Retry-After seconds, then retry. A simple, polite client:
async function vocenya(path, options = {}) {
for (let attempt = 0; attempt < 5; attempt++) {
const response = await fetch(`https://vocenya.com/api/public/v1${path}`, {
...options,
headers: {
Authorization: `Bearer ${process.env.VOCENYA_API_KEY}`,
...options.headers,
},
});
if (response.status !== 429) {
return response;
}
const seconds = Number(response.headers.get('Retry-After') ?? 1);
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}
throw new Error('Still rate limited after 5 attempts');
}Staying under the limit
- Use webhooks instead of polling for new records.
- Ask for 100 records per page when you page through a list.
- Give each integration its own key, so one busy job does not slow the others down.