Skip to main content
1

Send the code

auth.signin.start takes a method and an identifier and returns a challengeId. The methods are email_code, email_link and sms_code.It never reveals whether the address is already a user. That is deliberate: an endpoint that answers differently for a known address is an account-enumeration oracle, and this one cannot be used as one.Its permission is auth:public, so your frontend can call it with a publishable key. No secret key in a browser.
2

Exchange it for a session

auth.signin.verify takes the challengeId and the six digits. On a first sign-in it creates the user and a verified identity, then issues a session: a short-lived access token and a rotating refresh token.There is no separate sign-up call, and that is the point — an account is a side effect of proving an address, so there is no window in which a user exists with an address nobody has proved.
3

Handle the second factor

When the user has a second factor, or the environment requires one, verify returns mfa.mfaToken instead of a session. Read for the session before assuming you have one — a client that reads session.accessToken unconditionally crashes on exactly the accounts that took security seriously.Finish with auth.mfa.verify, which takes the token and the digits from the authenticator app, or a recovery code.
4

Check the token on your own API

verifyAccessToken in @trylath/sdk validates a token against your environment’s published keys, so your backend does not call Lath on every request. requireUser does it for a standard Request.See the SDK guide for the framework-shaped versions.
Last modified on September 13, 2026