Skip to main content
Limits are generous for real integrations and tight enough to blunt abuse.

The numbers

A principal is whoever authenticated: a given API key and a browser session count separately, but all keys of one account share its account-level protections. The two Aro Mail claim endpoints have their own budgets because a claim code is a bearer secret: the public preview is limited per IP, and the claim itself is limited per principal and IP instead of the general write budget, so a recipient’s few attempts never compete with an integration’s other writes, and a code cannot be brute-forced through either door. The operator-only POST /transfer/letter/sweep is authenticated by a shared secret and has no per-user limit.

When you exceed a limit

The API returns 429 with the standard envelope:
Back off and retry. A simple pattern with jitter:

Staying well under the limits

  • Poll gas, not balances. GET /gas is designed for polling; /balances does FHE work. See Balances.
  • Poll transactions at 3–10 s intervals; faster adds no information (Ethereum blocks land every ~12 s) and burns read budget. See Track transactions.
  • Batch-poll in-flight rows. If you have several transactions in flight, one GET /transactions?status=QUEUED (and likewise PENDING, SETTLING) per interval replaces one GET /transactions/{id} per row; each list call costs a single read regardless of pageSize.
  • Paginate deliberately. pageSize goes up to 100; one big page beats five small ones.
  • Money movement returns immediately with a QUEUED transaction; a successful 201 is final for the write budget, so don’t retry it. Switch to polling the transaction (reads) until it reaches CONFIRMED, SETTLED, or FAILED.
  • Poll letters, not the claim preview. GET /transfer/letter/{id} is the owner’s polling target for Aro Mail (10 s intervals are plenty; mailed letters refresh Lob status at most every 15 minutes anyway). The public preview is for the recipient’s claim page, not for tracking.

Lockout behavior

Five consecutive failed logins lock the account for 15 minutes; even correct credentials are refused until the window passes. Failed-attempt counters reset on successful login. Locked-out or disabled states are not distinguishable from bad credentials in the login response (deliberately), so surface the generic failure to end users.