> ## Documentation Index
> Fetch the complete documentation index at: https://docs.notifuse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Transactional API

> The Transactional API enables you to send event-driven emails directly from your application. Unlike broadcast campaigns, transactional emails are sent individually to specific contacts in real-time with automatic contact management, making them perfect for user-triggered notifications and automated workflows.

<img src="https://mintcdn.com/notifuse/Gw4P7NadUImyvZfw/assets/screenshots/transactional_api.png?fit=max&auto=format&n=Gw4P7NadUImyvZfw&q=85&s=21f4b90f2a864d9c410b4f25cb0a03ad" alt="Transactional templates screenshot" width="3005" height="1929" data-path="assets/screenshots/transactional_api.png" />

## Common Use Cases

```
- Password Reset
- Order Confirmation
- Welcome Email
- Account Deletion
- Purchase Receipt
- Shipping Notifications
- Account Verification
- Payment Confirmations
```

## Key Features

### Automatic Contact Management

* **Contact Upsert**: Contacts are automatically created or updated before sending
* **Profile Enrichment**: Template data is automatically merged with existing contact profile information
* **Data Consistency**: Ensures contact information is always current

### Template Data Enrichment

When you send a transactional email, Notifuse automatically:

1. **Looks up the contact** by email address in your workspace
2. **Merges your API data** with the existing contact profile
3. **Enriches the template** with the complete contact information
4. **Sends the personalized email** with all available data

**Example**: If your API sends `{"order_id": "12345"}` but the contact profile contains `{"first_name": "John", "last_name": "Doe"}`, the template will have access to both the order data and the contact's full profile.

### Deduplication with External ID

* **Prevent Duplicates**: Use `external_id` to prevent sending the same notification multiple times
* **Idempotent Requests**: Notifications with the same `external_id` will only be sent once
* **Custom Identifiers**: Use your own unique identifiers (order IDs, event IDs, etc.)

**Example**: Setting `external_id: "order-12345"` ensures that even if your system sends the same order confirmation multiple times, the email will only be delivered once.

### Email Delivery Options

Configure email routing with flexible options:

* **From Name**: Override the default sender display name
* **Subject**: Override the template subject line (supports Liquid templating)
* **Reply-To**: Set custom reply-to addresses
* **CC**: Add carbon copy recipients
* **BCC**: Include blind carbon copy recipients
* **Attachments**: Attach files to emails (PDFs, images, documents, etc.)

## API Endpoint

Send transactional emails using a simple POST request:

### Request

```bash theme={null}
curl -X POST \
  "https://v3.notifuse.com/api/transactional.send" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
  "workspace_id": "your_workspace",
  "notification": {
    "id": "password_reset",
    "external_id": "pwd-reset-user123-20240101",
    "channels": ["email"],
    "contact": {
      "email": "user@example.com"
    },
    "data": {
      "reset_token": "abc123",
      "expiry_time": "2024-01-01T12:00:00Z"
    },
    "metadata": {
      "user_id": "12345",
      "trigger": "forgot_password",
      "source": "web_app"
    },
    "email_options": {
      "from_name": "Support Team",
      "subject": "Reset your password, {{ contact.first_name }}",
      "reply_to": "support@yourcompany.com",
      "cc": ["admin@yourcompany.com"],
      "bcc": ["logs@yourcompany.com"],
      "attachments": [
        {
          "filename": "reset-guide.pdf",
          "content": "JVBERi0xLjQKJeLjz9MKMy4uLg==",
          "content_type": "application/pdf"
        }
      ]
    }
  }
}'
```

### Parameters

| Parameter                    | Type   | Required | Description                                 |
| ---------------------------- | ------ | -------- | ------------------------------------------- |
| `workspace_id`               | string | Yes      | Your workspace identifier                   |
| `notification.id`            | string | Yes      | Template identifier for the email           |
| `notification.external_id`   | string | No       | Unique identifier for deduplication         |
| `notification.channels`      | array  | Yes      | Must include "email"                        |
| `notification.contact`       | object | Yes      | Contact object with at least an email field |
| `notification.data`          | object | No       | Template variables for email content        |
| `notification.metadata`      | object | No       | Tracking data (not available in templates)  |
| `notification.email_options` | object | No       | Email routing configuration                 |

### Email Options

| Parameter     | Type   | Description                                                          |
| ------------- | ------ | -------------------------------------------------------------------- |
| `from_name`   | string | Override default sender display name                                 |
| `subject`     | string | Override template subject line (supports Liquid templating, max 255) |
| `reply_to`    | string | Set custom reply-to email address                                    |
| `cc`          | array  | List of carbon copy recipients                                       |
| `bcc`         | array  | List of blind carbon copy recipients                                 |
| `attachments` | array  | File attachments (max 20 files, 3MB per file, 10MB total)            |

## Data vs Metadata

### Template Variables (`data`)

The `data` object contains variables that will be available in your email templates:

```json theme={null}
{
  "data": {
    "order_id": "ORD-12345",
    "total": "$99.99",
    "discount_code": "WELCOME20"
  }
}
```

These can be used in templates as: `{{ order_id }}`, `{{ total }}`, `{{ discount_code }}`

### Tracking Data (`metadata`)

The `metadata` object stores information for analytics and tracking but is **not available** in templates:

```json theme={null}
{
  "metadata": {
    "campaign_id": "welcome-series",
    "source": "mobile_app",
    "user_segment": "premium"
  }
}
```

Use metadata for internal tracking, analytics, and reporting purposes.

## Email Attachments

Send files with your transactional emails such as invoices, receipts, tickets, or documents. Attachments are automatically deduplicated and stored efficiently.

### Attachment Limits

* **Maximum files**: 20 attachments per email
* **File size**: 3MB per file
* **Total size**: 10MB per email
* **Supported formats**: All file types (PDF, PNG, JPEG, DOCX, etc.)

### Attachment Parameters

| Parameter      | Type   | Required | Description                                                        |
| -------------- | ------ | -------- | ------------------------------------------------------------------ |
| `filename`     | string | Yes      | Name of the file (max 255 characters)                              |
| `content`      | string | Yes      | Base64-encoded file content                                        |
| `content_type` | string | No       | MIME type (e.g., "application/pdf"), auto-detected if not provided |
| `disposition`  | string | No       | "attachment" (default) or "inline"                                 |

### Example with PDF Invoice

```json theme={null}
{
  "workspace_id": "your_workspace",
  "notification": {
    "id": "order_confirmation",
    "contact": {
      "email": "customer@example.com"
    },
    "data": {
      "order_id": "ORD-12345",
      "total": "$99.99"
    },
    "email_options": {
      "attachments": [
        {
          "filename": "invoice-12345.pdf",
          "content": "JVBERi0xLjQKJeLjz9MKMy4uLg==",
          "content_type": "application/pdf",
          "disposition": "attachment"
        }
      ]
    }
  }
}
```

### Example with Multiple Attachments

```json theme={null}
{
  "email_options": {
    "attachments": [
      {
        "filename": "invoice.pdf",
        "content": "JVBERi0xLjQKJeLjz9MK...",
        "content_type": "application/pdf"
      },
      {
        "filename": "receipt.png",
        "content": "iVBORw0KGgoAAAANSUhEU...",
        "content_type": "image/png"
      },
      {
        "filename": "terms.docx",
        "content": "UEsDBBQABgAIAAAAIQ...",
        "content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
      }
    ]
  }
}
```

### Common Use Cases

* **Order Confirmations**: Attach invoices and receipts
* **Booking Confirmations**: Attach tickets and itineraries
* **Legal Documents**: Attach contracts and agreements
* **Reports**: Attach analytics reports and summaries
* **Certificates**: Attach completion certificates and badges

## SMTP Bridge

Notifuse includes a built-in SMTP bridge server that allows you to send transactional emails using standard SMTP clients instead of HTTP API calls. This is particularly useful when:

* **Legacy Systems**: Integrating with existing applications that only support SMTP
* **Email Libraries**: Using standard email libraries in any programming language
* **Framework Integration**: Working with frameworks that have built-in SMTP support
* **Gradual Migration**: Moving from existing email providers without changing application code

### How It Works

The SMTP bridge server accepts emails via SMTP on port 587 (STARTTLS) or 465 (implicit TLS). The email body must contain a JSON payload matching the Transactional API format. Authentication is done using your workspace API credentials.

### Sending Emails via SMTP

#### Authentication

* **Username**: Your workspace API email (the email associated with your API key)
* **Password**: Your workspace API key
* **Security**: STARTTLS (port 587) or implicit TLS / SMTPS (port 465), depending on your `SMTP_BRIDGE_TLS` setting
* **Server**: Your configured SMTP bridge host (e.g., `smtp.yourdomain.com`)

#### Email Format

The email body must be a JSON payload matching the Transactional API format:

```json theme={null}
{
  "workspace_id": "your_workspace",
  "notification": {
    "id": "password_reset",
    "external_id": "unique-id-123",
    "channels": ["email"],
    "contact": {
      "email": "user@example.com",
      "first_name": "John",
      "last_name": "Doe"
    },
    "data": {
      "reset_token": "abc123",
      "expiry_time": "1 hour"
    }
  }
}
```

## Template Integration

### Data Structure in Templates

Your templates have access to both API data and contact profile:

```liquid theme={null}
<!-- From API data -->
Hello! Your order #{{ order_id }} has been confirmed.

<!-- From contact profile (automatically enriched) -->
Dear {{ contact.first_name }} {{ contact.last_name }},

<!-- Combining both -->
We've sent your order #{{ order_id }} to {{ contact.email }}.
```

### Complete Example

**API Request**:

```json theme={null}
{
  "workspace_id": "your_workspace",
  "notification": {
    "id": "order_confirmation",
    "external_id": "order-12345-confirmation",
    "contact": {
      "email": "sarah@example.com"
    },
    "data": {
      "order_id": "ORD-12345",
      "total": "$99.99",
      "items": ["Product A", "Product B"]
    },
    "metadata": {
      "campaign_id": "order-confirmations",
      "source": "checkout"
    }
  }
}
```

**Existing Contact Profile**:

```json theme={null}
{
  "first_name": "Sarah",
  "last_name": "Johnson",
  "email": "sarah@example.com",
  "phone": "+1234567890"
}
```

**Available in Template**:

```liquid theme={null}
Hi {{ contact.first_name }}!

Your order #{{ order_id }} totaling {{ total }} has been confirmed.

Items:
{% for item in items %}
- {{ item }}
{% endfor %}

We'll send updates to {{ contact.email }}.
```

## API Reference

## Deduplication Examples

### Order Confirmations

```json theme={null}
{
  "external_id": "order-12345-confirmation"
}
```

### Password Resets

```json theme={null}
{
  "external_id": "pwd-reset-user123-20240101"
}
```

### Welcome Emails

```json theme={null}
{
  "external_id": "welcome-user123"
}
```

Using consistent `external_id` patterns ensures that duplicate notifications are automatically prevented, even if your application sends multiple requests.

For complete API documentation and additional parameters, see the [API Reference](/api-reference/send-a-transactional-notification).
