import { readFile } from "node:fs/promises";
import { createClient } from "@mailsai/sdk";
const client = createClient(); // reads MAILS_API_KEY
// This file is under chunk_bytes: one chunk, number 0.
const bytes = await readFile("order-10473.pdf");
const result = await client.drafts.attachments.putChunk(
"dft_01JZX8K3M9Q4P7VN2YB6RTDC0E",
"dfa_01JZX8K3M9Q4P7VN2YB6RTDC0E",
0,
bytes,
);
console.log(result);from pathlib import Path
from mailsai import create_client
client = create_client() # reads MAILS_API_KEY
# This file is under chunk_bytes: one chunk, number 0.
data = Path("order-10473.pdf").read_bytes()
result = client.put_draft_attachment_chunk(
"dft_01JZX8K3M9Q4P7VN2YB6RTDC0E",
"dfa_01JZX8K3M9Q4P7VN2YB6RTDC0E",
0,
data,
)
print(result)# This file is under chunk_bytes: one chunk, number 0.
curl -X PUT 'https://api.mails.ai/v1/drafts/dft_01JZX8K3M9Q4P7VN2YB6RTDC0E/attachments/dfa_01JZX8K3M9Q4P7VN2YB6RTDC0E/chunks/0' \
-H "Authorization: Bearer $MAILS_API_KEY" \
-H 'Content-Type: application/octet-stream' \
--data-binary @order-10473.pdf{
"id": "dfa_01JZX8K3M9Q4P7VN2YB6RTDC0E",
"filename": "<filename>",
"content_type": "<content_type>",
"size": 0,
"status": "uploading",
"chunk_bytes": 0,
"chunk_count": 0,
"from_message_id": "<from_message_id>",
"created_at": "2026-10-04T12:00:00.000Z",
"storage": { "used_bytes": 0, "limit_bytes": 0 }
}200 The file.
400 Invalid request — malformed JSON or a field failed
validation. Also feature_not_enabled when this
server has a feature switched off (custom domains
before they are available).
401 Missing or invalid API key.
402 Payment required: a plan limit
(plan_limit_exceeded) or a feature the current plan
does not include (feature_not_enabled). The error
object carries upgrade_url, the dashboard page
where the plan can be changed.
403 The API key lacks the required scope
(insufficient_scope), or the token belongs to an
app connected by sign-in and this operation is
closed to connected apps
(connected_app_not_allowed).
404 Resource not found in this workspace, or the agent
a send names is archived (agent_archived).
409 Conflict — duplicate resource, an in-progress
idempotent request, a draft or scheduled message
that started sending while it was being changed, or
a thread deleted for good while one of its messages
is being sent (duplicate_resource); or an agent
name more than one agent has (agent_name_conflict:
use the agent's id); or a status change on an
archived agent, since archiving cannot be undone
(agent_archived).
413 Payload too large (body_too_large): raw_base64
decodes to more than 3 MB, the most this route
takes.
500 Internal server error.Upload a chunk of a draft's file
import { readFile } from "node:fs/promises";
import { createClient } from "@mailsai/sdk";
const client = createClient(); // reads MAILS_API_KEY
// This file is under chunk_bytes: one chunk, number 0.
const bytes = await readFile("order-10473.pdf");
const result = await client.drafts.attachments.putChunk(
"dft_01JZX8K3M9Q4P7VN2YB6RTDC0E",
"dfa_01JZX8K3M9Q4P7VN2YB6RTDC0E",
0,
bytes,
);
console.log(result);from pathlib import Path
from mailsai import create_client
client = create_client() # reads MAILS_API_KEY
# This file is under chunk_bytes: one chunk, number 0.
data = Path("order-10473.pdf").read_bytes()
result = client.put_draft_attachment_chunk(
"dft_01JZX8K3M9Q4P7VN2YB6RTDC0E",
"dfa_01JZX8K3M9Q4P7VN2YB6RTDC0E",
0,
data,
)
print(result)# This file is under chunk_bytes: one chunk, number 0.
curl -X PUT 'https://api.mails.ai/v1/drafts/dft_01JZX8K3M9Q4P7VN2YB6RTDC0E/attachments/dfa_01JZX8K3M9Q4P7VN2YB6RTDC0E/chunks/0' \
-H "Authorization: Bearer $MAILS_API_KEY" \
-H 'Content-Type: application/octet-stream' \
--data-binary @order-10473.pdf{
"id": "dfa_01JZX8K3M9Q4P7VN2YB6RTDC0E",
"filename": "<filename>",
"content_type": "<content_type>",
"size": 0,
"status": "uploading",
"chunk_bytes": 0,
"chunk_count": 0,
"from_message_id": "<from_message_id>",
"created_at": "2026-10-04T12:00:00.000Z",
"storage": { "used_bytes": 0, "limit_bytes": 0 }
}200 The file.
400 Invalid request — malformed JSON or a field failed
validation. Also feature_not_enabled when this
server has a feature switched off (custom domains
before they are available).
401 Missing or invalid API key.
402 Payment required: a plan limit
(plan_limit_exceeded) or a feature the current plan
does not include (feature_not_enabled). The error
object carries upgrade_url, the dashboard page
where the plan can be changed.
403 The API key lacks the required scope
(insufficient_scope), or the token belongs to an
app connected by sign-in and this operation is
closed to connected apps
(connected_app_not_allowed).
404 Resource not found in this workspace, or the agent
a send names is archived (agent_archived).
409 Conflict — duplicate resource, an in-progress
idempotent request, a draft or scheduled message
that started sending while it was being changed, or
a thread deleted for good while one of its messages
is being sent (duplicate_resource); or an agent
name more than one agent has (agent_name_conflict:
use the agent's id); or a status change on an
archived agent, since archiving cannot be undone
(agent_archived).
413 Payload too large (body_too_large): raw_base64
decodes to more than 3 MB, the most this route
takes.
500 Internal server error.Path Parameters
Draft id.
File id (dfa_…).
The chunk's number, from 0.
Every chunk is chunk_bytes long except the last, which is what is left of size; any other length is a 400. Until the file is finished, sending a chunk again replaces it, so a dropped connection can simply be retried; a chunk sent to a finished file is a 409 and changes nothing. The file turns ready when the last chunk arrives, in any order. A plan that has fallen below what the workspace's drafts hold refuses the chunk (402 resource_cap_exceeded).
Response
File id (dfa_…).
The file's name, as the recipient sees it.
The file's MIME type.
The file's size in bytes.
uploading: some chunks have not arrived, and the draft cannot be sent or scheduled. ready: every chunk is in.
How long each chunk is, except the last, in bytes: 3 MiB.
How many chunks the file is sent in, numbered from 0. 0 on a forward's file, which is read from the email.
On a forward's file: the received message it is read from when the draft is sent. Absent on a file that was uploaded.
When the file was added.
On the answer to adding a file: how much room the workspace's drafts have left for files. Absent otherwise.
Was this page helpful?