Open-source infrastructure for SMS and phone verification.
Connect Android devices or professional messaging providers through one developer API. Use hosted Bridge or run it on your own server.
Application
| POST /v1/messages
v
Bridge -- queue, retries, delivery status, logs
|
v
Android phone + SIM or MSG91 / Twilio / Vonage / Plivo
|
v
SMS
Your application talks to one stable API. What delivers the message underneath (your own Android phone, or a messaging provider as a fallback or instead) can change without rewriting your code.
Bridge 1.0 is the first stable release. Documentation: bridge.kroszborg.co/docs.
- SMS through your own phones. The Android app pairs by QR code or by signing in, sends through the phone's SIM (dual-SIM aware), reports sent and delivered, and can forward the SMS it receives. Bridge paces each phone under Android's limit and a daily cap that keeps SIMs within their operator's allowance.
- SMS providers. MSG91, Twilio, Vonage and Plivo, as a fallback when no phone can send or for everything, with delivery reports.
- Delivery you can follow. Every message has a timeline from queued to the carrier's delivery report, retries that never send a code twice, and signed webhooks (Standard Webhooks) for deliveries and incoming SMS, plus a live event stream.
- Verify. One-time passwords that Bridge generates, sends and checks, with Verify apps per product, failover to another route, fraud limits, Cloudflare Turnstile, and a drop-in widget or hosted page that returns a signed token.
- Messaging tools. Broadcasts to up to 10,000 numbers with variables, scheduled and repeating messages in any time zone, and an opt-out list, keyword auto-replies and forwarding rules (to another phone, Telegram, Slack, Discord, a signed webhook or email).
- A dashboard for the whole team. Messages, Send (one, bulk CSV, scheduled), Verify, Automation, Phones, Providers, Integrations, API keys, webhooks, request logs, a playground, usage charts, teams with roles and invite links, an audit log and a public status page.
- Developer tools. A zero-dependency TypeScript SDK
(
npm install @kroszborg/bridge), thebridgectlCLI, and an MCP server for AI assistants. - Integrations. Supabase Auth (built-in Send SMS hook), Better Auth, Auth0, Firebase and Clerk, and n8n, Zapier or Make.
- Secure by default. Hashed keys and tokens, argon2id passwords, encrypted provider credentials, SSRF-safe webhooks, rate limits, and message text erased after 30 days. See the security model.
Create an account. You get a workspace and a
default project on the Free plan (1 phone, 100 live SMS a month); test messages are always free and
unlimited. Pro ($5/month) and Team ($15/month) add phones, SMS, projects and members; see
plans and billing. The API is at https://api.bridge.kroszborg.co.
You need Docker with Compose.
git clone https://github.com/kroszborg/bridge.git
cd bridge
docker compose up -d| Service | URL |
|---|---|
| Dashboard | http://localhost:3000 |
| API | http://localhost:8080 |
| API reference | http://localhost:8080/docs |
| Status page | http://localhost:3000/status |
This builds the images from source. To run a published release instead, set
BRIDGE_IMAGE_PREFIX=ghcr.io/kroszborg/ and BRIDGE_VERSION=1.1.0 in .env (see
Releases). Self-hosted servers have no plans or
limits. For a public server, read the self-hosting guide; configuration
lives in environment variables, see .env.example.
Create an API key under API keys, pair a phone under Phones (or add an SMS provider), then send:
export BRIDGE_URL="https://api.bridge.kroszborg.co" # or http://localhost:8080
export BRIDGE_API_KEY="bk_test_..."
curl "$BRIDGE_URL/v1/messages" \
-H "Authorization: Bearer $BRIDGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to": "+919876543210", "message": "Your order has shipped."}'{ "id": "msg_01ja8z3k5wq2v7c9e4r2n0w6yb", "status": "queued", "to": "+919876543210", "segments": 1, "...": "..." }bk_test_ keys use the full API but never send a real SMS. bk_live_ keys send through your paired
phones (or your SMS providers, if the project routes to them).
Follow the message under Messages, or with GET /v1/messages/{id}, which includes the full
delivery timeline. To be told when it is delivered, or when a phone receives an SMS, add a webhook
endpoint. See Sending messages and Webhooks.
For login and sign-up codes, use Verify: POST /v1/otp, then
POST /v1/otp/verify, or drop in the verification widget and
check its signed token.
From TypeScript, use the SDK:
import { Bridge } from '@kroszborg/bridge';
const bridge = new Bridge({ apiKey: process.env.BRIDGE_API_KEY, baseUrl: process.env.BRIDGE_URL });
const msg = await bridge.messages.send({ to: '+919876543210', message: 'Your order has shipped.' });From a terminal, use bridgectl: bridgectl send +919876543210 "Hello" --wait.
To check a key without sending anything:
curl "$BRIDGE_URL/v1/whoami" -H "Authorization: Bearer $BRIDGE_API_KEY"{
"project_id": "prj_01j9tq4m2xk3v8c7e5r2n0w6yb",
"project_name": "Default",
"organization_id": "org_01j9tq4m2xk3v8c7e5r2n0w6yb",
"environment": "test",
"api_key_id": "key_01j9tq4m2xk3v8c7e5r2n0w6yb",
"api_key_name": "Local test"
}| Path | What |
|---|---|
apps/api |
Go API, background worker and migrations in one binary (bridge serve, bridge worker, bridge migrate) |
apps/dashboard |
Next.js dashboard, including the public status page and the hosted Verify page |
apps/web |
Public website and documentation site |
apps/api/cmd/bridgectl |
Command-line tool and MCP server: send, broadcast from CSV, opt-outs, follow, tail events, forward webhooks locally, see docs/cli |
packages/sdk |
TypeScript SDK (MIT, zero dependencies), see its README |
packages/api-types |
TypeScript types generated from the API's OpenAPI document |
examples |
curl and Node.js examples |
android/gateway |
Android gateway app (Kotlin, foss and gms builds), see docs/android |
docs |
Guides (messages, broadcasts, schedules, automation, Verify, providers, integrations), security model, self-hosting, hosted plans, releasing |
The stack is deliberately boring: Go, PostgreSQL (data and job queue), Next.js. Self-hosting needs one binary and one database. What changed in each release is in the changelog.
Bridge is not a marketing tool, and it does not help you bypass carrier rules, DLT registration or provider policies. Broadcasts are for messages people expect from you, are paced to your phones' send limits, and always honour opt-outs. Each phone sends at most its daily cap (100 SMS in any 24 hours by default), because operators limit SIMs and may block those that send far more. Throughput is limited by your SIM and carrier, and Bridge reports those limits rather than hiding them.
Read CONTRIBUTING.md for local setup, tests and conventions. Report security issues privately as described in SECURITY.md.
The Bridge server, dashboard and Android app are licensed under AGPL-3.0. Client SDKs are MIT-licensed so you can embed them anywhere.