verify-phone-sms
SMS Phone Verification API using AWS SNS HTTP API with Hono server on Cloudflare Workers
π€ Agent skill β npx skills@latest add https://github.com/OpenSourceAGI/dev-tools-starter-agent --skill verify-phone-sms (what it covers)
A complete Hono-based server for SMS verification using AWS SNS. Built for Cloudflare Workers with comprehensive API documentation and security features.
Features
- β SMS Verification: Send verification codes via AWS SNS
- β VoIP Blocking: Optional blocking of VoIP numbers
- β API Authentication: Secure API key-based authentication
- β Rate Limiting: Built-in rate limiting protection
- β OpenAPI Documentation: Auto-generated API documentation
- β CORS Support: Cross-origin resource sharing enabled
- β Security Headers: Secure headers middleware
- β Error Handling: Comprehensive error handling
- β Health Checks: Built-in health monitoring
- β General SMS: Send custom SMS messages
Quick Start
Install
npm install verify-phone-sms # use verifyPhone() from your own backendOr clone the repo and install its dependencies to run the server itself:
npm installSet Environment Variables
Create a .env file or set environment variables:
# AWS Credentials
AWS_ACCESS_KEY_ID=your_aws_access_key
AWS_SECRET_ACCESS_KEY=your_aws_secret_key
AWS_REGION=us-east-1
# API Configuration
API_KEY=sms_1234567890abcdef1234567890abcdef
SMS_SENDER_ID=VerifyDeploy to Cloudflare Workers
# Deploy API only
npm run deploy
# Deploy docs only
npm run build:docs
npm run deploy:docs
# Deploy both API and docs
npm run deploy:all
# Deploy to specific environments
npm run deploy:staging
npm run deploy:production
npm run deploy:all:staging
npm run deploy:all:productionQuick Deployment Script
# Deploy everything to default environment
./scripts/deploy.sh
# Deploy to staging
./scripts/deploy.sh staging
# Deploy to production
./scripts/deploy.sh production
# Deploy only API
./scripts/deploy.sh default api
# Deploy only docs
./scripts/deploy.sh default docsDeployment
Prerequisites
-
Install Wrangler CLI:
npm install -g wrangler -
Login to Cloudflare:
wrangler login -
Set Secrets:
wrangler secret put AWS_ACCESS_KEY_ID wrangler secret put AWS_SECRET_ACCESS_KEY wrangler secret put API_KEY
Environment Configuration
The project supports multiple deployment environments:
- Default: Development/testing environment
- Staging: Pre-production testing
- Production: Live production environment
Each environment can have its own configuration and secrets.
Automated Deployment
GitHub Actions workflows are included for automated deployment:
- Push to
main: Deploys to production - Push to
staging: Deploys to staging - Pull Requests: Runs tests and builds
Required GitHub Secrets:
CLOUDFLARE_API_TOKENCLOUDFLARE_ACCOUNT_ID
For detailed deployment instructions, see DEPLOYMENT.md.
API Endpoints
Health Check
GET /
GET /healthSend Verification Code
POST /api/send
Content-Type: application/json
X-API-Key: your_api_key
{
"phoneNumber": "+1234567890",
"code": "123456", // optional, auto-generated if not provided
"blockVoip": true, // optional, default: false
"senderId": "MyApp", // optional, default: "Verify"
"messageTemplate": "Your code is: {code}", // optional
"smsType": "Transactional" // optional, "Transactional" or "Promotional"
}Response:
{
"success": true,
"message": "Verification code sent successfully",
"messageId": "abc123def456",
"code": "123456",
"phoneNumber": "+1234567890",
"expiresIn": 600
}Verify Code
POST /api/verify
Content-Type: application/json
X-API-Key: your_api_key
{
"phoneNumber": "+1234567890",
"code": "123456"
}Response:
{
"success": true,
"message": "Code verified successfully",
"verified": true
}Send General SMS
POST /api/sms
Content-Type: application/json
X-API-Key: your_api_key
{
"phoneNumber": "+1234567890",
"message": "Hello from your app!",
"senderId": "MyApp",
"smsType": "Transactional"
}Response:
{
"success": true,
"message": "SMS sent successfully",
"messageId": "abc123def456",
"phoneNumber": "+1234567890"
}API Documentation
Visit /docs to see the interactive OpenAPI documentation.
Authentication
All API endpoints require authentication using an API key. Include the key in the request header:
X-API-Key: your_api_keyOr as a Bearer token:
Authorization: Bearer your_api_keyConfiguration
Environment Variables
| Variable | Description | Default |
|---|---|---|
AWS_ACCESS_KEY_ID | AWS Access Key ID | Required |
AWS_SECRET_ACCESS_KEY | AWS Secret Access Key | Required |
AWS_REGION | AWS Region | us-east-1 |
API_KEY | API Key for authentication | Required |
SMS_SENDER_ID | Default SMS sender ID | Verify |
Rate Limiting
- Window: 15 minutes
- Max Requests: 100 per IP
- Headers: Standard rate limit headers included
Phone Number Validation Options
The API supports two methods for phone number validation and VoIP detection:
External API Method (Default)
- Uses external phone lookup service for VoIP detection
- Basic phone number formatting and validation
- Requires internet access for VoIP checks
- More accurate VoIP detection
libphonenumber-js Method
- Uses Google's libphonenumber library for local analysis
- Advanced phone number formatting and validation
- No external API calls required
- Heuristic-based VoIP detection
- Smaller bundle size (145 kB vs 550 kB for full libphonenumber)
- Better international number support
Usage Examples
// Using libphonenumber-js for VoIP detection with full metadata
const result = await verifyPhone({
phoneNumber: '+1-800-555-0123',
code: '123456',
blockVoip: true,
voipDetectionMethod: 'libphonenumber', // Use local analysis
useLibPhoneNumber: true, // Use libphonenumber-js for formatting/validation
metadataType: 'full' // Use full metadata (140KB) for better phone type detection
});
// Using libphonenumber-js for formatting only
const result = await verifyPhone({
phoneNumber: '555-123-4567', // US number without country code
code: '789012',
useLibPhoneNumber: true, // Use libphonenumber-js for formatting/validation
blockVoip: false // Don't block VoIP numbers
});
// Traditional approach (external API)
const result = await verifyPhone({
phoneNumber: '+44 20 7946 0958', // UK number
code: 'ABCDEF',
blockVoip: true,
voipDetectionMethod: 'api', // Use external API (default)
useLibPhoneNumber: false // Use basic formatting/validation
});VoIP Detection Methods
External API (voipDetectionMethod: 'api'):
- Checks carrier information from phone lookup service
- Identifies Bandwidth, VoIP, and mobile line types
- More accurate but requires external API calls
libphonenumber-js (voipDetectionMethod: 'libphonenumber'):
- Analyzes phone number patterns and structure
- Identifies common VoIP area codes (800, 888, 877, etc.)
- Detects non-geographic numbers
- Recognizes patterns like repeated digits, sequential numbers
- Heuristic-based approach for common VoIP characteristics
Metadata Options
Minimal Metadata (metadataType: 'minimal' - Default, 75KB):
- Uses pattern-based heuristics for VoIP detection
- Smaller bundle size
- Works with all countries
- Less accurate but faster
Full Metadata (`metadataType: 'full' - 140KB):
- Uses phone number type detection (MOBILE, FIXED_LINE, VOIP, etc.)
- More accurate VoIP detection
- Larger bundle size (65KB additional)
- Matches Google's libphonenumber behavior
- Phone number types: MOBILE, FIXED_LINE, VOIP, PREMIUM_RATE, TOLL_FREE, SHARED_COST
Development
Running Tests
npm test
npm run test:run
npm run test:uiLocal Development
npm run devDeployment
# Deploy to production
npm run deploy
# Deploy to staging
npm run deploy:staging
# Deploy to specific environment
npm run deploy:productionExample Usage
JavaScript/Node.js
// Send verification code
const response = await fetch('https://your-api.workers.dev/api/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your_api_key'
},
body: JSON.stringify({
phoneNumber: '+1234567890',
blockVoip: true,
senderId: 'MyApp'
})
});
const result = await response.json();
console.log(result);cURL
# Send verification code
curl -X POST https://your-api.workers.dev/api/send \
-H "Content-Type: application/json" \
-H "X-API-Key: your_api_key" \
-d '{
"phoneNumber": "+1234567890",
"blockVoip": true,
"senderId": "MyApp"
}'
# Verify code
curl -X POST https://your-api.workers.dev/api/verify \
-H "Content-Type: application/json" \
-H "X-API-Key: your_api_key" \
-d '{
"phoneNumber": "+1234567890",
"code": "123456"
}'Error Handling
The API returns consistent error responses:
{
"success": false,
"error": "Error message",
"details": "Additional error details"
}Common HTTP status codes:
200: Success400: Bad request (invalid input)401: Unauthorized (invalid API key)429: Too many requests (rate limited)500: Internal server error
Security Features
- β API key authentication
- β Rate limiting
- β CORS protection
- β Secure headers
- β Input validation
- β Error sanitization
- β VoIP number blocking (optional)
Architecture
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β Client App βββββΆβ Hono Server βββββΆβ AWS SNS β
β β β β β β
β - Web App β β - Rate Limiting β β - SMS Delivery β
β - Mobile App β β - Auth β β - Message ID β
β - API Client β β - Validation β β - Error Handlingβ
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββRoadmap: Identity Verification
Phone verification proves control of a number. The next tier proves the person behind that number is real β and turns that proof into something businesses pay for.
Planned integrations
- Persona API β document and selfie identity verification. Entry plan is **1.50 each); volume past the included allowance is billed per verification.
- Auto sign-in by phone β once a registered user's number is verified and on file, authenticate them from the phone itself instead of re-sending a code on every login.
- Address history over legal ID β a chain of past addresses is a stronger identity signal than a photo of a government ID, which can be AI-generated or reused across accounts. Treat document capture as corroboration, not proof.
- Liveness and face check β confirm a live human is present at capture time, rather than a printed photo, a replayed video, or a generated face.
Product opportunities
- Verification as a service β sell corporations the ability to confirm their customers are real people, with this stack as the verification backend.
- Verified demographics β verified age, location, and demographic attributes make high-quality ad targeting inventory, subject to user consent and applicable privacy law.
References
- NIST FRVT 1:1 leaderboard β accuracy rankings for face recognition algorithms
- Faceplugin FaceRecognition-Android β on-device face recognition with liveness check
- Doubango FaceLivenessDetection-SDK β passive face liveness / anti-spoofing
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License
MIT License - see LICENSE file for details.
Please star this repo for updates! π
Last updated on