Attach a file to a message and download it from a message
Files pass through Plum's attachment safety checks. A file rejected by those is reported per file rather than failing the request, because the message itself is still sent — so check the success flag on every entry.
Like a plain reply, sending attachments marks the conversation read.
Sending
Send multipart/form-data with a Body field and one Attachments field per file:
POST /v2/messaging/conversations/23722/messages/attachments
Authorization: Bearer {token}
Content-Type: multipart/form-data
Body=Here are the check-in instructions.
[email protected]
[email protected]Limits
- At least 1 file — a request with none is a 400 pointing you back at the plain reply route
- Up to 10 files per message
- Up to 20 MiB (20971520 bytes) per file
.jpg,.jpeg,.png,.pdfor.docxonly
A file of the wrong type or over the size limit fails the whole request with 400, naming the offending file by its position — for example Attachments[1].
Request
| Field | Type | Description |
|---|---|---|
body | string | The text of the message. May be empty when the files are the point of the reply |
Attachements | file | One field per file, repeated. At least one is required |
Response
| Field | Type | Description |
|---|---|---|
messageId | integer | The message the files were sent on. Downloads need it |
name | string | The name you uploaded the file under, and the one shown to a person |
fileName | string | The name the file is stored under. Downloads use this, not name |
contentType | string | Media type of the stored file |
size | string | Size of the file in bytes, sent as a string rather than a number |
success | boolean | Whether the file passed Plum's attachment safety checks |
errors | boolean | Why a file did not pass, and empty for one that did |
{
"messageId": 325926,
"attachments": [
{
"name": "directions.pdf",
"fileName": "04de6d75-91e5-42ad-9c8e-82e003e85f4b.pdf",
"contentType": "application/pdf",
"size": "190",
"success": true,
"errors": []
}
]
}Downloading
GET /v2/messaging/conversations/{conversationId}/messages/{messageId}/attachments/{fileName}Returns one file. Use the fileName from the response, not the original name:
GET /v2/messaging/conversations/23722/messages/325926/attachments/04de6d75-91e5-42ad-9c8e-82e003e85f4b.pdf
Authorization: Bearer {token}The file is returned as-is, byte for byte, with its stored content type and a Content-Disposition header naming it. A file whose type Plum cannot determine comes back as application/octet-stream.
Response
| Status | When it happens |
|---|---|
200 | Sending: the message was created, and every file is reported separately in attachments. Downloading: the file follows |
400 | No files, more than 10 files, a file too large, a file type not allowed, or the token carries no usable user id |
401 | The Authorization header is missing, malformed or expired |
404 | No conversation with that id belongs to the authenticated host, or that message has no file stored under that name |
5xx | A transient failure reaching the messaging back end. |
A 200 on the send route does not mean every file arrived. It means the message was created — the per-file success flags say which files went with it.
