Download an attachment
Stream an attachment’s binary content.
Streams the binary content of a single attachment. Use List attachments first to list available attachments and pick an attachmentId.
/ api/ v1/ messages/ {messageId}/ attachments/ {attachmentId}/ download- Auth
- Bearer API key — requires
messages:contentscope - Async
- No
- Pagination
- N/A — single binary response
Authorization
The API key must include the messages:content scope, and have the message’s mailbox in its allowlist. A missing scope returns 403; a mailbox outside the allowlist returns 404.
Only attachments with attachmentType: "fileAttachment" can be downloaded. Calls targeting referenceAttachment or itemAttachment types return 403.
Path parameters
messageIdstringThe message identifier.
attachmentIdstringThe attachment identifier from List attachments. Must reference a fileAttachment.
Response
A successful response is the raw file content (binary, not JSON), with these headers:
Content-TypestringThe file’s MIME type — for example, application/pdf.
Content-DispositionstringIncludes the original filename, e.g. attachment; filename="invoice.pdf".
Content-LengthintegerFile size in bytes.
X-Content-Type-OptionsstringAlways nosniff.
There is no JSON envelope on success. On failure, the response is JSON in the standard error envelope.
Request
curl -OJ 'https://c1.emailgistics.com/api/v1/messages/AAMkAGI2.../attachments/AAMkADk5.../download' \
-H 'Authorization: Bearer YOUR_API_KEY'The -OJ flags tell curl to save the response to disk using the filename from the Content-Disposition header.
import requests
response = requests.get(
f"https://c1.emailgistics.com/api/v1/messages/{message_id}/attachments/{attachment_id}/download",
headers={"Authorization": f"Bearer {API_KEY}"},
stream=True,
)
response.raise_for_status()
filename = response.headers.get("Content-Disposition", "").split("filename=")[-1].strip('"')
with open(filename, "wb") as f:
for chunk in response.iter_content(chunk_size=64 * 1024):
f.write(chunk)Errors
| Status | When |
|---|---|
401 | API key missing, malformed, or expired. |
403 | Key is missing the messages:content scope, or the attachment’s type isn’t supported for download (only fileAttachment can be downloaded). |
404 | messageId or attachmentId is unknown, or the message’s mailbox is not in the key’s allowlist (the cases are indistinguishable). |
429 | Rate limit exceeded — see Rate limits. |
5xx | Transient upstream issue (typically the underlying Exchange tenant). |
If the underlying Microsoft Graph call fails, its status code may be forwarded directly (in addition to the 5xx case above) — for example, a 401 or 403 from Graph if the upstream tenant has revoked permission, or a 404 if Graph cannot find the message. Treat any unexpected status from this endpoint as transient and retry.
Error bodies follow the standard shape — see Errors.
Notes
- Attachment content is fetched on demand from the customer’s Exchange tenant; nothing is stored on Emailgistics servers.
- Stream large files rather than buffering them in memory — there is no documented size limit.
Related
- List attachments — list available attachments first.
- Webhook request payload — receive
messageIdfor incoming messages.