A high-performance, production-ready REST API for phone number validation built with Zig and wrapping Google's libphonenumber C++ library.
π Free alternative to Twilio Lookup - Validate 10M numbers/month for $40 instead of $50,000
β‘ 2,500+ req/s throughput - Battle-tested with simulated annealing load analysis
π Memory-safe - Zig's compile-time guarantees + arena allocators
- Quick Start - Get started in 5 minutes
- Architecture - Technical design and implementation
- Testing - Comprehensive testing guide
- Production Readiness - Deployment checklist
- Advanced Testing - Simulated annealing breaking point analysis
- Industry-Standard Validation: Powered by Google's libphonenumber (used by Google, Android, iOS)
- Zero-Copy FFI: Direct C/C++ interop with no marshalling overhead
- Ultra-Fast: Zig's performance + libphonenumber's battle-tested algorithms
- Comprehensive Analysis:
- β Validity checking (correct for region)
- β Possibility checking (correct length/structure)
- β Phone type detection (mobile, fixed-line, toll-free, etc.)
- β Region/country code extraction
- β Multiple format outputs (E.164, international, national)
- β Number comparison and matching
- 190+ Countries: Full international support
- REST API: Simple HTTP JSON interface
- Production-Ready: CORS support, error handling, health checks
You need to install Google's libphonenumber C++ library:
Ubuntu/Debian:
sudo apt-get update
sudo apt-get install -y \
libphonenumber-dev \
libprotobuf-dev \
libicu-dev \
cmake \
build-essentialmacOS (Homebrew):
brew install libphonenumber protobuf icu4cArch Linux:
sudo pacman -S libphonenumber protobuf icuBuild from source (if packages not available):
# Clone and build libphonenumber
git clone https://github.com/google/libphonenumber.git
cd libphonenumber/cpp
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfigInstall Zig 0.15.2 or later:
# Download from https://ziglang.org/download/
# Or use your package manager- Clone the repository:
git clone <your-repo>
cd phonecheck- Build the C++ wrapper:
./build_wrapper.sh- Build the Zig application:
zig build- Run the server:
zig build runThe API will start on http://0.0.0.0:8080
Endpoint: GET /health
Response:
{
"status": "healthy",
"service": "phonecheck",
"version": "1.0.0"
}Endpoint: POST /validate
Request Body:
{
"phone_number": "+14155552671",
"region": "US" // Optional: ISO 3166-1 alpha-2 country code
}Response:
{
"valid": true,
"possible": true,
"type": "FIXED_LINE_OR_MOBILE",
"country_code": 1,
"national_number": 4155552671,
"region": "US",
"e164_format": "+14155552671",
"international_format": "+1 415-555-2671",
"national_format": "(415) 555-2671",
"possibility_reason": "IS_POSSIBLE"
}Phone Types:
FIXED_LINE- Traditional landlineMOBILE- Mobile phoneFIXED_LINE_OR_MOBILE- Could be eitherTOLL_FREE- Toll-free numberPREMIUM_RATE- Premium rate numberSHARED_COST- Shared cost serviceVOIP- VoIP numberPERSONAL_NUMBER- Personal numberPAGER- PagerUAN- Universal Access NumberVOICEMAIL- Voicemail accessUNKNOWN- Unknown type
Possibility Reasons:
IS_POSSIBLE- Number is validINVALID_COUNTRY_CODE- Invalid country codeTOO_SHORT- Too few digitsTOO_LONG- Too many digitsIS_POSSIBLE_LOCAL_ONLY- Valid locally onlyINVALID_LENGTH- Invalid length for region
Run the test suite:
zig build test# Validate a US number
curl -X POST http://localhost:8080/validate \
-H "Content-Type: application/json" \
-d '{"phone_number": "+14155552671"}'
# Validate with explicit region
curl -X POST http://localhost:8080/validate \
-H "Content-Type: application/json" \
-d '{"phone_number": "4155552671", "region": "US"}'
# International number
curl -X POST http://localhost:8080/validate \
-H "Content-Type: application/json" \
-d '{"phone_number": "+442071838750", "region": "GB"}'import requests
def validate_phone(number: str, region: str = None):
response = requests.post(
"http://localhost:8080/validate",
json={"phone_number": number, "region": region}
)
return response.json()
# Example usage
result = validate_phone("+14155552671")
print(f"Valid: {result['valid']}")
print(f"Type: {result['type']}")
print(f"International: {result['international_format']}")async function validatePhone(
phoneNumber: string,
region?: string
): Promise<ValidationResult> {
const response = await fetch('http://localhost:8080/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone_number: phoneNumber, region })
});
return response.json();
}
// Example usage
const result = await validatePhone('+14155552671');
console.log(`Valid: ${result.valid}`);
console.log(`Type: ${result.type}`);βββββββββββββββ
β Client β
β (HTTP/JSON) β
ββββββββ¬βββββββ
β
βΌ
βββββββββββββββββββββββ
β Zig HTTP Server β
β - Routing β
β - JSON parsing β
β - Error handling β
ββββββββ¬βββββββββββββββ
β Zero-copy FFI
βΌ
βββββββββββββββββββββββ
β C++ Wrapper β
β - Type conversion β
β - Memory safety β
ββββββββ¬βββββββββββββββ
β
βΌ
βββββββββββββββββββββββ
β libphonenumber β
β - Parsing β
β - Validation β
β - Formatting β
βββββββββββββββββββββββ
- Sub-millisecond validation latency
- Zero allocation in hot paths (using arena allocators)
- Concurrent request handling via Zig threads
- Direct C FFI with no serialization overhead
Following Tiger Style principles:
- β Explicit bounds on all buffers
- β No recursion
- β Arena allocators for request scoping
- β Fail-fast error handling
- β Comprehensive input validation
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
libphonenumber-dev libprotobuf-dev libicu-dev
COPY zig-out/bin/phonecheck /usr/local/bin/
EXPOSE 8080
CMD ["phonecheck"][Unit]
Description=PhoneCheck REST API
After=network.target
[Service]
Type=simple
User=phonecheck
ExecStart=/usr/local/bin/phonecheck
Restart=always
[Install]
WantedBy=multi-user.targetThe API exposes structured logs via stdout. Key metrics:
- Request method and path
- Response status codes
- Error messages
- Connection handling
Integrate with your logging infrastructure (ELK, Loki, CloudWatch, etc.)
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
zig build test - Submit a pull request
MIT License - See LICENSE file
- Google's libphonenumber: The gold standard for phone number handling
- Zig: Modern systems programming with safety and performance
- TigerBeetle: Inspiration for robust, zero-technical-debt coding practices
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Built with β€οΈ using Zig and libphonenumber