| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Send and receive SMS messages using your own Android phone - no Twilio, no per-message fees. Free, open-source, and self-hostable.
The open-source SMS gateway for developers, automations, and AI agents. Manage SMS messages through a web dashboard, a REST API, or the MCP server for AI agents. textbee is ideal for businesses, developers, and hobbyists looking for a reliable and cost-effective solution to automate SMS messaging.
Website: https://textbee.dev
| textbee | Twilio & similar APIs | |
|---|---|---|
| Cost per SMS | Your carrier plan (often free/unlimited) | ~$0.008+ per message |
| Phone number | Your own SIM | Rented number |
| Self-hostable | ✅ Full control over your data | ❌ |
| Open source | ✅ | ❌ |
| Setup time | ~2 minutes | Account approval, compliance forms |
Messages go out through your default device, or otherwise the enabled device with the most recent heartbeat. Pass an optional deviceId in the request body to send from a specific device instead. The older /gateway/devices/{deviceId}/send-sms route still works but is deprecated.
const API_KEY = 'YOUR_API_KEY';
await axios.post('https://api.textbee.dev/api/v1/gateway/send-sms', {
recipients: [ '+12025550123' ],
message: 'Hello World!',
}, {
headers: { 'x-api-key': API_KEY },
});API_KEY = 'YOUR_API_KEY'
requests.post( 'https://api.textbee.dev/api/v1/gateway/send-sms', json={ 'recipients': ['+12025550123'], 'message': 'Hello World!', }, headers={'x-api-key': API_KEY}, )
</details>
<details>
<summary><b>curl</b></summary>
```bash
curl -X POST "https://api.textbee.dev/api/v1/gateway/send-sms" \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"recipients": [ "+12025550123" ],
"message": "Hello World!"
}'
Enable SMS receiving in the mobile app, then access incoming messages via the REST API, the dashboard, or webhook notifications delivered to your preferred URL. Message history is account-level: one call covers every device, no device id needed.
const API_KEY = 'YOUR_API_KEY';
await axios.get('https://api.textbee.dev/api/v1/gateway/messages?direction=received', {
headers: { 'x-api-key': API_KEY },
});The official textbee MCP server lets Claude Desktop, Claude Code, Cursor, and any MCP-compatible client send and read SMS through your account. Your API key stays on your machine, and plan limits apply server-side like any other send.
{
"mcpServers": {
"textbee": {
"command": "npx",
"args": ["-y", "@textbee/mcp"],
"env": { "TEXTBEE_API_KEY": "YOUR_API_KEY" }
}
}
}Three tools: send_sms (send to one or many recipients), get_messages (read replies and verification codes, check delivery status), and list_devices. Self-hosted instances work with TEXTBEE_BASE_URL. Details at textbee.dev/mcp and the agent docs.
Technology stack: React, Next.js, Node.js, NestJS, MongoDB, Android, Kotlin, Jetpack Compose, Java (legacy)
./gradlew assembleReleasecp .env.example .envpnpm installpnpm buildcp .env.example .envpnpm installpnpm buildA self-hosted instance reports nothing to anyone by default. With no analytics environment variables set, the web app loads no analytics or ad-platform scripts and the API sends no analytics events to any external service. Every provider below is opt-in, and one that is listed without its id is skipped.
(This is separate from the services the API talks to when you configure them yourself: Firebase for push, Cloudflare Turnstile, Polar for billing, and your own SMTP server.)
Web (web/.env, and the marketing site if you run it):
| Variable | Purpose |
|---|---|
| NEXT_PUBLIC_ANALYTICS_PROVIDERS | Comma separated list of providers to load: ga, clarity, meta. Unset means none. |
| NEXT_PUBLIC_GA_MEASUREMENT_ID | Google Analytics measurement id, required for ga. |
| NEXT_PUBLIC_CLARITY_PROJECT_ID | Microsoft Clarity project id, required for clarity. |
| NEXT_PUBLIC_META_PIXEL_ID | Meta pixel id, required for meta. |
| NEXT_PUBLIC_ATTRIBUTION_COOKIE_DOMAIN | Cookie domain for signup attribution, for example .example.com, when the dashboard and the marketing site are on different subdomains. Leave unset for a single domain. |
API (api/.env):
| Variable | Purpose |
|---|---|
| ANALYTICS_PROVIDERS | Comma separated list of server-side destinations. Only meta today. Unset means no events are sent. |
| META_PIXEL_ID | Same id as the browser pixel. |
| META_CAPI_ACCESS_TOKEN | Conversions API token. Keep it out of version control and out of any NEXT_PUBLIC_ variable. |
| META_CAPI_TEST_EVENT_CODE | Optional. Routes events to Events Manager's test view instead of live reporting. |
NEXT_PUBLIC_ values are baked in at build time, so changing them means a rebuild, not just a restart. ANALYTICS_PROVIDERS on the API is read at runtime, so unsetting it and restarting stops all outbound events immediately.
Signup attribution (which channel an account came from) is separate from the providers above. It is stored only in your own database, makes no external request, and is always on.
pm2 start dist/main.js --name textbee-apitextbee.dev {
reverse_proxy /api/* localhost:3000
reverse_proxy /* localhost:3001
}
cd web && cp .env.example .env \
&& cd ../api && cp .env.example .envdocker compose up -ddocker compose downContributions are welcome!
Please feel free to create an issue in the repository for any bug reports or feature requests. Make sure to provide a detailed description of the issue or feature you are requesting and properly label whether it is a bug or a feature request.
Please note that if you discover any vulnerability or security issue, we kindly request that you refrain from creating a public issue. Instead, send an email detailing the vulnerability to contact@textbee.dev.
Feel free to reach out to us at contact@textbee.dev or Join our Discord server
| Back | FazBrowse Home | New Git URL |