Skip to Content
Public APISend with Attachments

Send with attachments

Both transactional send endpoints accept an attachments[] array — POST /public/email/send and POST /public/email/send-template. Each attachment carries the file bytes inline as base64; we build the multipart/mixed MIME structure for you, DKIM-sign it with your verified sender domain, and ship it to the recipient through the same self-hosted pipeline as plain-body emails.

Attachment object

Each entry in attachments[] is shaped like this:

{ "filename": "invoice-2026-04.pdf", "content_type": "application/pdf", "content_base64": "<base64-encoded file bytes>", "content_id": "logo-header", "inline": false }
FieldTypeRequiredMeaning
filenamestringyesDisplayed by the recipient’s mail client. Directory separators + control chars are stripped automatically. Max 256 chars.
content_typestringoptionalMIME type (e.g. application/pdf). When omitted, we infer from the filename extension and fall back to application/octet-stream. Max 256 chars.
content_base64stringyesStandard base64 encoding of the file bytes. Not URL-safe base64 — use the standard alphabet.
content_idstringoptionalSets Content-ID so HTML can reference the attachment as <img src="cid:logo-header">. Pair with inline: true.
inlinebooleanoptionalWhen true, sets Content-Disposition: inline (image renders in the body). When false (default), sets attachment (file appears in the recipient’s attachments list).

Limits

CapValueWhat happens when exceeded
Files per message20Returns 400 INVALID_ATTACHMENT with "max 20 attachments per message"
Total decoded bytes10 MiBReturns 400 INVALID_ATTACHMENT with the bytes-cap message. Sum runs across all attachments — a single 10.1 MiB PDF is rejected just like 11 × 1 MiB files.
Filename length256 charsRejected at validation.
Content-Type length256 charsRejected at validation.

Blocked file types

Executable + script extensions are refused at the API layer because recipient mail providers (Gmail, Outlook, corporate gateways) block them outright — sending one would cost a wallet deduction for a guaranteed bounce. Blocked extensions:

.exe .bat .cmd .com .scr .msi .vbs .vbe .js .jse .wsf .wsh .ps1 .dll .jar .app .sh .pl .py .lnk

Workaround: bundle them inside a .zip. ZIPs are allowed.

Example — single PDF

ATT=$(base64 -i invoice.pdf | tr -d '\n') curl https://apis.splashifypro.com/api/v1/public/email/send \ -H "Authorization: Basic YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"to\": \"customer@example.com\", \"subject\": \"Invoice for March\", \"html\": \"<p>Hi! Your invoice for March is attached.</p>\", \"from_name\": \"Acme Store\", \"from_email\": \"billing@your-domain.com\", \"attachments\": [ { \"filename\": \"invoice-march-2026.pdf\", \"content_type\": \"application/pdf\", \"content_base64\": \"$ATT\" } ] }"

Example — Node.js (multiple files)

import { readFileSync } from 'node:fs' const toAtt = (path, contentType) => ({ filename: path.split('/').pop(), content_type: contentType, content_base64: readFileSync(path).toString('base64'), }) const r = await fetch('https://apis.splashifypro.com/api/v1/public/email/send', { method: 'POST', headers: { 'Authorization': `Basic ${process.env.SPLASHIFY_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ to: 'customer@example.com', subject: 'Your March documents', html: '<p>Attached: invoice + receipt + signed contract.</p>', from_name: 'Acme Store', from_email: 'billing@your-domain.com', attachments: [ toAtt('./invoice.pdf', 'application/pdf'), toAtt('./receipt.pdf', 'application/pdf'), toAtt('./contract.pdf', 'application/pdf'), ], }), }) console.log(await r.json())

Example — Python

import base64, requests, os def att(path, ct): with open(path, 'rb') as f: return { 'filename': os.path.basename(path), 'content_type': ct, 'content_base64': base64.b64encode(f.read()).decode(), } r = requests.post( 'https://apis.splashifypro.com/api/v1/public/email/send', headers={'Authorization': f"Basic {os.environ['SPLASHIFY_API_KEY']}"}, json={ 'to': 'customer@example.com', 'subject': 'Attached photo', 'html': "<p>Here's the photo from your visit.</p>", 'from_name': 'Acme Store', 'from_email': 'support@your-domain.com', 'attachments': [att('./photo.jpg', 'image/jpeg')], }, ) print(r.json())

Example — Inline image (CID reference)

When you want the image to render inside the email body instead of as a separate downloadable file, use inline: true + content_id, then reference it from your HTML with cid::

{ "to": "customer@example.com", "subject": "Today's newsletter", "html": "<p>Welcome!</p><img src=\"cid:hero-banner\" />", "from_name": "Acme Store", "from_email": "newsletter@your-domain.com", "attachments": [ { "filename": "banner.png", "content_type": "image/png", "content_base64": "iVBORw0KGgo…", "content_id": "hero-banner", "inline": true } ] }

Most modern mail clients (Gmail web + mobile, Outlook, Apple Mail) render inline images correctly. A few hardened corporate gateways strip them — the file falls back to a regular attachment in those.

Using attachments with templates

The same attachments[] field is accepted on POST /public/email/send-template. The files are attached to the rendered template output exactly as if you’d inlined the HTML on /send:

{ "to": "customer@example.com", "template_id": "0190ed42-1234-7c8e-9f0a-abcdef012345", "variables": { "first_name": "Alice", "invoice_no": "INV-1042" }, "from_email": "billing@your-domain.com", "attachments": [ { "filename": "invoice-1042.pdf", "content_type": "application/pdf", "content_base64": "JVBERi0xLjcKJeLjz9MK…" } ] }

Errors

StatusCodeReason
400INVALID_ATTACHMENTToo many files, total size exceeded, blocked extension, invalid base64, or empty content
400from_email domain '<x>' is not verified. (same as plain send)
401Missing / invalid API key
402email_marketing not enabled on your plan
429Per-plan rate limit; check Retry-After header

Pricing

Attachments do not incur a per-byte charge. You’re billed at the per-recipient transactional rate (₹0.05/email beyond the daily-100 free tier + reseller markup if any), regardless of attachment size. The only practical cost is the 10 MiB total cap which limits how big each individual message can be.

Best practices

  • Compress where you can. A PDF with images compressed to 200 dpi vs 600 dpi can be 5× smaller and still look perfect at on-screen resolution. Smaller messages deliver faster + use less of your 10 MiB budget.
  • Use links for files > 5 MiB. Recipient mail providers throttle large messages and some flag them as suspicious. For anything bigger, host on object storage and put a download link in the body.
  • Set content_type explicitly when you can — saves us a filename-extension guess. The mail client’s “open with” picker uses this header.
  • Prefer real filenames. Generic attachment.pdf is allowed but hurts deliverability slightly (Gmail’s spam filter weights template-shaped filenames). invoice-march-2026.pdf is better.

See also