Skip to main content

The key decides the environment

account.signup creates a live and a test environment for every project, each with its own secret and publishable key. Which one a request acts in is decided by the key it carries — there is no mode flag to set, and so none to forget. A key says which it is. Secret keys start lath_live_ or lath_test_; publishable keys start lath_live_pk or lath_test_pk. The two environments hold separate data, so the same person in live and in test is two records.

Email reaches your own team, and nobody else

email.send from a test environment reaches only the account’s own members — people who have accepted an invitation. Any other address is refused with test_mode_recipient (403), and the refusal names account.member.invite as the way to add a colleague. A broadcast in test does not refuse: it skips everyone else and counts them as held. Mail Lath sends for your users — sign-in codes, magic links, invitations — is not fenced this way. A test environment signs people in at any address, within the auth mail budget the rate limits guide describes, because testing a sign-in flow needs the code to arrive. A member’s address with a plus-tag counts as that member, so dev+welcome@yourco.com and dev+bounce@yourco.com both reach dev@yourco.com. One member can stand in for every case in a test suite. Being invited is not enough. An address that was sent an invitation but has not accepted it is refused too, because nothing yet shows that anyone reads that mailbox.

SMS is not sent from test

A test environment refuses every text with test_mode_recipient. An account’s members are identified by email address, and nothing in the account proves control of a phone number — so rather than pretend, there is no test allow-list for SMS. Send texts from the live environment, where the carrier registration applies.

Fifty messages a day

email.send in a test environment is refused with test_mode_limit (429) once the environment has 50 messages from the last 24 hours, until the window moves. Every message in the environment counts toward the 50, but only email.send is refused by it — broadcasts, automations and sign-in mail are not. It is not a billing control — test sends are never billed — it is the difference between a loop that wastes a morning and one that costs a sending domain its reputation.

What changes when you go live

Swap the test key for the live one. The operations, their inputs and their errors are the same on both, so nothing else in your code has to change. Live mail goes to any address that consent and suppression allow, live texts send, and usage is billed.
Last modified on September 23, 2026