T
Telephony SOPKnowledge Base
Search
← All topics

MMS Handling — Multimedia Messaging on SignalWire

runnable

MMS (Multimedia Messaging Service) sends images, audio, video, and vCards alongside text. Max file size 5 MB on most US carriers. Supported MIME types: image/jpeg, image/png, image/gif, audio/mpeg, video/mp4. Carriers transcode aggressively. Send via SignalWire LaML with the `MediaUrl` parameter or via REST `/Messages` with `MediaUrl[]`. Subject to the same A2P 10DLC campaign registration as SMS.

mmssmsmessagingsignalwiremediacarrier
Agent trigger phrases: send MMS SignalWire · MMS media attachment · image text message · MMS file size limit · multimedia messaging · MediaUrl SignalWire · MMS not delivering

MMS Handling

MMS (Multimedia Messaging Service) is the protocol for sending images, audio, video, and other attachments via the carrier messaging network. From a SignalWire developer's perspective MMS is sent the same way as SMS — you just add a MediaUrl parameter. Underneath, carrier transcoding, file-size limits, and message ID handling are noticeably different.

When to use MMS vs SMS

  • Use SMS for text-only confirmations, OTP codes, reminders, opt-in/opt-out flows.
  • Use MMS for receipts, before/after photos, product images, vCards, short voice clips, signed agreements (PDF rendered as image), promotional graphics.
  • Use a link to a hosted asset when the asset is larger than 1 MB, when delivery reliability matters more than inline preview, or when you need analytics on view rates.

File size and format limits

Carrier limits dominate. SignalWire's outbound limit is 5 MB, but most US carriers reject anything above 1.2 MB. Practical safe target: 600 KB.

| Carrier | Practical inbound limit | Practical outbound limit | |---|---|---| | Verizon | 1.2 MB | 600 KB | | AT&T | 1.0 MB | 600 KB | | T-Mobile | 1.5 MB | 800 KB | | US Cellular | 1.0 MB | 500 KB | | iMessage (Apple) | 100 MB | 100 MB (but only between iMessage users) |

When in doubt, send 600 KB or less. Anything over is transcoded down to 600 KB or rejected.

Supported MIME types

| Type | MIME | Notes | |---|---|---| | Image | image/jpeg, image/png, image/gif | GIFs animate on most modern phones | | Audio | audio/mpeg, audio/mp4, audio/wav | Often transcoded to AMR | | Video | video/mp4, video/3gpp | Often transcoded to 320x240 | | Contact | text/x-vcard, text/vcard | Renders as "Add contact" button on most clients | | SMIL | application/smil | Slideshow layout — rare, mostly legacy |

PDFs are not natively supported in MMS. Render the first page as PNG and send that, or send a link.

Sending MMS via SignalWire LaML

import requests

PROJECT = "your-project-id"
TOKEN = "your-auth-token"
SPACE = "your-space.signalwire.com"

response = requests.post(
    f"https://{SPACE}/api/laml/2010-04-01/Accounts/{PROJECT}/Messages.json",
    auth=(PROJECT, TOKEN),
    data={
        "From": "+12125551111",
        "To": "+13105552222",
        "Body": "Here's the photo you requested.",
        "MediaUrl": "https://cdn.example.com/photo.jpg",
    },
)

For multiple media items, pass MediaUrl repeatedly:

data = [
    ("From", "+12125551111"),
    ("To", "+13105552222"),
    ("Body", "Before and after"),
    ("MediaUrl", "https://cdn.example.com/before.jpg"),
    ("MediaUrl", "https://cdn.example.com/after.jpg"),
]

Max 10 media items per message on SignalWire. Most carriers cap at 4 displayed inline; the rest may render as attachments.

Sending MMS via REST

The same parameters work on the SignalWire REST API:

curl -X POST https://{space}/api/laml/2010-04-01/Accounts/{project}/Messages.json \
  -u "${PROJECT}:${TOKEN}" \
  -d "From=+12125551111" \
  -d "To=+13105552222" \
  -d "Body=Here's the photo" \
  -d "MediaUrl=https://cdn.example.com/photo.jpg"

Receiving MMS

Webhook URL configured on the phone number fires for both SMS and MMS. The webhook receives:

| Parameter | Type | Notes | |---|---|---| | From, To, Body | string | Same as SMS | | NumMedia | int | Number of media attachments (0 for text-only SMS) | | MediaUrl0, MediaUrl1, ... | URL | Signed URLs for each attachment, expire after 24 hours | | MediaContentType0, ... | MIME | Content type of each attachment |

Fetch each MediaUrl with the SignalWire credentials and move the asset to your own storage immediately — the signed URLs expire.

import requests

num_media = int(form["NumMedia"])
for i in range(num_media):
    url = form[f"MediaUrl{i}"]
    content_type = form[f"MediaContentType{i}"]
    response = requests.get(url, auth=(PROJECT, TOKEN))
    # Save response.content to your own storage

A2P 10DLC and MMS

MMS sent to US numbers requires the same A2P 10DLC campaign registration as SMS. The campaign use case applies — there is no separate "MMS campaign" tier. Throughput limits include MMS in the messages-per-second budget.

Toll-free MMS does not require TCR registration but is subject to Toll-Free Verification (TFV). Unverified toll-free MMS is heavily rate-limited and may be blocked entirely on T-Mobile.

Cost model

MMS costs more than SMS per segment:

| Channel | SMS outbound | MMS outbound | |---|---|---| | 10DLC | ~$0.0079 / segment | ~$0.0200 / message | | Toll-free | ~$0.0090 / segment | ~$0.0225 / message | | Short code | ~$0.0049 / segment | ~$0.0150 / message |

Pricing accurate as of 2025-11. Check the current SignalWire pricing page for live rates. SMS is billed per 160-character segment; MMS is billed per message regardless of size.

Common failure modes

| Symptom | Cause | Fix | |---|---|---| | Image arrives blurry or pixelated | Carrier transcoded to low resolution | Pre-size to 640×480 max, JPEG quality 80% | | GIF arrives as still image | Carrier dropped animation frames | Use very short GIFs (under 10 frames, 2 seconds) | | MMS not delivering to some carriers | File over 1 MB | Compress to 600 KB | | MMS delivers as SMS with link | Recipient on a non-MMS plan or feature phone | Fall back to SMS + link automatically | | Inbound MMS missing | Webhook only checking Body, not NumMedia | Read NumMedia and iterate MediaUrl* | | Recipient on iPhone shows green bubble | RCS/iMessage not engaged, MMS fell through | Expected — MMS is the green-bubble path |

Group MMS

Sending to multiple recipients with a shared media attachment creates a group MMS. Most carriers support up to 10 recipients per group MMS. Replies go to all participants.

data = {
    "From": "+12125551111",
    "To": "+13105552222,+14155553333,+16175554444",
    "Body": "Team update",
    "MediaUrl": "https://cdn.example.com/photo.jpg",
}

Use group MMS sparingly — replies fan out to all members, which surprises recipients and can trigger spam complaints.

Related patterns

References

  • 3GPP TS 23.140 — Multimedia Messaging Service (MMS) functional description
  • RFC 4356 — Mapping Between the SDP Bandwidth Modifiers
  • SignalWire docs — Messaging API, MediaUrl parameter