CLEMA protocol

Rate Limits

Requests that are cheap to send and expensive to serve are throttled. Exceeding a limit yields the rate_limited error; typing.set signals are silently dropped instead, since they carry no response.

Commands Scope Budget
auth.phone, phone.set client address 10 per minute
auth.qr client address 20 per minute
invite.get client address 30 per minute
auth.token, auth.refresh client address 60 per minute
auth.code, phone.code phone number 1 per 60 seconds; 5 SMS and 10 codes in the app per day
auth.code, phone.code client address 10 per hour
auth.code, phone.code country of the number set by the server
auth.phone, phone.set verification 5 wrong codes
phonebook.update account 10000 entries added per day
user.search, conversation.search, message.search, phonebook.update connection 20 per 30 seconds
Message, voice play, read, delivery, draft, notification, reactions-seen, pin, block, privacy, moderation, contact, profile, presence, session, transport, push, activity, conversation, membership and invitation changes; qr.get, qr.accept; typing.set; phonebook.clear; files and transfers but file.get connection 40 per 2 seconds

Credential checks are limited per client address rather than per connection, so reconnecting does not reset the budget. Every SMS costs money, and a stream of codes to premium-rate numbers is a known way to spend someone else's: sending is therefore limited by number, address and country at once, and a server may refuse whole countries with not_supported. A rate_limited answer to a code request carries retry_after. Behind a reverse proxy the address is taken from X-Forwarded-For, but only when the proxy is configured as trusted — otherwise every client would share the proxy's address, or be able to claim any address it likes.