SMS Authentication

AuthGate supports SMS OTP (one-time password) authentication alongside OAuth and email providers. End users authenticate by receiving a 6-digit code via SMS and verifying it.


Overview

SMS authentication is a passwordless auth method — users only need their phone number. Your application calls AuthGate's SMS endpoints directly to send a code and then verify it. On success, a JWT token is returned.

Key characteristics:

  • Two-step flow — send a code, then verify it
  • No passwords — users authenticate with their phone number only
  • 6-digit OTP — codes expire after 5 minutes with a maximum of 3 attempts
  • JWT includes provider: "sms" and phone_verified: true
  • Telnyx — SMS delivery is powered by the Telnyx Messaging API

Enable SMS auth

SMS authentication is enabled by default for new projects. You can toggle it in the dashboard under your project's Providers settings.


Send code flow

To start authentication, send a POST request to the send-code endpoint with the user's phone number:

curl -X POST https://auth.example.com/api/proxy/sms/send-code \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+15551234567",
    "callback_url": "https://myapp.com/auth/callback"
  }'

The response confirms the code was sent:

{
  "success": true
}

The endpoint always returns 200 even if the phone number is rate-limited (to prevent enumeration). The user receives a 6-digit verification code via SMS.

Rate limits

  • 2 requests per 10 minutes per IP address
  • 3 requests per 30 minutes per phone number per project

Verify code flow

After the user receives the code, verify it:

curl -X POST https://auth.example.com/api/proxy/sms/verify-code \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+15551234567",
    "code": "123456",
    "callback_url": "https://myapp.com/auth/callback"
  }'

On success, the response includes a JWT token and user info:

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "user": {
    "id": "user_abc123",
    "phone": "+15551234567",
    "email": null,
    "name": null,
    "phone_verified": true
  }
}

If the user doesn't exist, they are created automatically on first successful verification. Subsequent verifications return the same user.

OTP rules

  • Codes are 6 digits long
  • Codes expire after 5 minutes
  • Maximum 3 verification attempts per code
  • A new code invalidates any existing code for the same phone + project

Phone number format

Phone numbers must be in E.164 format (e.g., +15551234567). AuthGate normalizes phone numbers before processing:

  • Strips non-digit characters (except leading +)
  • Assumes US/Canada country code (+1) for 10-digit numbers
  • Validates the result is 7-15 digits with a country code

Examples of accepted formats:

InputNormalized
+15551234567+15551234567
(555) 123-4567+15551234567
555-123-4567+15551234567
+44 20 7946 0958+442079460958

Was this page helpful?