# CSV File Format Reference
This document explains the CSV file formats used by the batch and merge commands.
## General Rules
- **Required column**: `email` - Must be present in all CSV files
- **Optional column**: `type` - Specifies recipient type (values: `to`, `cc`, `bcc`)
- Defaults to `to` if not specified or if value is empty
- Column names are case-insensitive
- Encoding: UTF-8
---
## Batch Command
### Purpose
Send the **same email** to multiple recipients with optional rate limiting.
### CSV Format
#### Basic (TO recipients only)
```csv
email
user1@example.com
user2@example.com
user3@example.com
```
**Example file**: `csv-examples/batch-simple.csv`
#### With Recipient Types
```csv
email,type
primary@example.com,to
manager@example.com,cc
supervisor@example.com,cc
admin@example.com,bcc
audit@example.com,bcc
recipient2@example.com,to
```
**Example file**: `csv-examples/batch-with-types.csv`
### Notes
- All columns except `email` and `type` are **ignored** in batch mode
- The same email content is sent to all recipients
- Use `--batch-size` and `--delay-minutes` for rate limiting
- Progress is tracked in `<filename>.progress` file
### Example Command
```bash
cargo run -- batch \
--profile work \
--recipients csv-examples/batch-simple.csv \
--subject "Monthly Newsletter" \
--template ./templates/newsletter.html \
--attachments ./files/brochure.pdf \
--batch-size 25 \
--delay-minutes 5 \
--limit 1000
```
---
## Merge Command
### Purpose
Send **personalized emails** to each recipient using template variables.
### CSV Format
#### Basic Template Variables
```csv
email,name,event,date
john@example.com,John Doe,Tech Summit 2025,January 15
jane@example.com,Jane Smith,Tech Summit 2025,January 15
bob@example.com,Bob Johnson,Workshop Series,February 10
```
**Example file**: `csv-examples/merge-basic.csv`
**Template usage**: In your HTML template, use `{{name}}`, `{{event}}`, `{{date}}`
#### With Per-Recipient Attachments
```csv
email,name,event,attachment
john@example.com,John Doe,Workshop A,./certificates/john-cert.pdf
jane@example.com,Jane Smith,Workshop B,./certificates/jane-cert.pdf
bob@example.com,Bob Johnson,Workshop A,./certificates/bob-cert.pdf
```
**Example file**: `csv-examples/merge-with-attachments.csv`
**Special column**: `attachment` or `attachments` - File path for recipient-specific attachment
#### Full Example (All Features)
```csv
email,name,event,date,score,grade,type,attachment
student1@example.com,Alice Brown,Python Course,2025-01-20,95,A,to,./certs/alice.pdf
student2@example.com,Charlie Davis,Python Course,2025-01-20,88,B+,to,./certs/charlie.pdf
instructor@example.com,Dr. Smith,Python Course,2025-01-20,,,cc,
admin@example.com,Admin,Python Course,2025-01-20,,,bcc,
```
**Example file**: `csv-examples/merge-full.csv`
### Notes
- All columns (except `email`, `type`, `attachment`/`attachments`) become **template variables**
- Each recipient gets a unique email with their specific data
- Empty values are allowed (template will receive empty string)
- Use `--delay-seconds` to add delay between sends (default: 10)
### Example Command
```bash
cargo run -- merge \
--profile personal \
--data csv-examples/merge-basic.csv \
--subject "Your Certificate - {{event}}" \
--template ./templates/certificate.html \
--delay-seconds 5 \
--limit 100
```
### Template Example
```html
<!DOCTYPE html>
<html>
<body>
<h1>Certificate of Completion</h1>
<p>This certifies that <strong>{{name}}</strong> has completed:</p>
<p>Event: {{event}}</p>
<p>Date: {{date}}</p>
<p>Score: {{score}}</p>
<p>Grade: {{grade}}</p>
</body>
</html>
```
---
## Comparison Table
| Same content for all | ✅ Yes | ❌ No (personalized) |
| Template variables | ❌ No | ✅ Yes (all columns) |
| Per-recipient attachments | ❌ No | ✅ Yes (via CSV) |
| Global attachments | ✅ Yes (--attachments) | ❌ No |
| Recipient types (TO/CC/BCC) | ✅ Yes (via `type` column) | ✅ Yes (via `type` column) |
| Rate limiting | ✅ Yes (batch-size + delay) | ✅ Yes (delay-seconds) |
| Progress tracking | ✅ Yes (.progress file) | ❌ No |
| Use case | Newsletters, announcements | Certificates, personalized content |
---
## Progress Tracking (Batch Only)
When using batch mode, a `.progress` file is created:
**File**: `<csv-filename>.progress`
**Format**:
```json
{
"last_processed_line": 150,
"processed_emails": 6,
"total_emails": 500,
"last_reset_date": "2025-01-15T14:30:00Z"
}
```
**Fields**:
- `last_processed_line`: Number of CSV rows processed (resume point)
- `processed_emails`: Number of batches sent today
- `total_emails`: Total rows in CSV
- `last_reset_date`: Resets daily count at midnight
**Resume**: The command automatically resumes from `last_processed_line` if interrupted
---
## Example Files
The project includes example CSV files in the `csv-examples/` directory:
1. **batch-simple.csv** - Basic batch with TO recipients only
2. **batch-with-types.csv** - Batch with TO/CC/BCC recipient types
3. **merge-basic.csv** - Simple mail merge with template variables
4. **merge-with-attachments.csv** - Merge with per-recipient attachments
5. **merge-full.csv** - Complete example with all features (types, attachments, variables)
---
## Tips
### For Batch Sending
- Start with small `--limit` values to test (e.g., `--limit 5`)
- Use appropriate `--batch-size` to avoid SMTP rate limits (default: 25)
- Add `--delay-minutes` between batches for large sends (default: 5)
- Check the `.progress` file to monitor progress
- Resume automatically after interruption - progress is preserved
### For Mail Merge
- Test your template with a small CSV first
- Use descriptive column names (they become template variables)
- Empty values in CSV columns are handled gracefully
- Subject line can also use template variables: `--subject "Certificate - {{name}}"`
- Adjust `--delay-seconds` based on your SMTP provider limits (default: 10)
### Common Mistakes
- ❌ Forgetting the `email` column in CSV
- ❌ Using wrong case for recipient types (use lowercase: `to`, `cc`, `bcc`)
- ❌ Trying to use template variables in batch mode (use merge instead)
- ❌ Expecting global attachments to work in merge mode (use CSV `attachment` column)