To integrate Lovable with Bandwidth, create a Supabase Edge Function that proxies Bandwidth API calls using your API Token and Secret. Store credentials in Cloud → Secrets, then build Edge Functions to send SMS, make voice calls, and receive inbound message webhooks. Bandwidth is an enterprise CPaaS with direct carrier connections — its API is best suited for high-volume or mission-critical communication workflows.
Enterprise voice and messaging in Lovable with Bandwidth's direct carrier API
Bandwidth operates its own nationwide voice and messaging network rather than reselling carrier services, which is what distinguishes it from other CPaaS providers. This direct carrier model gives Bandwidth advantages in regulatory compliance (particularly for 911/emergency services), throughput at scale, and latency — making it the choice for enterprises in healthcare, financial services, and public safety where carrier-grade reliability is non-negotiable. The trade-off is that Bandwidth has historically targeted enterprise buyers rather than individual developers, so setup involves account configuration that is more involved than Twilio or Sinch.
In Lovable, Bandwidth calls are made from a server-side Edge Function using HTTP Basic Auth with your API Token and Secret. The Messaging API v2 endpoint accepts JSON bodies specifying the from number (one of your purchased Bandwidth numbers), to number, text content, and account/application identifiers. Voice calls use a different endpoint and a BXML (Bandwidth XML) response format similar to TwiML. Both services are proxied through your Edge Function, keeping your credentials secure in Cloud → Secrets.
This guide focuses on the Messaging API v2 — the current production API for SMS and MMS — with a secondary section on receiving inbound message callbacks. If you need voice call integration or 911 emergency calling, the patterns are similar but require additional Bandwidth account configuration for BXML hosting and emergency address registration.
Integration method
Bandwidth has no native Lovable connector, so all API communication is handled through Supabase Edge Functions acting as a secure server-side proxy. Your Lovable frontend calls the Edge Function, which authenticates with Bandwidth using HTTP Basic Auth (API Token and Secret), executes SMS or voice API requests, and returns results to the UI. Credentials stay encrypted in Cloud → Secrets and are never sent to the browser.
Prerequisites
- A Lovable project with Lovable Cloud enabled (verify via the Cloud tab in the editor)
- A Bandwidth account with API access at dashboard.bandwidth.com — enterprise accounts are provisioned by Bandwidth sales
- A Bandwidth phone number purchased and configured with a Messaging Application in the Bandwidth Dashboard
- Your Bandwidth Account ID, API Token, and API Secret from the dashboard
- Familiarity with Lovable's Edge Function pattern — all authenticated API calls go through server-side functions
Step-by-step guide
Locate your Bandwidth credentials in the dashboard
Locate your Bandwidth credentials in the dashboard
Sign in to the Bandwidth Dashboard at dashboard.bandwidth.com. Your Account ID is displayed prominently at the top of the main dashboard page — it is a numeric identifier like 12345678. Next, navigate to 'Account' → 'API Credentials' in the left sidebar. Here you will find your API Token (username) and API Secret (password). These are used together for HTTP Basic Auth on all Bandwidth API v2 requests. You also need to note your Messaging Application ID. Go to 'Applications' in the left sidebar and find or create a Messaging Application — this is a Bandwidth configuration entity that links your phone numbers to a callback URL. The Application ID is a UUID like a1b2c3d4-e5f6-7890-abcd-ef1234567890. If you do not have an application yet, create one now and associate your purchased Bandwidth phone number to it. The callback URL will be your inbound webhook Edge Function URL, which you will configure in a later step.
Pro tip: Bandwidth's API v2 is organized under https://messaging.bandwidth.com/api/v2 for messaging and https://voice.bandwidth.com/api/v2 for voice. Do not confuse these with older v1 endpoints which use a different authentication scheme.
Expected result: Account ID, API Token, API Secret, and Messaging Application ID copied and ready to store in Lovable's Secrets panel.
Store Bandwidth credentials in Cloud → Secrets
Store Bandwidth credentials in Cloud → Secrets
In your Lovable editor, click the '+' icon near the top-right to open the panel selector, then choose the Cloud tab. Scroll to the 'Secrets' section and add four secrets by clicking the '+' button next to Secrets for each one. Name the first secret BANDWIDTH_ACCOUNT_ID and paste your numeric Account ID. Name the second BANDWIDTH_API_TOKEN and paste your API Token. Name the third BANDWIDTH_API_SECRET and paste your API Secret. Name the fourth BANDWIDTH_APPLICATION_ID and paste your Messaging Application ID. Name the fifth BANDWIDTH_FROM_NUMBER and paste your Bandwidth phone number in E.164 format (e.g. +12025551234). Secret names must match exactly what your Edge Function will call with Deno.env.get(). Bandwidth uses Basic Auth where the username is the API Token and the password is the API Secret — both are required. Lovable's security layer encrypts all secrets at rest and prevents them from appearing in generated code. The platform actively blocks approximately 1,200 hardcoded API keys per day, so always use the Secrets panel rather than pasting credentials into chat prompts or code fields.
Pro tip: Store your Bandwidth phone number in E.164 format (+12025551234) as a secret. This prevents hardcoding it in the Edge Function and makes it easy to swap numbers for different environments.
Expected result: Five secrets (BANDWIDTH_ACCOUNT_ID, BANDWIDTH_API_TOKEN, BANDWIDTH_API_SECRET, BANDWIDTH_APPLICATION_ID, BANDWIDTH_FROM_NUMBER) saved in Cloud → Secrets.
Build the SMS sending Edge Function
Build the SMS sending Edge Function
Use the Lovable chat to generate the SMS Edge Function. The function must construct an HTTP Basic Auth header from the API Token and Secret (using btoa), then POST to Bandwidth's messaging endpoint at https://messaging.bandwidth.com/api/v2/users/{accountId}/messages. The request body is JSON with applicationId, to (array of destination numbers), from (your Bandwidth number), and text. Bandwidth's Messaging API v2 returns a 202 Accepted status on success (not 200), with a response body containing the message ID. Your Edge Function should parse this and return the messageId to your Lovable frontend. For MMS, add media (array of URLs) and omit the text field or include both. The API supports up to 10 recipient numbers per request for group messaging, though each number is billed separately. After Lovable deploys the function, test it from the Lovable chat by asking it to add a simple test trigger, or verify in Cloud → Logs that the function is deploying without errors.
Create a Supabase Edge Function called bandwidth-sms that: 1) Reads BANDWIDTH_ACCOUNT_ID, BANDWIDTH_API_TOKEN, BANDWIDTH_API_SECRET, BANDWIDTH_APPLICATION_ID, and BANDWIDTH_FROM_NUMBER from environment variables. 2) Accepts a POST request with JSON body containing: to (string, E.164 phone number) and text (string, message content). 3) Constructs HTTP Basic Auth header using btoa(token + ':' + secret). 4) POSTs to https://messaging.bandwidth.com/api/v2/users/{accountId}/messages with applicationId, to (as array), from, and text. 5) Returns the messageId from Bandwidth's response. Handle 202 as success. Include CORS headers and error handling.
Paste this in Lovable chat
1// supabase/functions/bandwidth-sms/index.ts2import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';34const corsHeaders = {5 'Access-Control-Allow-Origin': '*',6 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',7};89serve(async (req) => {10 if (req.method === 'OPTIONS') {11 return new Response('ok', { headers: corsHeaders });12 }1314 try {15 const accountId = Deno.env.get('BANDWIDTH_ACCOUNT_ID')!;16 const apiToken = Deno.env.get('BANDWIDTH_API_TOKEN')!;17 const apiSecret = Deno.env.get('BANDWIDTH_API_SECRET')!;18 const applicationId = Deno.env.get('BANDWIDTH_APPLICATION_ID')!;19 const fromNumber = Deno.env.get('BANDWIDTH_FROM_NUMBER')!;2021 const { to, text } = await req.json();2223 const credentials = btoa(`${apiToken}:${apiSecret}`);2425 const response = await fetch(26 `https://messaging.bandwidth.com/api/v2/users/${accountId}/messages`,27 {28 method: 'POST',29 headers: {30 'Authorization': `Basic ${credentials}`,31 'Content-Type': 'application/json',32 },33 body: JSON.stringify({34 applicationId,35 to: [to],36 from: fromNumber,37 text,38 }),39 }40 );4142 // Bandwidth returns 202 on success43 if (response.status !== 202 && !response.ok) {44 const error = await response.text();45 throw new Error(`Bandwidth API error ${response.status}: ${error}`);46 }4748 const data = await response.json();4950 return new Response(51 JSON.stringify({ messageId: data.id, status: 'queued' }),52 { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }53 );54 } catch (error) {55 return new Response(56 JSON.stringify({ error: error.message }),57 { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }58 );59 }60});Pro tip: Bandwidth's Messaging API v2 returns 202 Accepted — not 200 OK — on success. If you check for response.ok only, note that 202 is also in the 2xx range and will pass. Always also check for response.status === 202 explicitly if you want certainty.
Expected result: A deployed bandwidth-sms Edge Function that sends SMS messages via the Bandwidth API and returns a message ID.
Handle inbound SMS callbacks from Bandwidth
Handle inbound SMS callbacks from Bandwidth
When someone replies to your Bandwidth number or sends an inbound SMS, Bandwidth posts a JSON callback to the URL you configured in your Messaging Application. You need a second Edge Function to receive these callbacks, validate they are from Bandwidth, and store the inbound messages in your Supabase database. Create a second Edge Function called bandwidth-inbound. This function receives POST requests from Bandwidth with a JSON array of message event objects. Each event contains type (message-received), message.id, message.from, message.to, message.text, and message.time. Parse the array, extract the relevant fields, and insert a row into your Supabase database using the service role key for server-side writes. After deploying the Edge Function, copy its URL from Cloud → Edge Functions. Go back to Bandwidth Dashboard → Applications → your Messaging Application, and paste the Edge Function URL as the 'Inbound Message Callback' URL. Set the callback method to POST. Bandwidth will now forward all inbound SMS events to your Edge Function. Test by sending a text message to your Bandwidth number from any phone.
Create a Supabase Edge Function called bandwidth-inbound that: 1) Accepts POST requests from Bandwidth containing an array of message event objects. 2) Parses each event with type 'message-received'. 3) For each inbound message, inserts a row into an inbound_messages table with columns: bandwidth_message_id, from_number, to_number, text, received_at (timestamp). 4) Uses the Supabase service role key to insert the data. 5) Returns HTTP 200 immediately. Include error logging via console.error.
Paste this in Lovable chat
Pro tip: Bandwidth expects your callback endpoint to respond with HTTP 200 within a few seconds. Do any heavy processing asynchronously — use Supabase Edge Function background tasks or insert to a queue table and process separately.
Expected result: An inbound SMS callback Edge Function deployed and registered in Bandwidth Dashboard, storing incoming messages in your Supabase database.
Common use cases
High-volume SMS notification system for enterprise clients
Send transactional SMS notifications — appointment reminders, order updates, fraud alerts — to customers at enterprise scale. Bandwidth's direct carrier connections improve deliverability for high-volume senders and reduce the risk of messages being flagged as spam compared to aggregator-based providers.
Create an SMS notification system that calls my bandwidth-sms Edge Function to send appointment reminder messages. Add a Supabase table called sms_logs to track message ID, recipient, status, and timestamp. Show a send history table in the admin dashboard.
Copy this prompt to try it in Lovable
Two-way SMS customer support chat
Build an SMS-based support channel where your team can send and receive messages from customers. Inbound messages hit your Bandwidth callback Edge Function, get stored in Supabase, and appear in a real-time chat interface in Lovable built with Supabase Realtime subscriptions.
Build a two-way SMS support interface. Outbound messages go through my bandwidth-sms Edge Function. Inbound messages come in through my bandwidth-inbound Edge Function and get stored in a conversations table. Show a real-time chat thread grouped by phone number using Supabase Realtime.
Copy this prompt to try it in Lovable
Programmable voice call launcher for sales teams
Create a click-to-call feature in a Lovable CRM where sales reps can initiate outbound calls to leads. The Edge Function triggers a Bandwidth voice call and stores call logs. Call recordings and outcomes can be synced back via Bandwidth's call status callbacks.
Add a click-to-call button to each contact record in my CRM. When clicked, call my bandwidth-voice Edge Function to initiate an outbound call from our Bandwidth number to the contact's phone. Log the call_id, contact_id, and timestamp in a call_logs table.
Copy this prompt to try it in Lovable
Troubleshooting
Edge Function returns 401 Unauthorized when calling the Bandwidth API
Cause: The HTTP Basic Auth header is incorrectly constructed, or the API Token and Secret values in Cloud → Secrets contain extra whitespace or are swapped.
Solution: Verify the exact values in Cloud → Secrets — the API Token is the username and the API Secret is the password in the Basic Auth scheme. The btoa encoding must be btoa(token + ':' + secret) with a colon separator. Open Cloud → Logs to see the raw error response from Bandwidth for more detail.
1const credentials = btoa(`${Deno.env.get('BANDWIDTH_API_TOKEN')}:${Deno.env.get('BANDWIDTH_API_SECRET')}`);Bandwidth API returns 403 Forbidden with error mentioning the Application ID
Cause: The phone number is not associated with the Messaging Application ID stored in your secrets, or the Application ID is incorrect.
Solution: Log in to Bandwidth Dashboard → Applications and verify your Messaging Application ID (UUID format). Then check the phone number is associated with this application under 'Numbers'. If the number is associated with a different application, either update the BANDWIDTH_APPLICATION_ID secret or reassign the number.
SMS messages send successfully (202 returned) but recipients never receive them
Cause: The destination number may be in a format Bandwidth cannot route, or the Bandwidth account needs to be enabled for 10DLC registration for application-to-person messaging.
Solution: Ensure destination numbers are in E.164 format (+1XXXXXXXXXX for US numbers). Check Bandwidth Dashboard → Message Logs for delivery status. If messages show as 'undeliverable', your account may require 10DLC brand and campaign registration for A2P messaging compliance — contact Bandwidth support to check your account's registration status.
Bandwidth inbound callback never fires even after sending a test SMS to the Bandwidth number
Cause: The callback URL in the Messaging Application is pointing to the wrong Edge Function URL, or the Lovable app is not published and the Edge Function URL is not publicly accessible.
Solution: In Bandwidth Dashboard → Applications → your app, verify the Inbound Message Callback URL exactly matches your deployed Edge Function URL (from Cloud tab → Edge Functions list). The URL must be HTTPS and publicly reachable. Note that Lovable preview URLs are not suitable for webhooks — use the deployed production Edge Function URL.
Best practices
- Store all five Bandwidth credentials (Account ID, API Token, API Secret, Application ID, From Number) as separate Secrets for easy rotation and environment switching
- Always use E.164 format for phone numbers (+12025551234) — Bandwidth's API rejects national or local formats
- Check the Bandwidth Message Logs in the dashboard first when debugging delivery failures — they show detailed delivery status codes
- Return HTTP 200 from your inbound callback Edge Function immediately and process events asynchronously to avoid Bandwidth retry storms
- For 10DLC compliance, register your brand and campaign in the Bandwidth Dashboard before sending application-to-person marketing or transactional messages at scale
- Use separate Bandwidth Messaging Applications for development and production, each with different callback URLs pointing to your respective Edge Function environments
- Log the Bandwidth message ID returned by the API in your Supabase database — it is the key for looking up delivery status in Message Logs
Alternatives
Twilio has a native Lovable connector and a more developer-friendly API with better documentation, making it faster to prototype — choose Twilio unless you specifically need Bandwidth's direct carrier network or enterprise pricing.
Sinch offers a unified Conversation API covering SMS, RCS, WhatsApp, and voice in 200+ countries, making it better for multi-channel global messaging beyond North America enterprise use cases.
Plivo provides similar voice and SMS capabilities at competitive pricing with a simpler REST API, making it a better starting point for cost-sensitive startups that do not need Bandwidth's carrier-grade enterprise features.
Frequently asked questions
Is Bandwidth suitable for startups or is it only for enterprise?
Bandwidth primarily targets enterprise customers and requires an account provisioning process. Pricing is custom and typically volume-based rather than pay-per-message at the developer tier. For startups or small-volume SMS needs, Twilio or Plivo will be easier to set up and more cost-effective.
Does Bandwidth support WhatsApp or RCS messaging?
Bandwidth's primary messaging products are SMS and MMS over its own carrier network. It does not offer WhatsApp Business API access through its platform. For multi-channel messaging including WhatsApp, consider Sinch or Twilio, which have dedicated Conversation API products supporting WhatsApp, RCS, and other channels.
How does Bandwidth's 911 service integration work with Lovable apps?
Bandwidth's 911 service is a separate enterprise product requiring dedicated account setup, E911 provisioning, and address registration. It is not something you configure through a standard API integration — it requires direct coordination with Bandwidth's enterprise team. This feature is most relevant for UCaaS platforms and public safety applications rather than typical Lovable projects.
Can I receive voice call audio recordings via a Lovable Edge Function?
Yes — Bandwidth's Voice API uses BXML (Bandwidth XML) to control call flows, and you can include a Record verb in your BXML to record calls. Bandwidth posts a callback to your Edge Function with a recording URL when the call ends. Your Edge Function can then download and store the recording in Supabase Storage. This requires a separate voice-focused Edge Function that returns BXML responses, which is a more complex integration than SMS.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation