Overview
This endpoint allows you to download email attachments using the email ID and filename. The attachment URL is automatically provided in webhook payloads for easy access.
This endpoint is typically used with the downloadUrl field provided in webhook payloads, but you can also construct the URL manually if needed.
Authentication
Bearer token for API authentication. Format: Bearer YOUR_API_KEY
Path Parameters
The structured email ID (the email’s unique identifier in Inbound).
The filename of the attachment to download. Must be URL-encoded if it contains special characters.
Response
The endpoint returns the raw file content with appropriate headers:
Content-Type : The attachment’s MIME type (e.g., application/pdf, image/png)
Content-Disposition : Set to attachment; filename="..." for proper download behavior
Content-Length : Size of the file in bytes
Cache-Control : Set to private, max-age=3600 for secure caching
Examples
Download from Webhook Payload
Node.js (from webhook)
cURL
Python
PHP
import { NextRequest , NextResponse } from 'next/server'
import type { InboundWebhookPayload } from '@inboundemail/sdk'
export async function POST ( request : NextRequest ) {
const payload : InboundWebhookPayload = await request . json ()
const { email } = payload
// Download first attachment
if ( email . parsedData . attachments . length > 0 ) {
const attachment = email . parsedData . attachments [ 0 ]
const response = await fetch ( attachment . downloadUrl , {
headers: {
'Authorization' : `Bearer ${ process . env . INBOUND_API_KEY } `
}
})
if ( response . ok ) {
const fileBuffer = await response . arrayBuffer ()
console . log ( `Downloaded ${ attachment . filename } : ${ fileBuffer . byteLength } bytes` )
// Save to disk, cloud storage, etc.
await saveFile ( attachment . filename , fileBuffer )
}
}
return NextResponse . json ({ success: true })
}
Save to Cloud Storage
import { S3Client , PutObjectCommand } from '@aws-sdk/client-s3'
import type { InboundWebhookPayload } from '@inboundemail/sdk'
const s3Client = new S3Client ({ region: 'us-east-1' })
export async function POST ( request : NextRequest ) {
const payload : InboundWebhookPayload = await request . json ()
const { email } = payload
// Download and upload attachments to S3
for ( const attachment of email . parsedData . attachments ) {
// Download from Inbound
const response = await fetch ( attachment . downloadUrl , {
headers: {
'Authorization' : `Bearer ${ process . env . INBOUND_API_KEY } `
}
})
if ( response . ok ) {
const fileBuffer = await response . arrayBuffer ()
// Upload to S3
await s3Client . send ( new PutObjectCommand ({
Bucket: 'my-email-attachments' ,
Key: `emails/ ${ email . id } / ${ attachment . filename } ` ,
Body: Buffer . from ( fileBuffer ),
ContentType: attachment . contentType
}))
console . log ( `Uploaded ${ attachment . filename } to S3` )
}
}
return NextResponse . json ({ success: true })
}
Error Responses
404 Not Found - Email
404 Not Found - Attachment
404 Not Found - No Content
404 Not Found - No Attachments
401 Unauthorized
400 Bad Request
500 Internal Server Error
{
"error" : "Email not found or access denied"
}
Important Notes
Authentication Required : You must include a valid API key in the Authorization header to download attachments. Only the email owner can download attachments.
Smart Content Retrieval : The endpoint automatically tries S3 storage first, then falls back to direct email content if S3 is unavailable.
URL Encoding : If the filename contains special characters, it should be URL-encoded in the download URL. The downloadUrl in webhook payloads is already properly encoded.
Usage in Webhook Handlers
The most common use case is downloading attachments from webhook payloads:
import { InboundWebhookPayload } from '@inboundemail/sdk'
export async function POST ( request : Request ) {
const payload : InboundWebhookPayload = await request . json ()
const { email } = payload
console . log ( `Email has ${ email . parsedData . attachments . length } attachments` )
for ( const attachment of email . parsedData . attachments ) {
// The downloadUrl is ready to use
console . log ( `Download: ${ attachment . downloadUrl } ` )
// Fetch the file
const file = await fetch ( attachment . downloadUrl , {
headers: {
'Authorization' : `Bearer ${ process . env . INBOUND_API_KEY } `
}
})
if ( file . ok ) {
// Process the file
const data = await file . arrayBuffer ()
await processAttachment ( attachment . filename , data )
}
}
return new Response ( 'OK' )
}
Security Considerations
API Key Protection
Never expose your API key in client-side code. Always download attachments from server-side code.
User Verification
The endpoint automatically verifies that the requesting user owns the email before allowing downloads.
Content Type Validation
Always validate the content type before processing downloaded files to prevent security issues.
Notes
Attachments are downloaded as raw binary data
The endpoint respects S3 storage location and falls back to direct content
Only the email owner (authenticated user) can download attachments
The filename in the URL is used for proper Content-Disposition headers
Large attachments may take longer to download depending on size
Download URLs in webhook payloads are automatically URL-encoded
1.0 - ✅