Upload an Attachment
Use this endpoint when the bytes are already on your machine (or in memory) -- a file the user just selected, a PDF you just generated, an image returned from another API call, etc.
POST /api/v1/attachments/upload
Content-Type: multipart/form-data
Required scope: messages:create
Request
| Field | Type | Required | Description |
|---|---|---|---|
file | file (multipart) | Yes | The binary to upload. Max 50 MB. |
curl
curl -X POST "https://api.sendseven.com/api/v1/attachments/upload" \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" \
-F "file=@/path/to/photo.jpg"
Response (201 Created)
{
"id": "9b3f1a8e-7c2d-4e5b-9f01-12a3b4c5d6e7",
"attachment_id": "9b3f1a8e-7c2d-4e5b-9f01-12a3b4c5d6e7",
"filename": "photo.jpg",
"content_type": "image/jpeg",
"size": 245000,
"storage_path": "tenant_abc/attachments/9b3f1a8e-...jpg",
"download_url": "https://api.sendseven.com/api/v1/attachments/9b3f1a8e-.../download",
"public_url": "https://api.sendseven.com/api/v1/attachments/public/<tenant>/<id>/photo.jpg"
}
id and attachment_id are the same value -- both are returned for backward compatibility. Use either when referencing the attachment in a message.
Field reference
| Field | Description |
|---|---|
id / attachment_id | The UUID you pass to messages.attachments[]. |
filename | Original filename. |
content_type | Detected MIME type (validated against the file's magic bytes -- not just trusted from the upload header). |
size | Bytes. |
storage_path | Internal path in object storage. Informational only. |
download_url | Authenticated proxy URL. Requires messages:read. |
public_url | Capability-style public URL (no auth, but the path UUIDs are unguessable). Use for outbound contexts where an external service must fetch the bytes (e.g. WhatsApp template image.link). |
Python
import requests
BASE_URL = "https://api.sendseven.com/api/v1"
HEADERS = {"Authorization": "Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00"}
with open("invoice.pdf", "rb") as f:
r = requests.post(
f"{BASE_URL}/attachments/upload",
headers=HEADERS,
files={"file": ("invoice.pdf", f, "application/pdf")},
)
attachment = r.json()
print(attachment["id"])
JavaScript
const form = new FormData();
form.append("file", fileBlob, "invoice.pdf");
const r = await fetch("https://api.sendseven.com/api/v1/attachments/upload", {
method: "POST",
headers: { Authorization: "Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" },
body: form,
});
const attachment = await r.json();
console.log(attachment.id);
Limits and validation
- Max size: 50 MB.
- MIME validation: the upload allowlist is broader than the URL-fetch allowlist (see from-url). Common image, document, audio, video, and Office formats are accepted.
- Magic-byte check: the actual file content is sniffed and must match the declared
Content-Type. Renamingevil.exetocute.pngwill be rejected. - Blocked extensions: executables and script extensions (
.exe,.bat,.sh,.php,.js, etc.) are rejected regardless of MIME type. - Retention: attachments are deleted 90 days after their last use -- see Attachments FAQ: How long are attachments stored?.