Docs
Sending emails

Sending emails

Sending emails through Freesend.

API Endpoint

Prerequisites

Steps

Bearer Token

Ensure you put your API Key as a Bearer token in the Authorization header of the HTTP request:

'Authorization': `Bearer YOUR_API_KEY`

HTTP Body

{
    "fromName": "Your Company",  // (optional) Display name for the sender
    "fromEmail": "hello@yourdomain.com",  // Sender email address
    "to": "recipient@email.com",  // Receiver address
    "subject": "Email sent from Freesend!",  // Subject for the email
    "html": "<h1>Yay! You got the email.</h1>",  // (optional) HTML format of the email body
    "text": "Yay! You got the email.",  // (optional) Text format of the email body
    "attachments": [  // (optional) Array of attachments
        {
            "filename": "invoice.pdf",  // Name of the file
            "content": "base64EncodedContent",  // Base64 encoded file content (optional if url is provided)
            "url": "https://example.com/file.pdf",  // URL to external file (optional if content is provided)
            "contentType": "application/pdf"  // (optional) MIME type
        }
    ]
}

API Endpoint

Send a POST Request to https://freesend.metafog.io/api/send-email

Example Usage

💡 Pro Tip: For a better developer experience, consider using our Freesend SDK which provides type safety, error handling, and a cleaner API.

Send attachments from a remote file

Include the url parameter to send attachments from a remote file. This parameter accepts a URL to the file you want to attach. Define the file name that will be attached using the filename parameter.

curl -X POST https://freesend.metafog.io/api/send-email \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fromName": "Your Company",
    "fromEmail": "hello@yourdomain.com",
    "to": "recipient@email.com",
    "subject": "Email with external attachments!",
    "html": "<h1>Please find the files attached.</h1>",
    "text": "Please find the files attached.",
    "attachments": [
      {
        "filename": "monthly-report.pdf",
        "url": "https://example.com/reports/monthly-report.pdf",
        "contentType": "application/pdf"
      },
      {
        "filename": "company-logo.png",
        "url": "https://example.com/images/logo.png",
        "contentType": "image/png"
      }
    ]
  }'

Send attachments from a local file

Include the content parameter to send attachments from a local file. This parameter accepts the Base64 encoded content of the file you want to attach. Define the file name that will be attached using the filename parameter.

curl -X POST https://freesend.metafog.io/api/send-email \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fromName": "Your Company",
    "fromEmail": "hello@yourdomain.com",
    "to": "recipient@email.com",
    "subject": "Email with attachment from Freesend!",
    "html": "<h1>Please find the invoice attached.</h1>",
    "text": "Please find the invoice attached.",
    "attachments": [
      {
        "filename": "invoice.pdf",
        "content": "JVBERi0xLjQKJcOkw7zDtsOmCjUgMCBvYmoKPDwKL0ZpbHRlciAvRmxhdGVEZWNvZGUKL0xlbmd0aC...",
        "contentType": "application/pdf"
      }
    ]
  }'

Field Reference

Main Fields

FieldTypeRequiredDescription
fromNamestringNoDisplay name for the sender (e.g., "Your Company")
fromEmailstringYesSender email address
tostringYesRecipient email address
subjectstringYesEmail subject line
htmlstringNo*HTML content of the email
textstringNo*Plain text content of the email
attachmentsarrayNoArray of attachment objects (see below)

*At least one of html or text is required.

Attachment Object Fields

FieldTypeRequiredDescription
filenamestringYesName of the attachment file
contentstringNo*Base64 encoded file content
urlstringNo*URL to external file (HTTP/HTTPS only)
contentTypestringNoMIME type (e.g., "application/pdf", "image/png")

*Either content or url is required, but not both.

Attachment Examples

// Base64 content (recommended for API usage)
{
  "filename": "invoice.pdf",
  "content": "JVBERi0xLjQKJcOkw7zDtsOmCjUgMCBvYmoKPDwK...",
  "contentType": "application/pdf"
}
 
// URL-based attachment (external file)
{
  "filename": "report.pdf",
  "url": "https://example.com/reports/monthly-report.pdf",
  "contentType": "application/pdf"
}
 
// Text attachment with base64
{
  "filename": "notes.txt", 
  "content": "SGVsbG8gV29ybGQh",  // "Hello World!" in base64
  "contentType": "text/plain"
}
 
// Image attachment from URL
{
  "filename": "logo.png",
  "url": "https://example.com/images/company-logo.png",
  "contentType": "image/png"
}
 
// Mixed attachments (base64 + URL)
{
  "attachments": [
    {
      "filename": "invoice.pdf",
      "content": "base64EncodedPDF...",
      "contentType": "application/pdf"
    },
    {
      "filename": "receipt.jpg",
      "url": "https://example.com/receipts/12345.jpg",
      "contentType": "image/jpeg"
    }
  ]
}

Using the SDK Instead?

If you prefer a more developer-friendly experience with type safety, error handling, and simplified API calls, we provide official SDKs for multiple programming languages.

Available SDKs

  • JavaScript/TypeScript - Full TypeScript support, Node.js & browser compatibility
  • Python - Python SDK (Coming Soon)
  • Go - Go SDK (Coming Soon)
  • PHP - PHP SDK (Coming Soon)
  • Ruby - Ruby SDK (Coming Soon)

Benefits of Using an SDK

  • Type Safety - Full type definitions and IntelliSense
  • 🛡️ Error Handling - Proper error types and status codes
  • 🔧 Simplified API - No need to handle HTTP requests manually
  • 📎 Attachment Support - Easy file handling with base64 encoding
  • 🌐 Cross-Platform - Works in Node.js and browsers
  • ⚙️ Customizable - Support for custom base URLs

For complete SDK documentation, examples, and advanced usage, visit our SDK documentation.

Response

Success Response (200)

{
  "message": "Email sent successfully"
}

Error Responses

400 Bad Request - Missing Authorization Header

{
  "error": "Authorization header not found."
}

400 Bad Request - Invalid Authorization Format

{
  "error": "Invalid authorization header. Create a Bearer Token."
}

400 Bad Request - Missing API Key

{
  "error": "Invalid or missing API Key."
}

400 Bad Request - Missing Required Fields

{
  "error": "Missing required field 'fromEmail'."
}
{
  "error": "Missing required field 'to'."
}
{
  "error": "Missing required field 'subject'."
}
{
  "error": "Missing required field 'text' or 'html'."
}

400 Bad Request - Inactive API Key

{
  "error": "This API key is currently inactive."
}

403 Forbidden - Invalid API Key

{
  "error": "Invalid API Key or no SMTP configuration found."
}

400 Bad Request - Invalid Attachment Configuration

{
  "error": "Attachment 'filename.pdf' must have either 'content' or 'url' field."
}
{
  "error": "Attachment 'filename.pdf' cannot have both 'content' and 'url' fields. Use either one."
}
{
  "error": "Attachment 'filename.pdf' has invalid URL protocol. Only HTTP and HTTPS are allowed."
}
{
  "error": "Attachment 'filename.pdf' has invalid URL format."
}
{
  "error": "Attachment 'filename.pdf' URL is not allowed. Internal/local URLs are blocked for security."
}
{
  "error": "Attachment 'filename.pdf' URL port is not allowed. Internal service ports are blocked for security."
}
{
  "error": "Attachment 'filename.pdf' URL is not allowed. Access to the hosting server is blocked for security."
}

500 Internal Server Error - Email Sending Failed

{
  "error": "Error sending email: [specific error message]"
}

500 Internal Server Error - URL Fetch Failed

{
  "error": "Error processing attachment 'filename.pdf': Failed to fetch attachment from URL: 404 Not Found"
}
{
  "error": "Error processing attachment 'filename.pdf': Timeout fetching attachment from URL (30s limit)"
}
{
  "error": "Error processing attachment 'filename.pdf': Attachment file too large: 30MB (max 25MB)"
}

502 Bad Gateway - Transport Error

{
  "error": "Could not create the transporter object."
}

Common MIME Types

File ExtensionMIME Type
.pdfapplication/pdf
.jpg, .jpegimage/jpeg
.pngimage/png
.gifimage/gif
.txttext/plain
.htmltext/html
.csstext/css
.jsapplication/javascript
.jsonapplication/json
.xmlapplication/xml
.csvtext/csv
.zipapplication/zip
.xlsxapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.docxapplication/vnd.openxmlformats-officedocument.wordprocessingml.document
.pptxapplication/vnd.openxmlformats-officedocument.presentationml.presentation

Security Note

Important: Freesend supports two types of attachments:

  • Base64-encoded content: For direct file uploads (recommended for smaller files)
  • URL-based attachments: For external files accessible via HTTP/HTTPS URLs

Security Protections:

  • Server-side file paths are not supported
  • Internal/local URLs are blocked (localhost, private IPs, .local domains)
  • Access to the hosting server is blocked
  • Common internal service ports are blocked
  • Only public, external URLs are allowed

Best Practices

File Size Limits

  • Keep base64 attachments under 25MB for best performance
  • For larger files, consider using URL-based attachments instead
  • URL-based attachments can handle larger files since they're downloaded on-demand

Base64 Encoding

  • Always encode binary files as base64
  • Remove any data URL prefixes (e.g., data:application/pdf;base64,)
  • Use proper content type headers for better email client compatibility

URL-based Attachments

  • Ensure URLs are publicly accessible and return proper HTTP status codes
  • Use HTTPS URLs for security
  • URLs should return the actual file content, not redirects
  • File size limit: 25MB per attachment
  • Timeout limit: 30 seconds per URL fetch
  • URLs must be accessible from Freesend's servers
  • Security: Only external, public URLs are allowed (internal/local URLs are blocked)

Multiple Attachments

{
  "attachments": [
    {
      "filename": "invoice.pdf",
      "content": "base64EncodedPDF...",
      "contentType": "application/pdf"
    },
    {
      "filename": "receipt.jpg",
      "url": "https://example.com/receipts/12345.jpg",
      "contentType": "image/jpeg"
    },
    {
      "filename": "report.pdf",
      "url": "https://api.example.com/reports/monthly.pdf",
      "contentType": "application/pdf"
    }
  ]
}