# Python (smtplib)

:::info
This guide covers SMTP integration. For full configuration options and available headers, see the [SMTP Introduction](/guides/send-email-with-smtp).
:::

## Basic Configuration

Use environment variables for credentials:

```python
import os

SMTP_HOST = 'smtp.lettermint.co'
SMTP_USERNAME = 'lettermint'
API_TOKEN = os.environ.get('LETTERMINT_PROJECT_TOKEN')
```

<CodeTabs>
```python title="Port 587 (STARTTLS)"
import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# SMTP configuration
SMTP_HOST = 'smtp.lettermint.co'
SMTP_PORT = 587
USERNAME = 'lettermint'
API_TOKEN = os.environ.get('LETTERMINT_PROJECT_TOKEN')

def send_email(to_email, subject, html_body, text_body=None):
    msg = MIMEMultipart('alternative')
    msg['From'] = 'sender@yourdomain.com'
    msg['To'] = to_email
    msg['Subject'] = subject

    if text_body:
        msg.attach(MIMEText(text_body, 'plain'))
    msg.attach(MIMEText(html_body, 'html'))

    try:
        with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
            server.starttls()
            server.login(USERNAME, API_TOKEN)
            server.send_message(msg)
        print("Email sent successfully")
    except Exception as e:
        print(f"Error sending email: {e}")

send_email(
    to_email='recipient@example.com',
    subject='Test Email',
    html_body='<h1>Hello!</h1><p>This is a test email.</p>',
    text_body='Hello! This is a test email.'
)
```

```python title="Port 465 (Implicit TLS)"
import smtplib
import ssl
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# SMTP configuration
SMTP_HOST = 'smtp.lettermint.co'
SMTP_PORT = 465
USERNAME = 'lettermint'
API_TOKEN = os.environ.get('LETTERMINT_PROJECT_TOKEN')

def send_email(to_email, subject, html_body, text_body=None):
    msg = MIMEMultipart('alternative')
    msg['From'] = 'sender@yourdomain.com'
    msg['To'] = to_email
    msg['Subject'] = subject

    if text_body:
        msg.attach(MIMEText(text_body, 'plain'))
    msg.attach(MIMEText(html_body, 'html'))

    context = ssl.create_default_context()

    try:
        with smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT, context=context) as server:
            server.login(USERNAME, API_TOKEN)
            server.send_message(msg)
        print("Email sent successfully")
    except Exception as e:
        print(f"Error sending email: {e}")

send_email(
    to_email='recipient@example.com',
    subject='Test Email',
    html_body='<h1>Hello!</h1><p>This is a test email.</p>',
    text_body='Hello! This is a test email.'
)
```
</CodeTabs>

## Advanced Features

### Multiple Recipients

```python
def send_bulk_email(recipients, subject, html_body):
    msg = MIMEMultipart('alternative')
    msg['From'] = 'sender@yourdomain.com'
    msg['Subject'] = subject
    msg.attach(MIMEText(html_body, 'html'))

    with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
        server.starttls()
        server.login(USERNAME, API_TOKEN)

        for recipient in recipients:
            msg['To'] = recipient
            server.send_message(msg)
            del msg['To']  # Remove for next iteration
```

### Attachments

```python
def send_email_with_attachment(to_email, subject, body, file_path):
    msg = MIMEMultipart()
    msg['From'] = 'sender@yourdomain.com'
    msg['To'] = to_email
    msg['Subject'] = subject

    msg.attach(MIMEText(body, 'html'))

    # Add attachment
    with open(file_path, 'rb') as attachment:
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(attachment.read())

    encoders.encode_base64(part)
    part.add_header(
        'Content-Disposition',
        f'attachment; filename= {os.path.basename(file_path)}'
    )
    msg.attach(part)

    with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
        server.starttls()
        server.login(USERNAME, API_TOKEN)
        server.send_message(msg)
```

### Lettermint Headers

Add Lettermint-specific headers for tags, metadata, and routing:

```python
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

msg = MIMEMultipart('alternative')
msg['From'] = 'sender@yourdomain.com'
msg['To'] = 'recipient@example.com'
msg['Subject'] = 'Order Confirmation'

# Tag for categorization
msg['X-LM-Tag'] = 'order-confirmation'

# Metadata for tracking (included in webhooks)
msg['X-LM-Metadata-order_id'] = '12345'
msg['X-LM-Metadata-customer_id'] = 'cust_789'

# Route selection
msg['X-Lettermint-Route'] = 'transactional'

msg.attach(MIMEText('<p>Your order has been confirmed.</p>', 'html'))
```

:::note
Metadata headers are extracted by Lettermint and included in webhook payloads, but not added to the actual email sent to recipients.
See the [SMTP Introduction](/guides/send-email-with-smtp#custom-headers) for full details on available headers.
:::
