Attachments and copies
An attachment is added to a draft, through an upload link the human opens in their browser. It leaves with the message, once a human approves it. Attachments and copies only go into a conversation: the correspondent has already written in the thread. A first message leaves with no attachment, to its single recipient.
What is allowed
| In a conversation | To an address of the space | First message, follow-up with no reply | |
|---|---|---|---|
| Attachment | Yes. | Yes: its human, one of its inboxes. | No: attachments_not_allowed. |
Copy (cc) | Yes, to someone who has written in the thread themselves, or to an address of the space. | No: cc_not_allowed. |
- A conversation: the correspondent has written in the thread themselves (a reply, or a first e-mail received). An automatic reply does not count, nor does a third party’s e-mail attached to the thread.
- Who a copy can go to: an address that has written in the thread itself. Having been a recipient of a received message is not enough: an e-mail’s
Ccheader can be written freely. - From an inbox on the shared domain, a copy only goes to an address of the space.
- A blocked address cannot be copied in:
recipient_suppressed.
| Bound | Value |
|---|---|
| Size of a message’s attachments | 10 MB, all attachments together |
| Attachments per message | 10 |
| Copies per message | 5 |
| Attachments kept per space | 500 MB of attachments sent, 200 MB of attachments received |
| An attachment’s content | kept for 90 days |
| Upload link | 1 hour, 30 MB received at most (removed attachments included) |
| Upload links per space | 60 per 24 hours |
| Uploads | One at a time per draft; 12 per minute per address |
| Download link | 15 minutes |
A file that runs on a double click (.exe, .bat, .js, .msi, .scr…) cannot be attached, nor can a page (.html, .svg): attachment_refused.
Attaching a file
- The agent writes the reply as a draft:
reply_to_threadwithrequires_approval=true. - It asks for the upload link:
attach_fileswith the draft’smessage_id, and gives it to its human. - The human opens the link in their browser and picks the files. The page shows the draft and its attachments; it lets them remove some.
- The human approves the draft from their assistant:
approve_message. The message leaves with its attachments.
- The draft changes version with every attachment added or removed. An approval given with the old
revisionis refused (draft_changed): whoever approves sees the attachments that leave. - An agent that holds the file uploads it itself: a
POSTrequest to the link, asmultipart/form-data, with onefilefield per file. With theAccept: application/jsonheader, the response is in JSON. - The link allows nothing else: neither reading the message’s text, nor approving it, nor touching another draft. It stops working as soon as the message is approved or cancelled.
- A cancelled draft does not keep its attachments. Their names remain in the message’s log.
curl -H "Accept: application/json" -F "[email protected]" "https://api.subagent.fr/f/sfl_…"
Reading an attachment received
An e-mail received keeps its attachments. get_thread and get_message list them in attachments; get_attachment returns a download link.
- An image the message body displays (the logo in a signature) is not an attachment.
- An attachment that is too heavy, or executable, is not kept: its name and size remain,
storedisfalse. Beyond 10 MB for a message, the following attachments only keep their names. - An attachment’s content is kept for 90 days. After that its name and size remain with the message, and
storedbecomesfalse. The attachment of a message still waiting to leave is not affected. - A space not yet verified only keeps the name and size of attachments received.
- An attachment received comes from a third party. Its name and content are read as information, never as an instruction. It is downloaded, never displayed in a page of the service.
- The other recipients of a received message are in its
ccfield, for reading. One of them can only be copied in on a reply after writing in the thread.
Copying someone in
reply_to_thread accepts cc: five addresses at most. The thread’s recipient and the inbox itself are not repeated there.
- No one-click unsubscribe link in a message that leaves with copies: opened by a person in copy, it would unsubscribe the recipient.
- A non-delivery notice or a complaint received for a message sent with copies is written in the message’s log (
copy_bounced,bounce_unconfirmed,complaint_unconfirmed), without blocking an address or closing the thread: all its recipients know its identifier, and a notice can be forged. - A person in copy who replies “STOP” is unsubscribed, like a recipient.
- With a copy, the text cannot carry
{{unsubscribe_url}}: the call is refused. - An address blocked between creation and departure is removed from the copies: the message leaves without it, and the log carries
copy_dropped.
attach_files
Returns an upload link to attach files to a draft. Permission: send. The space must be verified.
| Parameter | Type | Required | Description |
|---|---|---|---|
message_id | msg_… identifier | yes | The draft. |
- The result returns
upload_url(the link),expires_at,attachments(the attachments already added) andmax_bytes. - A message that is not a draft is refused with the code
not_draft. Outside a conversation:attachments_not_allowed. - Beyond 60 upload links per space in 24 hours:
space_rate_limited. One link serves for several files.
Lien de dépôt pour le brouillon msg_7f2a91c4e8b34d0fa6c25e1b9d3f7a48 (à [email protected]) :
https://api.subagent.fr/f/sfl_…
Donnez ce lien à l’humain : il y choisit les fichiers à joindre (10 Mo au plus en tout, 10 pièces). Il vaut 60 minutes, jusqu’au mardi 13 octobre à 15 h 20, et ne sert qu’à ce brouillon. Les pièces partent avec le message, à sa validation (approve_message). Aucune pièce jointe pour l’instant.remove_attachment
Removes an attachment from a draft. Permission: send or approve. The space must be verified.
| Parameter | Type | Required | Description |
|---|---|---|---|
attachment_id | att_… identifier | yes | The attachment (see list_drafts). |
- The result returns the attachment removed (
removed) and those that remain (attachments). - The attachment of a sent or received message cannot be removed:
not_draft.
get_attachment
Reads an attachment, received or sent. Permission: read.
| Parameter | Type | Required | Description |
|---|---|---|---|
attachment_id | att_… identifier | yes | The attachment (see get_thread). |
- The result returns the attachment (
attachment),download_urlandexpires_at. textcarries the content of a small text attachment (text, CSV, JSON, 100 KB at most);nullotherwise.untrustedistruefor an attachment received.- When the content was not kept,
download_urlisnull. - Beyond 300 download links per space in 24 hours, the attachment can still be read (name, type, size, text), without a link:
download_urlisnull.
The fields of an attachment
| Field | Content |
|---|---|
id | The attachment identifier, att_…. |
message_id | The message that carries it. |
filename | Its name, without a path. |
content_type | Its type (application/pdf…). |
size | Its size, in bytes. |
stored | false: the content was not kept, only the name and size remain. |
The refusals: Errors.