Rate limits
Each API key may make 120 requests a minute. Every answer tells your program how many it has left, and a request over the limit is refused with the time to wait.
The limit
The limit belongs to the API key. Two keys of the same Business count apart, so a second program does not slow the first down. A Connected app has a limit of its own, counted the same way — one connected to the MCP server too, where every MCP request counts.
A minute starts with the key’s first request and ends 60 seconds later; the next request after that starts a new one. Every request the key makes in the minute counts, whatever it is answered — a request answered 404 for a record the Business does not have, or 422, costs what a success costs; an address the API has no endpoint for is answered 404 before the limit is counted, and costs nothing. A request with no key, or with an unknown or revoked one, is answered 401 and counts against no key.
The headers
Every answer to a request with a live API key or a Connected app’s access token carries three headers:
- Name
X-RateLimit-Limit- Type
- integer
- Description
How many requests the key or Connected app may make in a minute:
120.
- Name
X-RateLimit-Remaining- Type
- integer
- Description
How many it has left in this minute, the request just answered counted.
- Name
X-RateLimit-Reset- Type
- integer
- Description
When this minute ends and the count starts again, in Unix seconds (UTC).
An answer with 117 requests left
HTTP/2 200
Content-Type: application/json
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1790503260
Over the limit
A request over the limit is answered 429 with an error of type rate_limit, and nothing is done: no record is read, created or changed. Retry-After says how many seconds to wait; send the request again after that.
The 121st request in a minute: 429
{
"error": {
"type": "rate_limit",
"message": "This API key may make 120 requests a minute. Try again in 15 seconds."
}
}
A program that walks a long list or imports many records should read X-RateLimit-Remaining and wait for X-RateLimit-Reset when it reaches 0, rather than meet the 429. A create sent again after a 429 is safe with or without an Idempotency-Key: the refused request created nothing.
Pacing a program
Wait for the next minute when none are left, and wait Retry-After seconds when a request is answered 429 anyway — by another process sharing the key, for instance:
A request that keeps to the limit
while :; do
status=$(curl -s -D headers.txt -o clients.json -w '%{http_code}' https://api.essentio.pro/v1/clients \
-H "Authorization: Bearer $ESSENTIO_API_KEY")
[ "$status" != 429 ] && break
sleep "$(grep -i '^Retry-After:' headers.txt | tr -dc 0-9)"
done
remaining=$(grep -i '^X-RateLimit-Remaining:' headers.txt | tr -dc 0-9)
reset=$(grep -i '^X-RateLimit-Reset:' headers.txt | tr -dc 0-9)
[ "$remaining" = 0 ] && sleep $((reset - $(date +%s) + 1))
echo "$status, $remaining left this minute"
The request log
Essentio records every request an API key or a Connected app makes, for 30 days: when it was made, which key or app made it (and, for an app, the person who connected it), the operation — its method and path, such as GET /v1/clients/{client}, or for the MCP server what it asked, such as mcp tools/call essentio_search_clients — the status it was answered and the IP address it came from. The Owner and the Admins of the Business read it in Essentio under Settings → API Keys, below the keys.
The log never holds what a request sent or what it was answered: no body, no Client, no document, and nothing of the address after the path — a search or any other parameter is not kept. After 30 days an entry is erased.