Attachments
Email API supports adding file attachments to emails using the attachments
array in the JSON payload.
Attachment Structure
Each attachment is represented by an object with the following properties:
{
"type": "MIME type",
"filename": "file name",
"content": "Base64 encoded content"
}
type
: MIME type of the file (e.g., "image/png", "application/pdf")filename
: Name of the file as it will appear to the recipientcontent
: Base64 encoded file content
Usage Notes
- Multiple attachments can be included in a single email
- Maximum of 1000 attachments per email
- Combined size limit (attachments + email content) is 30MB
- Base64 encoding is required for all attachment content
If your email message exceeds the size limit, it will be rejected with an error.
Base64 encoding increases the data required for an attachment by about 33% over binary encoding. Be sure to check the size of your attachments after base64 encoding.
Example: Email with Attachment
{
"personalizations": [
{
"to": [{ "email": "recipient@example.com", "name": "Recipient Name" }]
}
],
"from": { "email": "sender@example.com", "name": "Sender Name" },
"subject": "Email with Attachment",
"content": [
{ "type": "text/plain", "value": "Please see the attached image." },
{ "type": "text/html", "value": "<html><body><p>Please see the attached image.</p></body></html>" }
],
"attachments": [
{
"type": "image/png",
"filename": "logo.png",
"content": "iVBORw0KGgoAAAANSUhEUgAAAKIAAA... (truncated for brevity)"
}
]
}
Implementation Examples
- cURL
- JavaScript
- Go
curl -X POST "https://api.mailchannels.net/tx/v1/send" \
-H 'X-Api-Key: YOUR-API-KEY' \
-H 'Content-Type: application/json' \
-d '{
"personalizations": [
{
"to": [{ "email": "recipient@example.com", "name": "Recipient Name" }]
}
],
"from": { "email": "sender@example.com", "name": "Sender Name" },
"subject": "Email with Attachment",
"content": [
{ "type": "text/plain", "value": "Please see the attached image." },
{ "type": "text/html", "value": "<html><body><p>Please see the attached image.</p></body></html>" }
],
"attachments": [
{
"type": "image/png",
"filename": "logo.png",
"content": "iVBORw0KGgoAAAANSUhEUgAAAKIAAA... (truncated for brevity)"
}
]
}'
const axios = require('axios');
const data = {
personalizations: [
{ to: [{ email: "recipient@example.com", name: "Recipient Name" }] }
],
from: { email: "sender@example.com", name: "Sender Name" },
subject: "Email with Attachment",
content: [
{ type: "text/plain", value: "Please see the attached image." },
{ type: "text/html", value: "<html><body><p>Please see the attached image.</p></body></html>" }
],
attachments: [
{
type: "image/png",
filename: "logo.png",
content: "iVBORw0KGgoAAAANSUhEUgAAAKIAAA... (truncated for brevity)"
}
]
};
axios.post('https://api.mailchannels.net/tx/v1/send', data, {
headers: {
'X-Api-Key': 'YOUR-API-KEY',
'Content-Type': 'application/json'
}
})
.then(response => console.log('Success:', response.data))
.catch(error => console.error('Error:', error));
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"io/ioutil"
)
type Email struct {
Personalizations []Personalization `json:"personalizations"`
From EmailAddress `json:"from"`
Subject string `json:"subject"`
Content []Content `json:"content"`
Attachments []Attachment `json:"attachments"`
}
type Personalization struct {
To []EmailAddress `json:"to"`
}
type EmailAddress struct {
Email string `json:"email"`
Name string `json:"name"`
}
type Content struct {
Type string `json:"type"`
Value string `json:"value"`
}
type Attachment struct {
Type string `json:"type"`
Filename string `json:"filename"`
Content string `json:"content"`
}
func main() {
emailData := Email{
Personalizations: []Personalization{
{
To: []EmailAddress{
{Email: "RECIPIENT@EMAIL.COM", Name: "RECIPIENT NAME"},
},
},
},
From: EmailAddress{Email: "SENDER@EMAIL.COM", Name: "SENDER NAME"},
Subject: "Please find attached!",
Content: []Content{
{Type: "text/plain", Value: "This is the plain text version of the email."},
{Type: "text/html", Value: "<html><body><h1>Hello,</h1><p>This is the HTML version of the email.</p></body></html>"},
},
Attachments: []Attachment{
{
Type: "image/png",
Filename: "mc-logo.png",
Content: "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",
},
},
}
jsonData, err := json.Marshal(emailData)
if err != nil {
fmt.Println("Error marshaling data:", err)
return
}
req, err := http.NewRequest("POST", "https://api.mailchannels.net/tx/v1/send", bytes.NewBuffer(jsonData))
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Set("X-Api-Key", "YOUR-API-KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println("Response:", string(body))
}
Ensure proper error handling and security measures when implementing attachment functionality in your application. Never send an attachment that you received from a user without first scanning it for viruses and malware.
Appendix: Common MIME Types
When adding attachments to your email, it is essential to specify the correct MIME type for the file. Below is a list of common MIME types for various file types:
Image Files
File Type | MIME Type |
---|---|
JPEG Image | image/jpeg |
PNG Image | image/png |
GIF Image | image/gif |
BMP Image | image/bmp |
SVG Image | image/svg+xml |
Document Files
File Type | MIME Type |
---|---|
PDF Document | application/pdf |
Microsoft Word | application/msword |
Microsoft Excel | application/vnd.ms-excel |
Microsoft PowerPoint | application/vnd.ms-powerpoint |
Plain Text | text/plain |
HTML Document | text/html |
Audio Files
File Type | MIME Type |
---|---|
MP3 Audio | audio/mpeg |
WAV Audio | audio/wav |
OGG Audio | audio/ogg |
Video Files
File Type | MIME Type |
---|---|
MP4 Video | video/mp4 |
AVI Video | video/x-msvideo |
WebM Video | video/webm |
Compressed Files
File Type | MIME Type |
---|---|
ZIP Archive | application/zip |
GZIP Archive | application/gzip |
7-Zip Archive | application/x-7z-compressed |
Other Common MIME Types
File Type | MIME Type |
---|---|
JSON | application/json |
XML | application/xml |
CSV | text/csv |
Ensure to select the appropriate MIME type for each file to avoid any issues with email delivery.
Appendix: Auto-Detecting MIME Types
Here are examples in Go and JavaScript that illustrate how you can detect the MIME type of an attachment automatically:
- Go
- JavaScript
Go Code Sample (Using net/http
and mime
packages)
In Go, you can use the net/http
package to detect the MIME type of a file based on its content. Here's a simple example:
package main
import (
"encoding/base64"
"fmt"
"io/ioutil"
"mime"
"net/http"
"path/filepath"
)
func detectMimeType(filePath string) (string, error) {
// Read the file content
data, err := ioutil.ReadFile(filePath)
if err != nil {
return "", err
}
// Detect MIME type based on file content
mimeType := http.DetectContentType(data)
return mimeType, nil
}
func main() {
filePath := "path/to/your/file.png" // Change this to the path of your file
// Detect MIME type
mimeType, err := detectMimeType(filePath)
if err != nil {
fmt.Println("Error detecting MIME type:", err)
return
}
// Convert file content to Base64
fileContent, err := ioutil.ReadFile(filePath)
if err != nil {
fmt.Println("Error reading file:", err)
return
}
encodedContent := base64.StdEncoding.EncodeToString(fileContent)
// Get the filename
fileName := filepath.Base(filePath)
fmt.Printf("MIME Type: %s\nFilename: %s\nBase64 Content: %s\n", mimeType, fileName, encodedContent)
}
JavaScript Code Sample (Using Node.js and mime-types
Package)
In JavaScript, with Node.js, you can use the mime-types
package to detect the MIME type based on the file extension.
First, install the mime-types
package:
npm install mime-types
Now you can use it to detect the MIME type:
const fs = require('fs');
const path = require('path');
const mime = require('mime-types');
// Function to detect MIME type and convert file to Base64
function detectMimeType(filePath) {
const mimeType = mime.lookup(filePath);
// Read file content
const fileContent = fs.readFileSync(filePath);
// Convert file content to Base64
const base64Content = fileContent.toString('base64');
return {
mimeType: mimeType || 'application/octet-stream', // Fallback for unknown types
fileName: path.basename(filePath),
base64Content: base64Content
};
}
// Example usage
const filePath = 'path/to/your/file.png'; // Change this to the path of your file
const attachment = detectMimeType(filePath);
console.log(`MIME Type: ${attachment.mimeType}`);
console.log(`Filename: ${attachment.fileName}`);
console.log(`Base64 Content: ${attachment.base64Content}`);