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.
  • Retention: attachments are deleted 90 days after their last use -- see Attachments FAQ: How long are attachments stored?.

Next