@sente.run address, the app
sends a verification email — a one-time code or a magic link. Sente classifies every inbound email
server-side and extracts the artifact, so your code can wait for exactly that message and get back just
the code or link.
During a Sente-driven register run, the run controller completes email verification
from the identity’s own inbox by itself — do not wrap
waitForOtp around a registration. Use this
guide when your own code drives the signup or login flow.How annotation works
Every inbound email gets an annotation before anything observable happens (webhook delivery,wait
matching):
wait shortly
after arrival still matches.
The robust pattern: stamp since first
Stamp a timestamp before triggering the action that sends the email, then wait with that since.
A code that lands instantly cannot be missed, and a stale code from an earlier flow cannot be grabbed
by mistake.
If you omit since, the wait falls back to a 60-second lookback — good enough for a one-off, but for
back-to-back flows on one identity an explicit since is the correct choice.
message alongside the extracted code/link, and null/None on
timeout. A single wait request holds for at most 60 seconds — loop and call again if you need to wait
longer.
The raw endpoints
The helpers above are thin wrappers over two REST endpoints. Long-poll for the next matching message:- Returns
200with the full message (includingannotation) as soon as one matches, or204on timeout. kindisotp,magic_link, orother.timeoutis in seconds, 1–60, default 25.sincedefaults to now−60s when omitted.
kind filter:
kind. Useful for auditing
which verification emails an identity has received. See the
messages API reference for all parameters.
Push instead of poll
If your service already has a public HTTPS endpoint, register a webhook formessage.received — Sente pushes a notification for every inbound
email (with retries), and you fetch the full message, annotation included, by id. For a process
without a public URL, long-polling as above is the right tool.