To integrate Replit with Bandwidth, store your Account ID, API credentials, and phone number in Replit Secrets (lock icon π), install the Bandwidth SDK, and call the Messaging or Voice API from your server-side code. Bandwidth owns its own carrier network, which delivers lower per-message costs at scale compared to resellers like Twilio. Deploy as Autoscale or Reserved VM to keep webhook endpoints live for inbound SMS and call events.
Enterprise Voice and SMS from Replit Using Bandwidth's Carrier Network
Bandwidth stands apart from most communications APIs because it is both a software platform and a licensed carrier β it owns the underlying network infrastructure that other CPaaS providers (including many Twilio resellers) rent. This vertical integration means lower per-message and per-minute costs at scale, carrier-level reliability for toll-free numbers, and direct 911 access for emergency services integrations. For Replit-based applications that expect high message volumes or need enterprise-grade SLAs, Bandwidth is a compelling alternative to reseller-based APIs.
The Bandwidth API uses a layered model: your Account contains Applications (which hold callback URLs), and your phone numbers are assigned to Applications. This means you configure your webhook URLs once per Application rather than per phone number β a cleaner architecture for multi-number deployments. Bandwidth splits its API into distinct services: the Messaging API for SMS/MMS, the Voice API for calls and conferencing, and the Numbers API for provisioning and porting. Each uses Basic Auth with your Account ID paired with either an API token and secret (Messaging) or your username and password (Voice).
For a Replit integration, the most important operational consideration is deployment. Bandwidth delivers message callbacks and call events to HTTP endpoints, and those endpoints must be consistently available. Development Repls sleep when you close your browser tab, causing webhook delivery failures. An Autoscale deployment on Replit gives you a stable HTTPS URL that stays live 24/7, handles Bandwidth's retry logic, and keeps your application responsive to both inbound messages and mid-call BXML instructions.
Integration method
Bandwidth integrates with Replit through Bandwidth's REST API and official SDKs for Node.js and Python. Your Replit server authenticates with Basic Auth (Account ID + API token/secret) to send outbound messages and make voice calls. For inbound messages and call events, Bandwidth sends HTTP POST webhooks to callback URLs you configure on your number β these URLs must be deployed Replit app endpoints, not development URLs, since Bandwidth expects consistent availability for event delivery.
Prerequisites
- A Replit account with a Node.js or Python Repl ready
- A Bandwidth account β visit bandwidth.com to sign up (contact sales for a trial or sandbox account)
- A Bandwidth phone number assigned to a Messaging Application with your callback URL configured
- For webhook receivers: your app deployed with a stable HTTPS URL (https://yourapp.replit.app)
- Basic familiarity with REST APIs and HTTP webhook patterns
Step-by-step guide
Set Up Your Bandwidth Account and Store Credentials in Replit Secrets
Set Up Your Bandwidth Account and Store Credentials in Replit Secrets
Bandwidth organizes credentials around your Account ID, which appears in the Bandwidth Dashboard URL and in Account Settings. For the Messaging API, you need an API token and secret β navigate to Account > Applications in the Bandwidth Dashboard, create a Messaging Application, and note the Token and Secret shown. For the Voice API, you use your Bandwidth username and password. Bandwidth requires you to create an Application before assigning phone numbers. In the Dashboard, go to Applications β Add Application β select Messaging or Voice. Set the Callback URL to your deployed Replit endpoint (e.g., https://yourapp.replit.app/bandwidth/messages). Save the Application ID shown β you will need it when provisioning numbers. Open your Replit project and click the lock icon (π) in the left sidebar to open Secrets. Add the following secrets: BANDWIDTH_ACCOUNT_ID: your numeric Account ID from the Dashboard. BANDWIDTH_API_TOKEN: the API token from your Messaging Application. BANDWIDTH_API_SECRET: the API secret from your Messaging Application. BANDWIDTH_USERNAME: your Bandwidth account username (for Voice API). BANDWIDTH_PASSWORD: your Bandwidth account password (for Voice API). BANDWIDTH_PHONE_NUMBER: your Bandwidth phone number in E.164 format (+15551234567). BANDWIDTH_APPLICATION_ID: the Application ID from your Messaging Application. Replit's Secret Scanner will flag any credentials you accidentally type into code files and remind you to move them to Secrets. Always use Secrets β Bandwidth API credentials with messaging permissions can run up significant charges if exposed.
1// check-bandwidth-secrets.js2const required = [3 'BANDWIDTH_ACCOUNT_ID',4 'BANDWIDTH_API_TOKEN',5 'BANDWIDTH_API_SECRET',6 'BANDWIDTH_PHONE_NUMBER',7 'BANDWIDTH_APPLICATION_ID'8];9for (const key of required) {10 if (!process.env[key]) {11 throw new Error(`Missing secret: ${key}. Add it in Replit Secrets (lock icon π).`);12 }13}14console.log('All Bandwidth secrets are configured.');15console.log('Account ID:', process.env.BANDWIDTH_ACCOUNT_ID);16console.log('Phone Number:', process.env.BANDWIDTH_PHONE_NUMBER);Pro tip: Bandwidth separates Messaging and Voice credentials. The API Token + Secret pair is for the Messaging API; the Username + Password pair is for the Voice API and Dashboard. You may need both if your app uses both services.
Expected result: All secrets appear in the Replit Secrets pane. The verification script prints all key names without errors.
Send SMS and MMS Messages with Node.js
Send SMS and MMS Messages with Node.js
Bandwidth's Node.js SDK provides a clean interface to the Messaging API. Install it with npm install @bandwidth/sdk in the Shell. The SDK client is initialized with your Account ID, API token, and API secret. To send a message, call the MessagingClient.createMessage() method with a MessageRequest object specifying the from number, to array (Bandwidth supports group messaging natively), message text, and your Application ID. The Application ID is required for all Bandwidth messages β it tells Bandwidth which callback URL to use for delivery receipts and inbound message notifications. Unlike some other APIs where the phone number carries its callback URL, Bandwidth uses the Application as the routing layer. For MMS, add a media array of publicly accessible URLs to the message request. Bandwidth supports images, videos, and audio files in MMS. International MMS is limited β check Bandwidth's coverage documentation for supported countries before deploying internationally. Bandwidth's message create response includes a message ID that you should log for delivery tracking. Delivery receipts arrive as callbacks to your Application's callback URL, so storing the message ID lets you correlate inbound callbacks with outbound sends. Error handling should catch Bandwidth's ApiError class, which includes an HTTP status code and a Bandwidth-specific error body with a code and description field that explains exactly what went wrong.
1// bandwidth-send.js β Send SMS and MMS via Bandwidth API2const Bandwidth = require('@bandwidth/sdk');34const client = new Bandwidth.ApiClient();5client.authentications['Basic'].username = process.env.BANDWIDTH_API_TOKEN;6client.authentications['Basic'].password = process.env.BANDWIDTH_API_SECRET;78const messagingApi = new Bandwidth.MessagesApi(client);910const ACCOUNT_ID = process.env.BANDWIDTH_ACCOUNT_ID;11const FROM_NUMBER = process.env.BANDWIDTH_PHONE_NUMBER;12const APP_ID = process.env.BANDWIDTH_APPLICATION_ID;1314// Send a simple SMS15async function sendSMS(to, text) {16 const messageRequest = new Bandwidth.MessageRequest();17 messageRequest.applicationId = APP_ID;18 messageRequest.from = FROM_NUMBER;19 messageRequest.to = [to]; // Bandwidth uses array for recipients20 messageRequest.text = text;2122 try {23 const response = await messagingApi.createMessage(ACCOUNT_ID, messageRequest);24 const message = response.body;25 console.log(`SMS sent: ${message.id} (status: ${message.status})`);26 return message.id;27 } catch (err) {28 if (err.response) {29 console.error('Bandwidth API error:', err.response.status, err.response.body);30 }31 throw err;32 }33}3435// Send an MMS with media36async function sendMMS(to, text, mediaUrls) {37 const messageRequest = new Bandwidth.MessageRequest();38 messageRequest.applicationId = APP_ID;39 messageRequest.from = FROM_NUMBER;40 messageRequest.to = [to];41 messageRequest.text = text;42 messageRequest.media = mediaUrls; // Array of publicly accessible URLs4344 const response = await messagingApi.createMessage(ACCOUNT_ID, messageRequest);45 return response.body.id;46}4748(async () => {49 try {50 const messageId = await sendSMS('+15559876543', 'Hello from Replit + Bandwidth!');51 console.log('Message ID:', messageId);52 } catch (err) {53 console.error('Error:', err.message);54 }55})();Pro tip: The Bandwidth 'to' field is always an array, even for single recipients. This design supports group messaging (sending to multiple numbers in one API call) β a feature not available in all SMS APIs.
Expected result: Running the script sends an SMS to the test number. The console logs the Bandwidth message ID (a UUID string). The message arrives on the recipient's phone within seconds.
Send SMS with Python
Send SMS with Python
The Bandwidth Python SDK provides the same messaging capabilities as the Node.js version. Install it with pip install bandwidth-sdk in the Shell. Initialize the ApiClient with Basic Auth using your API token as username and API secret as password. The Python SDK mirrors the Node.js structure closely β you create a MessageRequest object, set the required fields (applicationId, from_, to, text), and call messages_api.create_message(account_id, message_request). Note the Python from_ naming convention (underscore suffix) to avoid conflicting with Python's built-in from keyword. For async Python applications using FastAPI or asyncio, run Bandwidth SDK calls in a thread pool since the SDK is synchronous. Use asyncio.get_event_loop().run_in_executor(None, lambda: messages_api.create_message(...)) for non-blocking execution. Bandwidth raises a bandwidth.exceptions.ApiException on errors. The exception object includes a status (HTTP status code), reason (HTTP reason phrase), and body (parsed JSON error response) that contains a Bandwidth error description. Log the full body for debugging, as it often includes the specific field or configuration that caused the error.
1# bandwidth_send.py β Send SMS via Bandwidth API from Replit2import os3import bandwidth4from bandwidth.models import MessageRequest5from bandwidth.exceptions import ApiException67# Configure authentication8configuration = bandwidth.Configuration(9 username=os.environ['BANDWIDTH_API_TOKEN'],10 password=os.environ['BANDWIDTH_API_SECRET']11)1213ACCOUNT_ID = os.environ['BANDWIDTH_ACCOUNT_ID']14FROM_NUMBER = os.environ['BANDWIDTH_PHONE_NUMBER']15APP_ID = os.environ['BANDWIDTH_APPLICATION_ID']1617def send_sms(to: str, text: str) -> str:18 """Send an SMS via Bandwidth and return the message ID."""19 with bandwidth.ApiClient(configuration) as api_client:20 messages_api = bandwidth.MessagesApi(api_client)21 message_request = MessageRequest(22 application_id=APP_ID,23 to=[to], # Bandwidth requires array even for single recipient24 from_=FROM_NUMBER,25 text=text26 )27 try:28 response = messages_api.create_message(ACCOUNT_ID, message_request)29 print(f'SMS sent: {response.id}')30 return response.id31 except ApiException as e:32 print(f'Bandwidth API error {e.status}: {e.reason}')33 print(f'Error body: {e.body}')34 raise3536def send_mms(to: str, text: str, media_urls: list) -> str:37 """Send an MMS with media attachments."""38 with bandwidth.ApiClient(configuration) as api_client:39 messages_api = bandwidth.MessagesApi(api_client)40 message_request = MessageRequest(41 application_id=APP_ID,42 to=[to],43 from_=FROM_NUMBER,44 text=text,45 media=media_urls46 )47 response = messages_api.create_message(ACCOUNT_ID, message_request)48 return response.id4950if __name__ == '__main__':51 msg_id = send_sms('+15559876543', 'Hello from Replit + Bandwidth (Python)!')52 print(f'Message ID: {msg_id}')Pro tip: The Python SDK uses snake_case field names (application_id, from_) while the REST API uses camelCase. The SDK handles the conversion automatically β use snake_case in Python code.
Expected result: Running python bandwidth_send.py sends an SMS and prints the UUID message ID. The message arrives on the test phone within seconds.
Receive Inbound SMS Callbacks and Handle Delivery Receipts
Receive Inbound SMS Callbacks and Handle Delivery Receipts
Bandwidth sends HTTP POST callbacks to your Application's callback URL for two types of events: inbound messages (when someone texts your Bandwidth number) and message status updates (queued, sending, sent, delivered, error). Both arrive at the same callback URL in the form of JSON payloads β you distinguish them by the 'type' field in the request body. For inbound messages, the type is 'message-received' and the body contains the message text, sender number, recipient number, and any media URLs for MMS. For delivery receipts, the type is 'message-sending', 'message-sent', 'message-delivered', or 'message-failed' depending on the delivery stage. Your webhook endpoint must return a 200 OK response quickly (within a few seconds) β Bandwidth considers anything else a delivery failure and may retry. Process the event asynchronously if it involves database writes or external API calls. Important: configure your Bandwidth Application's callback URL to point to your deployed Replit URL, not a development URL. Development Repls go offline when you close your browser, causing Bandwidth to mark the callback as failed. Use Autoscale deployment for reliable message receiving. Bandwidth does not include a signature in message callbacks by default (unlike Twilio). To secure your endpoint, use a secret token in the callback URL path or query string that only you and Bandwidth know, and verify it on every incoming request.
1// bandwidth-webhook.js β Receive Bandwidth SMS callbacks with Express2const express = require('express');3const app = express();4app.use(express.json());56// Simple security: verify a shared secret token in the path7const WEBHOOK_SECRET = process.env.BANDWIDTH_WEBHOOK_SECRET || 'change-me';89// Configure this URL in your Bandwidth Application:10// https://yourapp.replit.app/bandwidth/messages/{WEBHOOK_SECRET}11app.post('/bandwidth/messages/:secret', (req, res) => {12 if (req.params.secret !== WEBHOOK_SECRET) {13 return res.status(403).json({ error: 'Unauthorized' });14 }1516 // Bandwidth sends an array of callback events17 const events = Array.isArray(req.body) ? req.body : [req.body];1819 for (const event of events) {20 const type = event.type;21 console.log('Bandwidth event type:', type);2223 if (type === 'message-received') {24 const { from, to, text, media } = event.message;25 console.log(`Inbound SMS from ${from}: ${text}`);26 if (media && media.length > 0) {27 console.log('MMS media URLs:', media);28 }29 // TODO: add your inbound message handling logic here30 // e.g., look up user by phone number, trigger workflow3132 } else if (type === 'message-delivered') {33 const messageId = event.message.id;34 console.log(`Message ${messageId} delivered successfully`);35 // TODO: update delivery status in database3637 } else if (type === 'message-failed') {38 const { id, errorCode } = event.message;39 console.error(`Message ${id} failed with error code: ${errorCode}`);40 // TODO: handle failure β retry, alert, or log4142 } else {43 console.log('Unhandled event type:', type, JSON.stringify(event, null, 2));44 }45 }4647 // Must return 200 quickly48 res.status(200).json({ received: true });49});5051app.listen(3000, '0.0.0.0', () => {52 console.log('Bandwidth webhook server running on port 3000');53 console.log(`Configure callback URL in Bandwidth App: https://yourapp.replit.app/bandwidth/messages/${WEBHOOK_SECRET}`);54});Pro tip: Bandwidth sends an array of events in a single callback POST β always handle req.body as a potential array, even though typically you will receive one event at a time. Failing to handle the array structure causes silent drops of some events.
Expected result: The server starts on port 3000. After deploying and updating the Application callback URL in the Bandwidth Dashboard, inbound SMS and delivery receipts trigger the /bandwidth/messages route and log the event details to the console.
Deploy to Replit and Configure Bandwidth Webhooks
Deploy to Replit and Configure Bandwidth Webhooks
Bandwidth's callback architecture requires your webhook URL to be consistently available β it must respond within a timeout window or Bandwidth will mark the delivery as failed. This makes proper deployment essential for any production Bandwidth integration. For most Bandwidth use cases, Autoscale deployment is the right choice. Go to your Repl's Deploy tab, select Autoscale, and deploy. Replit will provide a stable HTTPS URL like https://yourapp.replit.app. Autoscale keeps your app available 24/7 and scales with traffic β Bandwidth message callbacks typically arrive in bursts (many messages at once), and Autoscale handles concurrent webhook delivery naturally. For high-throughput voice applications (where a 1-3 second cold start could disrupt a live phone call), consider Reserved VM deployment instead β it guarantees a warm instance is always running and eliminates cold start latency in call control responses. Once deployed, update your Bandwidth Application: in the Bandwidth Dashboard β Applications β your app β set the Message Callback URL to your deployed URL (e.g., https://yourapp.replit.app/bandwidth/messages/your-secret). For voice, set the Answer URL and Disconnect URL similarly. Verify the setup by sending a test SMS to your Bandwidth number from another phone. You should see the callback arrive in your deployment logs (accessible via the Replit deployment logs panel) within a second or two of sending the text. The .replit configuration below ensures your app binds to the right port and restarts cleanly on deployment.
1# .replit β deployment configuration for Bandwidth webhook server2# Add this to your .replit file34# For Node.js:5# [[ports]]6# internalPort = 30007# externalPort = 808#9# [deployment]10# run = ["node", "bandwidth-webhook.js"]11# deploymentTarget = "cloudrun"1213# For Python/Flask:14# [[ports]]15# internalPort = 300016# externalPort = 8017#18# [deployment]19# run = ["gunicorn", "app:app", "--bind", "0.0.0.0:3000", "--workers", "2"]20# deploymentTarget = "cloudrun"2122# Python Flask webhook receiver23from flask import Flask, request, jsonify24import os2526app = Flask(__name__)27WEBHOOK_SECRET = os.environ.get('BANDWIDTH_WEBHOOK_SECRET', 'change-me')2829@app.route('/bandwidth/messages/<secret>', methods=['POST'])30def bandwidth_callback(secret):31 if secret != WEBHOOK_SECRET:32 return jsonify({'error': 'Unauthorized'}), 4033334 events = request.json35 if not isinstance(events, list):36 events = [events]3738 for event in events:39 event_type = event.get('type')40 print(f'Bandwidth event: {event_type}')4142 if event_type == 'message-received':43 msg = event.get('message', {})44 print(f'Inbound from {msg.get("from")}: {msg.get("text")}')45 elif event_type == 'message-delivered':46 print(f'Delivered: {event["message"]["id"]}')47 elif event_type == 'message-failed':48 print(f'Failed: {event["message"]["id"]} code={event["message"].get("errorCode")}')4950 return jsonify({'received': True}), 2005152if __name__ == '__main__':53 app.run(host='0.0.0.0', port=3000)Pro tip: After updating your Bandwidth Application callback URL, send yourself a test SMS to your Bandwidth number and watch the Replit deployment logs in real time. If the callback does not appear within 5 seconds, check that the URL matches exactly what Bandwidth has configured (protocol, domain, path, query string).
Expected result: The deployed app receives Bandwidth callbacks. Sending an SMS to your Bandwidth number triggers the webhook route and logs the inbound message event in your Replit deployment logs.
Common use cases
High-Volume SMS Notification System
Send transactional SMS alerts β shipping updates, appointment reminders, account notifications β to thousands of users at lower per-message cost than reseller APIs. Bandwidth's direct carrier access reduces message latency and improves deliverability for toll-free SMS campaigns, which require carrier registration but offer higher throughput limits.
Build a bulk SMS notification service that reads a list of phone numbers and messages from a database, sends them via Bandwidth Messaging API using a toll-free number, and tracks delivery status by handling Bandwidth message status callbacks.
Copy this prompt to try it in Replit
Programmable Voice IVR System
Create an interactive voice response system where callers reach your Bandwidth number and are guided through menu options using BXML (Bandwidth XML). Your Replit server returns BXML instructions to handle call routing, play audio prompts, collect digit input, and forward calls to agents β all controlled programmatically from your backend.
Create a voice IVR system that answers incoming calls on a Bandwidth number, plays a menu prompt asking callers to press 1 for sales or 2 for support, collects their input with BXML Gather, then forwards the call to different phone numbers based on their selection.
Copy this prompt to try it in Replit
Two-Way SMS Business Messaging
Enable customers to text your business number and receive automated responses based on their message content. The Replit server receives Bandwidth message callbacks, parses the inbound SMS, looks up the customer record in your database, and replies with relevant information β order status, account balance, or support instructions β creating a self-service SMS channel.
Build a two-way SMS system where customers text a Bandwidth number with an order number, the server looks up the order in the database, and automatically replies with the current shipping status and estimated delivery date.
Copy this prompt to try it in Replit
Troubleshooting
HTTP 401 Unauthorized when calling the Bandwidth Messaging API
Cause: The BANDWIDTH_API_TOKEN or BANDWIDTH_API_SECRET is incorrect, or you are using Username/Password credentials (for Voice) where Token/Secret is required (for Messaging). Bandwidth uses different credential sets for different API services.
Solution: In the Bandwidth Dashboard, navigate to Applications β your Messaging Application β show credentials. Verify that BANDWIDTH_API_TOKEN and BANDWIDTH_API_SECRET in Replit Secrets exactly match (no extra spaces, correct case). If you regenerated credentials in the Dashboard, update Replit Secrets and redeploy.
1// Quick auth test β runs before your main app logic2const https = require('https');3const auth = Buffer.from(`${process.env.BANDWIDTH_API_TOKEN}:${process.env.BANDWIDTH_API_SECRET}`).toString('base64');4const options = {5 hostname: 'messaging.bandwidth.com',6 path: `/api/v2/users/${process.env.BANDWIDTH_ACCOUNT_ID}/messages`,7 headers: { 'Authorization': `Basic ${auth}` }8};9https.get(options, res => console.log('Auth test status:', res.statusCode));Bandwidth callbacks are not arriving β the Bandwidth Dashboard shows 'Callback Error' or no callbacks at all
Cause: The callback URL is set to a development Replit URL that goes offline when your browser closes, or the deployed app is not running, or the URL path does not match your route definition.
Solution: Deploy your app using Autoscale or Reserved VM and use the deployed URL (https://yourapp.replit.app/...) not the development URL. In the Bandwidth Dashboard, verify the Message Callback URL is correct and test it by sending a text to your Bandwidth number. Check Replit deployment logs for incoming POST requests.
Message send fails with error: 'Application not found' or 'Invalid applicationId'
Cause: The BANDWIDTH_APPLICATION_ID in Replit Secrets does not match any existing Messaging Application in your Bandwidth account, or the application was deleted and recreated with a new ID.
Solution: In the Bandwidth Dashboard, navigate to Applications and copy the exact Application ID (a UUID). Update BANDWIDTH_APPLICATION_ID in Replit Secrets. The Application must be a Messaging-type Application (not Voice) for the Messaging API.
Phone number sends fail with 'Number not associated with application' error
Cause: Your Bandwidth phone number has not been assigned to the Messaging Application. Bandwidth requires an explicit association between numbers and applications before the number can send or receive messages.
Solution: In the Bandwidth Dashboard, navigate to Phone Numbers β your number β edit β assign it to your Messaging Application. Alternatively, use the Numbers API to associate the number programmatically. The number must be in the same account as the application.
Best practices
- Store all Bandwidth credentials (Account ID, API Token, API Secret, Application ID) in Replit Secrets (lock icon π) β never hardcode them in source files
- Use a secret token in your callback URL path and verify it on every incoming webhook to prevent unauthorized requests to your Bandwidth callback endpoint
- Deploy as Autoscale or Reserved VM for production β development Repls go offline when you close your browser, causing Bandwidth to log callback failures
- Log Bandwidth message IDs returned from create_message calls so you can correlate delivery receipt callbacks with your outbound sends
- Handle Bandwidth callbacks as arrays β Bandwidth can batch multiple events into one POST, and failing to iterate the array causes missed events
- Use Bandwidth toll-free numbers for high-volume messaging campaigns β they support higher throughput than local numbers and require A2P 10DLC registration for long codes
- Implement idempotency in your callback handler β Bandwidth may deliver the same event more than once; check message IDs against your database before processing
- Test with Bandwidth's sandbox environment before switching to production credentials to avoid accidental charges during development
Alternatives
Twilio has a more developer-friendly onboarding experience and larger SDK ecosystem, making it faster to integrate for smaller projects that do not need Bandwidth's direct-carrier cost advantages.
Vonage offers competitive SMS pricing, especially in Europe and Asia, and has a simpler API surface that is easier to integrate for applications that need basic SMS without voice features.
SendGrid handles transactional email rather than SMS or voice β use it alongside Bandwidth when your application needs multi-channel communication through both text messages and email.
Frequently asked questions
How do I store Bandwidth API credentials securely in Replit?
Click the lock icon (π) in the Replit sidebar to open Secrets. Add BANDWIDTH_ACCOUNT_ID, BANDWIDTH_API_TOKEN, BANDWIDTH_API_SECRET, BANDWIDTH_PHONE_NUMBER, and BANDWIDTH_APPLICATION_ID as separate secrets. Access them in Node.js with process.env.BANDWIDTH_API_TOKEN or in Python with os.environ['BANDWIDTH_API_TOKEN']. Never write credentials directly in your code files β Replit's Secret Scanner will flag this.
Does Replit work with Bandwidth for free?
Bandwidth does not offer a traditional free tier like Twilio's trial credits. You need to contact Bandwidth to set up an account and get API access β pricing is typically volume-based and negotiated for enterprise customers. For small-scale testing, ask Bandwidth support about a sandbox environment or limited trial credits.
Why is Bandwidth cheaper than Twilio for high-volume SMS?
Bandwidth owns its own carrier network infrastructure (it holds FCC licenses as a carrier), while Twilio and many other CPaaS providers resell access to carrier networks they do not own. Bandwidth's direct-carrier model eliminates the middleman markup on per-message costs, which can be significant at millions of messages per month. The tradeoff is a more complex setup process and less beginner-friendly documentation than Twilio.
What deployment type should I use for a Bandwidth webhook receiver on Replit?
Use Autoscale deployment for most SMS callback receivers β it stays live 24/7, handles concurrent callbacks, and is cost-effective for event-driven workloads. Use Reserved VM if you are building a voice application where Bandwidth needs fast responses to BXML requests during live calls, since the 1-3 second cold start on Autoscale could cause noticeable pauses in call control.
Can I receive inbound SMS from Bandwidth in a Replit development environment?
Development Repls only run while your browser tab is open, making them unreliable for receiving Bandwidth callbacks. For occasional testing, you can expose your development Repl temporarily by keeping the tab open, but for any ongoing testing deploy the app. Use Autoscale deployment and update your Bandwidth Application callback URL to the deployed URL.
How is the Bandwidth Application ID different from the Account ID?
Your Account ID is a top-level identifier for your entire Bandwidth account β think of it like a company account number. An Application ID identifies a specific configuration within your account that defines callback URLs for a group of phone numbers. You can have multiple Applications in one account (e.g., one for SMS, one for voice). Phone numbers must be assigned to an Application before they can send or receive messages.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation