Codync
무료 오픈소스 1:1 대안, Grok Bot과 Muse 대신
Android 번호로 SMS를 보내고 받을 수 있는 REST API와 대시보드 제공, 개발자·스타트업·소규모 사업자용, 무료 tier, 오픈소스
Send and receive SMS text messages from your own Android number. REST API, dashboard, n8n and Zapier, for developers, startups and small businesses. Free tier, open source.
개발 도구TypeScript · KotlinGitHub @textbee온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
Open-source SMS gateway. Turn your Android phone into an SMS API: send and receive SMS from your apps over REST and webhooks. Self-hostable, with a free hosted plan.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗textbee is a free, open-source SMS gateway that uses an Android phone and its SIM card to send and receive SMS. Your code talks to a REST API, the API pushes each message to the phone, and the phone sends it over the carrier network. Incoming messages flow back to you through the API, the web dashboard, or webhooks.
It is a drop-in Twilio alternative for OTP codes, alerts, reminders, and two-way SMS, at the cost of your carrier plan. Over 40,000 developers and businesses use it, and the whole stack is in this repository: the NestJS API, the Next.js dashboard, and the Kotlin Android app. textbee is built and maintained by Nuver Labs, a small software studio.
| textbee | Twilio and similar SMS APIs | |
|---|---|---|
| Cost per SMS | Your carrier plan, often free or unlimited | Per-message fee plus a monthly number fee |
| Sender number | Your own SIM. Recipients see a real local number | Rented number, often flagged as unknown |
| Setup | About 2 minutes: install the app, scan a QR code | Account approval, compliance forms, number registration |
| Receive SMS | Yes, on the same SIM | Yes, on the rented number |
| Self-hostable | Yes, full control over your data | No |
| Open source | Yes, MIT | No |
| Works with AI agents | Yes, official MCP server | Third-party only |
Send
pending, dispatched, sent, delivered, failedReceive
Integrate
Operate
You need an Android phone (Android 7.0 or newer) with a SIM card. The app is distributed as an APK from textbee.dev/download, not through the Play Store.
That is the whole setup. The getting started guide covers each step with screenshots.
If textbee saves you money or time, star the repo. It helps other developers find it.
One request. Messages go out through your default device, or the enabled device with the most recent heartbeat. Pass deviceId to pick a phone, simSubscriptionId to pick a SIM, or scheduledAt to send later.
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": "Your verification code is 481920. It expires in 10 minutes."
}'
npm install @textbee/sdk
import { Textbee } from '@textbee/sdk'
const textbee = new Textbee({ apiKey: process.env.TEXTBEE_API_KEY })
await textbee.sendSms({
recipients: ['+12025550123'],
message: 'Your verification code is 481920. It expires in 10 minutes.',
})
Zero dependencies, typed, runs on Node 18+, Bun, Deno, Cloudflare Workers, and Vercel Edge. See textbee/textbee-js.
await fetch('https://api.textbee.dev/api/v1/gateway/send-sms', {
method: 'POST',
headers: {
'x-api-key': process.env.TEXTBEE_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
recipients: ['+12025550123'],
message: 'Your verification code is 481920. It expires in 10 minutes.',
}),
})
pip install textbee
import os
from textbee import Textbee
textbee = Textbee(api_key=os.environ["TEXTBEE_API_KEY"])
textbee.send_sms(
recipients=["+12025550123"],
message="Your verification code is 481920. It expires in 10 minutes.",
)
Zero dependencies, typed, runs on Python 3.9+. See textbee/textbee-python.
import requests
requests.post(
"https://api.textbee.dev/api/v1/gateway/send-sms",
json={
"recipients": ["+12025550123"],
"message": "Your verification code is 481920. It expires in 10 minutes.",
},
headers={"x-api-key": "YOUR_API_KEY"},
)
$ch = curl_init('https://api.textbee.dev/api/v1/gateway/send-sms');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'recipients' => ['+12025550123'],
'message' => 'Your verification code is 481920. It expires in 10 minutes.',
]),
]);
$response = curl_exec($ch);
body := strings.NewReader(`{"recipients":["+12025550123"],"message":"Your verification code is 481920. It expires in 10 minutes."}`)
req, _ := http.NewRequest("POST", "https://api.textbee.dev/api/v1/gateway/send-sms", body)
req.Header.Set("x-api-key", os.Getenv("TEXTBEE_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
Every endpoint, field, and error code is in the API reference. The API also serves an interactive OpenAPI (Swagger) page at api.textbee.dev.
Turn on Receive SMS in the Android app. Incoming messages are then available from the API, the dashboard, and webhooks. History is account-level, so one call covers every device.
curl "https://api.textbee.dev/api/v1/gateway/messages?direction=received" \
-H "x-api-key: YOUR_API_KEY"
const messages = await textbee.getMessages({ direction: 'received' })
messages = textbee.get_messages(direction="received")
Read the receiving SMS guide for pagination, filters, and SIM details.
Get events on your server the moment they happen. Create a subscription in the dashboard or through the API, then handle these events:
| Event | When it fires |
|---|---|
MESSAGE_RECEIVED | The phone received an SMS |
MESSAGE_SENT | The carrier accepted an outgoing SMS |
MESSAGE_DELIVERED | The recipient's handset confirmed delivery |
MESSAGE_FAILED | The message could not be sent |
SMS_STATUS_UPDATED | Any status change on an outgoing message |
Every delivery carries an X-Signature header: the HMAC-SHA256 of the raw body, keyed with the subscription's signing secret. Verify it before you trust the payload.
import { verifyWebhookSignature } from '@textbee/sdk'
app.post('/webhooks/textbee', express.raw({ type: 'application/json' }), async (req, res) => {
const valid = await verifyWebhookSignature({
payload: req.body.toString('utf8'),
signature: req.get('x-signature'),
signingSecret: process.env.TEXTBEE_WEBHOOK_SECRET,
})
if (!valid) return res.sendStatus(401)
const event = JSON.parse(req.body.toString('utf8'))
res.sendStatus(200)
})
import json
import os
from flask import Flask, request
from textbee import verify_webhook_signature
app = Flask(__name__)
@app.post("/webhooks/textbee")
def textbee_webhook():
valid = verify_webhook_signature(
payload=request.get_data(),
signature=request.headers.get("X-Signature"),
signing_secret=os.environ["TEXTBEE_WEBHOOK_SECRET"],
)
if not valid:
return "", 401
event = json.loads(request.get_data())
return "", 200
Retries, pauses, and the full payload shape are in the webhooks docs.
The official textbee MCP server gives Claude, Cursor, and any MCP-compatible client a phone number. Three tools: send_sms (one or many recipients), get_messages (read replies and verification codes, check delivery status), and list_devices. Plan limits apply server-side like any other send.
claude.ai, Claude Desktop, and the Claude mobile apps (nothing to install; the Free plan allows one custom connector):
textbee and the URL https://mcp.textbee.dev/mcp, then click Continue twice.The mobile apps use connectors added on the web or desktop. On Team and Enterprise plans, an owner adds the connector for the organization first.
Claude Code:
# Hosted: run /mcp afterwards and choose Authenticate to sign in with your API key
claude mcp add --transport http -s user textbee https://mcp.textbee.dev/mcp
# Or local: the key stays on your machine
claude mcp add textbee -s user -e TEXTBEE_API_KEY=YOUR_API_KEY -- npx -y @textbee/mcp
Cursor and other MCP clients (local server, the key stays on your machine):
{
"mcpServers": {
"textbee": {
"command": "npx",
"args": ["-y", "@textbee/mcp"],
"env": { "TEXTBEE_API_KEY": "YOUR_API_KEY" }
}
}
}
With the hosted connector, textbee checks your key and does not store it. Self-hosted instances use the local server with TEXTBEE_BASE_URL. Full setup at textbee.dev/mcp and the MCP docs.
| What it is | Where | |
|---|---|---|
| JavaScript SDK | @textbee/sdk: typed client, message iteration, webhook verification, segment counting | textbee/textbee-js · npm |
| Python SDK | textbee: the same client for Python 3.9+, with zero dependencies | textbee/textbee-python · PyPI |
| MCP server | @textbee/mcp: send and read SMS from any MCP client, hosted or local | textbee/textbee-mcp · npm |
| REST API | Any language with an HTTP client | API reference |
Step-by-step guides for no-code and automation tools:
n8n · Zapier · Make · Home Assistant · Node-RED · Google Sheets · Slack · Shopify · WooCommerce · GoHighLevel
textbee ships new features and fixes every few weeks across the API, the dashboard, and the Android app.
textbee is fully self-hostable. You run the API, the web dashboard, MongoDB, and Redis. You create a Firebase project for push messages, and you build the Android app for your own domain. All messages and account data stay in your database.
The complete guide, with every environment variable explained, is at textbee.dev/docs/self-hosting. The short version is below.
pnpm, pm2, MongoDB, and Redisgoogle-services.json for the Android appgit clone https://github.com/textbee/textbee.git
cd textbee
cp api/.env.example api/.env
cp web/.env.example web/.env
Fill in both .env files. The ones that matter first:
| File | Variable | Value |
|---|---|---|
api/.env | MONGO_URI, MONGO_ROOT_USER, MONGO_ROOT_PASS | Change the default user and password. The example URI already points at the textbee-db container |
api/.env | JWT_SECRET | A long random string |
api/.env | FRONTEND_URL | The public URL of your dashboard |
api/.env | FIREBASE_* | Fields from your Firebase service account JSON |
api/.env | MAIL_*, ADMIN_EMAIL | Your SMTP server |
api/.env | USE_SMS_QUEUE | true to run sends through the Redis queue. Scheduled messages need it |
web/.env | NEXT_PUBLIC_API_BASE_URL | Your API URL with /api/v1 |
web/.env | NEXTAUTH_SECRET, NEXTAUTH_URL | A long random string and the public dashboard URL |
Then start everything:
docker compose up -d
This builds the API and web images from source and starts them with MongoDB, Redis, and an optional Mongo Express admin UI. The dashboard listens on port 3000 and the API on port 3001. Stop with docker compose down.
API (api/):
cd api
cp .env.example .env # then fill it in
pnpm install
pnpm build
pm2 start dist/main.js --name textbee-api
Web (web/):
cd web
cp .env.example .env # then fill it in
pnpm install
pnpm build
pm2 start pnpm --name textbee-web -- start
Reverse proxy: put both behind HTTPS. Example Caddy config:
sms.example.com {
reverse_proxy /api/* localhost:3001
reverse_proxy /* localhost:3000
}
MongoDB can run on the same server or on MongoDB Atlas. Redis runs the send queue and background jobs; point REDIS_URL at it.
The app must point at your domain and your Firebase project.
Place your google-services.json in android/app/.
Replace every occurrence of textbee.dev in the Android project with your own domain.
Build:
cd android
./gradlew assembleRelease
Install the APK on the phone, then register it from your dashboard the same way as on the hosted service.
textbee has three parts: the API, the Android app, and the web dashboard. Your code never talks to the phone directly. It calls the API, and the API uses Firebase Cloud Messaging to push each message to the phone, which sends it over the carrier network through its own SIM.
How a message flows:
pending, and picks the device.dispatched, sent, delivered, or failed.The web dashboard is a Next.js app that calls the same API your code does. It is where you register devices, create API keys, send and read messages, and manage webhooks.
| Directory | What it is | Stack |
|---|---|---|
api/ | REST API, device registration, send queue, webhooks, billing | NestJS, MongoDB, Redis (BullMQ), Firebase Cloud Messaging |
web/ | Dashboard: devices, API keys, messaging, history, webhooks | Next.js, React, Tailwind CSS |
android/ | The gateway app: sends and receives SMS, reports status | Kotlin, Jetpack Compose, WorkManager |
docker-compose.yaml | One-command self-hosted stack | Docker |
Yes. Messages are sent through the phone, so it needs power, the app, and an internet connection. A spare Android phone on a charger works well as a dedicated gateway. The keep the phone online guide lists the battery and background settings to change.
Carriers apply their own rate limits and anti-spam rules, which vary by country and plan. Personal and low-volume use is rarely a problem. For higher volume, spread sends across several devices or SIMs and keep rates reasonable. You are responsible for staying within your carrier's terms.
SMS marketing is regulated in most countries. textbee is a tool. You are responsible for getting consent and following the laws that apply to you and your recipients.
Yes. Register as many devices as your plan allows and pass deviceId to choose the phone. On dual-SIM phones, pass simSubscriptionId to choose the SIM. See choosing a SIM.
No. Download the APK from textbee.dev/download. The app needs SMS permissions that the Play Store restricts for this kind of app.
There is a free plan, and paid plans with higher limits and more devices. See textbee.dev/pricing. Self-hosting has no plan limits.
No. iOS does not let apps send or read SMS on your behalf. The gateway app is Android only. You can still call the API from any device or platform.
Contributions are welcome: bug fixes, features, docs, and translations. Look for good first issues and help wanted to get started.
main.main and describe what changed and why.# API (needs MongoDB; the Docker Compose file starts one)
cd api && cp .env.example .env && pnpm install && pnpm start:dev
# Web dashboard
cd web && cp .env.example .env && pnpm install && pnpm dev
# Tests
cd api && pnpm exec jest
cd web && pnpm test
Open the Android project in Android Studio from the android/ folder. It has dev and prod build variants, described in android/BUILD_VARIANTS_SETUP.md.
textbee is built and maintained by Nuver Labs, a small software studio that makes developer tools and AI products. The team also offers custom development: integrations, SMS workflows, and self-hosted setups built on textbee.
Do not open a public issue for a vulnerability. Email [email protected] with the details. See SECURITY.md.
textbee is open source under the MIT License.