OTP that gives you the code
One call sends the login code to your user and returns the same code to you, so your app verifies it however it likes. Most WhatsApp OTP integrations spend a week building exactly this.
Send and get the code
import { Whatsapi } from "@whatsapi.sh/sdk";
const wa = new Whatsapi({ apiKey: "wa_your_key" });
const data = await wa.sendOtp({ to: "+5511988887777" });{
"data": {
"code": "482913",
"expiresAt": "2026-08-24T19:05:00.000Z",
"to": "+5511988887777",
"messageId": "3EB0…"
}
}The code is yours: compare it in your own backend, show it in your own UI, or do neither and use /v1/otp/check. To check it, we keep only a salted hash. The message that carried it stays in the chat's history, like any other. The code goes out right away, with no “typing…” first. The first code to someone your number has never talked to (they never wrote to it, and it never sent them anything through us) uses one of its new conversations for the day.
Or let us check it
import { Whatsapi } from "@whatsapi.sh/sdk";
const wa = new Whatsapi({ apiKey: "wa_your_key" });
const data = await wa.checkOtp({ to: "+5511988887777", code: "482913" });{ "data": { "verified": true, "to": "+5511988887777" } }A wrong or expired code is a 400 OTP_INVALID, never a 200 with verified: false. A verification endpoint that answers 200 to a wrong code is one forgotten if away from letting anyone in. Five guesses per code, then it burns. A fresh code has a 60-second resend cooldown.