Twilio Integration
Send SMS/MMS messages using your own Twilio account
Blooio supports sending SMS and MMS messages through your own Twilio account. This guide covers setup, usage, and key differences from Blooio's native iMessage integration.
Overview
The Twilio integration allows you to:
- Send SMS/MMS using your existing Twilio phone numbers
- Receive inbound messages via webhooks
- Track message delivery status
- Use multiple Twilio accounts per organization
Twilio integration is completely separate from Blooio's iMessage service. Messages sent via Twilio use SMS/MMS protocols, not iMessage.
When to use Twilio vs Blooio
Twilio and Blooio serve different messaging needs:
| Use Case | Recommended | Why |
|---|---|---|
| Broadcast campaigns | Twilio | High-volume SMS to many recipients, carrier-approved for marketing |
| Promotional outreach | Twilio | A2P 10DLC registration supports commercial messaging at scale |
| 1-on-1 conversations | Blooio | iMessage provides richer experience with reactions, read receipts, and typing indicators |
| Customer support | Blooio | Personal, conversational feel builds stronger relationships |
| High-touch sales | Blooio | iMessage feels like texting a friend, not a business |
The hybrid approach
A popular pattern combines both services:
- Outreach via Twilio - Send initial SMS broadcasts to generate interest (e.g., "Reply YES to learn more")
- Engagement via Blooio - Direct interested responders to text your Blooio iMessage number for personal follow-up
This gives you the best of both worlds: Twilio's broadcast scale for top-of-funnel outreach, and Blooio's intimate iMessage experience for converting warm leads into customers.
Include your Blooio number in Twilio broadcasts: "Text us at (555) 123-4567 to chat directly!" - responses come through as iMessage conversations.
Setup
1. Connect your Twilio account
In the Blooio dashboard, navigate to Integrations and click Connect on the Twilio card.
You'll need:
- Account SID - Found on your Twilio Console dashboard
- API Key SID - Create under Account → API keys & tokens
- API Key Secret - Generated when you create the API key
- Auth Token (optional) - Your account auth token, used to verify webhook signatures
Store your API Key Secret securely - Twilio only shows it once when created.
2. Import phone numbers
After connecting, select which Twilio phone numbers to import into Blooio. Webhooks are automatically configured for imported numbers.
3. Create an API key for Twilio
In the dashboard, go to API Keys and create a new key. Then assign your imported Twilio numbers to this API key.
An API key can only be assigned to either Blooio numbers or Twilio numbers, not both. This ensures clear separation between iMessage and SMS messaging.
Sending messages
Using the API
Send messages the same way as with Blooio, using your API key that has Twilio numbers assigned:
curl -X POST 'https://backend.blooio.com/v2/api/chats/%2B15551234567/messages' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"text": "Hello via Twilio!"
}'const chatId = encodeURIComponent('+15551234567')
await fetch(`https://backend.blooio.com/v2/api/chats/${chatId}/messages`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.BLOOIO_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: 'Hello via Twilio!'
})
})import os, requests
from urllib.parse import quote
chat_id = quote('+15551234567', safe='')
requests.post(f'https://backend.blooio.com/v2/api/chats/{chat_id}/messages',
headers={
'Authorization': f"Bearer {os.environ['BLOOIO_API_KEY']}",
'Content-Type': 'application/json'
},
json={'text': 'Hello via Twilio!'}
)Specifying the sender number
The from_number parameter is optional:
- Omitted: Blooio auto-selects from your API key's number pool (see below)
- Provided: Uses the specified number (must be in your API key's number pool)
curl -X POST 'https://backend.blooio.com/v2/api/chats/%2B15551234567/messages' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"text": "Hello!",
"from_number": "+15559876543"
}'Number pools
What is a number pool?
A number pool is the collection of Twilio phone numbers assigned to your API key. When you send a message without specifying from_number, Blooio automatically selects a number from this pool.
To set up your number pool:
- Import phone numbers from your Twilio account (in the Integrations page)
- Assign one or more numbers to your API key (in the Numbers page)
Each API key has its own number pool. Numbers assigned to one API key cannot be used by another.
How auto-selection works
When you omit from_number from your request:
- Blooio looks up all Twilio numbers assigned to your API key
- The first number in the pool is selected
- The message is sent from that number
# from_number omitted - Blooio uses your API key's first Twilio number
curl -X POST 'https://backend.blooio.com/v2/api/chats/%2B15551234567/messages' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"text": "Hello!"}'Twilio vs Blooio number pools
| Feature | Blooio (iMessage) | Twilio |
|---|---|---|
| Number selection | Automatic rotation with conversation history | First available or manual selection |
| Pool management | Built-in allocation pools | Assign numbers to API key |
| Conversation stickiness | Same number for ongoing conversations | Use from_number to maintain consistency |
There is currently no automatic rotation for Twilio numbers. If you need to distribute traffic across multiple numbers, specify from_number explicitly in your application logic.
Receiving messages
Inbound Twilio messages are delivered to your webhooks the same way as iMessage:
{
"event": "message.received",
"message_id": "msg_abc123",
"external_id": "+15551234567",
"internal_id": "+15559876543",
"protocol": "sms",
"text": "Incoming SMS",
"sender": "+15551234567",
"is_group": false,
"timestamp": 1706640000000
}external_idis the sender (the person who texted you)internal_idis the Twilio number that received the messageprotocolissmsfor Twilio messages (vsimessagefor Blooio)
Message status
Twilio messages go through these statuses (as reported by Blooio webhooks):
| Status | Description |
|---|---|
queued | Message accepted, pending send |
sending | Being transmitted to carrier |
sent | Delivered to carrier |
delivered | Confirmed delivery to recipient |
failed | Delivery failed or carrier rejected the message |
Twilio reports undelivered and failed as separate statuses. Blooio maps both to failed in webhook payloads for simplicity.
Status updates are delivered via webhooks if you have message.status events enabled.
Limitations
Compared to Blooio (iMessage)
- No iMessage features: Reactions, read receipts, typing indicators, and group chats are not available via Twilio
- No automatic number rotation: You must manage sender number selection yourself
- SMS/MMS only: Messages are sent as standard SMS or MMS, not iMessage
- Carrier restrictions: Subject to carrier filtering and rate limits
Rate limits
Twilio enforces its own rate limits. Blooio does not queue or retry Twilio messages - they are sent directly through the Twilio API.
Webhook validation
For production use, provide your Twilio Auth Token when setting up the integration. This enables signature validation for incoming webhooks, preventing spoofed requests.
Best practices
- Use separate API keys: Keep Twilio and iMessage API keys separate for clear traffic separation
- Store from_number for conversations: If message continuity matters, track which number was used and reuse it
- Monitor delivery status: Set up webhooks for
message.statusevents to track deliverability - Provide auth token: Enable webhook signature validation for security
- Handle failures gracefully: Twilio messages fail immediately with no retry - implement your own retry logic if needed
Troubleshooting
"No Twilio numbers assigned to this API key"
You need to assign at least one Twilio number to your API key before sending. Go to the Numbers page in the dashboard and use the "Assigned To" dropdown.
"This API key does not own the specified from_number"
The from_number you specified isn't assigned to your API key. Either remove from_number to auto-select, or assign the number to your API key.
"API key already owns Blooio numbers"
An API key can only be assigned to Blooio OR Twilio numbers, not both. Create a separate API key for Twilio.
Messages not being received
Check that:
- Webhook URLs were automatically configured when you imported the number (you can verify in your Twilio Console under the phone number's settings)
- You have webhooks set up in Blooio for
message.receivedevents - If you manually changed webhook URLs in Twilio Console, re-import the number in Blooio to reconfigure them