MessagesSend Messages

Send Messages

Send iMessages with automatic SMS fallback via POST /v1/messages.

Basic Message

curl -X POST https://api.textbubbles.com/v1/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155551234",
    "content": {
      "text": "Hello!"
    }
  }'

Phone numbers must be in E.164 format (e.g., +14155551234). The content.text field supports 1-10,000 characters.

With Effects (iMessage Only)

curl -X POST https://api.textbubbles.com/v1/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155551234",
    "content": { "text": "Congratulations!" },
    "effect": "confetti"
  }'

See Message Effects for all available effects.

Reply to a Message

Create a threaded reply using the replyTo field (iMessage only):

curl -X POST https://api.textbubbles.com/v1/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155551234",
    "content": { "text": "Thanks for letting me know!" },
    "replyTo": "msg_550e8400-e29b-41d4-a716-446655440000"
  }'

With Attachments

URL attachment (iMessage):

curl -X POST https://api.textbubbles.com/v1/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155551234",
    "content": { "text": "Check out this image" },
    "attachments": [
      {
        "type": "url",
        "url": "https://example.com/photo.jpg",
        "mimeType": "image/jpeg",
        "filename": "photo.jpg"
      }
    ]
  }'

Media URL (SMS/MMS):

curl -X POST https://api.textbubbles.com/v1/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155551234",
    "content": {
      "text": "Check out this image",
      "mediaUrl": "https://example.com/photo.jpg"
    },
    "routing": { "preference": ["sms"] }
  }'

Channel Routing

By default, messages try iMessage first and fall back to SMS. Customize with the routing field:

{
  "to": "+14155551234",
  "content": { "text": "Hello!" },
  "routing": {
    "preference": ["imessage", "sms"],
    "fallback": true
  }
}
  • preference — ordered list of channels: "imessage", "sms"
  • fallback — try the next channel if the first fails (default: true)

Unsend a Message

Retract a sent iMessage:

curl -X POST https://api.textbubbles.com/v1/messages/msg_abc123/unsend \
  -H "Authorization: Bearer YOUR_API_KEY"

Edit a Message

Update sent message content (iMessage only):

curl -X PUT https://api.textbubbles.com/v1/messages/msg_abc123 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": { "text": "Updated message text" }
  }'

Idempotency

Include an idempotencyKey to prevent duplicate sends during retries:

{
  "to": "+14155551234",
  "content": { "text": "Your order #12345 has shipped!" },
  "idempotencyKey": "shipment-notification-12345"
}

If a message with the same key already exists, the API returns 200 OK with the existing message.

Full Request Schema

FieldTypeRequiredDescription
tostringYesRecipient phone number (E.164 format)
content.textstringYesMessage text (1-10,000 chars)
content.mediaUrlstringNoMedia URL for SMS/MMS
routing.preferencestring[]NoChannel priority (default: ["imessage", "sms"])
routing.fallbackbooleanNoEnable fallback (default: true)
replyTostringNoMessage ID to reply to (iMessage only)
attachmentsobject[]NoFile attachments (iMessage only)
effectstringNoMessage effect (iMessage only)
mentionsobject[]No@mentions in group chats
scheduledAtstringNoISO 8601 datetime for scheduled delivery
idempotencyKeystringNoUnique key for deduplication
callbackUrlstringNoPer-message webhook URL
metadataobjectNoCustom key-value data
createContactbooleanNoAuto-create contact if not exists