File Cache attachments
Upload your logo, brochure, or terms PDF once. Reference by id forever. Cut payload size by 95%.
Why File Cache?
The naive way to send attachments is to base64-encode them inline in every request. A 5 MB PDF in a 10k-email batch is 50 GB of JSON. File Cache solves this:
- Upload once → get a
fileId - Reference
{ fileId }in every send - Mailgrid streams from R2, base64-encodes, embeds in SES Raw MIME
- Your request payloads stay tiny
Upload
Node.js example:
const fs = require('node:fs/promises'); const bytes = await fs.readFile('./logo.png'); const base64 = bytes.toString('base64'); const r = await fetch('https://api.mailgrid.space/api/files', { method: 'POST', headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ filename: 'logo.png', content: base64, contentType: 'image/png', }), }); const { data: { id } } = await r.json(); console.log('File id:', id); // → "a1b2c3d4-..."
Reference in a send
{
"from": "hello@yourdomain.com",
"to": "user@example.com",
"subject": "Invoice INV-1024",
"html": "<p>Your invoice is attached.</p>",
"attachments": [
{ "fileId": "a1b2c3d4-...", "filename": "invoice.pdf" }
]
}You can mix inline + by-reference in the same attachments array:
"attachments": [ { "fileId": "logo-id" }, // cached { "filename": "per-customer.pdf", "content": "<base64>" } // inline ]
Limits
- Max 25 MB per file.
- Max 20 attachments per email.
- Total raw MIME size must stay under SES's 40 MB limit.
Auto-expiry
Set expiresAt on upload. A cron job purges expired files from both D1 and R2:
{
"filename": "one-time-link.pdf",
"content": "...",
"expiresAt": "2026-05-20T00:00:00Z"
}