textbee Logotextbee.dev
Plans from $9.99/mo.View Plans

OTP and two-factor authentication with SMS from your own Android number

Published and updated

Users need to prove they hold the phone number on their account, at signup or login. The code has to arrive within seconds from a sender the carrier trusts, and the flow has to survive a code that never arrives. With textbee the sender is an Android phone holding your SIM, so the message comes from your own number, recipients can reply, and the Pro plan, up to 5,000 messages for $9.99 a month with no per message fee.

How it works

  1. Generate a random six digit code on the server, store a hash of it with a five to ten minute expiry and an attempt counter, bound to the session that asked for it.
  2. Send the code with one POST to /gateway/send-sms. Keep the text in one GSM-7 segment, put the code early, name your service, state the expiry, and never include a link.
  3. Verify the code the user types against the hash, check the expiry and the attempt count, then mark it used so it cannot be replayed.
  4. Offer a resend after thirty to sixty seconds, rate limited per number and per IP, because a slow carrier is the common failure and a resend button beats a spinner.

Send it

The API key comes from the dashboard and the phone registered on your account does the sending. Recipients are E.164 numbers; the example is fictional.

send-otp.sh
curl -X POST https://api.textbee.dev/api/v1/gateway/send-sms \
  -H "x-api-key: $TEXTBEE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"recipients": ["+12015550123"], "message": "Your textbee code is 482913. It expires in 10 minutes."}'

Message template

Placeholders in double braces are filled per recipient by your code or by the CSV upload in the dashboard. Keep the result under 160 GSM-7 characters so it stays one segment.

template.txt
Your verification code is: {{ code }}. Do not share. Expires in 10 min.

Consent and compliance

A code the user requested is a transactional message, so the number the user gave for the account is the consent. Do not reuse the OTP channel for marketing without separate written consent, and never put a link in a verification message, since carriers filter them and several countries forbid them.

Honest limits

One phone sends roughly 10 to 15 messages a minute, so a large blast takes time to drain. That is fine for a login peak of a few hundred an hour and too slow for thousands in a minute, where a second device or a carrier route belongs. Delivery time depends on the recipient's carrier, so design the resend path before you need it.

One phone sends roughly 10 to 15 messages a minute, so a large blast takes time to drain. Carriers can filter bulk patterns on consumer SIMs. Marketing messages still need consent from the recipient under the local rules.

Frequently asked questions

How fast does an OTP arrive from a phone-based gateway?

The phone hands the message to the network within seconds of the API call, and the rest is carrier delivery, the same as any text. The queue on the phone is the variable: at a few messages a minute it is empty, at a few hundred it is not.

Should the code be six digits?

Six digits with a ten minute expiry and a handful of attempts is the common balance between guessability and typing errors. Generate it with a cryptographic random source, never from the time or the user id.

Can I use a real number for OTP in every country?

Yes. A SIM in the country gives you a local long code, which recipients and verification filters treat as a phone. In India the daily cap on an ordinary SIM applies, so heavy OTP traffic there belongs on a registered route.

Is SMS OTP secure enough?

It is a second factor for ordinary accounts, not for high value ones, because of SIM swap and interception. Offer TOTP or a hardware key as the upgrade and keep SMS as the default everyone can use.

Read next