Developer GuideGenerating Attachments

Generating Attachments

Learn how FormaMail automatically generates PDF and Excel attachments from templates when sending emails.

Overview

FormaMail can automatically generate PDF invoices, reports, and Excel spreadsheets from templates and attach them to your emails. Attachments are generated dynamically using variables you provide when sending emails.

Important: Attachment templates are created and configured exclusively in the Dashboard. When you send an email via API, FormaMail automatically generates the attachments based on your template configuration.


How Attachment Generation Works

1. Create Attachment Template (Dashboard)

All attachment template design happens in the dashboard:

  • Navigate to Templates → Attachment Templates
  • Create a PDF or Excel template
  • Design the layout using visual components
  • Define variables for dynamic content
  • Configure attachment settings

See the Attachment Templates User Guide for detailed instructions.

2. Send Email with Attachment (API)

When you send an email that references an attachment template, FormaMail:

  1. Receives your API request
  2. Validates the template and variables
  3. Generates the attachment (PDF/Excel)
  4. Attaches the file to the email
  5. Sends the email with attachment
const response = await fetch('https://api.formamail.com/api/emails/send', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    templateId: 'tmpl_invoice_email',  // Email template with attachment reference
    to: [{ email: 'customer@example.com', name: 'John Doe' }],
    variables: {
      invoiceNumber: 'INV-12345',
      customer: {
        name: 'John Doe',
        company: 'Acme Corp'
      },
      items: [
        { name: 'Product A', quantity: 2, price: 49.99 },
        { name: 'Product B', quantity: 1, price: 29.99 }
      ],
      total: 129.97
    }
  })
});

Attachment Types

FormaMail supports two types of dynamically generated attachments:

PDF Attachments

Generate professional PDF documents:

  • Invoices: Itemized invoices with calculations
  • Reports: Business reports with charts and tables
  • Certificates: Completion certificates
  • Tickets: Event tickets with QR codes
  • Receipts: Payment receipts

Features:

  • Custom branding and styling
  • Charts and graphs
  • Tables with calculations
  • Headers and footers
  • Page breaks
  • Custom fonts

Excel Attachments

Generate Excel spreadsheets:

  • Data exports: Tabular data export
  • Reports: Financial reports with calculated columns
  • Invoices: Editable invoices
  • Statements: Account statements
  • Logs: Activity logs

Features:

  • Multiple worksheets
  • Calculated columns (JavaScript expressions)
  • Cell styling and formatting
  • Charts and graphs
  • Data validation
  • Conditional formatting

Configuring Attachments in Templates

Email Template with Attachment

When creating an email template in the dashboard, you can configure it to include attachments:

  1. Create or edit an email template
  2. In the template settings, add attachment reference
  3. Select the attachment template to use
  4. Configure attachment filename pattern
  5. Save and publish

Example Configuration (Dashboard)

Email Template: “Invoice Email”

  • Template ID: tmpl_invoice_email
  • Subject: Invoice {{invoiceNumber}}
  • Attachments:
    • PDF Template: tmpl_invoice_pdf
    • Filename: Invoice-{{invoiceNumber}}.pdf

API Usage:

// Sending email automatically generates PDF
{
  templateId: 'tmpl_invoice_email',
  to: [{ email: 'customer@example.com' }],
  variables: {
    invoiceNumber: 'INV-12345',
    // ... other variables
  }
}
// Result: Email sent with "Invoice-INV-12345.pdf" attached

Variables in Attachments

Attachments support variable inheritance from email variables, making your API calls simpler:

How Variable Inheritance Works

  1. Email variables (from the variables field) are automatically available to all attachments
  2. Attachment-specific variables (from attachments[].variables) can override or extend inherited values
  3. Priority: Attachment-specific variables override email variables with the same name

This means you don’t need to duplicate variables - provide them once at the email level!

Simple Example

API Request:

{
  templateId: 'tmpl_receipt_email',
  to: [{ email: 'customer@example.com' }],
  variables: {
    receiptNumber: 'RCP-789',
    date: '2025-11-07',
    amount: 99.99,
    paymentMethod: 'Credit Card'
  }
}

Generated PDF contains:

  • Receipt Number: RCP-789
  • Date: November 7, 2025
  • Amount: $99.99
  • Payment Method: Credit Card

Complex Data Example

For invoices with line items:

{
  templateId: 'tmpl_invoice_email',
  to: [{ email: 'customer@example.com' }],
  variables: {
    invoiceNumber: 'INV-12345',
    issueDate: '2025-11-07',
    dueDate: '2025-12-07',
 
    customer: {
      name: 'John Doe',
      company: 'Acme Corp',
      email: 'john@acme.com',
      address: '123 Main St, City, ST 12345'
    },
 
    items: [
      {
        description: 'Professional Services',
        quantity: 10,
        rate: 150.00,
        amount: 1500.00
      },
      {
        description: 'Consulting Fee',
        quantity: 5,
        rate: 200.00,
        amount: 1000.00
      }
    ],
 
    subtotal: 2500.00,
    tax: 250.00,
    total: 2750.00
  }
}

Charts in Attachments

Attachment templates can include charts for visual data representation:

Supported Chart Types

  • Bar Chart: Compare values across categories
  • Line Chart: Show trends over time
  • Pie Chart: Show proportions
  • Area Chart: Show cumulative trends
  • Scatter Chart: Show correlations

Example with Charts

Sales Report with Chart:

{
  templateId: 'tmpl_sales_report',
  to: [{ email: 'manager@company.com' }],
  variables: {
    reportMonth: 'October 2025',
 
    salesByRegion: [
      { region: 'North', sales: 125000 },
      { region: 'South', sales: 98000 },
      { region: 'East', sales: 156000 },
      { region: 'West', sales: 142000 }
    ],
 
    monthlySales: [
      { month: 'July', sales: 98000 },
      { month: 'August', sales: 112000 },
      { month: 'September', sales: 135000 },
      { month: 'October', sales: 156000 }
    ],
 
    totalSales: 521000
  }
}

The attachment template (configured in dashboard) renders:

  • Bar chart showing sales by region
  • Line chart showing monthly trend
  • Summary table with totals

Calculated Columns

Attachments support calculated columns using JavaScript expressions. These work identically for both PDF and Excel outputs.

Configuration (Dashboard)

When creating an attachment template in the dashboard:

  1. Add table components
  2. Enable “Calculated Column” for computed values
  3. Write JavaScript expressions (e.g., row.quantity * row.price)
  4. Expressions are evaluated when the attachment is generated

Example: Invoice with Calculations

API Request:

{
  templateId: 'tmpl_invoice',
  to: [{ email: 'customer@example.com' }],
  variables: {
    invoiceNumber: 'INV-12345',
    items: [
      { description: 'Item A', quantity: 2, price: 49.99 },
      { description: 'Item B', quantity: 1, price: 29.99 },
      { description: 'Item C', quantity: 3, price: 19.99 }
    ]
  }
}

Generated Attachment contains:

  • Description column (field: description)
  • Quantity column (field: quantity)
  • Price column (field: price, formatted as currency)
  • Amount column (calculated: row.quantity * row.price)

Attachment File Names

Control attachment filenames using template variables:

Static Filename (Dashboard Configuration)

Invoice.pdf

Dynamic Filename (Dashboard Configuration)

Invoice-{{invoiceNumber}}.pdf
Report-{{month}}-{{year}}.xlsx
Receipt-{{date}}.pdf

API Usage:

{
  templateId: 'tmpl_invoice_email',
  to: [{ email: 'customer@example.com' }],
  variables: {
    invoiceNumber: 'INV-12345'
  }
}
// Generated filename: "Invoice-INV-12345.pdf"

Multiple Attachments

Email templates can be configured to generate multiple attachments:

Dashboard Configuration

Email Template Settings:

  • Attachment 1: Invoice PDF (tmpl_invoice_pdf)
  • Attachment 2: Detailed Report Excel (tmpl_detailed_report_excel)

API Usage:

{
  templateId: 'tmpl_invoice_with_report',
  to: [{ email: 'customer@example.com' }],
  variables: {
    invoiceNumber: 'INV-12345',
    // Email template variables
  },
  attachments: [
    {
      attachmentTemplateId: 'tmpl_invoice_pdf',
      variables: { /* Override or provide attachment-specific variables */ }
    },
    {
      attachmentTemplateId: 'tmpl_detailed_report_excel',
      variables: { /* Override or provide attachment-specific variables */ }
    }
  ]
}
// Result: Email with both Invoice.pdf and Report.xlsx attached

Attachment Generation Status

Successful Generation

{
  "id": "email_abc123",
  "status": "sent",
  "attachments": [
    {
      "id": "attach_xyz789",
      "filename": "Invoice-INV-12345.pdf",
      "size": 45678,
      "contentType": "application/pdf",
      "status": "completed"
    }
  ]
}

Generation Failed

{
  "statusCode": 500,
  "code": "ERR_ATTACH_001",
  "message": "Attachment generation failed",
  "relatedInfo": {
    "templateId": "tmpl_invoice_pdf",
    "error": "Invalid chart data format"
  }
}

Attachment Errors

Missing Required Data

If attachment template requires data not provided:

{
  "statusCode": 400,
  "code": "ERR_TMPL_004",
  "message": "Missing required template variable",
  "relatedInfo": {
    "variable": "items",
    "templateId": "tmpl_invoice_pdf"
  }
}

Solution: Provide all required variables for both email and attachment templates.

Invalid Data Format

If data doesn’t match expected format:

{
  "statusCode": 400,
  "code": "ERR_ATTACH_002",
  "message": "Invalid attachment data format",
  "relatedInfo": {
    "field": "items",
    "expected": "array",
    "received": "string"
  }
}

Solution: Ensure data types match template expectations (arrays for tables, objects for nested data, etc.).


Best Practices

1. Use Meaningful Variable Names

âś… Good:

{
  variables: {
    invoiceNumber: 'INV-12345',
    lineItems: [...],
    customerDetails: {...}
  }
}

❌ Bad:

{
  variables: {
    inv: 'INV-12345',
    items: [...],
    cust: {...}
  }
}

2. Validate Data Before Sending

function validateInvoiceData(data) {
  if (!data.invoiceNumber) {
    throw new Error('Invoice number required');
  }
  if (!Array.isArray(data.items) || data.items.length === 0) {
    throw new Error('Invoice must have at least one item');
  }
  if (typeof data.total !== 'number') {
    throw new Error('Total must be a number');
  }
  return true;
}
 
// Use it
validateInvoiceData(invoiceData);
 
await sendEmail({
  templateId: 'tmpl_invoice_email',
  to: [{ email: customer.email }],
  variables: invoiceData
});

3. Test Attachments with Real Data

Always test attachments with production-like data:

const testData = {
  invoiceNumber: 'TEST-001',
  customer: {
    name: 'Test Customer',
    company: 'Test Corp',
    email: 'test@example.com'
  },
  items: [
    { description: 'Test Product A', quantity: 2, price: 49.99 },
    { description: 'Test Product B', quantity: 1, price: 29.99 }
  ],
  total: 129.97
};
 
// Send test email
await sendEmail({
  templateId: 'tmpl_invoice_email',
  to: [{ email: 'test@yourdomain.com' }],
  variables: testData
});

4. Handle Large Attachments

Be mindful of attachment sizes:

  • Keep PDFs under 5MB
  • Limit Excel rows to reasonable amounts (< 10,000 rows)
  • Optimize images in PDFs
  • Consider pagination for large reports

5. Use Descriptive Filenames

Include relevant information in filenames:

// Good filenames
Invoice-{{invoiceNumber}}-{{date}}.pdf
Report-{{month}}-{{year}}.xlsx
Receipt-{{transactionId}}.pdf
 
// Examples:
// Invoice-INV-12345-2025-11-07.pdf
// Report-October-2025.xlsx
// Receipt-TXN-789.pdf

Common Use Cases

Invoice with PDF

{
  templateId: 'tmpl_invoice_email',
  to: [{ email: 'customer@example.com' }],
  variables: {
    invoiceNumber: 'INV-12345',
    issueDate: '2025-11-07',
    dueDate: '2025-12-07',
    customer: {
      name: 'John Doe',
      company: 'Acme Corp'
    },
    items: [
      { description: 'Service A', quantity: 10, rate: 150, amount: 1500 },
      { description: 'Service B', quantity: 5, rate: 200, amount: 1000 }
    ],
    subtotal: 2500,
    tax: 250,
    total: 2750
  }
}

Sales Report with Excel

{
  templateId: 'tmpl_sales_report',
  to: [{ email: 'manager@company.com' }],
  variables: {
    reportMonth: 'October 2025',
    salesData: [
      { date: '2025-10-01', revenue: 5000, orders: 50 },
      { date: '2025-10-02', revenue: 6200, orders: 62 },
      // ... more daily data
    ],
    totalRevenue: 156000,
    totalOrders: 1540
  }
}

Certificate with PDF

{
  templateId: 'tmpl_certificate_email',
  to: [{ email: 'student@example.com' }],
  variables: {
    studentName: 'John Doe',
    courseName: 'Advanced JavaScript',
    completionDate: '2025-11-07',
    instructorName: 'Jane Smith',
    certificateId: 'CERT-2025-12345'
  }
}

Performance Considerations

Generation Time

Attachment generation adds processing time:

  • Simple PDF: 1-3 seconds
  • PDF with charts: 3-5 seconds
  • Excel with formulas: 2-4 seconds
  • Large Excel (1000+ rows): 5-10 seconds

Optimization Tips

  1. Limit data size: Send only necessary data
  2. Use pagination: For large datasets, generate multiple reports
  3. Optimize images: Compress images before including in PDFs
  4. Cache templates: Templates are cached automatically
  5. Test performance: Monitor generation times with your data

Troubleshooting

Attachment Not Generated

Possible causes:

  1. Template not published in dashboard
  2. Missing required variables
  3. Invalid data format
  4. Template configuration error

Solution:

  • Check template status in dashboard
  • Verify all required variables are provided
  • Validate data types match expectations
  • Review error message in API response

Attachment Looks Wrong

Possible causes:

  1. Variable values not formatted correctly
  2. Template styling issues
  3. Missing data

Solution:

  • Test template with same data in dashboard preview
  • Check variable formatting (dates, currencies, etc.)
  • Update template design in dashboard

Next Steps


Related: Sending Emails | Working with Templates | Attachments User Guide