Attachments

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, .pdf or .docx only

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

FieldTypeDescription
bodystringThe text of the message. May be empty when the files are the point of the reply
AttachementsfileOne field per file, repeated. At least one is required

Response

FieldTypeDescription
messageIdintegerThe message the files were sent on. Downloads need it
namestringThe name you uploaded the file under, and the one shown to a person
fileNamestringThe name the file is stored under. Downloads use this, not name
contentTypestringMedia type of the stored file
sizestringSize of the file in bytes, sent as a string rather than a number
successbooleanWhether the file passed Plum's attachment safety checks
errorsbooleanWhy 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

StatusWhen it happens
200Sending: the message was created, and every file is reported separately in attachments. Downloading: the file follows
400No files, more than 10 files, a file too large, a file type not allowed, or the token carries no usable user id
401The Authorization header is missing, malformed or expired
404No conversation with that id belongs to the authenticated host, or that message has no file stored under that name
5xxA 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.