Skip to main content

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​

FieldTypeRequiredDescription
filefile (multipart)YesThe 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​

FieldDescription
id / attachment_idThe UUID you pass to messages.attachments[].
filenameOriginal filename.
content_typeDetected MIME type (validated against the file's magic bytes -- not just trusted from the upload header).
sizeBytes.
storage_pathInternal path in object storage. Informational only.
download_urlAuthenticated proxy URL. Requires messages:read.
public_urlCapability-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. Renaming evil.exe to cute.png will be rejected.
  • Blocked extensions: executables and script extensions (.exe, .bat, .sh, .php, .js, etc.) are rejected regardless of MIME type.
  • message_id (optional query parameter): must be a message of your workspace, otherwise 404 "Message not found" and nothing is uploaded.
  • Retention: attachments are deleted 90 days after their last use -- see Attachments FAQ: How long are attachments stored?.

Next​