Skip to content

Get users through verification without making them wait.

Deliver OTPs, login verification, password resets, and security alerts through a controlled messaging path with real-time status and fallback.

A verification code arriving on a phone beside a laptop, with the route that carried it drawn above

Every second of delivery friction becomes authentication friction.

Users do not distinguish between a messaging route and the product. When the code is late, duplicated, or sent to an unavailable channel, the login experience feels broken.

  • An auth request taking a low-latency route in under three seconds to an auto-expiring code

    Delay becomes drop-off

    A verification code that arrives after the user has switched screens or requested another code creates confusion and abandonment.

  • An idempotency guard turning three user taps into a single active verification code

    Uncontrolled retries create competing codes

    Repeated taps and network retries can issue duplicate sends unless the authentication and messaging states are coordinated.

  • A failed primary SMS route falling back automatically to WhatsApp or a voice OTP

    One unavailable route blocks access

    Carrier filtering, unsupported channels, or temporary route issues should not silently end the verification attempt.

Meet Sent: reliable delivery for the verification state your product owns.

A person reading a verification message that names the product, the code and how long it lasts

From verification request to confirmed access

Your authentication service owns the code and verification state. Sent delivers the approved message through the configured route and returns the status of every attempt.

Everything needed for a clear, observable verification flow.

Sent keeps message delivery fast, traceable, and recoverable while your authentication service remains the source of truth.

  • A verification message carrying the code, its expiry and a warning not to share it

    Deliver codes with clear context

    Use a dedicated template containing the code, expiry, product name, and a warning not to share it.

  • Repeated taps held behind a cooldown so only one active code is ever sent

    Control the resend experience

    Coordinate cooldowns, attempt limits, code invalidation, and idempotent requests so retries do not create ambiguity.

  • A timed-out SMS route moving down a defined channel order to WhatsApp or a voice OTP

    Fall back when a channel is unavailable

    Use a defined channel order so a verification attempt can move to another supported route when appropriate.

  • A delivery event arriving by webhook to update the interface and the support log

    Watch every attempt in real time

    Use message status webhooks to update the UI, enable recovery, and give support a clear failure reason.

Keep authentication logic and delivery logic correctly separated.

Give each system one clear responsibility, then connect the verification session and delivery record with stable identifiers.

Raw system data held inside the authentication service while only delivery variables travel onward

Security around every verification attempt.

  • Store keys in environment variables, separate them by environment, rotate them, and never expose them in browser or mobile code.

  • Check the signature on every delivery webhook before it is allowed to change a verification state, and drop any payload that does not pass.

  • Rate-limit verification requests per user and per number, so repeated or automated attempts are dropped before they reach a route.

API keys held server-side and separated by environment rather than exposed to the client

Frequently asked questions

No. Your authentication service creates, hashes, expires and verifies the code. Sent receives only the variables needed to deliver the message, and returns the status of every attempt.

SMS, WhatsApp and RCS, through one integration. The channel order is yours to define, so an attempt can move to another supported route when the first is unavailable.

Yes. Define the channel order once, and a verification attempt that cannot complete on the primary route moves to the next supported one without the user asking for a new code.

Behind a cooldown and an attempt limit, with idempotent requests, so repeated taps and network retries reuse the active code instead of issuing competing ones.

Message status webhooks report queued, sent, delivered and failed against one message ID, so your interface can react as the state changes rather than waiting.

No, and it should not. Verification stays inside your authentication boundary. Sent reports whether the message reached the user, which is a separate question from whether the code matched.

In environment variables on the server, separated by environment and rotated on a schedule. They should never appear in browser or mobile code.

Every delivery event is signed. Check the signature before the payload is allowed to change any auth state, and drop anything that does not pass.

Yes. Templates carry the code, expiry and product name as variables, so the same verification flow can render per language and region.

No. Delivered and read describe the message, not the session. Only your authentication service can confirm that the code was entered and the verification succeeded.

Yes. Test credentials are separate from production, so a full verification flow can be run end to end without a message reaching a real user.

The verification session ID, the request ID and the message ID. With the message status, failure reason, channel and timestamp, they identify exactly where the attempt stopped.