Skip to content
P
API for partners
Connecting your application — access, authentication and endpoints
API for partners / Limits and CORS

Rate limits and CORS#

Rate limiting#

Three layers apply: application limits, per-caller limits under them and special endpoint limits on selected sensitive endpoints.

Limits per application#

Every application key has its own limits: a short window per second and a longer one per minute. The defaults are 20 per second and 600 per minute; the operator can set different values for a particular client.

The application limit is shared by all its users

When the application exceeds its limit, all its users are refused until the window ends. One overloaded user (or a faulty loop) can therefore stop the whole application. That is why per-caller limits exist.

Per-caller limits#

Under the application ceiling there is a limit per caller, so that one caller cannot use up the whole capacity:

Caller Counted by Default limit
signed-in user the account from the token 120 per minute
anonymous (no token) IP address 120 per minute

Public actions that do not read the token (sign-in, token refresh, forgotten password) are also counted by address — even if you send a token. The website administrator can change both limits per application.

An invalid token never reaches the per-caller limit

An invalid or expired token ends with a 401 before the per-caller limit is counted. The application limit is counted all the same.

Windows and exceeding a limit#

The windows are fixed: a new second, or a new minute, starts a new window and the counter resets. An exceeded limit (application or caller) returns HTTP 429, a Retry-After header with the number of seconds until the window ends and this body:

{"success":false,"message":"Too many requests.","data":{"retryAfter":3},"code":404}

code 404 is the result code RATE_LIMIT_EXCEEDED, not an HTTP status. data.retryAfter carries the same number as the header. The client should wait Retry-After seconds and only then retry.

Special endpoint limits#

These apply on top of the limits above — sign-in, token refresh, password reset, phone reveal, content creation and others. The limit is not global; these apply only to selected sensitive endpoints.

Endpoint Key Limit When exceeded
auth/login username and IP, failed attempts only 5 per 5 minutes 429 with Retry-After, code 404
auth/login account from all addresses, failed attempts only 20 per hour 429 with Retry-After, code 404
auth/refresh IP, every attempt 30 per 5 minutes 429 with Retry-After, code 404
user/update-password account, wrong current password only 5 per 5 minutes HTTP 200, code 404
user/show-phone IP 20 per hour HTTP 200, empty phone
user/send-new-password IP / user 10 per hour / 3 per hour HTTP 200, the same response as on success
user/reset-password IP 10 per hour HTTP 200, code 112
user/send-activation-email IP / user 10 per hour / 3 per hour HTTP 200, the same response as on success

The sign-in and token refresh limits return HTTP 429, a Retry-After header and a body with the same keys; only the message also carries the number of seconds:

{"success":false,"message":"Too many requests, retry in 240s","data":{"retryAfter":240},"code":404}

Decide by code and data.retryAfter, not by the message text.

Sign-in from an unknown device

The limit of 20 per hour per account and the limits on pairs (name or account, address) apply in full only to an unknown device: above the limit the password is not checked at all and the client gets the same 429 as before. A browser that has signed in to the account before is recognised by the website's signed cookie, and an address with a successful sign-in in the last 30 days gets past the account limit. An external auth/login call sends no cookie, so it is always an unknown device; only an address from which the account recently signed in successfully can help it. An integration should therefore not wait for a lift from another address when the account is blocked: it should follow the Retry-After header.

A throttled response must not reveal more than a passing one

That is why "forgotten password" returns the same success with or without the limit, and the password reset the same code as an invalid key. Only sign-in and token refresh report the limit with status 429.

Content creation quota#

Creating selected content has an hourly cap. It applies to the website and to an external save with a token alike.

What Key Limit
a response to an advert or a company profile, a discussion post or report, a comment, an advert report, a contact message — signed-in user user / IP, separately for each kind of content 30 per hour / 60 per hour
a contact message — anonymous visitor e-mail from the form / IP 5 per hour / 20 per hour
a newsletter subscription activation e-mail IP / e-mail 10 per hour / 3 per hour

Only inserts count, updates do not. Above the limit save returns HTTP 200, success: false and code 404 with the message Too many new records, try again later. — without a Retry-After header. An administrator is exempt from the quota.

Ordinary reads and writes have only the application and per-caller limits

They have no special limit. That does not mean anything goes — large includes and frequent queries load the server just the same.

Failed sign-ins count, successful ones do not

A correctly authenticated client does not hit the limit.

CORS#

This concerns browser calls only. A server-side request is not restricted by CORS.

Setting Value
Allowed origins a list; by default only local development addresses
Methods GET, POST, PUT, PATCH, DELETE, OPTIONS
Headers Authorization, X-API-Key, Content-Type, X-Requested-With, Accept
Exposed headers none
Credentials allowed
Preflight lifetime 1 hour

X-API-Key is an allowed header

The browser preflight permits it. A key embedded in a browser script is not secret, though — see Authentication.

Your domain must be on the list

If it is not, the server responds and the browser discards the response. It looks like an API outage. Ask the operator to add your domain.

You cannot read Retry-After from a browser

The header is not exposed. When rate limited in a browser you cannot tell how long to wait — apply your own backoff. The response body does carry data.retryAfter.

Preflight#

An OPTIONS request is handled before authentication and returns 204. For a disallowed origin it returns 204 without the allow header.

Client recommendations#

On receiving a 429, wait Retry-After seconds

Retrying immediately only extends the limit. If you cannot read the header (a browser), back off progressively.

Refresh the token ahead of time, not on a 401

An access token lasts 15 minutes. Refreshing a minute early saves pointless failed requests.

Do not use includes=*

The fastest way to slow your own integration down.

Cookie settings