Documentation Index
Fetch the complete documentation index at: https://messages.dev/docs/llms.txt
Use this file to discover all available pages before exploring further.
You can send images, videos, documents, and other files as iMessage attachments.
Incoming messages with attachments include metadata and a download URL for each file.
Send an attachment
Upload a file first, then reference it by ID when sending a message:
import { createClient } from "@messages-dev/sdk";
const client = createClient();
const file = await client.uploadFile({
from: "+15551234567",
file: Buffer.from(imageData),
filename: "photo.jpg",
mimeType: "image/jpeg",
});
await client.sendMessage({
from: "+15551234567",
to: "+15559876543",
text: "Check out this photo!",
attachments: [file.id],
});
await client.sendMessage({
from: "+15551234567",
to: "+15559876543",
attachments: [file.id],
});
| Field | Required | Description |
|---|
to | Yes | Recipient phone number or Apple ID |
text | No | Optional message text (can be omitted when sending a file) |
attachments | No | Array of file IDs (max 1) from the upload endpoint |
At least one of text or attachments must be provided.
Supported file types
iMessage supports most common file types. The recipient’s device determines how
the attachment is displayed:
| Type | Examples | Display |
|---|
| Images | .jpg, .png, .gif, .heic, .webp | Inline preview |
| Videos | .mp4, .mov | Inline player |
| Audio | .mp3, .m4a, .aac | Audio player |
| Documents | .pdf, .docx, .xlsx | File icon with preview |
| Other | Any file type | Generic file attachment |
Receive attachments
Incoming messages with attachments include an attachments array with metadata
and a download URL for each file:
{
"event": "message.received",
"data": {
"id": "msg_abc123",
"sender": "+15559876543",
"text": null,
"attachments": [
{
"filename": "IMG_1234.jpg",
"mime_type": "image/jpeg",
"size": 245760,
"url": "https://storage.convex.cloud/..."
}
],
"sent_at": 1710000005000
}
}
Handle attachments in your webhook:
import { verifyWebhook } from "@messages-dev/sdk";
app.post("/webhooks", async (req, res) => {
const event = await verifyWebhook(
req.body,
req.headers["x-webhook-signature"],
"your_webhook_secret",
);
if (event.event === "message.received") {
if (event.data.attachments?.length) {
for (const att of event.data.attachments) {
console.log(`Received: ${att.filename} (${att.mimeType}, ${att.size} bytes)`);
console.log(`Download: ${att.url}`);
}
}
if (event.data.text) {
console.log(`Text: ${event.data.text}`);
}
}
res.sendStatus(200);
});
You can also retrieve attachment URLs when listing messages:
const messages = await client.listMessages({
from: "+15551234567",
to: "+15559876543",
});
for (const msg of messages.data) {
for (const att of msg.attachments) {
console.log(att.url);
console.log(att.filename);
console.log(att.mimeType);
}
}