LettrLabs API

Rate limits and batch sizes

What the API enforces today, the batch limits that do exist, and how to pace a bulk load.

There is no request rate limit today

The public API does not enforce a request-rate limit and never returns 429. You do not need to implement backoff for rate limiting.

No enforced limit is not a promise of unlimited throughput. Everything below shares one database, so a fast enough loop degrades your own calls before anything rejects them. Treat the guidance in this page as the supported shape of a bulk load.

If a limit is introduced it will arrive as 429 with a Retry-After header, and it will be announced on the changelog first.

The limits that do exist

These are per-request size limits, not rate limits. Each rejects the whole request — no partial application — so split client-side before sending.

OperationLimitOn exceeding
Create conversions5,000 records per request400, nothing stored
Add recipients to an order5,000 recipients per request400, no recipients added

Both are enforced before any processing, so a rejected batch leaves no partial state — you can safely resubmit smaller batches.

Pacing a bulk load

Adding recipients is the expensive step: every recipient is address-validated and deduplicated against your suppression lists before it is stored. So:

  • Send recipients in sequential batches, not in parallel. Concurrent appends to the same order contend on the same rows and are slower in aggregate than one batch after another.
  • Batch in the low thousands rather than at the 5,000 ceiling. Smaller batches fail smaller: a rejected batch of 1,000 is cheaper to diagnose and resend.
  • Expect the call to be slow — it does real work per recipient. Set a generous client timeout (minutes, not seconds) rather than retrying, because a retry after a client-side timeout can re-send recipients the first call already stored.

Retrying safely

The API does not implement idempotency keys, so a blind retry can duplicate work. Before retrying anything that writes:

  • Adding recipients — re-read the order's recipients and compare against what you sent, rather than resending the batch.
  • Checkout — re-read the order's status. If it moved past payment, the checkout succeeded and must not be repeated.
  • Creating conversions — a resend is comparatively safe: matchback deduplicates on the identifiers you supply, so the same record submitted twice does not double-count.

And do not retry a 400, 403, 404, 409, 422, or a bodiless 500 on an entitlement-gated operation — see response shapes. Those are all deterministic; the same request will fail the same way.

On this page