# Plivo

- Tool: Bubble
- Difficulty: Beginner
- Time required: 45 minutes
- Last updated: July 2026

## TL;DR

Connect Bubble to Plivo using HTTP Basic authentication in the API Connector — enter your Auth ID as the username and Auth Token as the password, mark both Private, and Bubble handles the rest server-side. No plugins, no OAuth, no token expiry. One API Connector group covers SMS sending, delivery status checks, and inbound SMS processing via a Backend Workflow endpoint pointed at your Plivo number's Message URL.

## The Simplest SMS Integration for Bubble — No Tokens, No Plugins

Plivo stands out in the Bubble ecosystem because it avoids every common integration pain point. There is no Bubble plugin to install (you use the API Connector directly), no OAuth flow to build, no token expiry to manage, and no multi-step auth chain. Your Auth ID and Auth Token are static — they are set once in the API Connector and work indefinitely unless you manually regenerate them in the Plivo Console.

The cost advantage is real. Plivo's US outbound SMS pricing is typically 30-50% lower per message than Twilio's published rates at comparable volumes. For Bubble apps that send high volumes of transactional SMS — appointment reminders, verification codes, shipping notifications — this cost difference is meaningful at scale.

The integration covers the same core use-cases as Twilio's SMS capability: outbound SMS, delivery status checks, and inbound SMS via webhook. Voice calls are also available through the same API. What Plivo does not offer from this single API is multi-channel delivery (no WhatsApp, no RCS) — for those capabilities, Sinch's Conversation API is the right choice.

For inbound SMS (receiving messages sent to your Plivo number), you need a Bubble Backend Workflow exposed as a public endpoint. This requires Bubble's Starter plan ($32/month or higher). For outbound-only SMS sending, the API Connector works on Bubble's Free plan.

One important note about trial accounts: Plivo trial accounts can only send to phone numbers you have explicitly verified in the Plivo Console. Attempting to send to any other number returns a 400 error. Upgrade your Plivo account or verify your test numbers before running integration tests.

## Before you start

- A Plivo account created at console.plivo.com — free trial available with limited test credits
- Your Plivo Auth ID and Auth Token from the Plivo Console dashboard (visible on the main console page after login)
- A Plivo phone number (purchased from Console → Phone Numbers → Buy a Number) for sending outbound SMS
- For trial accounts: at least one verified 'sandbox' recipient phone number (Console → Sandbox Numbers → Add Number)
- The API Connector plugin by Bubble installed in your app (Plugins tab → Add plugins → search 'API Connector')
- A Bubble app on Starter plan ($32/month) or higher if you need inbound SMS via Backend Workflows

## Step-by-step guide

### 1. Get Your Plivo Credentials and a Phone Number

Log in to the Plivo Console at console.plivo.com. On the main dashboard page, you will see your Auth ID and Auth Token displayed prominently in the top section. Click the copy icon next to each one and save them securely — you will need both for the API Connector setup.

Next, purchase a phone number to use as your SMS sender. Click 'Phone Numbers' in the left sidebar, then 'Buy a Number'. Filter by country (US for domestic SMS), select a number type (Long Code for standard SMS), and click Search. Choose a number from the results and click Buy. The cost is typically $0.80/month for a US long code number.

If you are on a trial account, also navigate to 'Sandbox Numbers' in the left sidebar and add the phone number(s) you want to send test messages to. Plivo trial accounts can only send to verified sandbox numbers — attempts to send to any other number return a 400 error with the message 'Unverified number'. You must verify the number via a confirmation code that Plivo sends to the actual device.

Note the format of your phone number as shown in the Console — Plivo requires E.164 format for API calls. This means the number starts with + and includes the country code, with no spaces, dashes, or parentheses: +12125551234 for a US number. Your purchased Plivo number is already shown in E.164 format in the Console.

**Expected result:** You have your Plivo Auth ID and Auth Token saved. You have a Plivo phone number in E.164 format (e.g., +12125550199) for sending SMS. Trial account users have added at least one sandbox (verified) recipient number.

### 2. Configure the API Connector with Plivo Basic Auth

Open your Bubble app editor and click the 'Plugins' tab in the left sidebar. Install the API Connector plugin if not already present (search 'API Connector' in the plugin marketplace, install the one by Bubble). Click 'API Connector' in the plugins list to open the configuration.

Click 'Add another API' and name this group 'Plivo'. Now, for authentication, look for the 'Authentication' dropdown at the top of the group configuration — this is where you select 'Basic auth'. Enter your Plivo Auth ID in the Username field and your Plivo Auth Token in the Password field. Tick the 'Private' checkbox next to the Password field.

IMPORTANT: Do not add the Authorization header manually as a raw 'Authorization: Basic base64string' shared header. While this technically works, it bypasses Bubble's credential storage mechanism and the base64-encoded value would be visible in the API Connector UI to anyone who opens it. Use the built-in 'Basic auth' type instead.

For the base URL note: Plivo's API base URL includes your Auth ID in the path: https://api.plivo.com/v1/Account/{your_auth_id}. When adding individual calls, you will use this path prefix with your actual Auth ID filled in — or keep it as a shared base URL if you prefer. You can store the Auth ID in the shared base URL field of the group, or repeat it in each call's URL.

Add a shared header: Content-Type → application/json. This is not secret, so no Private checkbox needed here.

```
{
  "api_group": "Plivo",
  "authentication": "Basic auth",
  "username": "<Your Auth ID>",
  "password": "<Your Auth Token -- PRIVATE>",
  "shared_headers": {
    "Content-Type": "application/json"
  }
}
```

**Expected result:** The Plivo API group is created with Basic auth configured — Auth ID as username and Auth Token as password (marked Private). A Content-Type shared header is set. The group shows the authentication type as 'Basic auth'.

### 3. Add the Send SMS Call and Initialize It

Click 'Add a call' within the Plivo group. Name it 'Send SMS'. Set the method to POST. For the URL, enter:
https://api.plivo.com/v1/Account/YOUR_AUTH_ID/Message/

Replace YOUR_AUTH_ID with your actual Auth ID (copy it from the Console). Note the trailing slash after 'Message/' — this is required. Omitting it causes Plivo to return a 301 redirect that Bubble does not follow, resulting in a silent failure where no error is shown but the message is never sent.

Set 'Use as' to 'Action'.

In the body section, add these dynamic parameters:
- src: the sender (your Plivo phone number in E.164 format, e.g., +12125550199)
- dst: the recipient phone number (dynamic, will be passed at runtime)
- text: the message text (dynamic)

Click 'Initialize call'. For the initialization, fill in:
- src: your actual Plivo phone number
- dst: your sandbox/verified recipient number (trial account) or any number (paid account)
- text: 'Test message from Bubble'

Click Initialize. A successful initialization returns a JSON response containing 'api_id' and 'message_uuid' and 'message' (with value 'message(s) queued'). Bubble will detect these response fields — make sure 'message_uuid' is detected, as you will need it for delivery status checks.

If initialization fails with a 400 error and 'Unverified number', your trial account cannot send to that number — add it to Sandbox Numbers in the Plivo Console first. If you get a 401, check that Basic auth is configured correctly with the right credentials in the right fields.

```
{
  "call_name": "Send SMS",
  "method": "POST",
  "url": "https://api.plivo.com/v1/Account/<your_auth_id>/Message/",
  "authentication": "Basic auth (inherited from group)",
  "use_as": "Action",
  "body": {
    "src": "<plivo_number_e164 -- your sender number>",
    "dst": "<recipient_phone_e164 -- dynamic>",
    "text": "<message_text -- dynamic>"
  }
}
```

**Expected result:** The 'Send SMS' call is initialized successfully with a 202 Accepted response. Bubble detected the response fields including 'message_uuid'. The test SMS was received on your phone.

### 4. Add Delivery Status Check Call

Add a second call to check whether a sent message was actually delivered. Click 'Add a call' within the Plivo group. Name it 'Get Message Status'. Set method to GET and URL to:
https://api.plivo.com/v1/Account/YOUR_AUTH_ID/Message/[message_uuid]/

Note the trailing slash here as well. Mark [message_uuid] as a dynamic parameter. Set 'Use as' to 'Data'.

Click 'Initialize call'. You need a real message_uuid from a previously sent message. Copy a message_uuid from the response of a 'Send SMS' call you have already made (visible in Bubble's Logs tab or in the Initialize response from the previous step). The response from this call includes fields like 'message_state' (queued, sent, delivered, rejected, undelivered), 'message_direction', and 'message_time'.

Once initialized, you can use this call in a Bubble workflow to display delivery status — for example, showing 'Delivered' or 'Pending' next to an SMS log record in an admin dashboard. Bind the 'Get Message Status' call result's 'message_state' field to a text element.

Note: Plivo updates delivery status asynchronously — a message that was just sent may show 'queued' immediately after sending and 'delivered' a few seconds later. If you need real-time delivery updates in Bubble, consider setting up a Plivo Delivery Report URL pointing to a Backend Workflow endpoint, similar to the inbound SMS setup in the next step.

```
{
  "call_name": "Get Message Status",
  "method": "GET",
  "url": "https://api.plivo.com/v1/Account/<your_auth_id>/Message/[message_uuid]/",
  "use_as": "Data"
}
```

**Expected result:** The 'Get Message Status' call is initialized and returns message state for the provided UUID. The 'message_state' field is detected and can be bound to UI elements or stored in your database.

### 5. Set Up Inbound SMS via Backend Workflow (Paid Plan Required)

To receive SMS messages sent to your Plivo number inside Bubble, you need a Backend Workflow endpoint. This feature requires Bubble's Starter plan ($32/month) or higher.

First, enable Backend Workflows: in your Bubble editor, go to Settings → API and enable 'This app exposes a Workflow API'. Then navigate to Backend Workflows in the left panel.

Click 'New API workflow' and name it 'plivo-inbound-sms'. Click 'Detect request data' to activate the endpoint and copy the URL that appears — it will be in the format:
https://yourapp.bubbleapps.io/api/1.1/wf/plivo-inbound-sms

Now go to the Plivo Console. Navigate to Phone Numbers → your number → click the number to open its settings. In the 'Message URL' field, paste your Bubble endpoint URL. Set the HTTP method to POST. Save the settings.

To trigger detection: send an SMS to your Plivo number from any phone. Plivo will POST the incoming message data to your Bubble endpoint. Return to your Backend Workflow and click 'Detect request data' again — Bubble should detect the incoming fields: From (sender's number), To (your Plivo number), Text (message content), MessageUUID, and others.

Once detected, add workflow steps: for example, create a new 'Inbound SMS' data type record with From, Text, and received_at fields. You can also trigger a reply by adding a 'Send SMS' API action in the same workflow, passing the detected From number as the dst.

Privacy rules note: if storing inbound message content in a Bubble database type, set Data → Privacy rules so the 'Everyone else can see' option is disabled. Plivo webhooks write via the Backend Workflow with server-side privileges, so storing data is possible even with privacy rules active — but prevent unauthorized reads by setting appropriate privacy configurations. RapidDev has helped dozens of Bubble teams set up this inbound/outbound SMS loop securely — reach out at rapidevelopers.com/contact for a free scoping call if you run into edge cases.

```
{
  "plivo_inbound_webhook_fields": {
    "From": "+12125559876",
    "To": "+12125550199",
    "Text": "Hello from Plivo",
    "MessageUUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "Type": "sms",
    "Units": "1",
    "TotalAmount": "0.00550",
    "TotalRate": "0.00550"
  }
}
```

**Expected result:** Sending an SMS to your Plivo number triggers the Bubble Backend Workflow. The inbound SMS content appears in Bubble's Logs tab and a new Inbound SMS record is created in your Bubble database with the sender's number and message text.

### 6. Wire Send SMS to Bubble Workflows and Test End-to-End

With the API Connector configured, the last step is triggering SMS sends from actual Bubble workflows in your app. The pattern is the same for any trigger type — a button click, a data change, a scheduled workflow, or a form submission.

For a simple button-triggered send: select the button, click 'Start/Edit Workflow', add an action. Search for 'Plivo - Send SMS'. You will see the initialized call appear as an available action. Set the dst parameter to the phone number from an input element (make sure the user enters it in E.164 format with + and country code, or clean it in a Bubble expression). Set the text parameter to your message content.

For an automated send on data change: add a Workflow that fires 'When a Thing is changed' on your data type. Under 'Only when' conditions, set the condition for the status or field change that should trigger the SMS. Then add the Plivo Send SMS action.

For bulk SMS sends (sending to a list of phone numbers): use 'Schedule API workflow for a list' targeting a Backend Workflow that sends one SMS per item. This staggers the sends and avoids hitting rate limits (Plivo's default is 10 requests/second per account). For large batches, also use a 'Wait' action between sends or build a queue using Bubble's scheduling features.

Test the complete flow: trigger a send from your app, check Bubble's Logs tab for the API call result, and verify the SMS arrives on your test phone. Then run the Get Message Status call with the returned message_uuid to confirm the delivery state moves from 'queued' to 'delivered' within a few seconds.

**Expected result:** Triggering the workflow sends an SMS delivered to the test phone within seconds. Bubble's Logs tab shows the API call response with a message_uuid. Get Message Status confirms 'delivered' state. The Plivo Console → Message Logs also shows the sent message.

## Best practices

- Always use Bubble's built-in 'Basic auth' type in the API Connector group instead of manually encoding the Authorization header. The built-in type keeps credentials in Bubble's credential storage — a raw encoded header is visible in the API Connector UI and does not benefit from Bubble's Private credential handling.
- Store phone numbers in E.164 format (+12125551234) in your Bubble database from the point of user entry. Add input validation on phone number fields that checks for the + prefix and rejects inputs that do not match the pattern. Formatting at send time increases workflow complexity and is a frequent source of delivery failures.
- Include the trailing slash in all Plivo endpoint URLs — especially /Message/. Plivo's API returns a 301 redirect without the slash, and Bubble's API Connector does not follow redirects, causing silent message-not-sent failures with no visible error.
- On trial accounts, always add recipient numbers to Sandbox Numbers in the Plivo Console before testing. Build a test checklist: add sandbox number, send test SMS, verify receipt, then proceed to production. This prevents 400 errors during development that can be mistaken for configuration problems.
- Set Data → Privacy rules for any Bubble data type that stores sent or received SMS content. These records may contain sensitive information (OTP codes, personal messages). The 'Everyone else can see' checkbox should be off on these types — Backend Workflows can still write to them with server-side privileges.
- For high-volume sends (hundreds or thousands of messages), use Bubble's 'Schedule API workflow for a list' rather than calling Plivo from a loop in a single workflow. Stagger sends by scheduling each workflow item a few seconds apart to stay within Plivo's 10 requests/second rate limit and avoid 429 errors.
- Save the message_uuid returned by every Send SMS call to a Bubble SMS Log data type, alongside the recipient number, message content, and send timestamp. This creates a full audit trail and lets you look up delivery status or troubleshoot missing messages without querying the Plivo Console.
- Use separate Plivo phone numbers for different message types — for example, one number for OTP codes and one for marketing messages. Carriers and spam filters treat numbers differently based on message volume and content patterns. Mixing high-volume marketing SMS with transactional codes on the same number can affect deliverability of both.

## Use cases

### SMS Verification Codes (2FA)

Generate a random 6-digit OTP in Bubble, save it with a 10-minute expiry timestamp to the user's record, and send it via Plivo SMS. On the verification page, check the submitted code against the stored value and expiry before granting access. Plivo's low per-message cost makes this economical even for high-traffic verification flows.

Prompt example:

```
When a user clicks 'Send verification code', generate a random 6-digit number, save it to the User's otp_code and otp_expiry (Current date/time + 10 minutes) fields, then call the Plivo Send SMS API action with the user's phone number as dst and the code as the text body.
```

### Appointment Reminder SMS

Schedule Backend Workflows to run 24 hours before each appointment and send an SMS reminder to the customer's phone number. Bubble's 'Schedule API workflow' action queues the Plivo send at the right time automatically — no manual reminder management needed.

Prompt example:

```
When a new Appointment is created, schedule a Backend Workflow to run 24 hours before the appointment start time that calls the Plivo Send SMS API with the customer's phone, the appointment date/time, and a confirmation message with a link to the appointment page.
```

### Inbound SMS-to-Database Logging

Receive SMS messages sent to your Plivo number and store them in a Bubble database. Point your Plivo number's Message URL to a Bubble Backend Workflow. When a text arrives, the workflow creates a new SMS Message record with the sender's number, message text, and timestamp — enabling a simple SMS inbox inside your Bubble app.

Prompt example:

```
When the Plivo inbound webhook fires the Backend Workflow, create a new SMS Record with From = webhook From field, Message = webhook Text field, Received At = Current date/time, and optionally auto-reply by calling the Plivo Send SMS API with a confirmation message to the From number.
```

## Troubleshooting

### Send SMS returns 400 with 'Unverified number' or 'No permission to send to this number'

Cause: Your Plivo account is on a trial plan and the recipient number is not in your verified Sandbox Numbers list.

Solution: Go to Plivo Console → Sandbox Numbers → Add Number. Enter the recipient's phone number and complete the verification code flow (Plivo sends a code to the actual phone). Once verified, the number is whitelisted for trial sends. Alternatively, upgrade your Plivo account to a paid plan to send to any number without sandbox restrictions.

### Send SMS appears to succeed (no error in Bubble logs) but the message is never received

Cause: The Plivo Message endpoint URL is missing the required trailing slash, causing a 301 redirect that Bubble's API Connector does not follow — the message is never actually sent.

Solution: Open the Send SMS call in your API Connector and check the URL: it must end with /Message/ (trailing slash included). Correct URL: https://api.plivo.com/v1/Account/YOUR_AUTH_ID/Message/ — note the slash after 'Message'. Add the trailing slash and re-initialize the call. This is the most common 'silent failure' with Plivo in Bubble.

### API Connector returns 401 Unauthorized on all calls

Cause: The Auth ID and Auth Token are swapped (username/password reversed) or one of them has incorrect characters due to a copy error.

Solution: Open the Plivo API group in your API Connector. In the Basic auth section, verify: Username = Auth ID (the shorter alphanumeric string from the Plivo Console header, typically 20 characters), Password = Auth Token (the longer string, typically 40 characters), Private checkbox is on the Password. Re-copy both values directly from console.plivo.com (the Dashboard page shows both). The Auth Token is case-sensitive.

### Initialize call fails with 'There was an issue setting up your call'

Cause: The Initialize call requires real values to make a successful API request — placeholder values or invalid phone number format cause it to fail.

Solution: For initialization, provide your actual Plivo sender number (in E.164 format: +12125550199) as the src, a verified recipient number as dst, and a short message as text. The Initialize call makes a real API request — if you are on a trial account, the dst must be a sandbox-verified number. Check that all three body parameters have non-empty test values before clicking Initialize.

### Inbound SMS Backend Workflow is not firing when SMS is sent to the Plivo number

Cause: The Message URL in Plivo Console is not set to the correct Bubble endpoint URL, or the Workflow API is not enabled in Bubble settings.

Solution: Go to Settings → API in your Bubble editor and confirm 'This app exposes a Workflow API' is enabled. Then check the Plivo Console → Phone Numbers → your number → Message URL. The URL should be exactly: https://yourapp.bubbleapps.io/api/1.1/wf/plivo-inbound-sms (no trailing slash, correct app name, correct workflow name). Also ensure the HTTP method is set to POST in Plivo's settings. If unsure, test the endpoint directly: use a tool like Postman to POST a sample payload to the URL — if Bubble's Logs show the request, the endpoint is correct.

## Frequently asked questions

### Do Plivo credentials ever expire?

No — Plivo Auth ID and Auth Token are static credentials that do not expire unless you manually regenerate them in the Plivo Console under Account → API. Once set in your Bubble API Connector, they work indefinitely. This is the primary advantage over integrations like Sinch (1-hour tokens) or GoToWebinar (1-hour OAuth tokens) — no refresh workflows are needed.

### Can I send to multiple phone numbers in one API call?

Yes. Plivo's POST /Message/ endpoint accepts a comma-separated list of E.164 phone numbers in the dst field for bulk sending. For example: '+12125551234,+12125555678,+14155559012'. In Bubble, if you have a list of phone numbers in a data type, you can join them using a 'join with' comma expression. Note that each number in the list counts as a separate message for billing purposes.

### Does the Plivo integration work on Bubble's Free plan?

For outbound SMS only, yes — the API Connector works on Bubble's Free plan. For receiving inbound SMS (pointing your Plivo number's Message URL to a Bubble Backend Workflow), no — Backend Workflows require Bubble's Starter plan ($32/month) or higher. Free plan users cannot process incoming webhooks from Plivo.

### What phone number format does Plivo require?

E.164 format: a plus sign, country code, and full national number with no spaces, dashes, or parentheses. US example: +12125551234. UK example: +442012345678. Both the src (your Plivo number) and dst (recipient) must be in E.164 format. Plivo returns a clear error if the format is wrong: '400 Bad Request' with a message about the number format.

### How does Plivo compare in price to Twilio for US SMS?

Plivo's US outbound SMS pricing is typically 30-50% lower per message than Twilio's standard rates at comparable volumes. For exact current pricing, check plivo.com/pricing and twilio.com/sms/pricing/us — rates change and volume discounts apply. For high-volume transactional SMS (thousands of messages per month), the cost difference is significant enough to justify Plivo's manual setup over Twilio's more convenient plugin.

### Why does the Plivo API URL include my Auth ID?

Plivo embeds the account identifier in the REST API path: https://api.plivo.com/v1/Account/{auth_id}/. This is Plivo's API design — your Auth ID in the URL path tells Plivo which account the request belongs to, separate from the Basic auth credentials that authenticate the request. Both the URL path Auth ID and the Basic auth credentials must be correct for the call to succeed.

---

Source: https://www.rapidevelopers.com/bubble-integrations/plivo
© RapidDev — https://www.rapidevelopers.com/bubble-integrations/plivo
