Files and voice memos
Upload pictures, video, audio, PDFs and contact cards and send them on a text, read the pictures and voice memos people send you, and know the limits on each.
A text can carry pictures, video, audio, a PDF or a contact card, and texts that come in carry whatever people send you, voice memos included. Sending a file takes two calls: upload it, then send its id.
Send a file
Dana wants to send Maria the photos of 412 Oak St.
Upload it
POST/v1/files takes the file as multipart/form-data in a field named file:
/v1/filescurl -X POST "https://usebluebot.com/api/v1/files" \
-H "Authorization: Bearer $BLUEBOT_API_KEY" \
-H "Idempotency-Key: upload-412-oak-kitchen" \
-F "file=@kitchen.jpg"{
"id": "file_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "file",
"name": "kitchen.jpg",
"content_type": "image/jpeg",
"size": 482113,
"kind": "image",
"status": "ready",
"url": "https://usebluebot.com/files/f/2Bf8QzD4kJmA6nXwEuTr1c?sig=…",
"url_expires_at": "2026-11-13T20:41:00.000Z",
"transcript": null,
"transcript_language": null,
"created_at": "2026-11-13T19:40:00.000Z"
}The file goes by the name it was uploaded with. To send it under another name, add a name form field (-F name=412-oak-kitchen.jpg with curl). The person sees that name on a PDF or a contact card.
BlueBot reads the file’s type from the Content-Type of the form part. curl and the SDKs set it from the file’s extension. If your code builds the form by hand, set it, or the upload is refused as 415 unsupported_media_type.
Send it
Put the id in files, with words or without:
/v1/messagescurl -X POST "https://usebluebot.com/api/v1/messages" \
-H "Authorization: Bearer $BLUEBOT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: listing-412-oak-photos" \
-d '{
"to": "+15555550123",
"text": "Here’s the kitchen at 412 Oak St, as promised.",
"files": [
"file_1Hq2LxW9cVbN3mKpRtYs0a"
]
}'Up to 10 files go on one text. They follow the words in the order you list them. Each one arrives as its own picture or attachment in the conversation, the way it would if you dragged them into Messages one after another.
Check it went
message.sent fires once the words and every file went. If the words went and a file didn’t, the text is still sent, with failure set to say which file:
{
"id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "message",
"state": "sent",
"service": "imessage",
"failure": {
"reason": "file_unavailable",
"detail": "Messages didn’t send kitchen.jpg."
}
}If the Mac couldn’t download a file to send it, nothing goes: the text fails with failure.reason: "file_unavailable", so the person never gets words that point at a picture they don’t have.
What you can send
| Kind | Types | kind on the file |
|---|---|---|
| Pictures | JPEG, PNG, GIF, HEIC, HEIF, WebP | image |
| Video | MP4, QuickTime (.mov) | video |
| Audio | MP3, M4A, AAC, WAV, CAF | audio |
| Documents | pdf | |
| Contact cards | vCard (.vcf, text/vcard) | contact_card |
Each file can be up to 25 MB. Anything else is 415 unsupported_media_type, and a larger file is 413 payload_too_large. An empty file is 400 invalid_request.
One upload can go on more than one text, so a logo or a menu you send to many people needs uploading once. An upload no text uses is deleted after a day, and a file that went out is kept for 30 days, the same as the words of a text. After that its status is deleted. Upload again for a text after that.
iMessage and regular texts
Over iMessage, files up to the 25 MB limit go as they are. Over a regular text, a file goes as a picture message (MMS) through your iPhone, and your carrier decides how large that may be: phones usually shrink a big photo to fit, and may refuse a long video. Send large files to people on iMessage, or send a link to the file instead.
Contact cards
Upload a .vcf file and send it like any other file. The person can tap it to save your details. A good first text to a new client carries one, so your name shows up when you text them next time:
/v1/messagescurl -X POST "https://usebluebot.com/api/v1/messages" \
-H "Authorization: Bearer $BLUEBOT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: deal-48213-card" \
-d '{
"to": "+15555550123",
"text": "Here’s my card so you have my number saved.",
"files": [
"file_3Lp3VsC7hGqE5tZyKbWn2d"
]
}'Voice memos
Sending audio
Upload an audio file (M4A, MP3, AAC, WAV or CAF) and send it. It arrives as audio the person can play in the conversation. BlueBot can’t record a voice memo in Messages for you, so a recording made elsewhere goes as an audio file.
Voice memos you receive
When somebody sends you a voice memo, it comes on the message as a file with "kind": "voice_memo" and "content_type": "audio/x-caf". Safari plays CAF files and most other browsers don’t, so convert one before you play it on a web page. ffmpeg -i memo.caf memo.m4a does it.
If you turn on transcription in BlueBot’s settings on the Mac, the Mac transcribes each voice memo with Apple’s own speech recognition, on the Mac itself, before it copies the message. The words come in transcript, with the language in transcript_language:
{
"id": "file_2Bf8QzD4kJmA6nXwEuTr1c",
"object": "file",
"name": "Audio Message.caf",
"content_type": "audio/x-caf",
"size": 41022,
"kind": "voice_memo",
"status": "ready",
"url": "https://usebluebot.com/files/f/3Lp3VsC7hGqE5tZyKbWn2d?sig=…",
"url_expires_at": "2026-11-13T20:44:00.000Z",
"transcript": "Hey Dana, Thursday works, can we do 3 instead of 2?",
"transcript_language": "en-US",
"created_at": "2026-11-13T19:44:00.000Z"
}Transcription is off until you turn it on, costs nothing, and sends no audio anywhere but BlueBot. GET /v1/device says whether it’s on, in transcription. A memo that couldn’t be transcribed has "transcript": null.
Files you receive
Pictures, videos, voice memos and documents people send you are on the message’s files, in order. A file’s status says whether you can read it:
status | It means | Do next |
|---|---|---|
ready | BlueBot has it. url reads it for an hour. | Download it now if you want to keep it. |
waiting | The Mac is still uploading it, usually for a few seconds. | Read the message or the file again shortly. |
too_large | It’s over 25 MB, so the Mac didn’t upload it. | Open it in Messages on your Mac or iPhone. |
deleted | It’s more than 30 days old. | Nothing. Copy files into your own storage when they come if you need them longer. |
message.received waits until the Mac has uploaded the text’s files, so the files on the event are usually ready. If they take more than 2 minutes, the event goes anyway and the slow ones are waiting.
Each url is a signed link that works for an hour and needs no key, so anyone with it can read the file in that hour. Don’t paste it anywhere public. When a link has run out, ask for the file again and you get a fresh one:
/v1/files/file_2Bf8QzD4kJmA6nXwEuTr1ccurl "https://usebluebot.com/api/v1/files/file_2Bf8QzD4kJmA6nXwEuTr1c" \
-H "Authorization: Bearer $BLUEBOT_API_KEY"The Mac uploads files only from the chats it copies. explains which those are.
Limits
| Limit | Value |
|---|---|
| One file | 25 MB |
| Files on one text | 10 |
| An upload no text uses | Deleted after a day |
| A file that was sent or received | Kept 30 days |
A file’s url | Works for an hour |
lists every limit in one place.