> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracklysms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Send MMS

> Send hosted images, video, audio, and other attachments with the Trackly API.

Use `media` to send MMS through an MMS-enabled sending number. The same attachment fields work on [single sends](/api-reference/v2/messages/send-single.md), [bulk sends](/api-reference/v2/messages/send-bulk.md), [raw single sends](/api-reference/v2/messages/send-raw-single.md), and [raw bulk sends](/api-reference/v2/messages/send-raw-bulk.md). MMS availability depends on your sending number and service availability; unavailable MMS requests return an explicit error.

## Send attachments

Add a non-empty `media` array to a message. Each attachment requires `url`; `content_type` and `content_id` are optional. You may send multiple attachments and mix media types. The `to` and `list_number` fields remain required. `body` becomes an optional caption, and `subject` is optional.

```bash theme={null}
curl -X POST https://api.tracklysms.com/api/v2/send \
  -H "X-Api-Key: trk_your_api_key_here" \
  -H "Idempotency-Key: product-guide-0001" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155551234",
    "list_number": "+18005551000",
    "body": "Your product guide and setup video.",
    "subject": "Getting started",
    "media": [
      {
        "url": "https://media.example.com/product-guide.pdf",
        "content_type": "application/pdf",
        "content_id": "guide.pdf"
      },
      {
        "url": "https://media.example.com/setup.mp4",
        "content_type": "video/mp4",
        "content_id": "setup.mp4"
      }
    ]
  }'
```

Replace the example URLs with publicly accessible files. Omitting `media` sends SMS and requires a non-empty `body`. Do not pass `null` or an empty array to request SMS. A bulk request may mix SMS and MMS by setting `media` separately on each message.

## Request requirements

| Field | Requirement |
| - | - |
| `media[].url` | Absolute HTTPS URL, at most 2,048 characters. No embedded credentials, fragment, whitespace, or port other than 443. Restricted hostnames and non-public IP literals are rejected. Live sends also require public DNS answers. |
| `media[].content_type` | Optional ASCII MIME type, at most 255 characters, such as `image/jpeg`, `video/mp4`, or `application/pdf`. |
| `media[].content_id` | Optional identifier of 1–255 characters, unique within the message. Start with an ASCII letter or digit; subsequent characters may also include `.`, `_`, and `-`. |
| `subject` | Optional string of at most 66 characters, without control characters. Requires `media`. |
| `body` | Optional or empty for MMS; at most 4,096 characters. |

Serialized media metadata—the URLs, MIME types, identifiers, and subject—is limited to **512 KiB per message**. This Trackly request limit excludes the hosted file bytes.

Trackly validates the request, URL syntax, and initial DNS answers for live sends, then checks DNS again before submission. Temporary DNS-validation failures return `503 mms_unavailable`. These checks do not fetch attachments, inspect file bytes, or verify their actual MIME type or size. The delivery service retrieves the files later, so an accepted request can still fail if hosting, DNS, or redirects change, or a carrier rejects it.

Keep each URL available for at least three days after the last send request. Give changed content a new URL to avoid a cached version being delivered.

## Formats and delivery limits

MMS can carry more than images. These are common formats; support varies by destination carrier, sending number, and handset.

| Content | Examples |
| - | - |
| Images | JPEG/JPG, PNG, GIF |
| Audio | MP3, MP4, MIDI, WAV |
| Video | MP4, MPEG/MPG, 3GP |
| Text and contacts | UTF-8 or US-ASCII text, VCF/vCard |
| Other files | PDF, SMIL, Passbook |

For video, MP4 with H.264 video and AAC audio offers broad handset compatibility. PDF needs a compatible reader, Passbook is for iOS, and some devices ignore SMIL presentation instructions or reject vCards. Test representative recipient devices before a large send.

Aim for **300 KB or less for the complete message**, including all attachments, text, headers, and metadata. For time-sensitive sends, aim for 150 KB or less. These are delivery recommendations, not byte limits enforced by Trackly. Carrier limits and attachment counts vary; a larger allowance on one carrier does not apply to every recipient. Trackly does not promise automatic resizing or transcoding.

For caption compatibility, stay within **1,600 characters**, even though the request accepts up to 4,096. Shorter captions and subjects are easier to display.

## Acceptance, retries, and charges

A `201` response means the message was queued, not delivered. Check [message status](/api-reference/v2/messages/get-message.md) or [delivery webhooks](/api-reference/v2/webhooks/events.md) for the result. In bulk responses, inspect both `queued_count` and `errors`.

Use an `Idempotency-Key` when retrying. The fingerprint includes the full request, including attachment URLs, content metadata, caption, and subject. If the key cannot be reserved for a request containing MMS, Trackly returns `503 idempotency_unavailable` before sending. Without the header, the request has no idempotency protection. Follow the [idempotency limits](/api-reference/v2/idempotency.md); the header does not guarantee exactly-once delivery.

An uncertain submission failure does not prove non-delivery. Such messages are not automatically resent; confirm the outcome before creating a new send.

Each accepted MMS uses one message from the API key's daily send cap. Platform usage bills one unit per submitted MMS, plus actual carrier charges; SMS text-segment calculations do not determine MMS charges.

[Preflight](/api-reference/v2/messages/preflight.md) and sandbox single-send responses identify `message_type: "mms"` and return `null` for `segment_count` and `encoding`. Preflight also returns `estimated_cost: null`; its `mms_supported` and `mms_enabled` checks must both pass for eligibility. Preflight and sandbox validate descriptors without resolving or fetching media URLs; they do not establish delivery reachability. Sandbox does not deliver messages, and bulk sandbox responses retain their counts-and-errors format.

MMS is unavailable through [pending sends](/api-reference/v2/pending-sends/create.md), which reject it with `mms_pending_approval_not_supported`. Keys that require approval remain blocked from direct sends with `confirmation_required`. These immediate-send fields do not add MMS support to schedules or journeys.

## MMS errors

| Code | Meaning |
| - | - |
| `invalid_mms_media` | Attachment fields, URL, MIME type, content identifier, subject, or caption fail validation, or a live media hostname cannot resolve to public addresses. |
| `mms_not_supported` | The sending number does not support MMS. |
| `mms_unavailable` | MMS sending or live media DNS validation is temporarily unavailable. SMS requests without `media` are unaffected. |

Single sends return `400` for invalid or unsupported MMS and `503` when MMS is unavailable. Bulk sends report message-specific failures in `errors` alongside their queue results.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.