Skip to main content

Download Attachment

curl -X GET "https://inbound.new/api/e2/attachments/eml_abc123/report.pdf" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --output report.pdf

GET /api/e2/attachments/:id/:filename

Download an email attachment by email ID and filename. Returns the binary file content with appropriate Content-Type and Content-Disposition headers.

Path Parameters

id
string
required
Email ID that contains the attachment.Example: eml_abc123
filename
string
required
Filename of the attachment to download. Will be URL-decoded automatically.Example: report.pdf or My%20Document.docx

Response

Returns binary file content with appropriate headers: Response Headers:
Content-Type
string
MIME type of the attachment (e.g., application/pdf, image/png, text/plain).Falls back to application/octet-stream if unknown.
Content-Disposition
string
Attachment disposition with filename. Uses both ASCII fallback and UTF-8 encoded filename per RFC 5987.Example: attachment; filename="report.pdf"; filename*=UTF-8''report.pdf
Content-Length
string
Size of the attachment in bytes.
Cache-Control
string
Cache control header: private, max-age=3600
Response Body: Raw binary content of the attachment.

Attachment Storage

Attachments are stored in two possible locations:
  1. Amazon S3 (Primary) - For emails stored in S3 buckets
  2. Database (Fallback) - For emails with inline content
The API automatically:
  • Tries S3 first if bucket and key are available
  • Falls back to database content if S3 fetch fails
  • Returns appropriate error if neither source is available

Size Limits

The maximum attachment size is determined by your email provider’s limits:
  • AWS SES: 10 MB per email (including all attachments)
  • Individual attachments: No specific limit, but total email size must not exceed 10 MB

Supported Formats

All attachment types are supported. Common MIME types:
FormatMIME TypeExtension
PDFapplication/pdf.pdf
Word Documentapplication/vnd.openxmlformats-officedocument.wordprocessingml.document.docx
Excel Spreadsheetapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet.xlsx
PowerPointapplication/vnd.openxmlformats-officedocument.presentationml.presentation.pptx
ZIP Archiveapplication/zip.zip
PNG Imageimage/png.png
JPEG Imageimage/jpeg.jpg, .jpeg
GIF Imageimage/gif.gif
Text Filetext/plain.txt
CSV Filetext/csv.csv
JSON Fileapplication/json.json

Error Responses

error
string
Error message describing what went wrong.
details
string
Additional error details (if available).

Common Error Scenarios

404 - Email Not Found
{
  "error": "Email not found or access denied"
}
404 - Attachment Not Found
{
  "error": "Attachment not found"
}
404 - No Attachments
{
  "error": "No attachments found in this email"
}
404 - Email Content Not Available
{
  "error": "Email content not available"
}
401 - Unauthorized
{
  "error": "Unauthorized",
  "details": "Invalid or missing API key"
}

Listing Email Attachments

To get a list of attachments for an email, use the Get Email endpoint:
const email = await inbound.emails.get('eml_abc123')

if (email.has_attachments) {
  console.log('Attachments:', email.attachments)
  // [
  //   {
  //     filename: 'report.pdf',
  //     contentType: 'application/pdf',
  //     size: 245678,
  //     contentId: null
  //   },
  //   ...
  // ]
}
Then download each attachment:
for (const attachment of email.attachments) {
  const file = await inbound.attachments.download(
    email.id,
    attachment.filename
  )
  
  await Bun.write(`downloads/${attachment.filename}`, file)
}

Inline Attachments

Inline attachments (images embedded in HTML emails) have a contentId field:
{
  "filename": "logo.png",
  "contentType": "image/png",
  "size": 15234,
  "contentId": "<[email protected]>"
}
These can still be downloaded using the same endpoint, but they’re also referenced in the HTML body:
<img src="cid:[email protected]" alt="Logo">

Security

  • Authentication Required: All attachment downloads require a valid API key
  • User Scoping: Users can only download attachments from their own emails
  • Content Validation: Filenames are URL-decoded and validated
  • Binary Safety: Files are returned as-is without modification
  • Private Caching: Cache-Control header set to private to prevent public caching

Best Practices

  1. Check Email First: Use the Get Email endpoint to verify attachments exist before downloading
  2. Handle Large Files: Implement streaming for large attachment downloads
  3. Validate Content-Type: Always check the Content-Type header before processing
  4. URL Encode Filenames: Encode special characters in filenames when constructing URLs
  5. Error Handling: Implement proper error handling for missing or inaccessible attachments
// Example: Safe attachment download
async function downloadAttachment(emailId: string, filename: string) {
  try {
    // URL encode the filename
    const encodedFilename = encodeURIComponent(filename)
    
    const response = await fetch(
      `https://inbound.new/api/e2/attachments/${emailId}/${encodedFilename}`,
      {
        headers: {
          'Authorization': `Bearer ${process.env.INBOUND_API_KEY}`
        }
      }
    )
    
    if (!response.ok) {
      const error = await response.json()
      throw new Error(error.error)
    }
    
    // Check content type
    const contentType = response.headers.get('Content-Type')
    console.log('Downloading:', contentType)
    
    // Get binary data
    const blob = await response.blob()
    
    // Save to file
    await Bun.write(`downloads/${filename}`, blob)
    
    return { success: true, filename, size: blob.size }
  } catch (error) {
    console.error('Download failed:', error)
    return { success: false, error: error.message }
  }
}

Build docs developers (and LLMs) love