Email attachments
Customer.io doesn't support attachments of any type in Automations or Broadcasts. But, there are other, better ways to send files to recipients!
Why you shouldn’t send attachments
Sending attachments can create problems for your deliverability. Here’s a non-exhaustive list of potential problems stemming from attachments:
- Email attachments are often used to hide viruses and malware, so they are more likely to end up in spam folders or flagged as potentially malicious.
- Some email servers have strict policies around message size limits and/or attachments which can cause messages to bounce.
- Attachments impose a larger download for recipients, which can impact their data consumption and/or lead them to ignore your email.
All of these can damage your deliverability.
Send a link rather than an attachment
If you want to send a file to your recipients, the best approach is to send them a link to a landing page where they can download the file.
- You should host the file online—either on your own server or a cloud storage service like AWS S3, Google Drive, Dropbox, Box, etc.
- Create a page that links to the file. Your hosting service might already create one for you. Otherwise, you’ll need to add a page to your website.
- Copy that page’s URL and use it in your email.
Send attachments with transactional messages
In cases where an attachment is unavoidable, you can send them using our Transactional API through an attachments parameter.
With this parameter, you can specify a dictionary of attachments where the filename is the key and the value is the base64-encoded content. The total size of all attachments must be less than 2 MB. Do note that some file extensions are restricted.
Attach a file
The attachments parameter expects file contents as a base64-encoded string, not a path or a URL. Base64 encoding turns binary file data into text that you can include in a JSON request body.
Our official libraries encode the file for you. Pass the file to the request’s attach method, and the library encodes the contents and adds them to the attachments object under the filename you give it. The examples below attach a file named receipt.pdf.
Go
req := customerio.SendEmailRequest{
TransactionalMessageID: "purchase_confirmation",
To: "customer@example.com",
Identifiers: map[string]string{"id": "customer_1"},
}
file, err := os.Open("receipt.pdf")
if err != nil {
return err
}
defer file.Close()
if err := req.Attach("receipt.pdf", file); err != nil {
return err
}Node.js
const fs = require("fs");
const { SendEmailRequest } = require("customerio-node");
const req = new SendEmailRequest({
transactional_message_id: "purchase_confirmation",
to: "customer@example.com",
identifiers: { id: "customer_1" },
});
req.attach("receipt.pdf", fs.readFileSync("receipt.pdf"));Python
from customerio import SendEmailRequest
request = SendEmailRequest(
transactional_message_id="purchase_confirmation",
to="customer@example.com",
identifiers={"id": "customer_1"},
)
with open("receipt.pdf", "rb") as file:
request.attach("receipt.pdf", file.read())Ruby
require "customerio"
request = Customerio::SendEmailRequest.new(
transactional_message_id: "purchase_confirmation",
to: "customer@example.com",
identifiers: { id: "customer_1" }
)
request.attach("receipt.pdf", File.binread("receipt.pdf"))If you build the request body yourself, encode the file with your language’s standard base64 library and use the resulting string as the file’s value in your attachments object. Go has base64.StdEncoding, Node.js has Buffer.from(data).toString("base64"), Python has base64.b64encode, and Ruby has Base64.strict_encode64.
The 2 MB limit applies to the encoded string rather than the file it came from, and base64 encoding grows a file by about a third. That leaves room for roughly 1.5 MB of original files. If your attachments go over the limit, the API returns a 413 error.