Skip to main content

Send rate limiting

Logto applies a built-in, per-recipient rate limit to outbound verification codes and other messages sent over email and SMS. It protects your users and your messaging providers from send abuse—such as an attacker spamming a victim's inbox or phone with codes, or pumping SMS traffic to inflate your costs.

This limit is mandatory and system-level: it applies to every tenant regardless of plan and is not tenant-configurable. It is independent of:

  • The identifier lockout and CAPTCHA policies, which throttle failed verification attempts at verify-time rather than the act of sending.
  • The global per-tenant API rate limit (error code request.rate_limited), which bounds overall request volume across a tenant.

How it works​

  • Per-recipient cap: Logto limits how many messages can be sent to the same recipient (email address or phone number) within a short rolling time window. By default, this allows up to 10 sends per recipient every 10 minutes.
  • Where it applies: all server-side send paths, including Experience API and Account API verification-code sends (sign-in, register, reset password, MFA, and identifier binding), Management API verification-code sends, organization invitation send and resend, and Account (/me) verification-code sends.
  • When the cap is exceeded: the request is rejected with HTTP 429 and the error code request.message_rate_limited—distinct from the global tenant limiter (request.rate_limited) and the verify-time lockout (session.verification_blocked_too_many_attempts), so you can handle it specifically in your integration.

Monitor rate-limited sends with a webhook​

When an end user hits the per-recipient cap, Logto triggers the Message.RateLimited webhook event, so you can alert on or respond to send abuse.

  • Fires for: end-user verification-code send paths only—the Experience API and Account API. It does not fire for first-party or admin-initiated sends (Management API verification codes, organization invitations, or /me).
  • Payload: the webhook payload includes the action (for example, VerificationCodeSend) and the recipient (the email address or phone number).

Common use cases:

  • Send security alerts to your team for review.
  • Trigger downstream anti-abuse automation for the affected recipient.

Navigate to Console > Webhooks to subscribe, or create the Webhook via the Management API. For the detailed event structure and configuration, see Webhooks.

Suppressed delivery to unknown recipients​

To prevent account enumeration, when sign-up via an identifier is disabled, a sign-in verification code requested for an email address or phone number that no account owns is silently not delivered, and the API responds the same as it would for a real send. An attacker therefore can't use these responses to tell which addresses are registered. Delivery to existing users is unaffected. See also Hide account existence.