BuildBaseBuildBase

Set up phone sign-in

Send sign-in codes by text message, WhatsApp or voice call through Twilio or your own webhook, set the limits, and see the code flow your users get.

Phone sign-in lets people sign in, or create an account, with a 6-digit code sent to their phone by text message, WhatsApp or a voice call. They type their number, then the code, and they are in; someone new also gives a name and an email. It suits apps whose users would rather type a phone number than an email address. Every message goes out through your own provider, which bills you for it.

Before you start

  • A way to send messages: a Twilio account, or an HTTPS endpoint of your own that sends texts through any provider you already use.
  • A plan that includes phone sign-in codes. Without one, the console refuses to save the SMS provider and the Phone method.
  • An email sender, under Messaging, Sender accounts. People who sign up by phone also give an email address, and a code is emailed to confirm it.

1. Open the SMS tab

In the console's left rail, choose Users, then Authentication under Access, and open the SMS tab. Under How codes are sent, pick Twilio or Webhook. The card opens a guide for the one you pick.

The SMS tab in the console: the SMS provider card, Not connected, with the countries warning, How codes are sent set to Twilio or Webhook, and the open guide How to get your Twilio details in seven steps

2a. Connect Twilio

Twilio's console is at console.twilio.com. Copy these values from it into the matching BuildBase fields:

Copy this from TwilioWhere it is in TwilioPaste it into BuildBase
Account SID (starts with AC)The console's home page, under Account InfoAccount SID
Auth TokenSame place, hidden until you choose to show itAuth token
Service SID (starts with VA)Verify, then Services. RecommendedVerify service SID
Messaging Service SID (starts MG)Messaging, then ServicesMessaging service SID, if you have no Verify service
One of your numbers, like +14155550123Phone NumbersOr a number to send from, if you have neither

Fill in the first two and one of the last three, then press Connect. BuildBase checks the account SID and auth token with Twilio before it saves them, and shows Twilio's own message if something is wrong. The auth token works like the password to your Twilio account: it is stored encrypted and never shown again.

The Twilio fields filled with example values: Account SID AC1234567890abcdef1234567890abcdef, the Auth token hidden as dots, Verify service SID VA1234567890abcdef1234567890abcdef, and the Messaging service SID and number left empty

Nothing goes back the other way: you paste no BuildBase address into Twilio. A Verify service can send by text message, WhatsApp or voice call, and Twilio makes and checks the code. A Messaging service or a number sends text messages only.

2b. Or connect your own endpoint

Pick Webhook when you already send texts through another provider. Your developer builds an HTTPS endpoint that receives each code from BuildBase and sends it on.

  1. Paste the endpoint's address into Endpoint URL, for example https://api.acme.example/buildbase/sms, and press Connect. BuildBase refuses an address it cannot reach over the internet.
  2. Copy your signing secret now appears, once. Press Copy and give the secret to your developer, who keeps it in the endpoint's settings. Rotate secret makes a new one later; the old one stops working at once.

Webhook chosen: the guide How to connect your own endpoint in five steps, and the Endpoint URL box with https://api.acme.example/buildbase/sms typed in

After Connect: the box Copy your signing secret now, shown this once, with an example secret and its copy button

For each code, BuildBase sends your endpoint a POST like this one, waits up to 5 seconds, and does not retry:

{
  "to": "+14155550177",
  "code": "123456",
  "channel": "sms",
  "locale": "en-US",
  "purpose": "sign-up",
  "test": false
}

purpose is sign-in, sign-up, phone-add, mfa or test. Two headers sign it: x-buildbase-timestamp (Unix seconds) and x-buildbase-signature, sha256= followed by the HMAC-SHA256 of <timestamp>.<raw body> made with your signing secret. Check it on the raw body before you parse it; verifyWebhookSignature from the SDK does that in constant time and refuses a request older than 5 minutes:

import { verifyWebhookSignature } from '@buildbase/sdk';

export async function POST(req: Request) {
  const body = await req.text();
  const valid = verifyWebhookSignature({
    body,
    signature: req.headers.get('x-buildbase-signature'),
    timestamp: req.headers.get('x-buildbase-timestamp'),
    secret: process.env.BUILDBASE_SMS_SECRET!,
  });
  if (!valid) return new Response('Invalid signature', { status: 401 });

  const { to, code, channel } = JSON.parse(body);
  const sent = await sendWithYourProvider({ to, code, channel });
  // A number your provider will not deliver to: answer 422 with a reason.
  if (!sent.ok) return Response.json({ reason: sent.reason }, { status: 422 });
  return Response.json({ sent: true });
}

Any 2xx means sent. A 422 with { "reason": "..." } means the number was refused: the sign-in page says so, and the delivery log keeps your reason. Anything else, or no answer in 5 seconds, is a failure.

3. Send a test

Once a provider is connected, the Send a test card appears. Type your own number with its country code, pick a Channel and press Send a test code. The code signs nothing in, but it is a real message on your provider's bill and counts toward the daily cap.

The Send a test card after a test to +14155550123 by Text message: it says the test code was sent

4. Set the limits

Daily cap is the most codes your app sends in a day (UTC), tests included, from 1 to 100,000; the default is 1,000. Past it, nothing is sent and the sign-in page says codes cannot be sent right now. Warn at sends the auth.sms_budget_exceeded event to your webhooks when the day's codes reach that share of the cap, and again when the cap stops a code, each at most once a day. Sent today counts against the cap.

The limits: Daily cap 1000, Warn at 80 percent of the cap, and Sent today against the cap of 1,000

BuildBase also limits each number and each network address, on every install, before it looks the number up:

LimitDefault
One number, between two codes30 s
One number, an hour / a day5 / 10
One network address, an hour / a day20 / 50

Warning

SMS fraud. Some people run scripts that ask sign-in pages to text codes to expensive premium-rate numbers, and earn a share of what you pay (it is called SMS pumping). BuildBase sends to any valid number, because which countries can receive codes is set in your provider. Before you go live, allow only the countries your users are in: in Twilio, open Verify (or Messaging), then Settings, then Geo permissions. The daily cap limits how much a bad day can cost.

5. Choose the country and the channels

Under Phone sign-in on the same tab, pick the Default country: where the picker on the sign-in page starts, and how a number typed without a country code is read. Tick the Ways to send the code; with more than one, people choose on the sign-in page. Press Save.

The Phone sign-in card: Default country United States (+1), Ways to send the code with Text message, WhatsApp and Voice call ticked, and a Save button

6. Add the Phone method and attach it to your app

  1. Open the Methods tab, press Add auth method and choose Phone. Keep the Title Phone and press Create.
  2. Open the Settings tab, press Edit beside Acme Analytics, tick Phone under Methods and press Update. A method shows on the sign-in page only once it is ticked on the app.

Phone chosen in the Add new method dialog: what it does, when to pick it, How to set up phone sign-in, the Title box filled with Phone, and Create

The Acme Analytics client sheet, Methods: Email and password and Phone both ticked

7. Check the preview

The Preview on the Sign-in page tab draws your page's look with sample buttons, the same for every app, so it does not show the phone button. Press Open the live page for Acme Analytics above it: your real sign-in page opens in a new tab, with Continue with phone.

The Preview on the Sign-in page tab: a sample card titled Sign in to Acme, and above it the button Open the live page for Acme Analytics

The live Acme sign-in page: email and password, then a Continue with phone button

What people see

  1. Continue with phone opens the phone form: the country, the number and, with more than one channel, how to send the code. The button names the channel, such as Text me a code.

The phone form on the sign-in page: Country United States (+1), Phone number, Send the code by Text message, WhatsApp or Voice call, and the button Text me a code

  1. Check your phone asks for the 6-digit code. It lasts 10 minutes and allows 5 tries; Resend code works after 30 seconds, and a new code replaces the last.

Check your phone: Enter the 6-digit code we texted to +1 415 555 0177, with the code from the text message typed in, a Continue button and Use a different number

  1. A number with no account goes to Finish creating your account for a name and an email, then confirms the email with a code, as after any sign-up. A number that has an account is signed in, after a second step if you ask for one.

Finish creating your account: the number is confirmed, and the form asks for a name, Sam Rivera, and an email, sam.rivera@acme.example

A number with an account and one without get the same answers until the code is right, so nobody can use the page to find out who has an account. An email that already belongs to another account is never given the phone. On a phone the form fills the screen:

The phone form at phone width: the country picker, the number 415 555 0123, the three ways to send the code and Text me a code, filling the screen

A number your provider refuses is said under the field:

A number the provider refused: under the phone number the page says This number can't receive codes.

The delivery log

The Delivery log at the bottom of the SMS tab lists every code of the last 30 days, newest first: the last four digits of the number, the channel, what it was for, the outcome and your provider's error code. The full number and the code are never kept. Sent means your provider accepted the message, not that it arrived; your provider's own logs have the rest.

The Delivery log with three rows, newest first: a sign-up code to a number ending 0199 Refused with the provider error landline, a sign-up code to a number ending 0177 Sent, and a test code to 0123 Sent, all through the Webhook

In your app (SDK)

The SDK's Security screen has a Phone number section where a signed-in person adds a number, confirms it with a texted code, changes it or removes it. A verified number is also where text message codes for two-step sign-in go. See Account security screens.

The Phone number section once verified: a banner says +1 415 555 0142 is verified and on your account, and the number shows Verified with Change and Remove

Check it works

  • The SMS tab says Connected, and a test code reaches your phone.
  • The Delivery log shows the test as Sent.
  • Phone is listed on the Methods tab and ticked on your app.
  • The live page shows Continue with phone, and a new number can sign up with the code it receives.
  • Your provider allows only the countries your users are in.

Things to watch out for

  • A Twilio trial account sends only to numbers you have verified in Twilio. Upgrade the account before real people try to sign in.
  • WhatsApp needs a WhatsApp sender of your own. Since 1 March 2024, Twilio Verify sends WhatsApp codes only from your own WhatsApp sender. Tick WhatsApp only once your Verify service has one. A Messaging Service or a single number sends text messages only.
  • Without Verify, the text is fixed and in English. Through a Messaging Service or a number, the message always reads "Your verification code is" and the code. Verify sends Twilio's own wording in the person's language.
  • A United States number of your own needs A2P 10DLC registration. Twilio says anyone texting United States numbers from an app over a regular 10-digit number must register, and charges extra carrier fees otherwise. Verification codes sent through Verify are the exception.
  • Allow only the countries your users are in. Turn off every other country under Geo permissions in Twilio, and turn on Twilio's SMS fraud protection, before you go live.
  • Your own endpoint has 5 seconds and one try. A slow or failing endpoint means the person sees "Codes can't be sent right now." BuildBase does not try again.
  • Test codes are real messages. Each one is on your provider's bill and counts toward the daily cap.

If something goes wrong

What you or the person seesWhyWhat to do
Twilio's own message when you press Connect, or "Twilio could not be reached. Try again."Twilio refused the account SID, auth token or Verify serviceCopy the values again from Account Info and Verify
"That URL cannot be reached from BuildBase. Use a public HTTPS address."The endpoint address is private or not reachableUse a public HTTPS address
No Continue with phone on the sign-in pageNo provider connected, or Phone is not ticked on the appConnect a provider, tick Phone and press Update
"Enter a valid phone number, with its country code if it is not local."Not a valid numberType the number with its country code
"This number can't receive codes."Your provider refused the number (a 422 from your endpoint)The delivery log shows the reason
"Wait 30 seconds before asking for another code." (the number is the seconds left)A code went to this number moments agoWait, then press Resend code
"Too many codes have been sent to this number. Try again later."The number's or the address's hourly or daily limitWait
"Codes can't be sent right now. Try another way to sign in."The daily cap is reached, the provider failed, or none is connectedCheck Sent today, the delivery log and your provider
"That code did not match. Check the newest message and try again."A wrong code, or an older oneType the code from the newest message
"This code has expired. Ask for a new one."More than 10 minutes, or 5 wrong triesAsk for a new code
"That email address cannot be used here. Use another, or sign in to the account it belongs to and add your phone there."The email at sign-up already has an accountSign in to that account and add the phone from its Security screen

Next steps