Textze
A self-hosted SMS/MMS messaging system with an Android client and Python server backend. Each user gets their own phone number and SMS credentials, with complete isolation between users.
Architecture
Android App ←WebSocket→ Python Server ←→ Twilio/MessageBird/Vonage ←→ Carrier
- Outbound: Android app sends messages via REST API to the server, which routes through the user's configured SMS provider
- Inbound: Provider delivers messages to the server via webhook, which pushes them to the Android app over a persistent WebSocket connection
- Real-time: Delivery status updates, new messages, and group notifications are all pushed over WebSocket
Components
Android App (textze-android/)
- SMS/MMS messaging interface with conversation view
- Persistent WebSocket connection via foreground service for real-time notifications
- Contact integration (names, photos) from the device address book
- Media upload with progress tracking
- Group messaging (broadcast to multiple recipients)
- Conversation archiving and search
- Do Not Disturb settings
Python Server (textze-server/)
- FastAPI REST API with WebSocket support
- Pluggable SMS provider system (Twilio, MessageBird, Vonage)
- SQLite (default) or PostgreSQL database via SQLAlchemy
- Media handling: upload, compression, thumbnail generation, deduplication (SHA-256)
- Web-based admin panel for user and provider management
- Per-user storage quotas and media retention policies
Features
- SMS and MMS with image, video, audio, and document attachments
- Media compression for MMS size limits (images, video, audio)
- Thumbnail generation for all image uploads
- Media deduplication via SHA-256 hashing and hard links
- Group messaging with per-recipient delivery tracking
- Do Not Disturb auto-reply (one reply per sender per day)
- Delivery status tracking (sent, delivered, failed) with timestamps
- Conversation archiving and deletion
- Storage quotas with configurable retention and media purge
- Heads-up notifications for incoming messages
- Multi-user with complete data isolation between users
Setup
Server
- Install dependencies:
pip install -r textze-server/requirements.txt
- Copy
.env.example to .env and configure your provider credentials, database URL, and base URL
- Run:
python textze-server/main.py
Android App
- Build with Android Studio or Gradle:
./gradlew assembleDebug
- Install on device:
adb install -r app/build/outputs/apk/debug/app-debug.apk
- Configure server URL and API key in app settings
Authentication
API key bearer tokens. Each user gets a unique API key generated at account creation. No passwords.
Authorization: Bearer {API_KEY}
WebSocket connections authenticate via query parameter: ?token={api_key}
API Endpoints
All messaging endpoints are prefixed with /sms-api/.
Messaging
| Method |
Path |
Description |
| POST |
/sms-api/send-sms |
Send SMS |
| POST |
/sms-api/upload-media |
Upload media file |
| POST |
/sms-api/send-mms |
Send MMS with media |
| GET |
/sms-api/conversations |
List conversations |
| GET |
/sms-api/search/conversations |
Search conversations |
| GET |
/sms-api/messages/{phone} |
Get messages for a number |
| PUT |
/sms-api/conversations/{phone}/archive |
Archive/unarchive |
| DELETE |
/sms-api/conversations/{phone} |
Delete conversation |
Media
| Method |
Path |
Description |
| GET |
/media/{user_id}/{filename} |
Serve media file |
Groups
| Method |
Path |
Description |
| GET |
/sms-api/groups/availability |
Check if enabled |
| POST |
/sms-api/groups |
Create group |
| GET |
/sms-api/groups |
List groups |
| GET |
/sms-api/groups/{id} |
Group details |
| PUT |
/sms-api/groups/{id} |
Update group |
| DELETE |
/sms-api/groups/{id} |
Delete group |
| POST |
/sms-api/groups/{id}/members |
Add member |
| DELETE |
/sms-api/groups/{id}/members/{phone} |
Remove member |
| POST |
/sms-api/groups/{id}/send |
Send group message |
| GET |
/sms-api/groups/{id}/messages |
Group message history |
User Settings
| Method |
Path |
Description |
| GET |
/sms-api/user/settings |
Get settings |
| GET |
/sms-api/user/storage-quota |
Storage usage |
| GET |
/sms-api/user/purge-options |
Preview media purge |
| POST |
/sms-api/user/purge-media |
Purge old media |
| GET |
/sms-api/user/dnd-settings |
DND settings |
| PUT |
/sms-api/user/dnd-settings |
Update DND |
Device & WebSocket
| Method |
Path |
Description |
| POST |
/sms-api/register-device |
Register device |
| WS |
/ws/{device_id} |
Real-time WebSocket |
Webhooks (called by SMS providers)
| Method |
Path |
Description |
| POST |
/sms-api/webhook/twilio |
Inbound SMS |
| POST |
/sms-api/webhook/delivery-status |
Delivery updates |
Admin
| Method |
Path |
Description |
| GET |
/admin |
Admin panel UI |
| GET/POST |
/admin/users |
List/create users |
| PUT/DELETE |
/admin/users/{id} |
Update/delete user |
| POST |
/admin/users/{id}/regenerate-api-key |
New API key |
| GET |
/admin/sms-providers |
List providers |
| GET/POST |
/admin/sms-provider-configs |
List/create configs |
| PUT/DELETE |
/admin/sms-provider-configs/{id} |
Update/delete config |
| GET |
/admin/stats |
System statistics |
Admin Panel
Access at https://your-domain.com/admin. Provides:
- Dashboard: System stats (users, messages, providers)
- Users: Create/delete users, assign SMS providers, regenerate API keys
- SMS Providers: View supported providers (Twilio, MessageBird, Vonage)
- Provider Configs: Manage credentials and phone numbers per provider
Adding a new user
- Create an SMS provider config with their credentials and phone number
- Create the user and assign the provider config
- Give the user their API key for app configuration