# Attach contact to list
Source: https://docs.lettr.com/api-reference/audience/attach-contact-to-list
POST /audience/contacts/{contactId}/lists/{listId}
Add a contact to a list. Returns `201` if the contact was newly attached, or `200` if the contact was already in the list. Requires the `audience:write` scope and is blocked for sandbox API keys.
Add a contact to a list. Returns `201` if the contact was newly attached, or `200` if the contact was already in the list. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Bulk attach contacts to lists
Source: https://docs.lettr.com/api-reference/audience/bulk-attach-contacts-to-lists
POST /audience/contacts/lists/bulk
Attach every combination of `contact_ids × list_ids` (up to 1000 contacts × 50 lists). Existing pairs are reported in `already_attached`. Requires the `audience:write` scope and is blocked for sandbox API keys.
Attach every combination of `contact_ids × list_ids` (up to 1000 contacts × 50 lists). Existing pairs are reported in `already_attached`. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Bulk create contacts
Source: https://docs.lettr.com/api-reference/audience/bulk-create-contacts
POST /audience/contacts/bulk
Create up to 1000 contacts in a single request. Send `contacts` to give each row its own properties, lists and topics, or the legacy `emails` array when the whole batch shares one property map. Emails are normalized and deduplicated; addresses that already exist are reported in `already_existed`, are always attached to the requested lists and topics and always have a row-level `opt_out` applied, and have their properties merged only when `update_existing` is set. Rows that fail validation are skipped and returned in `errors` — the request only fails with 422 when nothing could be written. The response carries the contact ids, so a follow-up call to the bulk list or topic endpoints needs no lookup. Requires the `audience:write` scope and is blocked for sandbox API keys.
Create up to 1000 contacts in a single request. Emails are normalized and deduplicated. Requires the `audience:write` scope and is blocked for sandbox API keys.
Send **either** `emails` (a flat list of addresses that all share the batch-wide `list_ids`, `properties` and `topics`) **or** `contacts` (one row per contact, each with its own properties, lists and topic subscriptions). Row-level values are applied on top of the batch-wide ones: a row's `properties` key overrides the batch-wide value for that key, and a row-level `opt_out` beats a batch-level `opt_in`.
**A `201` does not mean every row landed.** Rows that fail validation are skipped and reported in `errors` — the rest of the batch still commits. Always check `error_count` / `errors` rather than treating a 2xx as full success.
`already_existed` and `updated` overlap by design. They answer different questions — "was the address already in the audience?" versus "did this request change the contact?" — so they do not sum to the number of submitted rows. A contact that already existed and got attached to a list is counted in both.
`update_existing` governs property merges and nothing else. By default (`update_existing: false`) existing contacts keep their properties; set it to `true` to merge instead — submitted keys overwrite, absent keys are preserved.
Lists, topic opt-ins and topic `opt_out` entries are applied either way. A row-level `opt_out` drops an existing subscription whether or not the flag is set, so a consent or suppression import does not need it.
The `contacts` array in the response returns `{ id, email, created }` for every contact that exists after the request, in submission order. Feed those ids straight into [bulk attach contacts to lists](/api-reference/audience/bulk-attach-contacts-to-lists) or [bulk subscribe contacts to topics](/api-reference/audience/bulk-subscribe-contacts-to-topics) without a follow-up lookup.
## Limits
| Limit | Value |
| --------------------------------------- | --------------- |
| Rows per batch (`emails` or `contacts`) | 1000 |
| Batch-wide `list_ids` | 50 |
| Batch-wide `topics` | 50 |
| Property value length | 1000 characters |
## Row error codes
Each entry in `errors` carries the zero-based `index` of the submitted row, the `email`, a human-readable `error`, and one of these `error_code` values:
| Code | Meaning |
| ---------------------------- | ---------------------------------------------------------- |
| `missing_email` | The row had no email address. |
| `invalid_email` | The address failed validation. |
| `invalid_property_value` | A property value was the wrong type or too long. |
| `unknown_property_key` | A property key is not defined for the team. |
| `unknown_list` | A list id does not exist. |
| `unknown_topic` | A topic id does not exist. |
| `invalid_topic_subscription` | A `subscription` value was neither `opt_in` nor `opt_out`. |
# Bulk delete audience lists
Source: https://docs.lettr.com/api-reference/audience/bulk-delete-audience-lists
DELETE /audience/lists/bulk
Delete up to 50 lists in a single request. All `list_ids` must belong to the authenticated team. Requires the `audience:write` scope and is blocked for sandbox API keys.
Delete up to 50 lists in a single request. All `list_ids` must belong to the authenticated team. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Bulk detach contacts from lists
Source: https://docs.lettr.com/api-reference/audience/bulk-detach-contacts-from-lists
DELETE /audience/contacts/lists/bulk
Detach every combination of `contact_ids × list_ids` (up to 1000 contacts × 50 lists). Pairs that were not attached are reported in `not_present`. Requires the `audience:write` scope and is blocked for sandbox API keys.
Detach every combination of `contact_ids × list_ids` (up to 1000 contacts × 50 lists). Pairs that were not attached are reported in `not_present`. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Bulk subscribe contacts to topics
Source: https://docs.lettr.com/api-reference/audience/bulk-subscribe-contacts-to-topics
POST /audience/contacts/topics/bulk
Subscribe every combination of `contact_ids × topic_ids` (up to 1000 contacts × 50 topics). Pairs that already exist are reported in `already_subscribed`. Requires the `audience:write` scope and is blocked for sandbox API keys.
Subscribe every combination of `contact_ids × topic_ids` (up to 1000 contacts × 50 topics). Pairs that already exist are reported in `already_subscribed`. Requires the `audience:write` scope and is blocked for sandbox API keys.
The `contacts` array returned by [bulk create contacts](/api-reference/audience/bulk-create-contacts) gives you the ids to pass here, so you can import and subscribe without a lookup in between.
# Bulk unsubscribe contacts from topics
Source: https://docs.lettr.com/api-reference/audience/bulk-unsubscribe-contacts-from-topics
DELETE /audience/contacts/topics/bulk
Remove every combination of `contact_ids × topic_ids`. Pairs that did not exist are ignored. Requires the `audience:write` scope and is blocked for sandbox API keys.
Remove every combination of `contact_ids × topic_ids`. Pairs that did not exist are ignored, so `unsubscribed` can be lower than `total_pairs`. Requires the `audience:write` scope and is blocked for sandbox API keys.
This `DELETE` carries a request body. Most HTTP clients support that, but some need it enabled explicitly — the same applies to [bulk detach contacts from lists](/api-reference/audience/bulk-detach-contacts-from-lists).
# Create a contact
Source: https://docs.lettr.com/api-reference/audience/create-a-contact
POST /audience/contacts
Create a single contact. If `double_opt_in` is provided the contact is created in `unverified` status and receives a confirmation email — they become `subscribed` only after clicking the confirmation link. Requires the `audience:write` scope and is blocked for sandbox API keys.
Create a single contact. If `double_opt_in` is provided the contact is created in `unverified` status and receives a confirmation email — they become `subscribed` only after clicking the confirmation link. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Create a property
Source: https://docs.lettr.com/api-reference/audience/create-a-property
POST /audience/properties
Create a new property that contacts can store. The `name` and `type` fields are immutable after creation — to change them, delete the property and create a new one. Requires the `audience:write` scope and is blocked for sandbox API keys.
Create a new property that contacts can store. The `name` and `type` fields are immutable after creation — to change them, delete the property and create a new one. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Create a segment
Source: https://docs.lettr.com/api-reference/audience/create-a-segment
POST /audience/segments
Create a segment defined by condition groups (conditions within a group are joined by OR; groups are joined by AND). Requires the `audience:write` scope and is blocked for sandbox API keys.
Create a segment defined by condition groups (conditions within a group are joined by OR; groups are joined by AND). Requires the `audience:write` scope and is blocked for sandbox API keys.
# Create a topic
Source: https://docs.lettr.com/api-reference/audience/create-a-topic
POST /audience/topics
Create a topic. The `default_subscription` field is set at creation and cannot be changed later. Requires the `audience:write` scope and is blocked for sandbox API keys.
Create a topic. The `default_subscription` field is set at creation and cannot be changed later. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Create an audience list
Source: https://docs.lettr.com/api-reference/audience/create-an-audience-list
POST /audience/lists
Create a new audience list. The name must be unique within the team. Requires the `audience:write` scope and is blocked for sandbox API keys.
Create a new audience list. The name must be unique within the team. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Delete a contact
Source: https://docs.lettr.com/api-reference/audience/delete-a-contact
DELETE /audience/contacts/{contactId}
Permanently delete a contact. Requires the `audience:write` scope and is blocked for sandbox API keys.
Permanently delete a contact. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Delete a property
Source: https://docs.lettr.com/api-reference/audience/delete-a-property
DELETE /audience/properties/{propertyId}
Permanently delete a property. Requires the `audience:write` scope and is blocked for sandbox API keys.
Permanently delete a property. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Delete a segment
Source: https://docs.lettr.com/api-reference/audience/delete-a-segment
DELETE /audience/segments/{segmentId}
Permanently delete a segment. Requires the `audience:write` scope and is blocked for sandbox API keys.
Permanently delete a segment. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Delete a topic
Source: https://docs.lettr.com/api-reference/audience/delete-a-topic
DELETE /audience/topics/{topicId}
Permanently delete a topic. Requires the `audience:write` scope and is blocked for sandbox API keys.
Permanently delete a topic. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Delete an audience list
Source: https://docs.lettr.com/api-reference/audience/delete-an-audience-list
DELETE /audience/lists/{listId}
Permanently delete an audience list. Requires the `audience:write` scope and is blocked for sandbox API keys.
Permanently delete an audience list. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Detach contact from list
Source: https://docs.lettr.com/api-reference/audience/detach-contact-from-list
DELETE /audience/contacts/{contactId}/lists/{listId}
Remove a contact from a list. Idempotent — returns `204` whether the pair existed or not. Requires the `audience:write` scope and is blocked for sandbox API keys.
Remove a contact from a list. Idempotent — returns `204` whether the pair existed or not. Requires the `audience:write` scope and is blocked for sandbox API keys.
# List audience contacts
Source: https://docs.lettr.com/api-reference/audience/list-audience-contacts
GET /audience/contacts
List contacts with pagination and filtering. Requires the `audience:read` scope.
List contacts with pagination and filtering. Requires the `audience:read` scope.
# List audience lists
Source: https://docs.lettr.com/api-reference/audience/list-audience-lists
GET /audience/lists
Returns all audience lists for the authenticated team. Requires the `audience:read` scope.
Returns all audience lists for the authenticated team. Requires the `audience:read` scope.
# List audience properties
Source: https://docs.lettr.com/api-reference/audience/list-audience-properties
GET /audience/properties
List the team's custom contact properties. Requires the `audience:read` scope.
List the team's custom contact properties. Requires the `audience:read` scope.
# List audience segments
Source: https://docs.lettr.com/api-reference/audience/list-audience-segments
GET /audience/segments
List segments with pagination. Requires the `audience:read` scope.
List segments with pagination. Requires the `audience:read` scope.
# List audience topics
Source: https://docs.lettr.com/api-reference/audience/list-audience-topics
GET /audience/topics
List topics with pagination. Requires the `audience:read` scope.
List topics with pagination. Requires the `audience:read` scope.
# Show a contact
Source: https://docs.lettr.com/api-reference/audience/show-a-contact
GET /audience/contacts/{contactId}
Retrieve a single contact. Requires the `audience:read` scope.
Retrieve a single contact. Requires the `audience:read` scope.
# Show a property
Source: https://docs.lettr.com/api-reference/audience/show-a-property
GET /audience/properties/{propertyId}
Retrieve a single property. Requires the `audience:read` scope.
Retrieve a single property. Requires the `audience:read` scope.
# Show a segment
Source: https://docs.lettr.com/api-reference/audience/show-a-segment
GET /audience/segments/{segmentId}
Retrieve a single segment. Requires the `audience:read` scope.
Retrieve a single segment. Requires the `audience:read` scope.
# Show a topic
Source: https://docs.lettr.com/api-reference/audience/show-a-topic
GET /audience/topics/{topicId}
Retrieve a single topic. Requires the `audience:read` scope.
Retrieve a single topic. Requires the `audience:read` scope.
# Show an audience list
Source: https://docs.lettr.com/api-reference/audience/show-an-audience-list
GET /audience/lists/{listId}
Retrieve a single audience list. Requires the `audience:read` scope.
Retrieve a single audience list. Requires the `audience:read` scope.
# Subscribe contact to topic
Source: https://docs.lettr.com/api-reference/audience/subscribe-contact-to-topic
POST /audience/contacts/{contactId}/topics/{topicId}
Subscribe a contact to a topic. Returns `201` if the subscription is new, or `200` if the contact was already subscribed. Requires the `audience:write` scope and is blocked for sandbox API keys.
Subscribe a contact to a topic. Returns `201` if the subscription is new, or `200` if the contact was already subscribed. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Unsubscribe contact from topic
Source: https://docs.lettr.com/api-reference/audience/unsubscribe-contact-from-topic
DELETE /audience/contacts/{contactId}/topics/{topicId}
Unsubscribe a contact from a topic. Idempotent — returns `204` whether the subscription existed or not. Requires the `audience:write` scope and is blocked for sandbox API keys.
Unsubscribe a contact from a topic. Idempotent — returns `204` whether the subscription existed or not. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Update a contact
Source: https://docs.lettr.com/api-reference/audience/update-a-contact
PATCH /audience/contacts/{contactId}
Partially update a contact. If no fields are provided the contact is returned unchanged. Requires the `audience:write` scope and is blocked for sandbox API keys.
Partially update a contact. If no fields are provided the contact is returned unchanged. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Update a property
Source: https://docs.lettr.com/api-reference/audience/update-a-property
PATCH /audience/properties/{propertyId}
Update the property's fallback value. The `name` and `type` fields cannot be changed (they would orphan data on existing contacts). If the request body contains no recognized fields, the property is returned unchanged with a `200` response. Requires the `audience:write` scope and is blocked for sandbox API keys.
Update the property's fallback value. The `name` and `type` fields cannot be changed (they would orphan data on existing contacts). If the request body contains no recognized fields, the property is returned unchanged with a `200` response. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Update a segment
Source: https://docs.lettr.com/api-reference/audience/update-a-segment
PATCH /audience/segments/{segmentId}
Partially update a segment. Requires the `audience:write` scope and is blocked for sandbox API keys.
Partially update a segment. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Update a topic
Source: https://docs.lettr.com/api-reference/audience/update-a-topic
PATCH /audience/topics/{topicId}
Partially update a topic. The `default_subscription` field is immutable. Requires the `audience:write` scope and is blocked for sandbox API keys.
Partially update a topic. The `default_subscription` field is immutable. Requires the `audience:write` scope and is blocked for sandbox API keys.
# Update an audience list
Source: https://docs.lettr.com/api-reference/audience/update-an-audience-list
PATCH /audience/lists/{listId}
Partially update an audience list. If no fields are provided the existing list is returned unchanged. Requires the `audience:write` scope and is blocked for sandbox API keys.
Partially update an audience list. If no fields are provided the existing list is returned unchanged. Requires the `audience:write` scope and is blocked for sandbox API keys.
# List campaign engagement events
Source: https://docs.lettr.com/api-reference/campaigns/list-campaign-engagement-events
GET /campaigns/{campaignId}/events
Returns engagement events (opens, clicks, bounces, etc.) for a campaign, with optional filtering by type, recipient email, and date range. Uses cursor-based pagination: keep requesting with the returned `next_cursor` until it is `null`. When a filter is applied, a page may come back with an empty `events` array **and** a non-null `next_cursor` — that means more pages remain, not that there are no matching events, so continue paginating until `next_cursor` is `null`. Requires the `campaigns:read` scope.
Returns engagement events (opens, clicks, bounces, etc.) for a campaign, with optional filtering by type, recipient email, and date range. Uses cursor-based pagination: keep requesting with the returned `next_cursor` until it is `null`. When a filter is applied, a page may come back with an empty `events` array **and** a non-null `next_cursor` — that means more pages remain, not that there are no matching events, so continue paginating until `next_cursor` is `null`. Requires the `campaigns:read` scope.
# List campaigns
Source: https://docs.lettr.com/api-reference/campaigns/list-campaigns
GET /campaigns
Returns a paginated list of campaigns for the authenticated team, each with embedded engagement stats. Requires the `campaigns:read` scope.
Returns a paginated list of campaigns for the authenticated team, each with embedded engagement stats. Requires the `campaigns:read` scope.
# Schedule a campaign
Source: https://docs.lettr.com/api-reference/campaigns/schedule-a-campaign
POST /campaigns/{campaignId}/schedule
Schedules a campaign for future delivery, or reschedules an already-scheduled campaign to a new time. The campaign transitions to (or stays) `scheduled` and is dispatched automatically at the given time. Requires the `campaigns:write` scope. Not available to sandbox keys.
Schedules a campaign for future delivery, or reschedules an already-scheduled campaign to a new time. The campaign transitions to (or stays) `scheduled` and is dispatched automatically at the given time. Requires the `campaigns:write` scope. Not available to sandbox keys.
# Send a campaign now
Source: https://docs.lettr.com/api-reference/campaigns/send-a-campaign-now
POST /campaigns/{campaignId}/send
Immediately dispatches a draft campaign. The campaign must be a draft with a subject, sender email, and content. Sending is asynchronous; the campaign transitions to `preparing`. Requires the `campaigns:write` scope. Not available to sandbox keys.
Immediately dispatches a draft campaign. The campaign must be a draft with a subject, sender email, and content. Sending is asynchronous; the campaign transitions to `preparing`. Requires the `campaigns:write` scope. Not available to sandbox keys.
# Show a campaign
Source: https://docs.lettr.com/api-reference/campaigns/show-a-campaign
GET /campaigns/{campaignId}
Retrieve a single campaign with embedded stats and rendered HTML content. Requires the `campaigns:read` scope.
Retrieve a single campaign with embedded stats and rendered HTML content. Requires the `campaigns:read` scope.
# Unschedule a campaign
Source: https://docs.lettr.com/api-reference/campaigns/unschedule-a-campaign
POST /campaigns/{campaignId}/unschedule
Cancels a scheduled send, returning the campaign to `draft`. The campaign must currently be `scheduled`. Requires the `campaigns:write` scope. Not available to sandbox keys.
Cancels a scheduled send, returning the campaign to `draft`. The campaign must currently be `scheduled`. Requires the `campaigns:write` scope. Not available to sandbox keys.
# Create Domain
Source: https://docs.lettr.com/api-reference/domains/create-domain
POST /domains
Register a new sending domain with your account. The domain will be created with SparkPost and stored as approved by default, unless global domain reputation marks it for review or blacklist.
Adds a new sending domain to your team. After creating, you'll need to add the required DNS records and [verify the domain](/api-reference/domains/verify-domain) before you can send from it.
# Delete Domain
Source: https://docs.lettr.com/api-reference/domains/delete-domain
DELETE /domains/{domain}
Delete a sending domain. This removes the domain from both SparkPost and the Lettr system. The domain will no longer be available for sending emails.
Removes a sending domain from your team. Emails can no longer be sent from this domain after deletion.
# Get Domain
Source: https://docs.lettr.com/api-reference/domains/get-domain
GET /domains/{domain}
Retrieve details of a single sending domain including DNS records and tracking domain configuration.
Retrieves details for a specific sending domain, including its current verification status and DNS record configuration.
# List Domains
Source: https://docs.lettr.com/api-reference/domains/list-domains
GET /domains
Retrieve all sending domains registered with your account. Returns domains with their current status, verification state, and timestamps.
Returns all sending domains configured for your team, including their verification status and DNS record information.
# Verify Domain
Source: https://docs.lettr.com/api-reference/domains/verify-domain
POST /domains/{domain}/verify
Verify a domain's DNS records (DKIM and CNAME) with SparkPost. This triggers a verification check and returns the current status of DNS records.
Triggers DNS verification for a sending domain. Lettr checks that the required CNAME and DKIM records are correctly configured. Call this after adding DNS records to your domain.
# Cancel Scheduled Email
Source: https://docs.lettr.com/api-reference/emails/cancel-scheduled-email
DELETE /emails/scheduled/{transmissionId}
Cancel a scheduled email transmission before it is sent. Once the scheduled delivery time has passed, the transmission can no longer be cancelled.
Cancel a scheduled email transmission before it is sent. Once the scheduled delivery time has passed, the transmission can no longer be cancelled.
# Get Email Detail
Source: https://docs.lettr.com/api-reference/emails/get-email-detail
GET /emails/{requestId}
Retrieve all events for a specific sent email by its request ID. Returns delivery, bounce, open, click, and other events in reverse chronological order. If no `from` date is provided, defaults to the last 10 days.
Retrieve all events for a specific sent email by its request ID.
# Get Scheduled Email
Source: https://docs.lettr.com/api-reference/emails/get-scheduled-email
GET /emails/scheduled/{transmissionId}
Retrieve details of a scheduled email transmission by its transmission ID. If the transmission is still pending, returns the scheduled state. If the transmission has already been processed by SparkPost, automatically falls back to returning delivery events with the same response shape.
# List Email Events
Source: https://docs.lettr.com/api-reference/emails/list-email-events
GET /emails/events
Retrieve email events (deliveries, bounces, opens, clicks, etc.) for your account. Events are returned in reverse chronological order. If no `from` date is provided, defaults to the last 10 days.
Retrieve email events (deliveries, bounces, opens, clicks, etc.) for your account. Events are returned in reverse chronological order.
# Schedule Email
Source: https://docs.lettr.com/api-reference/emails/schedule-email
POST /emails/scheduled
Schedule a transactional email for future delivery. Accepts the same payload as `POST /emails` with an additional required `scheduled_at` field. The email must be scheduled at least 5 minutes in the future and within 3 days.
Schedule a transactional email for future delivery. Accepts the same payload as `POST /emails` with an additional required `scheduled_at` field.
# Send Email
Source: https://docs.lettr.com/api-reference/emails/send-email
POST /emails
Send a transactional email with optional attachments, tracking, and personalization. At least one of `html` or `text` content must be provided.
Sends an email to one or more recipients. Supports HTML, plain text, AMP content, templates, merge tags, attachments, and tracking options.
Available to [sandbox API keys](/learn/api-keys/sandbox): all recipients are redirected to the key owner's inbox and the sender domain is replaced with the pre-verified sandbox domain.
# Introduction
Source: https://docs.lettr.com/api-reference/introduction
Complete reference for the Lettr REST API, with resource-oriented URLs, JSON requests and responses, Bearer authentication, and HTTP codes.
The Lettr API is organized around REST. Our API has predictable resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.
## Base URL
```
https://app.lettr.com/api/
```
## Authentication
Authenticate requests using an API key in the Authorization header:
```bash theme={null}
curl https://app.lettr.com/api/emails \
-H "Authorization: Bearer lttr_xxxxxxxxxxxx"
```
## Request Format
Send JSON-encoded bodies with the appropriate Content-Type header:
```bash theme={null}
curl -X POST https://app.lettr.com/api/emails \
-H "Authorization: Bearer lttr_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"from": "you@yourdomain.com", "to": ["recipient@example.com"], "subject": "Hello", "html": "
Hello!
"}'
```
## Response Format
**Success response (200):**
```json theme={null}
{
"message": "Email queued for delivery.",
"data": {
"request_id": "12345678901234567890",
"accepted": 1,
"rejected": 0
}
}
```
**Error response (400, 502):**
```json theme={null}
{
"message": "The sender domain is not configured or approved for sending.",
"error_code": "unconfigured_domain"
}
```
**Validation error response (422):**
```json theme={null}
{
"message": "Validation failed.",
"error_code": "validation_error",
"errors": {
"from": ["The sender email address is required."],
"to": ["At least one recipient email address is required."]
}
}
```
## HTTP Status Codes
| Code | Description |
| ----- | -------------------------------------------------------- |
| `200` | Success - Email queued for delivery |
| `400` | Bad Request - Domain configuration error |
| `401` | Unauthorized - Invalid or missing API key |
| `422` | Unprocessable Entity - Validation failed |
| `429` | Too Many Requests - Rate limit or sending quota exceeded |
| `502` | Bad Gateway - Upstream transmission failed |
## Error Codes
| Code | HTTP Status | Description |
| ---------------------- | ----------- | --------------------------------------------------------------------------------- |
| `validation_error` | 422 | Request validation failed. Check the `errors` object for field-specific messages. |
| `invalid_domain` | 400 | The sender domain could not be determined from the email address. |
| `unconfigured_domain` | 400 | The sender domain is not configured or approved for sending. |
| `send_error` | 400 | General error during email send preparation. |
| `rate_limit_exceeded` | 429 | Too many API requests. Slow down and retry after the `Retry-After` period. |
| `quota_exceeded` | 429 | Monthly sending quota exceeded. Upgrade your plan to continue sending. |
| `daily_quota_exceeded` | 429 | Daily sending quota exceeded (free tier). Try again tomorrow. |
| `transmission_failed` | 502 | Email transmission to the upstream provider failed. |
## Send Email Reference
### Subject
The `subject` field is conditionally required:
* **Required** when sending with `html` or `text` content directly.
* **Optional** when `template_slug` is provided — if omitted, Lettr uses the template's stored subject. If the template has no subject set, the template name is used instead.
* If provided alongside a `template_slug`, the `subject` **overrides** the template's subject. This is useful for A/B testing or dynamic subject lines.
Maximum length: 998 characters.
### Options
The `options` object controls tracking and email classification:
| Option | Type | Default | Description |
| ---------------- | ------- | ------- | --------------------------------------------------------------------------- |
| `transactional` | boolean | `true` | Whether this is a transactional email. Set to `false` for marketing emails. |
| `open_tracking` | boolean | `false` | Track email opens |
| `click_tracking` | boolean | `false` | Track link clicks |
Since `transactional` defaults to `true`, you only need to explicitly set it when sending marketing emails (`transactional: false`).
### Custom Headers
The `headers` field lets you add custom email headers to your message. Pass an object where each key is the header name and each value is the header value.
**Limits:**
* Maximum **10** custom headers per email
* Maximum **998** characters per header value
```json theme={null}
{
"headers": {
"X-My-Header": "custom-value",
"X-Campaign-ID": "spring-2026"
}
}
```
The following headers are **blocked** and cannot be set via the `headers` field — Lettr manages them automatically:
`From`, `To`, `Cc`, `Bcc`, `Reply-To`, `Subject`, `Date`, `Message-ID`, `MIME-Version`, `Content-Type`, `Content-Transfer-Encoding`, `DKIM-Signature`, `Return-Path`, `Received`, `List-Unsubscribe`, `List-Unsubscribe-Post`
## API Endpoints
Send emails to one or more recipients
Manage templates, merge tags, and rendered HTML
Create, verify, and manage sending domains
View webhook configurations
# Rate Limit
Source: https://docs.lettr.com/api-reference/rate-limit
Understand Lettr's per-team API rate limits, daily and monthly sending quotas, and the response headers that track your usage in real time.
Lettr enforces per-team rate limits on API requests to ensure fair usage across all customers and prevent any single integration from overwhelming the service. In addition to request-level rate limits, the Send Email endpoint returns quota headers that track your daily and monthly email usage.
Rate limits are different from **email quotas**. Rate limits control API request frequency (requests per second), while email quotas control sending volume (emails per month). For details on monthly email quotas, daily sending limits, and how usage is tracked, see [Email Usage & Quotas](/learn/sending/usage-quotas).
## Rate Limit
The default rate limit is **3 requests per second** per team, shared across all API keys belonging to the same team. If you exceed the limit, subsequent requests return `429 Too Many Requests` until the window resets.
| Limit Type | Value |
| ----------------------- | ------------------------------------- |
| API requests | 3 requests per second |
| Authentication failures | 5 failures / 5 minutes (15 min block) |
| Recipients per request | 50 (combined to, cc, bcc) |
If you continue sending requests after receiving a `429` response, the cooldown period may be extended. Always respect the `Retry-After` header before retrying.
## Rate Limit Headers
Every API response includes rate limit headers:
| Header | Type | Description |
| ----------------------- | --------- | -------------------------------------------------------------------------- |
| `X-RateLimit-Limit` | `integer` | Maximum number of requests allowed per second. |
| `X-RateLimit-Remaining` | `integer` | How many requests you have left in the current window. |
| `X-RateLimit-Reset` | `integer` | Unix timestamp (in seconds) when the rate limit window resets. |
| `Retry-After` | `integer` | How many seconds to wait before retrying. Only present on `429` responses. |
## Sending Quota Headers
The [Send Email](/api-reference/emails/send-email) endpoint returns additional headers that track your email sending quotas. These headers are present for **free tier** teams.
These counters are denominated in **recipients, not requests** — every address across `to`, `cc`, and `bcc` decrements them by one. A single request with 8 addresses moves `X-Daily-Remaining` by 8. Quota is also enforced all-or-nothing: a request that would exceed a limit is rejected in full rather than partially delivered. See [Email Usage & Quotas](/learn/sending/usage-quotas) for details.
### Daily Quota
| Header | Type | Description |
| ------------------- | --------- | ------------------------------------------------------------------------- |
| `X-Daily-Limit` | `integer` | Maximum number of emails you can send per day. |
| `X-Daily-Remaining` | `integer` | How many emails you have left today. |
| `X-Daily-Reset` | `integer` | Unix timestamp (in seconds) when the daily counter resets (midnight UTC). |
### Monthly Quota
| Header | Type | Description |
| --------------------- | --------- | ------------------------------------------------------------------------------------------ |
| `X-Monthly-Limit` | `integer` | Maximum number of emails you can send per billing month. |
| `X-Monthly-Remaining` | `integer` | How many emails you have left this month. |
| `X-Monthly-Reset` | `integer` | Unix timestamp (in seconds) when the monthly counter resets (start of next billing month). |
## Error Codes
When you exceed a limit, the API returns a `429` response with one of these error codes:
| Error Code | Description |
| ---------------------- | -------------------------------------------------------------------------- |
| `rate_limit_exceeded` | Too many API requests. Slow down and retry after the `Retry-After` period. |
| `daily_quota_exceeded` | Daily sending quota exceeded (free tier). Try again after midnight UTC. |
| `quota_exceeded` | Monthly sending quota exceeded. Upgrade your plan to continue sending. |
```json 429 Rate Limit Exceeded theme={null}
{
"message": "Rate limit exceeded. Please slow down your requests.",
"error_code": "rate_limit_exceeded"
}
```
```json 429 Daily Quota Exceeded theme={null}
{
"message": "Daily sending quota exceeded. Please try again tomorrow.",
"error_code": "daily_quota_exceeded"
}
```
```json 429 Monthly Quota Exceeded theme={null}
{
"message": "Sending quota exceeded. Upgrade your plan to continue sending.",
"error_code": "quota_exceeded"
}
```
## Handling Rate Limits
When you receive a `429` response, use the `Retry-After` header to determine how long to wait. Implement exponential backoff as a fallback:
```javascript theme={null}
async function sendWithBackoff(emailData, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await lettr.emails.send(emailData);
} catch (error) {
if (error.status === 429) {
const retryAfter = error.retryAfter || Math.pow(2, attempt);
console.log(`Rate limited. Retrying in ${retryAfter} seconds...`);
await sleep(retryAfter * 1000);
} else {
throw error;
}
}
}
throw new Error('Max retries exceeded');
}
```
## Batch Sending with Rate Limiting
When sending to large recipient lists, pace your API calls to stay within rate limits. Adding a short delay between batches prevents bursts that trigger throttling:
```javascript theme={null}
const recipients = [...]; // Large list
const batchSize = 50;
const delayBetweenBatches = 500; // milliseconds
for (let i = 0; i < recipients.length; i += batchSize) {
const batch = recipients.slice(i, i + batchSize);
await lettr.emails.send({
from: 'you@example.com',
to: batch,
subject: 'Newsletter',
html: content
});
// Pace your requests
if (i + batchSize < recipients.length) {
await sleep(delayBetweenBatches);
}
}
```
## Monthly Email Quotas
Your monthly email quota depends on your plan:
| Plan | Monthly Emails |
| ---------- | -------------- |
| Free | 3,000 |
| Pro 50K | 50,000 |
| Pro 100K | 100,000 |
| Pro 200K | 200,000 |
| Pro 500K | 500,000 |
| Pro 1M | 1,000,000 |
| Enterprise | Custom |
Emails beyond your tier limit are charged at \$0.80 per 1,000 emails. See [Billing](/learn/settings/billing) for details.
## Best Practices
Always implement exponential backoff for `429` responses. Use the `Retry-After` header from the response when available, and fall back to a `2^attempt` delay otherwise. Without backoff, rapid retries will keep hitting the limit and delay your sends further.
Check the `X-RateLimit-Remaining` header on every response. When it approaches zero, slow down your request rate proactively instead of waiting for a `429` response.
Each API request supports up to 50 recipients. Sending to 50 recipients per request instead of one-at-a-time reduces your API call count by 50x, making it far easier to stay within rate limits for large sends.
On free tier, check the `X-Daily-Remaining` and `X-Monthly-Remaining` headers to track your quota usage in real time. Set up internal alerts at 80% and 90% of your quota so you can upgrade your plan before hitting the limit.
For campaigns targeting thousands of recipients, use a job queue (such as BullMQ, Laravel Queues, or Celery) to pace sending over minutes or hours. This avoids burst patterns that trigger rate limits and gives you better control over delivery timing.
Polling the API to check delivery status consumes rate limit budget. Instead, set up [webhooks](/learn/webhooks/introduction) to receive delivery, bounce, and engagement events asynchronously. This eliminates polling requests entirely and gives you faster, event-driven status updates.
## Increasing Your Limits
If your current limits don't match your sending volume, you have several options:
* **Upgrade your plan** — Increases your monthly email quota immediately
* **Enterprise plans** — Custom rate limits tailored to your traffic patterns — contact sales to discuss your requirements
* **Batch recipients** — Send up to 50 recipients per request to reduce API call volume
* **Use webhooks** — Replace polling with event-driven notifications to save rate limit budget
* **Implement a queue** — Smooth out traffic spikes to avoid burst patterns
Need higher limits? Contact our sales team for Enterprise options.
# Auth Check
Source: https://docs.lettr.com/api-reference/system/auth-check
GET /auth/check
Validate the provided API key and return associated team information. Use this endpoint to verify API key validity in client libraries.
Validate your API key and confirm it is active. Returns the team ID associated with the key along with an ISO 8601 timestamp.
Use this endpoint to verify API key validity in client libraries or during initial setup before making other API calls.
# Health Check
Source: https://docs.lettr.com/api-reference/system/health-check
GET /health
Check the health status of the API. This endpoint does not require authentication.
Check the health status of the Lettr API. This endpoint does not require authentication and can be used for uptime monitoring or connectivity checks.
Returns the current status and an ISO 8601 timestamp.
# Create Template
Source: https://docs.lettr.com/api-reference/templates/create-template
POST /templates
Create a new email template with HTML or Topol editor JSON content. Automatically creates and publishes a template version with extracted merge tags.
Creates a new email template with either HTML or JSON content. Provide `html` for raw HTML templates or `json` for visual editor (Topol) templates — these fields are mutually exclusive.
The template is automatically assigned a URL-friendly slug based on its name. You can optionally assign it to a specific project and folder using `project_id` and `folder_id`. If omitted, the template is added to your team's default project.
# Delete Template
Source: https://docs.lettr.com/api-reference/templates/delete-template
DELETE /templates/{slug}
Permanently delete an email template and all its versions. If `project_id` is not provided, the template will be looked up in the team's default project.
Permanently deletes a template and all of its versions. This action cannot be undone. Any future [Send Email](/api-reference/emails/send-email) calls referencing this template's slug will fail.
Use the `project_id` query parameter if you have templates with the same slug across different projects.
# Get Merge Tags
Source: https://docs.lettr.com/api-reference/templates/get-merge-tags
GET /templates/{slug}/merge-tags
Retrieve the merge tags (variables) for a template version. By default, returns merge tags for the active version. Use the `version` parameter to get merge tags for a specific version.
Returns the merge tags found in a template's content. Use this to discover which `substitution_data` keys a template expects when [sending an email](/api-reference/emails/send-email).
By default, merge tags are extracted from the active version. Use the `version` query parameter to inspect a specific version instead.
# Get Template
Source: https://docs.lettr.com/api-reference/templates/get-template
GET /templates/{slug}
Retrieve a single email template by its slug. If `project_id` is not provided, the template will be looked up in the team's default project.
Retrieves the full details of a template by its slug, including the active version's HTML or JSON content, version count, and merge tag information.
Use the `project_id` query parameter if you have templates with the same slug across different projects.
# List Templates
Source: https://docs.lettr.com/api-reference/templates/list-templates
GET /templates
Retrieve a paginated list of email templates for a project. If `project_id` is not provided, templates from the team's default project will be returned.
Returns a paginated list of templates for your team. Optionally filter by project using the `project_id` query parameter.
Each template in the list includes its name, slug, project and folder assignment, and timestamps. To retrieve the full HTML content and version details for a specific template, use [Get Template](/api-reference/templates/get-template).
# Update Template
Source: https://docs.lettr.com/api-reference/templates/update-template
PUT /templates/{slug}
Update an existing email template's name and/or content. If content (html or json) is provided, a new active version will be created with extracted merge tags. If `project_id` is not provided, the template will be looked up in the team's default project.
Updates an existing template by its slug. You can update the template name, project assignment, or content. Providing new `html` or `json` content creates a new version of the template automatically.
The `html` and `json` fields are mutually exclusive. If neither is provided, only metadata (name, project) is updated without creating a new version.
# Create Webhook
Source: https://docs.lettr.com/api-reference/webhooks/create-webhook
POST /webhooks
Create a new webhook to receive event notifications at the specified URL.
# Delete Webhook
Source: https://docs.lettr.com/api-reference/webhooks/delete-webhook
DELETE /webhooks/{webhookId}
Delete a webhook. This removes the webhook from SparkPost and it will no longer receive event notifications.
# Get Webhook
Source: https://docs.lettr.com/api-reference/webhooks/get-webhook
GET /webhooks/{webhookId}
Retrieve details of a single webhook including its status, event types, and delivery information.
# List Webhooks
Source: https://docs.lettr.com/api-reference/webhooks/list-webhooks
GET /webhooks
Retrieve all webhooks configured for your account. Returns webhooks with their current status, event types, and delivery information.
# Update Webhook
Source: https://docs.lettr.com/api-reference/webhooks/update-webhook
PUT /webhooks/{webhookId}
Update an existing webhook. Only the fields provided will be updated (partial update). You can change the name, target URL, authentication, events, or active status.
# Introduction
Source: https://docs.lettr.com/integrations/introduction
Connect Lettr to platforms like Stripe, Supabase, WordPress, and Zapier for email delivery via SMTP, the HTTP API, or Edge Functions.
Integrate Lettr into third-party platforms and services. Each guide walks you through connecting Lettr for email delivery — whether through SMTP configuration, the HTTP API, or Edge Functions.
## Available Integrations
Send payment receipts, invoice emails, and subscription notifications
Send auth emails and transactional messages from Supabase using Lettr
Replace wp\_mail with Lettr for reliable email delivery from WordPress
Automate email sending with 8,000+ apps — no code required
## Don't See Your Platform?
You can integrate Lettr with any platform that supports SMTP or HTTP APIs.
Connect any platform that supports SMTP credentials
Send emails from any language or platform via REST API
Need help integrating with a specific platform? [Contact support](mailto:support@lettr.com) and we'll help you get set up.
# Stripe Email Integration
Source: https://docs.lettr.com/integrations/stripe
Install the Lettr Stripe app to send emails and saved templates to customers directly from the Stripe dashboard, with no code required.
The [Lettr Stripe App](https://marketplace.stripe.com/apps/lettr) lets you send emails and templates to your customers directly from the Stripe dashboard — without leaving Stripe or writing any code.
## Prerequisites
Before you begin, make sure you have:
Create an API key in the Lettr dashboard
Add and verify your sending domain
You'll also need:
* A [Stripe](https://stripe.com) account
* A sender address on your verified domain (e.g. `billing@yourdomain.com`)
## Install the Lettr App
Go to the [Lettr app on the Stripe Marketplace](https://marketplace.stripe.com/apps/lettr) and click **Install**. Follow the prompts to authorize the app for your Stripe account.
Enter your Lettr API key when prompted. The app uses this to send emails on your behalf.
Use an API key with sending permissions. Never share your API key publicly. See [API Key Permissions](/learn/api-keys/permissions) for details.
## Send Emails from Stripe
Once installed, the Lettr app appears in the sidebar when viewing a customer in Stripe. You can:
* **Send one-off emails** — Compose and send an email to any customer directly from their Stripe profile
* **Use Lettr templates** — Select from your saved Lettr templates and send them without leaving Stripe
* **Personalize content** — Customer details from Stripe are available to personalize your emails
No webhook setup, no code, no context switching. Open a customer in Stripe, pick a template or write a message, and send.
Create reusable templates in the [Lettr dashboard](https://app.lettr.com/templates) for common scenarios like payment reminders, onboarding sequences, or account updates. They'll be available to select directly in Stripe.
## Other Integrations
Auth emails and Edge Functions
Replace wp\_mail with Lettr
## What's Next
Create reusable email templates
Verify your sending domain
Send emails programmatically via the API
Improve email deliverability
# Supabase
Source: https://docs.lettr.com/integrations/supabase
Send transactional and auth emails from your Supabase project with Lettr, using SMTP for Supabase Auth or the HTTP API in Edge Functions.
Integrate [Supabase](https://supabase.com) with Lettr to send transactional emails from your Supabase project. This guide covers two approaches:
* **SMTP** — Configure Supabase Auth to send confirmation, password reset, and magic link emails through Lettr
* **Edge Functions** — Send emails programmatically from Supabase Edge Functions using Lettr's HTTP API
## Prerequisites
Before you begin, make sure you have:
Create an API key in the Lettr dashboard
Add and verify your sending domain
You'll also need:
* A [Supabase](https://supabase.com) project
* A sender address on your verified domain (e.g. `noreply@yourdomain.com`)
## Send Auth Emails via SMTP
Supabase Auth sends emails for user confirmations, password resets, magic links, and invitations. By default these go through Supabase's built-in email service, which has strict rate limits. Connecting Lettr via SMTP removes those limits and gives you full delivery visibility.
### SMTP Credentials
| Setting | Value |
| -------- | ---------------------------------- |
| Host | `smtp.lettr.com` |
| Port | `465` |
| Username | `lettr` |
| Password | Your API key (starts with `lttr_`) |
### Configure Supabase Auth
1. Go to your [Supabase project dashboard](https://supabase.com/dashboard)
2. Click **Authentication** in the left sidebar
3. Click **SMTP Settings** under the **Email** provider section
4. Toggle **Enable Custom SMTP** on
Fill in your sender information:
* **Sender email**: Your verified sending address (e.g. `noreply@yourdomain.com`)
* **Sender name**: Your application name (e.g. `My App`)
The sender email must use a domain you've verified in the [Lettr dashboard](https://app.lettr.com/domains). Emails from unverified domains will be rejected.
* **Host**: `smtp.lettr.com`
* **Port number**: `465`
* **Username**: `lettr`
* **Password**: Your Lettr API key (starts with `lttr_`)
Click **Save**. All Supabase Auth emails will now be sent through Lettr.
### Customize Auth Email Templates
Supabase lets you customize the HTML for each auth email type:
1. Go to **Authentication** → **Email Templates** in your Supabase dashboard
2. Select the template type (Confirm signup, Invite user, Magic Link, Reset password)
3. Edit the HTML and save
Supabase email templates use Go template syntax with variables like `{{ .ConfirmationURL }}`. These are processed by Supabase before the email is handed off to Lettr for delivery.
## Send Emails from Edge Functions
For transactional emails beyond auth (order confirmations, notifications, etc.), use Supabase Edge Functions with Lettr's HTTP API.
### Set Up Your API Key
Store your Lettr API key as a Supabase secret:
```bash theme={null}
supabase secrets set LETTR_API_KEY=lttr_your_api_key_here
```
### Create an Edge Function
```bash theme={null}
supabase functions new send-email
```
Replace the contents of `supabase/functions/send-email/index.ts` with:
```typescript theme={null}
Deno.serve(async (req) => {
const { to, subject, html } = await req.json();
const res = await fetch("https://app.lettr.com/api/emails", {
method: "POST",
headers: {
"Authorization": `Bearer ${Deno.env.get("LETTR_API_KEY")}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "noreply@yourdomain.com",
to: [to],
subject,
html,
}),
});
const data = await res.json();
return new Response(JSON.stringify(data), {
status: res.status,
headers: { "Content-Type": "application/json" },
});
});
```
### Deploy and Test
Deploy the function:
```bash theme={null}
supabase functions deploy send-email
```
Send a test email:
```bash theme={null}
curl -i --request POST \
'https://.supabase.co/functions/v1/send-email' \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"to": "recipient@example.com",
"subject": "Hello from Supabase + Lettr",
"html": "
It works!
This email was sent from a Supabase Edge Function using Lettr.
"
}'
```
### Call from Your App
Invoke the Edge Function from your client-side Supabase code:
```typescript theme={null}
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(
"https://.supabase.co",
""
);
const { data, error } = await supabase.functions.invoke("send-email", {
body: {
to: "recipient@example.com",
subject: "Order Confirmation",
html: "
Thanks for your order!
",
},
});
```
### Trigger from Database Webhooks
You can also trigger emails automatically when database rows change. Create a Database Webhook in Supabase that calls your Edge Function when a row is inserted into a table (e.g. `orders`):
1. Go to **Database** → **Webhooks** in your Supabase dashboard
2. Create a new webhook pointing to your `send-email` Edge Function
3. Set the trigger event (e.g. INSERT on the `orders` table)
```typescript theme={null}
Deno.serve(async (req) => {
const payload = await req.json();
const record = payload.record;
const res = await fetch("https://app.lettr.com/api/emails", {
method: "POST",
headers: {
"Authorization": `Bearer ${Deno.env.get("LETTR_API_KEY")}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "orders@yourdomain.com",
to: [record.customer_email],
subject: `Order #${record.id} confirmed`,
html: `
Order Confirmed
Thanks for your order, ${record.customer_name}!
`,
}),
});
const data = await res.json();
return new Response(JSON.stringify(data), {
status: res.status,
headers: { "Content-Type": "application/json" },
});
});
```
## Verify It Works
Check that emails are being delivered:
1. Trigger a test email (auth action or Edge Function call)
2. Verify delivery in the [Lettr logs](https://app.lettr.com/logs)
3. Check the recipient's inbox
Every email sent through Lettr appears in your [logs](https://app.lettr.com/logs) with full delivery status, so you can diagnose issues without guessing.
## Troubleshooting
* Verify the sender email uses a domain verified in Lettr
* Double-check that the host is `smtp.lettr.com` and the port is `465`
* Ensure your API key is correct and starts with `lttr_`
* Confirm the username is exactly `lettr` (lowercase)
* Verify the `LETTR_API_KEY` secret is set: `supabase secrets list`
* Ensure the API key starts with `lttr_` and hasn't been revoked
* Redeploy the function after setting secrets: `supabase functions deploy send-email`
Supabase applies its own rate limits on auth emails (e.g. one confirmation per 60 seconds per address). These are separate from Lettr's rate limits. Check your Supabase [Auth settings](https://supabase.com/dashboard) under **Rate Limits**.
Make sure your sending domain has proper DNS records:
* [SPF](/learn/domains/spf) — Authorizes Lettr to send on your behalf
* [DKIM](/learn/domains/dkim) — Cryptographically signs your emails
* [DMARC](/learn/domains/dmarc) — Tells receivers how to handle unauthenticated mail
See [Deliverability Best Practices](/knowledge-base/best-practices/deliverability) for more tips.
If port 465 doesn't work in your environment, use port 587 with STARTTLS instead. Both are secure.
## Other Integrations
Send payment emails from Stripe
Replace wp\_mail with Lettr
## What's Next
Full API documentation for sending emails
Verify your sending domain
Track delivery events in real-time
Create reusable email templates
# WordPress
Source: https://docs.lettr.com/integrations/wordpress
Install the Lettr WordPress plugin to replace wp_mail and route every email, including WooCommerce and contact forms, through Lettr's API.
The [Lettr WordPress plugin](https://github.com/lettr-com/lettr-wordpress) replaces the default `wp_mail()` function with Lettr's email API. Once activated, every outgoing email from your WordPress site — including emails from WooCommerce, contact form plugins, and any other plugin that uses `wp_mail()` — is sent through Lettr automatically.
No SMTP configuration needed. Just enter your API key and you're ready to go.
## Prerequisites
Before you begin, make sure you have:
Create an API key in the Lettr dashboard
Add and verify your sending domain
You'll also need:
* WordPress 5.8 or higher
* PHP 7.2 or higher
## Install the Plugin
Download the latest release as a ZIP from the [GitHub repository](https://github.com/lettr-com/lettr-wordpress).
In your WordPress admin panel, go to **Plugins → Add Plugin → Upload Plugin**, upload the ZIP file, click **Install**, and activate the plugin.
Alternatively, clone or extract the plugin into `/wp-content/plugins/lettr` and activate it from the **Plugins** page.
After activation, you're redirected to the plugin's setup page. Enter your Lettr API key (starts with `lttr_`) and configure your sender name and email address.
The sender email must use a domain you've verified in the [Lettr dashboard](https://app.lettr.com/domains). Emails from unverified domains will be rejected.
Use the built-in test email feature to confirm everything is working. Check the [Lettr logs](https://app.lettr.com/logs) to verify delivery.
## How It Works
The plugin overrides WordPress's built-in `wp_mail()` function and routes all emails through the [Lettr Send Email API](/api-reference/emails/send-email). This means:
* **All plugins are covered** — WooCommerce order confirmations, Contact Form 7 submissions, password resets, user notifications, and anything else that calls `wp_mail()`.
* **Attachments are supported** — File attachments are automatically encoded and sent via the API.
* **HTML and plain text** — The plugin detects the content type and sends the appropriate format.
* **Delivery tracking** — Every email appears in your [Lettr logs](https://app.lettr.com/logs) with full delivery status, opens, clicks, and bounces.
Since the plugin uses the Lettr HTTP API (not SMTP), there's no need to open any ports or configure SMTP settings on your server.
## Troubleshooting
* Verify your API key is correct and starts with `lttr_`
* Ensure the sender email uses a domain verified in Lettr
* Check the [Lettr logs](https://app.lettr.com/logs) for error details
* Confirm another plugin hasn't already overridden `wp_mail()` — the Lettr plugin shows an admin notice if this conflict is detected
The Lettr plugin replaces the `wp_mail()` function. If another plugin (e.g. another email delivery plugin) has already declared `wp_mail()`, the Lettr plugin cannot override it and will display a notice in the admin panel. Deactivate the conflicting plugin to resolve this.
Make sure your sending domain has proper DNS records:
* [SPF](/learn/domains/spf) — Authorizes Lettr to send on your behalf
* [DKIM](/learn/domains/dkim) — Cryptographically signs your emails
* [DMARC](/learn/domains/dmarc) — Tells receivers how to handle unauthenticated mail
See [Deliverability Best Practices](/knowledge-base/best-practices/deliverability) for more tips.
The plugin reads attachments from the local filesystem. Ensure the file paths passed to `wp_mail()` are readable by PHP. Temporary files that are deleted before the API request completes will fail silently.
## Other Integrations
Send payment emails from Stripe
Auth emails and Edge Functions
## What's Next
Verify your sending domain
Create reusable email templates
Track delivery events in real-time
Improve email deliverability
# Zapier Email Automation
Source: https://docs.lettr.com/integrations/zapier
Connect Lettr to Zapier to automate email sending across 8,000+ apps, send custom HTML messages or saved templates with no code required.
The [Lettr Zapier integration](https://zapier.com/apps/lettr/integrations) lets you automate email sending by connecting Lettr to 8,000+ apps — no code required.
## Prerequisites
Before you begin, make sure you have:
Create an API key in the Lettr dashboard
Add and verify your sending domain
You'll also need:
* A [Zapier](https://zapier.com) account (free tier available)
* A sender address on your verified domain (e.g. `notifications@yourdomain.com`)
## Available Actions
Send an email with custom HTML content, subject, sender, and reply-to address.
Send an email using a template saved in your Lettr account.
## Connect Lettr to Zapier
Go to [Zapier](https://zapier.com/apps/lettr/integrations) and create a new Zap.
Select your trigger app — the event that starts the workflow. For example, a new row in Google Sheets, a form submission in Typeform, or a payment in Stripe.
Search for **Lettr** and choose one of the available actions:
* **Send Email** — compose an email with custom HTML content
* **Send Email Template** — use a template from your Lettr account
Authenticate with your Lettr API key when prompted.
Use an API key with sending permissions. Never share your API key publicly. See [API Key Permissions](/learn/api-keys/permissions) for details.
Map fields from your trigger to the Lettr action:
* **From** (required) — sender address on your verified domain
* **Recipient** (required) — the recipient email address
* **Subject** (required) — email subject line
* **HTML content** (required for Send Email) — the email body
* **Reply to** (optional) — reply-to address
Test the Zap to verify emails are sent correctly, then turn it on.
## Example Use Cases
| Trigger | Action | Use Case |
| ----------------------- | ------------------- | --------------------------------------------- |
| New Typeform submission | Send Email Template | Send a confirmation email to form respondents |
| New Stripe payment | Send Email | Send a custom payment receipt |
| New Google Sheets row | Send Email Template | Send onboarding emails to imported contacts |
| New Calendly event | Send Email | Send meeting confirmation with details |
Use **Send Email Template** when you want to maintain consistent branding. Create templates in the [Lettr dashboard](https://app.lettr.com/templates) and reference them in your Zaps.
## Other Integrations
Send emails directly from Stripe
Auth emails and Edge Functions
Replace wp\_mail with Lettr
## What's Next
Create reusable email templates
Send emails programmatically via the API
# Introduction
Source: https://docs.lettr.com/introduction
Lettr is an email infrastructure platform for developers, offering reliable transactional and marketing delivery, inbound parsing, and tracking.
Lettr is an email infrastructure platform built for developers who need reliable, scalable email delivery without the complexity. Whether you're sending transactional emails like password resets and order confirmations, or building sophisticated email workflows with tracking and analytics, Lettr provides the APIs and tools to get it done.
Email delivery is deceptively complex. Between authentication protocols like SPF, DKIM, and DMARC, reputation management, bounce handling, and the ever-changing landscape of spam filtering, building reliable email infrastructure from scratch is a significant undertaking. Lettr handles this complexity so you can focus on your application.
## What You Can Build with Lettr
Password resets, order confirmations, shipping notifications, account alerts, and any email triggered by user actions.
Newsletters, announcements, and promotional emails with open and click tracking.
Receive and parse incoming emails to power support tickets, reply detection, and automated workflows.
Build complex email flows with webhooks, templates, and real-time event tracking.
## Core Capabilities
Lettr provides everything you need for production email infrastructure:
Send individual emails or batch thousands with a single API call. Lettr handles queuing, delivery optimization, and retry logic automatically. Support for HTML, plain text, and AMP email formats with automatic MIME handling.
Configure SPF, DKIM, and DMARC records through the dashboard or API. Lettr guides you through DNS setup and verifies your configuration to ensure maximum deliverability. Support for multiple sending domains, tracking domains, and custom storage domains for email assets.
Track opens, clicks, bounces, spam complaints, and unsubscribes as they happen. Receive instant webhook notifications or query the API for detailed analytics. Custom tracking domains keep your brand visible in every link.
Create email templates with the visual Topol.io editor or write HTML directly. Use variables for personalization and store templates in Lettr for consistent branding across your application.
Automatic handling of bounces, spam complaints, and unsubscribes protects your sender reputation. Lettr maintains suppression lists and prevents sending to problematic addresses without any code on your part.
Receive emails at your domain and process them programmatically. Parse sender information, subject, body, and attachments via webhooks. Build support inboxes, reply detection, or any workflow that starts with an incoming email.
## Get Started
Choose your integration path and send your first email:
Official SDK with interactive setup
Get started with Lettr using PHP
Get started with Lettr using Node.js
Connect via SMTP protocol
Prefer to be walked through it? **Adamko**, Lettr's built-in [AI assistant](/learn/ai-assistant/introduction), can set up your account for you — brand kit, branded transactional templates, sending domain, and API key — from nothing but your website URL.
## How It Works
Create an account at [app.lettr.com](https://app.lettr.com) and generate an API key from your dashboard. Keys can be scoped to sending-only or full access.
Add your sending domain and configure DNS records for SPF, DKIM, and DMARC authentication. Lettr provides the exact records to add and verifies your setup.
Make a single API call to send an email. Lettr handles delivery, tracking, and bounce processing automatically.
Track delivery metrics in the dashboard or receive real-time webhook notifications. Use analytics to optimize your email strategy.
## Why Lettr?
Clean REST APIs with predictable responses, comprehensive SDKs for popular languages, and documentation written by developers for developers. No enterprise sales calls required—sign up and start building.
Lettr maintains relationships with major email providers and continuously optimizes delivery infrastructure. Automatic warm-up for new domains, reputation monitoring, and feedback loop integration help ensure your emails reach the inbox.
Know exactly what's happening with every email. Track delivery status, opens, clicks, and bounces as they occur. Webhooks deliver events in real-time, and the dashboard provides at-a-glance analytics.
Use the REST API directly, integrate with official SDKs, or connect via standard SMTP. Lettr fits into your existing stack without requiring architectural changes. Works with serverless functions, traditional servers, and everything in between.
## Explore the Documentation
Authentication and permissions
SPF, DKIM, and DMARC setup
Email delivery options
Real-time event notifications
Visual email editor
Stripe, Supabase, WordPress
Adamko, your in-app helper
Complete API documentation
# Batch and Bulk Sending
Source: https://docs.lettr.com/knowledge-base/best-practices/batch-bulk-sending
Best practices for high-volume email sending including batching, rate management, and recipient grouping
When your application needs to send thousands or millions of emails, how you structure and pace those sends directly affects deliverability, performance, and cost. This guide covers practical strategies for batching, rate management, and recipient grouping at scale.
***
## Batch Sending with the API
Lettr's API supports sending to multiple recipients in a single request. This reduces HTTP overhead and simplifies your sending logic.
### Single Request, Multiple Recipients
```javascript theme={null}
const response = await fetch('https://app.lettr.com/api/emails', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'updates@mail.example.com',
to: [
{ email: 'user1@example.com', name: 'Alice' },
{ email: 'user2@example.com', name: 'Bob' },
{ email: 'user3@example.com', name: 'Charlie' }
],
subject: 'Your weekly summary',
templateId: 'weekly-summary',
substitutionData: {
// Shared data for all recipients
companyName: 'Acme Inc'
}
})
});
```
### Per-Recipient Substitution Data
When each recipient needs different content (personalized data, unique links), pass substitution data per recipient:
```javascript theme={null}
const response = await fetch('https://app.lettr.com/api/emails', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'orders@mail.example.com',
to: [
{
email: 'alice@example.com',
substitutionData: {
name: 'Alice',
orderId: 'ORD-1001',
total: '$49.99'
}
},
{
email: 'bob@example.com',
substitutionData: {
name: 'Bob',
orderId: 'ORD-1002',
total: '$129.00'
}
}
],
templateId: 'order-confirmation'
})
});
```
Using per-recipient substitution data with templates is more efficient than sending individual API calls for each recipient. One request with 100 recipients is faster than 100 individual requests.
***
## Structuring High-Volume Sends
When sending to large lists (tens of thousands or more), you need to break the work into manageable batches and pace them appropriately.
### Batch Size
Keep each API request to a reasonable number of recipients. Larger payloads take longer to process and are more likely to time out.
| List Size | Recommended Batch Size | Approach |
| -------------- | ---------------------- | -------------------------------------------- |
| \< 1,000 | All in one request | Single API call |
| 1,000–10,000 | 100–500 per request | Loop with sequential requests |
| 10,000–100,000 | 100–500 per request | Queue-based with rate limiting |
| 100,000+ | 100–500 per request | Queue-based with backpressure and monitoring |
### Queue-Based Architecture
For large sends, use a job queue to manage the workload. This gives you control over pacing, retry logic, and failure handling.
```javascript theme={null}
// Producer: Split recipients into batches and enqueue
async function enqueueBulkSend(recipients, templateId) {
const BATCH_SIZE = 200;
for (let i = 0; i < recipients.length; i += BATCH_SIZE) {
const batch = recipients.slice(i, i + BATCH_SIZE);
await queue.add('send-email-batch', {
recipients: batch,
templateId,
batchNumber: Math.floor(i / BATCH_SIZE) + 1,
totalBatches: Math.ceil(recipients.length / BATCH_SIZE)
});
}
}
// Consumer: Process each batch with rate limiting
queue.process('send-email-batch', async (job) => {
const { recipients, templateId } = job.data;
const response = await fetch('https://app.lettr.com/api/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LETTR_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'newsletter@mail.example.com',
to: recipients,
templateId
})
});
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
throw new Error(`Rate limited. Retry after ${retryAfter}s`);
}
if (!response.ok) {
throw new Error(`Send failed: ${response.status}`);
}
});
```
Configure your queue workers with appropriate concurrency limits. Running too many workers in parallel will hit Lettr's rate limits. Start with 2–3 concurrent workers and adjust based on observed throughput.
***
## Rate Management
Lettr enforces rate limits to protect deliverability for all senders. Understanding and working within these limits is essential for high-volume sending.
### Handling Rate Limit Responses
When you exceed the rate limit, the API returns a `429 Too Many Requests` response with a `Retry-After` header indicating how long to wait.
```javascript theme={null}
async function sendWithRetry(payload, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch('https://app.lettr.com/api/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LETTR_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '10');
console.log(`Rate limited. Waiting ${retryAfter}s before retry...`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}
```
### Proactive Rate Limiting
Rather than hitting rate limits and retrying, pace your sends proactively:
```javascript theme={null}
// Simple token bucket rate limiter
class RateLimiter {
constructor(maxRequests, windowMs) {
this.maxRequests = maxRequests;
this.windowMs = windowMs;
this.timestamps = [];
}
async waitForSlot() {
const now = Date.now();
this.timestamps = this.timestamps.filter(t => now - t < this.windowMs);
if (this.timestamps.length >= this.maxRequests) {
const oldestInWindow = this.timestamps[0];
const waitTime = this.windowMs - (now - oldestInWindow);
await new Promise(resolve => setTimeout(resolve, waitTime));
}
this.timestamps.push(Date.now());
}
}
// Usage: 300 requests per 5 minutes
const limiter = new RateLimiter(300, 5 * 60 * 1000);
for (const batch of batches) {
await limiter.waitForSlot();
await sendBatch(batch);
}
```
***
## Recipient Grouping Strategies
How you segment your recipients for bulk sends affects both deliverability and engagement.
### Group by Engagement Level
Send to your most engaged recipients first. This front-loads positive signals (opens, clicks) that improve your reputation for the remainder of the send.
| Send Order | Segment | Why |
| -------------- | ------------------------------ | -------------------------------------------------------- |
| First | Opened/clicked in last 7 days | Highest engagement probability — builds positive signals |
| Second | Opened/clicked in last 30 days | Still engaged, reinforces positive reputation |
| Third | Opened/clicked in last 90 days | Moderate risk, but still opted-in |
| Last (or skip) | No engagement in 90+ days | Highest risk — consider a re-engagement campaign first |
### Group by Domain
When sending to large lists, consider grouping recipients by their email domain. This lets you monitor deliverability per provider and respond if a specific provider starts throttling.
```javascript theme={null}
function groupByDomain(recipients) {
const groups = {};
for (const recipient of recipients) {
const domain = recipient.email.split('@')[1];
if (!groups[domain]) groups[domain] = [];
groups[domain].push(recipient);
}
return groups;
}
// Send to each domain group with independent monitoring
const groups = groupByDomain(allRecipients);
for (const [domain, recipients] of Object.entries(groups)) {
console.log(`Sending ${recipients.length} emails to ${domain}`);
await enqueueBulkSend(recipients, templateId);
}
```
***
## Monitoring Bulk Sends
Track the health of your bulk sends in real time using webhooks.
### Key Metrics to Track
| Metric | Healthy | Warning | Action Required |
| -------------- | ------- | -------- | ------------------------------ |
| Delivery rate | > 95% | 90–95% | Investigate bounce reasons |
| Bounce rate | \< 2% | 2–5% | Clean list, check data quality |
| Complaint rate | \< 0.1% | 0.1–0.3% | Review content and targeting |
| Deferral rate | \< 5% | 5–15% | Reduce sending speed |
### Real-Time Dashboard
Set up a simple counter to track bulk send progress:
```javascript theme={null}
const bulkSendMetrics = {
sent: 0,
delivered: 0,
bounced: 0,
complained: 0,
deferred: 0
};
app.post('/webhooks/lettr', (req, res) => {
const event = req.body;
switch (event.type) {
case 'email.delivered': bulkSendMetrics.delivered++; break;
case 'email.bounced': bulkSendMetrics.bounced++; break;
case 'email.complained': bulkSendMetrics.complained++; break;
case 'email.deferred': bulkSendMetrics.deferred++; break;
}
// Alert if complaint rate exceeds threshold
const total = bulkSendMetrics.delivered + bulkSendMetrics.bounced;
if (total > 100 && bulkSendMetrics.complained / total > 0.003) {
alertTeam('Complaint rate exceeding 0.3% — consider pausing send');
}
res.sendStatus(200);
});
```
Always set up monitoring before starting a bulk send. Discovering a problem after sending to your entire list is much worse than catching it after the first few thousand and pausing.
***
## Common Mistakes
Blasting your full list as fast as possible overwhelms receiving servers and triggers rate limiting or blocks. Pace your sends and start with engaged recipients.
Always check your suppression list before a bulk send. Sending to previously bounced or complained addresses damages your reputation with every hit. Lettr's suppression list handles this automatically, but you should also maintain your own internal suppression logic.
Treating 429 responses as permanent failures instead of implementing retry logic with backoff. Rate limits are temporary — wait and retry.
Launching a bulk send and walking away. Without real-time monitoring, you won't catch deliverability problems until it's too late.
Sending 50,000 individual API requests when you could batch 200 recipients per request (250 requests total). Batching is dramatically more efficient.
***
## Related Topics
API documentation for batch sending
Understanding and handling rate limits
Warm-up schedules for new domains
Maintain clean recipient lists before bulk sends
# Dark Mode Email Design
Source: https://docs.lettr.com/knowledge-base/best-practices/dark-mode-design
Design emails that look great in both light and dark mode with defensive CSS strategies and testing techniques
Most email clients now offer a dark mode that automatically adjusts email colors. Gmail, Apple Mail, Outlook, and Yahoo Mail each handle dark mode differently — some invert colors, some blend backgrounds, and some leave emails untouched. Without defensive design, your carefully crafted email can end up with invisible text, clashing colors, or unreadable content in dark mode.
***
## How Email Clients Handle Dark Mode
Email clients use three different strategies to render emails in dark mode, and the strategy varies by client and platform.
| Strategy | What Happens | Clients |
| --------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------- |
| **No change** | Email renders exactly as coded, even in dark mode | Apple Mail (partial), Gmail (with dark-mode meta support) |
| **Partial inversion** | Client changes background colors but preserves some text colors | Gmail Android, Outlook.com |
| **Full inversion** | Client inverts all colors — light backgrounds become dark, dark text becomes light | Outlook Windows (desktop), Gmail iOS, Yahoo Mail |
You cannot rely on any single strategy. Your email needs to look acceptable under all three scenarios. The techniques in this guide are defensive — they ensure readability regardless of what the client does.
***
## Defensive Design Fundamentals
### Always Set Explicit Colors
The most important rule for dark mode compatibility: never rely on default colors. If you don't set a text color, the email client decides — and in dark mode, that default might become white text on a white background you specified.
```html theme={null}
This text has no explicit color.
This text is always visible.
```
### Set Both bgcolor and background-color
Outlook desktop uses the `bgcolor` HTML attribute, while other clients use CSS `background-color`. Set both.
```html theme={null}
Works in Outlook desktop and all other clients.
```
### Avoid Pure Black and Pure White
Pure white (#ffffff) backgrounds and pure black (#000000) text create harsh contrast in both modes. Use near-white and near-black values that feel softer and adapt better when inverted.
```html theme={null}
Slightly off-white background, dark (not black) text.
```
***
## Images in Dark Mode
### Add Backgrounds to Transparent Images
Logos and icons with transparent backgrounds are the most common dark mode casualty. A dark logo on a transparent PNG becomes invisible when the background turns dark.
```html theme={null}
```
Export logos as PNG with a built-in white or light padding around the artwork. This creates a visible "safe zone" around the logo regardless of the email background color.
### Use Images With Built-In Contrast
For hero images and banners, ensure the image itself contains enough contrast to be readable on both light and dark backgrounds. Avoid images that bleed into the email background.
```html theme={null}
```
***
## Dark Mode Meta Tag
Some email clients (notably Apple Mail and some versions of Gmail) support a meta tag that indicates your email is dark-mode-aware. Adding this can prevent the client from applying its own color transformations.
```html theme={null}
```
This meta tag tells the email client "I handle dark mode myself." If you add it, you must provide dark mode styles via `@media (prefers-color-scheme: dark)`. Adding the meta tag without corresponding styles can result in a broken appearance.
***
## CSS Dark Mode Styles
For clients that support `
Your Weekly Update
Here's what happened this week...
```
The inline styles serve as the default (light mode) appearance. The `@media (prefers-color-scheme: dark)` block overrides them for clients that support it. The `!important` declarations are necessary because inline styles have higher specificity.
***
## Buttons in Dark Mode
Buttons are particularly vulnerable to dark mode issues. A white button on a light background can become invisible, or a dark button can lose its border against a dark background.
### Bulletproof Dark Mode Buttons
```html theme={null}
```
Key principles:
* Use a background color with enough contrast against both light and dark email backgrounds
* Add a border matching the button color — if the background gets inverted, the border maintains the button shape
* Use white text on colored buttons — white text stays readable against most inverted backgrounds
***
## Testing Dark Mode
### Manual Testing
Test your emails in dark mode on these clients, which cover the main rendering behaviors:
System Preferences → Appearance → Dark. Apple Mail generally respects `prefers-color-scheme` and applies minimal auto-inversion.
Gmail aggressively inverts colors in dark mode, especially on Android. Enable dark mode in the Gmail app settings and send yourself a test email.
Outlook's Word-based renderer applies full color inversion. File → Office Account → Office Theme → Dark Gray or Black. This is typically the most aggressive dark mode.
Click the gear icon → Dark mode. Outlook.com applies partial inversion and sometimes ignores explicit colors.
Use Lettr's [test email](/learn/sending/test-emails) feature to send tests to your own accounts. Check both light and dark mode every time you update a template.
### What to Check
| Check | Pass | Fail |
| --------------------- | ----------------------------------------- | --------------------------------------- |
| Body text readable | Text visible against all backgrounds | Text disappears or becomes hard to read |
| Logo visible | Logo has contrast against dark background | Logo blends into dark background |
| Buttons visible | Button shape and text clearly visible | Button blends in or text disappears |
| Images look natural | Images have clear boundaries | Images bleed into background |
| Links distinguishable | Links stand out from body text | Links indistinguishable from text |
***
## Common Mistakes
If you don't set an explicit text color, the email client assigns one. In dark mode, the client may change it to white — which becomes invisible if you've set a white background that the client didn't invert. Always set explicit colors on every text element.
A dark-colored logo on a transparent background disappears completely when the email background is inverted to dark. Either export logos with a built-in light background, or wrap the image in a container with an explicit white background.
The `color-scheme: light dark` meta tag tells the client you handle dark mode. If you declare this but don't provide `@media (prefers-color-scheme: dark)` styles, the client may not apply any automatic adjustments, leaving your email unreadable in dark mode.
Each email client handles dark mode differently. An email that looks perfect in Apple Mail dark mode may be unreadable in Outlook desktop dark mode. Test across at least three clients.
Background images in CSS (`background-image`) are unsupported in many email clients and don't adapt to dark mode at all. Use solid background colors for containers.
***
## Related Topics
Build and manage email templates with the Topol editor
Make your emails accessible to all recipients
How different email clients render HTML email
Send test emails before going live
# Deliverability Best Practices
Source: https://docs.lettr.com/knowledge-base/best-practices/deliverability
Maximize email deliverability and inbox placement with proper SPF, DKIM, and DMARC authentication, tracking domains, and domain warm-up.
Deliverability is the measure of how successfully your emails reach recipients' inboxes rather than spam folders or getting rejected entirely. Even well-crafted emails fail if they never arrive. This guide covers the foundational practices that keep your emails landing in the inbox.
***
## Authentication Is Non-Negotiable
Email authentication tells receiving mail servers that you are who you claim to be. Without proper authentication, your emails are far more likely to be filtered or rejected.
### Complete Your Domain Setup
Every sending domain in Lettr needs three DNS records configured:
| Record | Purpose | What It Does |
| ----------- | ------------------- | ----------------------------------------------------------------------------------- |
| CNAME | Domain verification | Proves you own the domain and authorizes Lettr to send on your behalf |
| DKIM (TXT) | Email signing | Adds a cryptographic signature to every email, proving it wasn't altered in transit |
| DMARC (TXT) | Policy enforcement | Tells receivers what to do when authentication fails, and where to send reports |
Lettr provides the exact DNS record values when you add a domain. Copy them precisely — even small differences cause verification failures. See [Sending Domains](/learn/domains/sending-domains) for the full setup guide.
### Set Up a Tracking Domain
Using a custom tracking domain (e.g., `track.yourdomain.com`) instead of a shared tracking domain improves deliverability. Links in your emails will use your own domain, which builds reputation under your brand rather than sharing it with other senders.
See [Tracking Domains](/learn/domains/tracking-domains) for setup instructions.
***
## Warm Up New Domains
Mailbox providers treat new sending domains with suspicion. If you send thousands of emails from a domain with no history, spam filters will likely intervene. Warming up means gradually increasing volume so providers can observe consistent, legitimate behavior.
### Recommended Warm-Up Schedule
| Week | Daily Volume | Notes |
| ---- | --------------- | ------------------------------------------ |
| 1 | 50–100 | Send to your most engaged recipients first |
| 2 | 200–500 | Monitor bounce and complaint rates closely |
| 3 | 500–2,000 | Continue only if metrics remain healthy |
| 4 | 2,000–5,000 | Gradually approach your target volume |
| 5+ | Scale as needed | Maintain consistent sending patterns |
Sending high volumes immediately from a new domain will damage your reputation before you've built one. This damage can take weeks to recover from.
### Warm-Up Tips
* **Start with engaged recipients**: Send first to users who regularly open and click your emails. Positive engagement signals help establish reputation.
* **Be consistent**: Send every day during warm-up. Sporadic large sends look suspicious.
* **Watch your metrics**: If bounce rates exceed 5% or spam complaints exceed 0.3%, slow down and investigate before continuing.
* **Separate transactional and marketing**: If you send both types, consider using separate subdomains so marketing reputation issues don't affect transactional delivery.
***
## Maintain Clean Recipient Lists
Sending to invalid or unengaged addresses is one of the fastest ways to damage deliverability. Mailbox providers monitor your bounce and complaint rates and will throttle or block senders with poor list hygiene.
### Process Bounces Immediately
Hard bounces mean the address is permanently undeliverable. Continuing to send to hard-bounced addresses signals to mailbox providers that you don't maintain your lists.
Set up a webhook to handle bounce events in real time:
```javascript theme={null}
app.post('/webhooks/lettr', (req, res) => {
const event = req.body;
if (event.type === 'email.bounced') {
const { to, bounceType } = event.data;
if (bounceType === 'hard') {
// Remove from your mailing list immediately
removeFromList(to);
}
}
res.sendStatus(200);
});
```
See [Bounces](/learn/suppressions/bounces) for detailed bounce handling guidance.
### Use Double Opt-In
Confirm subscriptions before adding addresses to your list. This ensures addresses are valid and that the owner actually wants your emails:
1. User submits their email address
2. You send a confirmation email with a unique link
3. User clicks the link to confirm
4. Only then add them to your sending list
### Remove Unengaged Subscribers
Recipients who never open your emails drag down your engagement metrics. Mailbox providers use engagement signals (opens, clicks) to decide inbox placement. Periodically remove or re-engage subscribers who haven't interacted in 6–12 months.
***
## Content That Avoids Spam Filters
Even with perfect authentication and a clean list, your email content affects deliverability.
### Subject Lines
| Do | Don't |
| ------------------------- | ---------------------------------------------- |
| Be clear and relevant | Use ALL CAPS |
| Keep under 50 characters | Use excessive punctuation!!! |
| Personalize when possible | Use spam trigger words (FREE, ACT NOW, URGENT) |
| Set accurate expectations | Mislead about content |
### Email Body
| Do | Don't |
| ---------------------------------- | ------------------------------------------------- |
| Balance text and images | Send image-only emails |
| Include a plain text version | Send HTML only |
| Use your own domain for links | Use URL shorteners (they're associated with spam) |
| Add a visible unsubscribe link | Hide or omit the unsubscribe option |
| Include a physical mailing address | Omit required compliance elements |
### Required Footer Elements
Every marketing and bulk email should include:
* **Unsubscribe link** — One-click unsubscribe is now required by major providers
* **Physical mailing address** — Required by CAN-SPAM
* **Reply-to address** — Allows recipients to respond
See [CAN-SPAM Requirements](/knowledge-base/compliance/can-spam) for detailed legal requirements.
***
## Monitor Your Metrics
Track these key indicators to catch problems early:
| Metric | Healthy Target | Warning Sign | Action |
| ------------------- | -------------- | ------------ | -------------------------------------------- |
| Bounce rate | \< 2% | > 5% | Clean your list, validate addresses |
| Spam complaint rate | \< 0.1% | > 0.3% | Review content, check unsubscribe visibility |
| Open rate | > 15% | \< 10% | Improve subject lines, check inbox placement |
| Click rate | > 2% | \< 1% | Improve CTAs and content relevance |
Open rates are increasingly unreliable due to Apple Mail Privacy Protection and other privacy features that pre-fetch images. Use click rates and direct engagement as more reliable indicators. See [Open & Click Tracking Accuracy](/knowledge-base/troubleshooting/tracking-accuracy) for details.
***
## Testing Before Sending
### Pre-Send Checklist
1. **Send test emails** — Send to yourself and colleagues across different email clients (Gmail, Outlook, Apple Mail)
2. **Check rendering** — Verify your email looks correct on both desktop and mobile
3. **Verify links** — Click every link in the test email to confirm they work
4. **Review content** — Read through for spam trigger words and formatting issues
5. **Validate authentication** — Check email headers to confirm DKIM is passing
See [Test Emails](/learn/sending/test-emails) for how to send test emails through Lettr.
***
## Common Deliverability Issues
* Verify all authentication records (DKIM, DMARC) are passing
* Review your email content for spam triggers
* Check that you have a visible unsubscribe link
* Ensure your domain has built sufficient reputation (warm up if new)
* See [Emails Landing in Spam](/knowledge-base/troubleshooting/spam-placement) for step-by-step diagnosis
* Implement double opt-in for new subscribers
* Validate email addresses at the point of collection
* Remove subscribers who haven't engaged in 6+ months
* Process bounce webhooks immediately — don't batch them
* See [Bounce Diagnosis](/knowledge-base/troubleshooting/bounce-diagnosis) for interpreting bounce codes
* Improve subject lines — test different approaches
* Send at times when your audience is most active
* Segment your audience for more relevant content
* Remove unengaged subscribers to improve overall metrics
* Check if Apple MPP is inflating or deflating your numbers
* Check if you're sending too fast during domain warm-up
* Verify your domain reputation hasn't been damaged
* Look for `email.deferred` webhook events for specific reasons
* Some delays are normal — receiving servers may throttle new senders
***
## Related Topics
Build and protect your sender reputation
Maintain healthy recipient lists
Configure and verify your sending domains
Understand bounce types and handling
# Email Accessibility
Source: https://docs.lettr.com/knowledge-base/best-practices/email-accessibility
Make your emails accessible to all recipients with alt text, semantic HTML, color contrast, and screen reader best practices
Accessible emails reach more people. Over 1 billion people worldwide live with some form of disability, and many of them use assistive technologies like screen readers, magnifiers, and keyboard navigation to read email. Building accessible emails isn't just good practice — it improves engagement for everyone, because the same techniques that help assistive technology users also make emails clearer and more readable on all devices.
***
## Semantic Structure
Screen readers rely on HTML structure to help users navigate content. Without proper structure, an email becomes a flat wall of text that's difficult to scan.
### Use Heading Tags for Hierarchy
Use `
` through `
` to create a logical content hierarchy. Never use font size or bold styling alone to indicate headings — screen readers won't recognize them.
```html theme={null}
Your Monthly Summary
Account Activity
Here's what happened this month...
Your Monthly Summary
```
### Use Lists for Sequential Content
When presenting a series of items, use proper list markup:
```html theme={null}
3 new orders received
2 shipments delivered
1 return processed
```
### Mark Layout Tables as Presentational
Email HTML relies on tables for layout. Add `role="presentation"` to every table that's used for layout (not data). This tells screen readers to ignore the table structure.
```html theme={null}
Content goes here
Item
Price
Widget Pro
$29.99
```
***
## Images and Alt Text
Images are one of the most common accessibility barriers in email. Many email clients block images by default, and screen readers can only convey image content through alt text.
### Write Descriptive Alt Text
Every image needs an `alt` attribute that describes its content or purpose.
```html theme={null}
```
A decorative image (borders, spacers, visual flourishes) should have `alt=""` — not a missing alt attribute. An empty alt tells screen readers to skip the image. A missing alt causes screen readers to announce the filename, which is confusing.
### Never Put Critical Content Only in Images
Discount codes, CTAs, dates, and important instructions must exist as live text, not just in images. If images are blocked, the recipient should still understand the email.
```html theme={null}
```
***
## Color and Contrast
### Minimum Contrast Ratios
The Web Content Accessibility Guidelines (WCAG) define minimum contrast ratios. Apply these to your email content:
| Element | Minimum Ratio | Example |
| -------------------------------- | ------------- | ---------------------------------------------- |
| Body text | 4.5:1 | Dark gray (#4a4a68) on white (#ffffff) = 7.2:1 |
| Large text (18px+ or 14px+ bold) | 3:1 | Medium gray (#6b7280) on white = 4.6:1 |
| UI components (buttons, links) | 3:1 | Indigo (#6366F1) on white = 4.5:1 |
Use the [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/) to verify your color combinations. Enter your foreground and background colors to get an instant pass/fail result.
### Don't Rely on Color Alone
Color should never be the only way to convey information. Always pair color with text labels, icons, or patterns.
```html theme={null}
● Failed
● Delivered
✕ Failed✓ Delivered
```
***
## Typography and Readability
### Font Size
Body text should be at least 14px, and 16px is preferred. Smaller text is difficult to read on mobile devices and for users with low vision.
```html theme={null}
Body text at 16px with 1.5 line height for comfortable reading.
Footer text can be smaller (12px minimum) but maintain adequate contrast.
```
### Line Length and Spacing
* **Line length**: Keep content within 600px max width. Lines longer than 75 characters are harder to read.
* **Line height**: Use 1.5 for body text. Tight line heights (1.0–1.2) make text harder to scan.
* **Paragraph spacing**: Add margins between paragraphs (16px minimum) to create visual separation.
### Font Stacks
Always include fallback fonts. Users with custom system fonts or accessibility settings should see readable text regardless.
```html theme={null}
This font stack covers all major operating systems with clean, readable defaults.
```
***
## Links and Buttons
### Descriptive Link Text
Screen readers can navigate by links, reading each link text out of context. Make sure every link makes sense on its own.
```html theme={null}
Click hereRead moreView your monthly reportManage notification settings
```
### Button Size and Touch Targets
Buttons should be large enough to tap easily on mobile devices. The minimum recommended touch target is 44×44 pixels.
```html theme={null}
```
### Underline Links in Body Text
In body text, always underline links. Users with color vision deficiencies may not be able to distinguish link color from body text color.
```html theme={null}
```
***
## Plain Text Fallbacks
Always include a plain text version of your email alongside the HTML version. Some recipients prefer plain text, and some email clients don't render HTML at all.
When using the Lettr API, include both `html` and `text` fields:
```javascript theme={null}
await fetch('https://app.lettr.com/api/emails', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'updates@mail.example.com',
to: 'recipient@example.com',
subject: 'Your order has shipped',
html: '
Order #1234 shipped
Your package is on its way.
',
text: 'Order #1234 shipped\n\nYour package is on its way.\n\nTrack your package: https://example.com/track/1234'
})
});
```
The plain text version doesn't need to mirror the HTML exactly. Focus on conveying the same information and include full URLs (not hyperlinked text) so recipients can copy and paste them.
***
## Language and Direction
### Set the Language Attribute
Screen readers use the `lang` attribute to switch pronunciation rules. Always set it on the outermost element.
```html theme={null}
Your Email Subject
```
### Support Right-to-Left Languages
If you send emails in Arabic, Hebrew, or other RTL languages, use the `dir` attribute:
```html theme={null}
مرحبًا بك في خدمتنا
```
***
## Accessibility Checklist
Use `
` through `
` for content hierarchy, not styled `
` tags.
Descriptive alt for content images, empty `alt=""` for decorative images.
All layout tables have `role="presentation"`.
4.5:1 minimum for body text, 3:1 for large text and UI components.
Status indicators, errors, and important cues use text labels alongside color.
No "click here" or "read more" — every link makes sense out of context.
Body text is 14px minimum (16px preferred), line height 1.5.
Both HTML and plain text versions are sent with every email.
The `lang` attribute is set on the outer HTML element.
***
## Common Mistakes
Omitting the `alt` attribute entirely causes screen readers to announce the image filename (e.g., "IMG\_20240115\_hero\_v3\_final.png"), which is confusing and unhelpful. Always add an `alt` attribute — even if it's empty for decorative images.
Light gray text on a white background or white text on a light-colored button may look subtle and elegant, but it fails contrast requirements and is unreadable for many users. Check every text/background combination.
Screen reader users often navigate by tabbing through links. A list of "click here" links provides no context about where each link goes. Use descriptive text like "View your invoice" or "Update payment method".
Legal text and footers are often set to 10px or smaller, making them illegible on mobile devices. Keep footer text at 12px minimum.
Sending HTML-only emails excludes recipients using text-only email clients or those who prefer plain text for accessibility reasons. Always include a `text` version.
***
## Related Topics
Build and manage email templates with the Topol editor
Ensure your emails look good in dark mode
HTML, plain text, and AMP email explained
How different email clients render HTML email
# Email Editor Best Practices
Source: https://docs.lettr.com/knowledge-base/best-practices/email-editor-best-practices
Best practices for the Topol email editor, covering structures, content blocks, responsive layouts, and common mistakes new users should avoid.
This guide helps new Topol Email editor users understand how the editor works—what the main features do, how they connect, and what pitfalls to avoid. Whether you're building your first template or looking to sharpen your workflow, this article covers the core concepts, practical tips, and common mistakes so you can create polished, responsive emails with confidence.
For a more technical, developer-oriented introduction to the editor, see the [Topol Email Editor technical guide](/learn/templates/topol-editor).
This article focuses on best practices and hands-on guidance. It complements—rather than duplicates—the technical guide, so both are worth reading. For in-depth walkthroughs of individual features, the [Topol support center](https://support.topol.io/en/) provides detailed articles with step-by-step instructions.
***
## Basic Building Blocks: Structures and Content Blocks
Email templates consist of **structures** and **content blocks**. Understanding the relationship between these two concepts is the single most important thing to learn as a new user—it makes every other feature easier to use.
A **structure** defines the layout. It controls how many columns appear in a row and how content behaves on desktop and mobile devices. Structures can have one, two, three, or four columns. To add a structure, open the **Structure** tab and drag it into the template.
**Content blocks** live inside structures. They include text, images, buttons, dividers, spacers, social icons, videos, GIFs, product blocks, and custom code. To add content, open the **Content** tab and drag a block into a column inside a structure. For a detailed overview of all available block types, see the [Content Blocks guide](https://support.topol.io/en/articles/10578060-content-blocks).
Build templates from **multiple structures** rather than placing everything into one or two large ones. This approach divides content clearly and prevents layout issues, especially in mobile responsive view.
Structures behave similarly to tables. If you want content to stack neatly on smaller screens, dividing it into separate structures is often the cleanest solution.
A common beginner mistake is to confuse structures with content blocks. Remember: structures define **where** content goes (the layout grid), while content blocks define **what** goes there (text, images, buttons, etc.). You cannot drag a content block onto the canvas without first placing a structure to hold it.
***
## Working with Structures
When you click inside any structure, a border appears with multiple action icons. Use these to move, duplicate, save, or perform other actions on the structure. For a deeper dive into structure options, see the [Structures article](https://support.topol.io/en/articles/6386312-structures).
The left-side panel provides structure-level settings. Here you can control the number of columns, background color or image, structure width, border style, layout (narrow or stretched), top and bottom margins, and column properties.
Be consistent about what represents a "section." If your hero area is one structure, keep it that way. Avoid spreading a single conceptual section across multiple structures unless you need different background or spacing rules. This makes templates easier to edit later, especially for teammates.
Use the **Save** action on a structure to store it as a reusable [Saved Block](https://support.topol.io/en/articles/6386405-saved-blocks). This is especially useful for headers, footers, and branded sections that appear across multiple templates.
***
## Working with Columns
Each structure can hold up to 8 columns, and each column can hold as many content blocks as needed. To change the number of columns, select the structure and adjust the column count in the left-side panel.
Columns have their own properties. You can adjust the background color, border, margin, padding, and more for each column independently. To access these options, select the structure and scroll to the bottom of the left-side panel to find the Columns properties section.
By default, columns stack vertically on mobile devices. If you want columns to remain side by side on mobile, disable the "Stack columns on mobile" option.
Think carefully before disabling column stacking on mobile. Side-by-side columns on a narrow screen often result in cramped, hard-to-read content. Only keep columns unstacked when the content is very short (such as two small icons or very brief labels) and reads well at narrow widths.
When using multi-column structures, keep related content together in the same column. For example, place an image, its caption, and a CTA button in the same column so they stack as a coherent unit on mobile.
***
## Working with Content Blocks
There are 10 types of basic content blocks, each designed for displaying a specific type of content. Similar to structures, you can perform actions directly through the buttons on the border of each block. For detailed guidance on working with individual block types, see the [Text, Image, and Button block guide](https://support.topol.io/en/articles/6386307-working-with-text-image-and-button-block).
Here's how to work with each type.
### Text Blocks
Edit text directly in the template using the formatting toolbar that appears above an active text block. These settings initially inherit global styles defined in the Settings tab but can be adjusted individually.
Keep text blocks clear, easy to scan, and consistent throughout the template. Use short paragraphs and simple sentences so readers can quickly understand the message, especially on mobile devices.
Resist the urge to override global font styles on every text block. If you find yourself changing the font or size frequently, consider updating the global defaults in the [Settings panel](https://support.topol.io/en/articles/6386317-settings-panel) instead. This keeps the template consistent and makes future edits simpler.
The toolbar also provides access to all defined merge tags. Select a tag from the dropdown to insert it at the cursor position. Inserted tags inherit the formatting already applied in the template.
Always check how merge tags appear in Preview Mode to ensure they read naturally and do not break formatting.
### Images
Images should support the message of the email, not overwhelm it. Use images intentionally and avoid decorative visuals that add no value. To insert an image, drag the Image block into a structure. This reserves space for an image, but nothing displays yet.
Upload images directly from your computer by dragging them into the Image block area, or click the block to open the File Manager. From there, select a previously uploaded image or upload a new one. The [File Manager](https://support.topol.io/en/articles/6386386-file-manager-move-and-delete-features) also lets you create folders to organize your library and search for images by name.
If you don't have a suitable image, search the Pexels image library directly from the File Manager.
Images uploaded to File Manager are available team-wide and can be reused across templates. They are stored in your team's [Storage Domain](/learn/domains/storage-domains) and served from your custom domain.
When you select an Image block, the left-side panel lets you adjust alignment, size, and margins. You can also add a link so users are redirected when they click the image.
Always include alternative text for images. Many email clients block images by default, and alt text ensures the message remains understandable when images don't display. Alt text should describe the purpose of the image rather than its visual details.
Keep image files optimized for email. Use JPEG or PNG formats, keep file sizes under 2 MB, and avoid widths greater than 600 pixels to ensure proper rendering across email clients. Large or unoptimized images increase loading time and negatively affect user experience and data usage.
Avoid using images for critical information like event dates, promo codes, or calls to action. When images are blocked by email clients (which is common), that information becomes invisible to the reader. Always include the essential message in text as well.
To adjust an image, click the Edit button to open the integrated [image editor](https://support.topol.io/en/articles/10902020-image-editor). From there, you can crop, resize, mask, and adjust other properties without leaving the editor.
### GIFs
GIFs can add motion and draw attention, but use them sparingly and with purpose. Short, subtle animations work best and help avoid distractions.
Working with GIFs is similar to working with images, but instead of uploading to the File Manager, you link a GIF directly from an external source. You can adjust most of the same properties as images in the left-side panel.
Search for GIFs on Giphy directly from the editor to speed up your workflow.
GIFs can significantly increase email size. Keep GIF file sizes as small as possible—ideally under 1 MB. Large GIFs slow down rendering, increase data usage on mobile, and may cause some email clients to clip the message entirely. Use GIFs only when they add clear value to the message.
### Buttons
Buttons should have a clear purpose and guide readers toward one specific action. Use short, direct text that describes what happens after the click, such as "Shop now" or "Read more." One to three words is usually enough.
To make buttons functional, add a link by selecting the button and entering the URL in the left-side panel.
Avoid vague labels like "Click here!" that don't clearly communicate value or intent.
Ensure buttons are easy to tap on mobile devices by using adequate padding and spacing. Buttons should stand out visually from surrounding content, using colors that contrast well with both the background and the button text.
For consistency and efficiency, define your main button style in the Settings tab instead of styling each button individually.
Don't forget to add a link URL to every button. It's easy to focus on styling and overlook the most important part: where the button actually leads. A button without a link does nothing when clicked.
### Spacers
Spacer blocks control vertical spacing between elements in a template. They create visual breathing room and improve readability without affecting the content itself.
To quickly adjust spacing, click inside the spacer block and drag up or down to change the height.
Use spacer blocks for clean, predictable vertical spacing. They are the preferred method for adding space between text, images, buttons, or entire sections—use them instead of empty text blocks or repeated line breaks.
Avoid excessively large spacers. Too much empty space can push important content too far down, especially on mobile devices.
### Dividers
Divider blocks visually separate sections and help structure email content. They provide a clear visual break between different parts of a template without adding extra text.
When selected, the left-side panel lets you adjust the divider's color, thickness, style, margin, and height.
Keep divider styles simple. Thin lines with subtle colors look more professional and work better across different email clients.
Preview the template on both desktop and mobile to ensure dividers don't appear too dominant or too subtle on smaller screens.
### Social
Social blocks link recipients to your brand's social media profiles on networks such as Facebook, Instagram, X (Twitter), LinkedIn, or custom URLs. Each icon can be enabled or disabled individually, reordered, and linked to the correct destination. For more details, see the [Social Network Icons guide](https://support.topol.io/en/articles/6386407-social-network-icons).
Keep social icons visually consistent across templates. Use the same icon style, size, and alignment so they feel like a natural part of the design rather than an afterthought.
Social blocks are most commonly placed in the footer but can also work well near the end of a message when aligned with the content flow.
Double-check that every social icon links to the correct profile URL. Broken or mismatched social links are a common oversight and can confuse recipients or damage trust.
### Video
The Video block lets you include video content in an email-friendly way. Because most email clients don't support embedded video playback, the Video block displays a clickable thumbnail image that links to the video.
Paste a video URL (for example, from YouTube or Vimeo), and the editor automatically generates a preview image. You can then adjust alignment, size, margins, and the link destination.
When clicked, the video opens in the recipient's browser or video platform app.
Place videos intentionally and close to related text so recipients understand what they'll see after clicking.
### HTML
HTML blocks let you insert custom HTML code directly into your template. This is useful for advanced layouts, custom tracking elements, or integrations that standard content blocks can't achieve. For guidance on what works well, see the [HTML in Topol guide](https://support.topol.io/en/articles/6386406-html-code-in-topol).
Use HTML blocks carefully. Scripts and complex interactive elements aren't supported by most email clients and may break rendering or affect deliverability. Always test custom HTML across multiple email clients before sending.
The integrated HTML editor includes a spell checker that helps you write valid HTML. Use HTML blocks only when you fully understand the code being added. When in doubt, rely on native content blocks instead of custom HTML.
If you're not confident writing email-compatible HTML, stick to the built-in content blocks. They are tested to render correctly across major email clients, which custom HTML may not.
### Product
Product blocks are designed for e-commerce emails and work with Product Feeds. A Product block represents a complete product unit, including image, name, description, price, and button. For setup instructions, see the [E-commerce Products guide](https://support.topol.io/en/articles/11059916-e-commerce-products-in-topol).
To use a Product block, drag it into a structure and select a product feed and product in the left-side panel.
Once connected, the block automatically pulls product data from the XML feed.
Product blocks behave as single units. You can reorder or hide elements within the block using layout options, but you cannot add additional content blocks inside a Product block.
If you need extra text or visuals near products, place them in a separate structure above or below the Product block.
***
## Working with Top Bar
The Top Bar gives you quick access to the tools you'll use most while building and reviewing templates. These buttons help you stay in control as you edit, experiment, preview, and prepare templates for use.
Knowing what each option does and when it's best to use it can make your work faster, safer, and much less stressful, especially when templates become longer or more complex.
### Undo and Redo
Undo and Redo are your safety net while editing. They let you quickly step backward or forward through recent changes, whether you've edited text, moved blocks, adjusted layouts, or changed settings. Just keep in mind that Undo and Redo only work within your current editing session, so they don't replace saving or autosaves.
It's usually faster and safer to use Undo than to manually fix mistakes. Get comfortable reaching for Undo early and often—it's one of the most useful habits you can build.
### Multilingual options
The Multilingual option is used when you're working with templates that need to exist in more than one language. It lets you switch between language versions of the same template while keeping the layout consistent. For a full walkthrough, see the [Multilingual Templates guide](https://support.topol.io/en/articles/12665820-multilingual-templates).
Each language version shares the same structure but has its own text content. This makes it much easier to manage translations without duplicating templates or worrying about layout differences.
A good approach is to finalize your structure first and then add additional languages. Making major layout changes later can mean more work across all language versions.
Structural changes made in one language version affect all languages. If you add, remove, or rearrange structures after translations are in place, you may need to re-check text content in every language version.
### Desktop and Mobile view
One of the greatest advantages of our editor is that all your templates are built mobile-first and are responsive by default. The Desktop/Mobile view toggle lets you quickly see how your email will look on larger screens versus smaller mobile devices. For more on responsive design, see the [Desktop and Mobile optimization guide](https://support.topol.io/en/articles/6386409-optimizing-your-email-templates-for-desktop-and-mobile-in-topol-pro) and the [Mobile-first email template design article](https://support.topol.io/en/articles/6386366-mobile-first-email-template-design).
Mobile view shows how content stacks, how text wraps, and whether buttons and images are still easy to read and tap on smaller screens.
Instead of waiting until the end, it's best to switch between desktop and mobile views regularly while building a template. Catching layout issues early is much easier than fixing them after the template is fully built.
### Show hidden
The Show hidden button reveals content that is set to be hidden on the currently active view (desktop or mobile). This is essential when you want to create a different layout for mobile that doesn't include all the same content as the desktop version.
To achieve this, first duplicate the section or block that should appear differently on desktop and mobile. Then, while switching between Mobile and Desktop views, create the desired layout for each version.
Then, enable "Hide on desktop" for the version that should be visible only on mobile and "Hide on mobile" for the version that should be visible only on desktop.
As a result, the structures set as "Hide on desktop" will disappear from your editor. That is where this "Show hidden" button comes in handy—it temporarily shows all hidden content so you can still edit it.
When using the hide/show approach for different mobile and desktop layouts, clearly name or visually distinguish the two versions (for example, by adding a temporary colored background) so you don't accidentally edit the wrong one.
Hidden content is still included in the email's HTML—it's just visually hidden using CSS. This means it still contributes to the overall email size. Avoid hiding large amounts of content, as it can increase load times and may trigger email clipping in clients like Gmail.
### Autosave history
Autosave history lets you view and restore earlier versions of your template that were saved automatically in the background. Autosaves happen at regular intervals and help protect your work if something goes wrong. For more details, see the [Autosave with version history article](https://support.topol.io/en/articles/10760052-autosave-with-version-history).
This feature is especially helpful during long editing sessions or when you're making big changes. If you ever need to go back to a previous version, autosave history gives you that option.
Think of autosaves as a safety net. They're there to protect you, but they don't replace intentionally saving your work. After completing a major section or before making significant structural changes, save manually.
### Save
The Save button stores the current state of your template. Saving makes sure your latest changes are preserved and available the next time you open the template.
Even though autosaves run in the background, it's still a good habit to save manually after finishing meaningful changes, such as finalizing content, adjusting layouts, or preparing a template for review.
The Save button also contains the "Save and Close" option that is accessible through the three vertical dots on the right. When clicked, this saves and then closes the editor in one step—useful when you've finished editing and want to return to the template list.
### Fullscreen
The Fullscreen option expands the editor to fill your entire screen, removing surrounding distractions.
Fullscreen mode is useful when working on long templates, reviewing the overall flow, or focusing on fine visual details like spacing and alignment. Having more space makes it easier to spot inconsistencies or areas that need adjustment.
Use Fullscreen mode when doing your final review pass. The extra screen space makes it easier to spot alignment issues, inconsistent spacing, and other visual problems you might miss in the normal view.
***
## Ideal Workflow
A reliable workflow that works for most templates follows these steps:
**1. Place structures for your layout.** Don't worry about content yet. Focus on creating the main skeleton: header area, hero section, main content sections, product areas, and footer.
To move faster, start with a pre-made structure and customize it to match your design.
**2. Define your global styles.** Open the **Settings** tab and configure background color, block color, button color, link color, text styles, spacing, and more. For a full overview of available settings, see the [Settings panel guide](https://support.topol.io/en/articles/6386317-settings-panel).
Defining these values early reduces the amount of manual styling later.
**3. Add content blocks.** Drag text, images, buttons, dividers, spacers, social icons, videos, GIFs, or product blocks into the structures you prepared.
**4. Review on desktop and mobile.** Switch between views regularly as you build, and do a thorough review once all content is in place. Check stacking order, spacing, button tap targets, and text readability on both views.
**5. Preview and test.** Use the [Preview and Testing tools](https://support.topol.io/en/articles/6386319-preview-testing-of-the-template) to see how the email renders. Send a test email to yourself and check it in at least one desktop and one mobile email client before finalizing.
This workflow reduces rework. When global styles are defined first, individual blocks require fewer adjustments and the final template looks more consistent.
***
## Common Issues and Troubleshooting
Even experienced users run into issues from time to time. This section covers the most common problems and how to solve them.
You're likely trying to drag a content block directly onto the canvas without a structure in place. Content blocks must be placed **inside** a column within a structure. First drag a structure onto the canvas, then drag the content block into one of its columns.
Multi-column structures stack vertically on mobile by default, but if you've disabled "Stack columns on mobile," columns will try to remain side-by-side on narrow screens. Re-enable stacking unless the content is very short. Also check that column padding isn't set to zero—some spacing helps readability on smaller screens.
Email client rendering varies significantly. The editor preview is a good approximation, but some clients (particularly Outlook on Windows) handle spacing, fonts, and backgrounds differently. Always send a test email and check it in multiple clients. Stick to standard content blocks and avoid custom HTML when possible, as built-in blocks are tested for cross-client compatibility.
Check that images were uploaded through the File Manager (not just linked from a temporary source). Externally hosted images may be blocked by email clients or firewalls. Also verify that the image URL is HTTPS—some email clients block HTTP images. If images still don't appear, the file may have been deleted from the File Manager or the Storage Domain may not be configured correctly.
Large image files (over 2 MB) may fail to upload. Resize and compress images before uploading. Use JPEG for photos and PNG for graphics with transparency. Also check your internet connection—slow or unstable connections can cause upload timeouts.
This usually happens when content is too wide for mobile screens. Check image widths (keep them under 600px), ensure text blocks aren't using fixed widths, and verify that column stacking is enabled. Also check for structures with "Do not stack on mobile" enabled—these are the most common source of mobile layout issues.
Merge tags only get replaced with real values when the email is actually sent with substitution data. In the editor and in previews, they appear as placeholders. To verify they work correctly, send a test email with sample data. If tags still appear raw after sending, check that the tag names match exactly what you're passing in `substitution_data`.
Hidden content uses CSS to hide elements, which works in most email clients. However, some older or less common clients may not respect the CSS rules. Also check that you've set the visibility correctly—"Hide on mobile" and "Hide on desktop" are separate options. Make sure you've toggled the right one for each version of the content.
In multilingual templates, all language versions share the same structure. Adding, removing, or rearranging structures in one language affects all of them. Only text content is independent per language. If you need a different layout for a specific language, consider using separate templates instead of the multilingual feature.
Gmail clips emails larger than approximately 102 KB. This can happen when templates include many large images, excessive hidden content, or bloated custom HTML. To avoid clipping, optimize image sizes, minimize hidden content, keep the template concise, and avoid unnecessary custom HTML. You can check your template's approximate size by exporting the HTML and checking the file size.
***
## Further Reading
Developer-oriented introduction to the editor's architecture and workflows
Create reusable sections and synced content across templates
Merge tags, conditionals, loops, and default values
Detailed step-by-step guides for every editor feature
# IP and Domain Warm-Up Guide
Source: https://docs.lettr.com/knowledge-base/best-practices/ip-domain-warmup
Warm-up schedules and strategies for new domains and IPs, gradually increasing volume to build sender reputation and avoid deliverability blocks.
When you start sending from a new domain or IP address, mailbox providers have no history to judge you by. Warm-up is the process of gradually increasing your sending volume so providers can observe positive engagement signals and build trust in your sender identity. Skipping or rushing this process is one of the most common causes of long-term deliverability problems.
***
## Why Warm-Up Matters
Mailbox providers like Gmail, Outlook, and Yahoo are designed to protect their users from spam. When they see a new domain suddenly sending thousands of emails, they treat it as suspicious — the same pattern spammers use with disposable domains.
A proper warm-up demonstrates that:
* Real recipients want your emails (they open, click, and reply)
* You maintain a clean list (low bounce rates)
* You respect recipient preferences (low complaint rates)
* Your sending patterns are predictable and consistent
Sending high volumes immediately from a new domain can result in blocks that take weeks or months to lift. Some providers may permanently flag your domain, making recovery extremely difficult.
***
## Domain Warm-Up Schedule
This schedule applies when you add a new sending domain to Lettr. Adjust the numbers based on your total list size — the key principle is gradual, consistent growth.
### Low-Volume Senders (under 10,000 emails/month)
| Week | Daily Volume | Target Audience | Key Metrics to Watch |
| ---- | --------------- | ------------------------------------------------------- | ---------------------------------- |
| 1 | 50–100 | Most engaged recipients (opened/clicked in last 7 days) | Bounce rate, complaints |
| 2 | 200–500 | Engaged in last 30 days | Bounce rate, complaints, deferrals |
| 3 | 500–1,000 | Engaged in last 90 days | All metrics, inbox placement |
| 4+ | Scale to target | Full active list | All metrics |
### High-Volume Senders (over 10,000 emails/month)
| Week | Daily Volume | Target Audience | Key Metrics to Watch |
| ---- | ------------------- | ------------------------------------------------------- | ---------------------------------- |
| 1 | 100–200 | Most engaged recipients (opened/clicked in last 7 days) | Bounce rate, complaints |
| 2 | 500–1,000 | Engaged in last 14 days | Bounce rate, complaints, deferrals |
| 3 | 2,000–5,000 | Engaged in last 30 days | All metrics, inbox placement |
| 4 | 5,000–10,000 | Engaged in last 60 days | All metrics |
| 5 | 10,000–25,000 | Engaged in last 90 days | All metrics |
| 6+ | Scale toward target | Full active list (excluding unengaged) | All metrics |
These are guidelines, not rigid rules. The right pace depends on your engagement metrics. If bounce rates stay below 2% and complaint rates below 0.1%, you can accelerate. If either metric spikes, slow down immediately.
***
## Warm-Up Principles
### Send to Engaged Recipients First
Start with recipients who have recently interacted with your emails — opens, clicks, or replies in the last 7–14 days. These recipients are most likely to engage again, which sends strong positive signals to mailbox providers.
```javascript theme={null}
// Example: Query engaged recipients for warm-up phases
const warmupRecipients = await db.recipients.find({
lastEngagedAt: {
$gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) // Last 7 days
},
status: 'active',
suppressionStatus: null
}).limit(100); // Week 1 daily cap
```
### Send Consistently Every Day
Sending every day during warm-up is more important than sending large volumes. Sporadic bursts followed by silence look suspicious. A steady 100 emails per day is better than 700 emails once a week.
### Authenticate Before You Start
All DNS records must be verified and passing before you send your first warm-up email. This is non-negotiable.
Navigate to **Domains** → **Add Domain** and enter your sending subdomain (e.g., `mail.example.com`).
Add the CNAME and DKIM records shown in your Lettr dashboard to your DNS provider.
Publish a DMARC record for your domain. Start with `p=none` during warm-up so you can monitor without risking rejections.
Wait for verification to complete in your dashboard. All records should show a green checkmark before you send.
### Monitor After Every Send
Check your metrics in the Lettr dashboard after each warm-up send. Set up webhook endpoints for real-time monitoring:
```javascript theme={null}
app.post('/webhooks/lettr', (req, res) => {
const event = req.body;
switch (event.type) {
case 'email.bounced':
logWarmupMetric('bounce', event.data);
break;
case 'email.complained':
logWarmupMetric('complaint', event.data);
// Immediately suppress this recipient
suppressRecipient(event.data.to, 'spam_complaint');
break;
case 'email.deferred':
logWarmupMetric('deferral', event.data);
break;
case 'email.delivered':
logWarmupMetric('delivered', event.data);
break;
}
res.sendStatus(200);
});
```
***
## Stop Signals
Pause your warm-up and investigate immediately if you observe any of these:
| Signal | Threshold | Action |
| --------------- | ------------------------------------------ | ---------------------------------------------------------------------------------- |
| Bounce rate | > 5% on any single send | Stop sending. Clean your list before resuming. |
| Complaint rate | > 0.3% | Stop sending. Review content and targeting. |
| Deferrals spike | Sudden increase in `email.deferred` events | Reduce volume by 50%. Resume previous volume after deferrals normalize. |
| Block messages | 421 or 550 responses mentioning reputation | Stop sending to that provider. Wait 24–48 hours before retrying at reduced volume. |
Do not ignore deferrals. A deferral means the receiving server accepted the connection but delayed delivery — it's a warning that the provider is becoming cautious about your domain. Continuing at the same volume will likely escalate to blocks.
***
## Warm-Up by Provider
Different mailbox providers have different thresholds and behaviors during warm-up.
### Gmail
Gmail relies heavily on domain reputation and engagement signals. During warm-up:
* Keep daily volume to Gmail addresses especially conservative (start with 20–50)
* Gmail is the most sensitive to complaint rates — stay well below 0.1%
* Use [Google Postmaster Tools](https://postmaster.google.com/) to monitor your domain reputation directly
### Outlook / Microsoft 365
Microsoft uses SmartScreen filtering and has its own reputation system:
* Outlook tends to be more forgiving during initial warm-up than Gmail
* Register with [SNDS (Smart Network Data Services)](https://sendersupport.olc.protection.outlook.com/snds/) to monitor your reputation
* Outlook may silently route emails to Junk without bouncing — monitor open rates closely
### Yahoo
Yahoo was an early adopter of domain-based reputation:
* Yahoo provides feedback loops (FBL) — ensure Lettr is processing these
* Yahoo tends to defer rather than block during warm-up, so watch for deferral patterns
***
## Warming Up a Damaged Domain
If you're recovering from reputation damage rather than starting fresh, the warm-up process is similar but stricter.
Cut sending to 10–20% of your pre-damage volume, or pause entirely for 48 hours.
Check webhook logs for `email.bounced`, `email.complained`, and `email.deferred` events. Common causes: stale list, broken authentication, sudden volume spike.
Remove all hard bounces, all complainants, and anyone who hasn't engaged in 6 months.
Follow the warm-up schedule above, starting from week 1 with your most engaged recipients only.
Reputation recovery is slower than initial warm-up. Expect 2–6 weeks of consistent good behavior before providers fully trust your domain again.
***
## Common Mistakes
The most common warm-up mistake. Even if your list is opt-in and legitimate, sending thousands of emails from a brand-new domain triggers spam filters. Always start small and scale gradually.
Gaps in sending volume (like skipping weekends) create an inconsistent pattern. If you can't send every day, at least send smaller volumes on off-days to maintain continuity.
Warm-up isn't just about volume — it's about engagement quality. If your open rates are low even during warm-up, your content or targeting needs work before you scale up.
Sending to your full list sorted by signup date instead of engagement recency. Always prioritize recipients who have recently opened or clicked.
Sending emails without verified DKIM, SPF, and DMARC records during warm-up wastes every positive signal you generate. Authenticate first, then warm up.
***
## Related Topics
Build and protect your sender reputation over time
Maintain clean, engaged recipient lists
Configure and verify your sending domains
Maximize inbox placement across all providers
# List Hygiene
Source: https://docs.lettr.com/knowledge-base/best-practices/list-hygiene
Maintain healthy recipient lists to protect sender reputation, validate addresses at signup, and remove bounces, complaints, and spam traps.
A clean recipient list is the foundation of good deliverability. Every email you send to an invalid, disengaged, or unwilling recipient damages your sender reputation and makes it harder for your legitimate emails to reach the inbox. This guide walks through the practices that keep your lists healthy.
***
## Why List Hygiene Matters
Mailbox providers like Gmail, Outlook, and Yahoo continuously evaluate your sending behavior. They use signals from your recipient list quality to decide whether your emails deserve the inbox or the spam folder.
Poor list hygiene leads to a compounding cycle of damage:
| Problem | Consequence |
| ----------------------- | ------------------------------------------------------ |
| High bounce rates | Providers flag you as a careless sender |
| Spam complaints | Providers actively block your emails |
| Low engagement | Providers deprioritize your messages |
| Spam traps on your list | Immediate reputation damage and potential blocklisting |
A single send to a poorly maintained list can undo months of reputation building. Sender reputation is slow to build and fast to destroy.
***
## Validate at the Point of Collection
The best time to prevent a bad address from entering your list is before it gets there.
### Client-Side Format Validation
Catch obvious typos and formatting errors before the address is submitted:
```javascript theme={null}
function isValidEmailFormat(email) {
const pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return pattern.test(email);
}
// Example usage in a signup form
const emailInput = document.getElementById('email');
emailInput.addEventListener('blur', () => {
if (!isValidEmailFormat(emailInput.value)) {
showError('Please enter a valid email address.');
}
});
```
Client-side validation catches formatting mistakes but cannot confirm the address actually exists. Always pair it with a confirmation email.
### Confirmation Emails
After a user submits their address, send an immediate confirmation email to verify it is real and reachable:
```javascript theme={null}
const response = await fetch('https://app.lettr.com/api/emails', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: 'noreply@yourdomain.com',
to: 'new-subscriber@example.com',
subject: 'Confirm your subscription',
html: '
Click the link below to confirm your email address:
Confirm Subscription',
}),
});
```
### Double Opt-In Flow
Double opt-in is the gold standard for list quality. It ensures every address on your list is valid, reachable, and belongs to someone who genuinely wants your emails.
Collect the address through your signup form with client-side validation.
Use the Lettr API to send an email containing a unique confirmation link.
This proves the address is valid and the owner consented to receive emails.
Only after confirmation should the address be eligible for marketing emails.
Double opt-in typically results in a smaller list, but the engagement rates are significantly higher. A list of 5,000 confirmed subscribers will outperform a list of 50,000 unverified addresses.
***
## Handle Bounces in Real Time
When an email bounces, you need to act immediately. Continuing to send to bounced addresses tells mailbox providers that you are not maintaining your list.
### Bounce Types
| Type | Meaning | Action |
| ----------- | ---------------------------------------------------- | --------------------------------------------------- |
| Hard bounce | Address is permanently invalid (e.g., doesn't exist) | Remove from your list immediately |
| Soft bounce | Temporary issue (e.g., mailbox full, server down) | Retry automatically; remove after repeated failures |
### Webhook Handler for Bounces
Set up a webhook endpoint to process bounce events from Lettr as they happen:
```javascript theme={null}
app.post('/webhooks/lettr', (req, res) => {
const event = req.body;
if (event.type === 'email.bounced') {
const { to, bounceType } = event.data;
if (bounceType === 'hard') {
// Permanently remove from all mailing lists
removeFromAllLists(to);
logBounce(to, 'hard', event.data.reason);
}
if (bounceType === 'soft') {
// Track soft bounces — remove after 3 consecutive failures
incrementSoftBounceCount(to);
const count = getSoftBounceCount(to);
if (count >= 3) {
removeFromAllLists(to);
logBounce(to, 'soft_permanent', event.data.reason);
}
}
}
res.sendStatus(200);
});
```
### Lettr Auto-Suppression
Lettr automatically adds hard-bounced addresses to your account's suppression list. Even if the address remains in your application database, Lettr will not attempt delivery to a suppressed address.
Lettr's auto-suppression protects you from repeated hard bounces, but you should still update your own database to keep your list accurate. You can view and manage your suppression list in the [Lettr dashboard](https://app.lettr.com).
***
## Process Spam Complaints
Spam complaints are more damaging than bounces. A bounce means the address is bad. A complaint means a real person is telling their mailbox provider that your email is unwanted. Providers weigh complaints heavily.
### Why Complaints Are Worse Than Bounces
* A hard bounce is a technical failure — providers understand addresses go stale.
* A spam complaint is a human judgment — providers interpret it as evidence that you send unwanted email.
* Even a complaint rate of 0.3% can trigger spam filtering for your entire sending domain.
### Webhook Handler for Complaints
Remove complainants from your list immediately and never email them again:
```javascript theme={null}
app.post('/webhooks/lettr', (req, res) => {
const event = req.body;
if (event.type === 'email.complained') {
const { to } = event.data;
// Remove from all lists immediately — do not email this person again
removeFromAllLists(to);
addToInternalBlocklist(to);
// Log for analysis — high complaint rates need investigation
logComplaint(to, event.data);
}
res.sendStatus(200);
});
```
Never re-add a complainant to your list, even if they later submit their email through a signup form. Once someone marks your email as spam, sending to them again risks further reputation damage and potential legal issues.
***
## Re-Engage or Remove Inactive Subscribers
Subscribers who never open or click your emails are dead weight on your list. Mailbox providers notice when a large portion of your recipients ignore your emails, and they use that as a signal to deprioritize your messages for everyone.
### Define Your Inactivity Window
A subscriber is typically considered inactive if they have not opened or clicked any email in the past **6 to 12 months**. The right window depends on your sending frequency:
| Sending Frequency | Recommended Inactivity Window |
| ----------------- | ----------------------------- |
| Daily | 3–6 months |
| Weekly | 6–9 months |
| Monthly | 9–12 months |
### Re-Engagement Campaign Strategy
Before removing inactive subscribers, give them a chance to re-engage:
Identify subscribers with no opens or clicks within your inactivity window.
Use a clear subject line like "We miss you — do you still want to hear from us?" Include a prominent call-to-action to confirm their interest.
Give recipients time to see and act on the re-engagement email.
For those who didn't respond, send one last email explaining they will be removed unless they take action.
Anyone who did not engage with either email should be removed from your active list.
### Sunset Policy
A sunset policy is a standing rule that automatically removes subscribers after a defined period of inactivity. Implement this as an automated process rather than relying on manual cleanup:
```javascript theme={null}
async function applySunsetPolicy() {
const inactiveWindow = 270; // days (9 months)
const cutoffDate = new Date(Date.now() - inactiveWindow * 24 * 60 * 60 * 1000);
const inactiveSubscribers = await db.subscribers.findMany({
where: {
lastEngagement: { lt: cutoffDate },
status: 'active',
},
});
for (const subscriber of inactiveSubscribers) {
await db.subscribers.update({
where: { id: subscriber.id },
data: { status: 'sunset_removed' },
});
}
console.log(`Sunset policy removed ${inactiveSubscribers.length} inactive subscribers.`);
}
```
Run your sunset policy on a regular schedule — monthly or quarterly. Automate it so it doesn't depend on someone remembering to do it.
***
## Avoid Purchased or Scraped Lists
Sending to purchased, rented, or scraped email lists is one of the fastest ways to destroy your sender reputation and get blocked.
### Why Purchased Lists Are Harmful
* **No consent**: Recipients never asked for your emails. Expect high complaint rates.
* **Spam traps**: Purchased lists frequently contain spam trap addresses maintained by mailbox providers and blocklist operators. Hitting a spam trap leads to immediate blocklisting.
* **Invalid addresses**: These lists are rarely maintained and are full of outdated, invalid addresses that produce hard bounces.
* **Low engagement**: Even valid addresses will not engage with emails they did not ask for, dragging down your sender reputation.
### Legal Risks
| Regulation | Risk |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| CAN-SPAM (US) | Fines up to \$51,744 per email sent to recipients who did not opt in. Requires functioning unsubscribe and physical address. |
| GDPR (EU/UK) | Fines up to 4% of annual global revenue or 20 million EUR. Requires explicit consent before sending marketing emails. |
| CASL (Canada) | Fines up to \$10 million CAD per violation. Requires express or implied consent. |
There is no legitimate shortcut to building an email list. Every address on your list should belong to someone who explicitly chose to receive your emails.
Lettr's AI assistant enforces this too: when [Adamko reviews a contact import](/learn/ai-assistant/audience-and-imports#import-review) and finds no consent signal in the file, he warns you plainly — checking for invalid addresses, duplicates, and consent risks before the contacts ever enter your audience.
***
## Regular List Audits
Don't wait for deliverability problems to appear. Schedule a quarterly audit to proactively identify and resolve list quality issues.
### Quarterly Review Checklist
Pull your bounce data for the past quarter. If your hard bounce rate is above 2%, investigate the source of bad addresses and tighten your collection process.
Check your spam complaint rate. If it's above 0.1%, review your email content, frequency, and whether your unsubscribe link is clearly visible.
Segment subscribers with no engagement in the past 6–12 months. Run a re-engagement campaign or apply your sunset policy.
Remove or suppress role-based addresses like `info@`, `admin@`, `support@` — these often go to shared inboxes and generate complaints.
Review where new subscribers are coming from. Ensure every source uses proper opt-in and validation.
Check your suppression list in the Lettr dashboard. Ensure suppressed addresses have not been accidentally re-added to active lists in your application.
Record what you found and what you changed. This creates an audit trail and helps you spot trends over time.
***
## Key Metrics to Monitor
Track these metrics consistently to gauge the health of your recipient list:
| Metric | Healthy Target | Warning Threshold | What It Tells You |
| -------------------------------- | -------------- | -------------------- | ------------------------------------------------------------- |
| Bounce rate | \< 2% | > 5% | Whether your list contains invalid addresses |
| Complaint rate | \< 0.1% | > 0.3% | Whether recipients consider your emails unwanted |
| Unsubscribe rate | \< 0.5% | > 1% | Whether your content and frequency match expectations |
| List growth rate | Positive | Negative (shrinking) | Whether you are acquiring subscribers faster than losing them |
| Engagement rate (opens + clicks) | > 15% | \< 10% | Whether your list is active and interested |
If you notice any metric crossing into the warning threshold, investigate immediately. Small problems become big ones quickly in email deliverability. If you need help diagnosing an issue, contact [support@lettr.com](mailto:support@lettr.com).
***
## Related Topics
Foundational practices for reaching the inbox
Understand bounce types and handling
Handle spam complaints and unsubscribe requests
Legal requirements for commercial email
# Personalization and Dynamic Content
Source: https://docs.lettr.com/knowledge-base/best-practices/personalization-dynamic-content
Use Lettr merge tags, conditionals, loops, and filters to build one template that renders personalized, relevant content for each recipient.
Personalized emails outperform generic ones. Recipients are more likely to open, read, and act on emails that address them by name, reference their specific activity, and show content relevant to their situation. Lettr's [template language](/learn/templates/template-language) provides merge tags, conditionals, loops, and filters that let you build a single template that renders differently for each recipient.
***
## Merge Tags
Merge tags are placeholders in your template that get replaced with recipient-specific data at send time. They use double curly braces.
### Basic Substitution
```html theme={null}
Hello {{ name }},
Your account ({{ email }}) has been active since {{ signup_date }}.
```
Pass the substitution data in your API request:
```javascript theme={null}
await fetch('https://app.lettr.com/api/emails', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'hello@mail.example.com',
to: 'alice@example.com',
templateId: 'welcome-email',
substitutionData: {
name: 'Alice',
email: 'alice@example.com',
signup_date: 'January 15, 2025'
}
})
});
```
### Default Values
Always provide defaults for personalization fields. An email that reads "Hello ," because the name field is missing looks broken.
```html theme={null}
Hello {{ name or 'there' }},
Your {{ plan_name or 'current' }} plan includes {{ email_limit or '1,000' }} emails per month.
```
Never assume all substitution data will be present. Missing fields render as empty strings by default, which creates gaps in your content. Use the `or` keyword on every variable that appears in visible text.
### HTML Escaping
By default, merge tags are HTML-escaped to prevent cross-site scripting. If you need to render trusted HTML content, use triple curly braces:
```html theme={null}
{{ user_message }}
{{{ custom_html_block }}}
```
Only use triple curly braces (`{{{ }}}`) with content you control — never with user-submitted data. Unescaped content can inject arbitrary HTML into your emails.
***
## Conditional Content
Show different content to different recipients based on their attributes, plan level, activity, or any other data you pass.
### Basic Conditionals
```html theme={null}
{{if premium}}
Premium Member
Enjoy free priority support and advanced analytics.
{{end}}
```
### Practical Use Cases for Conditionals
| Use Case | Condition | Effect |
| ------------------------------ | ---------------------------- | ---------------------------------------------------- |
| Show upgrade CTA to free users | `{{if plan == 'free'}}` | Display upgrade banner only for free-tier recipients |
| Trial expiry warning | `{{if days_remaining <= 3}}` | Show urgent renewal message for expiring trials |
| Locale-specific content | `{{if locale == 'de'}}` | Show German-language support links for German users |
| Feature announcement | `{{if feature_enabled}}` | Show feature details only to users who have access |
| Empty state handling | `{{if items_count == 0}}` | Show "no activity" message instead of an empty list |
***
## Dynamic Loops
Use `{{each}}` to iterate over arrays of data — order items, activity logs, recommendations, or any list.
### Order Items
```html theme={null}
{{end}}
```
***
## Per-Recipient Personalization at Scale
When sending to multiple recipients in a single API call, pass individual substitution data for each recipient:
```javascript theme={null}
await fetch('https://app.lettr.com/api/emails', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'billing@mail.example.com',
to: [
{
email: 'alice@example.com',
substitutionData: {
name: 'Alice',
plan: 'pro',
usage: '12,450',
limit: '50,000',
invoice_url: 'https://example.com/invoices/inv_001'
}
},
{
email: 'bob@example.com',
substitutionData: {
name: 'Bob',
plan: 'starter',
usage: '4,820',
limit: '5,000',
invoice_url: 'https://example.com/invoices/inv_002'
}
}
],
templateId: 'monthly-usage-report'
})
});
```
Batch sending with per-recipient substitution data is the most efficient way to send personalized emails at scale. One API call with 200 recipients and individual data is much faster than 200 separate calls.
***
## Personalization Strategy
### What to Personalize
Not everything needs personalization. Focus on elements that make the email feel relevant and useful.
| Element | Impact | Example |
| --------------------------- | ------ | ---------------------------------------------------------- |
| **Recipient name** | Medium | "Hello Alice" vs "Hello" |
| **Account-specific data** | High | Usage stats, plan details, recent activity |
| **Contextual actions** | High | "Upgrade your plan" vs "Manage your Enterprise account" |
| **Timing references** | Medium | "Your trial ends in 3 days" vs "Your trial is ending soon" |
| **Product recommendations** | High | Items based on purchase history or browsing behavior |
### What Not to Personalize
| Element | Why |
| ----------------------------------- | ------------------------------------------------------------------------ |
| Subject lines with first names only | Overused; no longer increases open rates for most audiences |
| Location unless action-relevant | "Hello from Seattle!" feels surveillance-like if not contextually useful |
| Personal details you shouldn't know | Avoid revealing data the recipient didn't knowingly provide |
***
## Testing Personalized Templates
### Preview with Sample Data
Before sending, test your template with different substitution data to verify all branches render correctly.
```javascript theme={null}
// Test case 1: Premium user with items
const premiumData = {
name: 'Alice',
premium: true,
plan: 'enterprise',
items: [
{ name: 'Item A', quantity: '1', price: '$10.00' }
]
};
// Test case 2: Free user with no items
const freeData = {
name: '', // Test missing name → should fall back to default
premium: false,
plan: 'free',
items: [] // Test empty loop
};
// Test case 3: Edge case — very long values
const edgeCaseData = {
name: 'Alexandrina Konstantinopolskaya-Featherington',
premium: true,
plan: 'pro',
items: Array(20).fill({ name: 'Item', quantity: '1', price: '$5.00' })
};
```
Pay special attention to empty states. What does your template look like when `items` is an empty array? When `name` is missing? When a conditional branch has no matching case? Every possible state should render cleanly.
***
## Common Mistakes
Forgetting the `or` keyword results in empty strings when data is missing. "Hello ," or "Your plan includes emails per month" looks broken. Always add fallbacks: `{{ name or 'there' }}`.
Using "Hey !" in every subject line has diminishing returns. Recipients learn to ignore it, and some find it off-putting. Save name personalization for the email body and keep subject lines focused on the content.
If you have 4 plan tiers, you need to test all 4 renderings plus the `else` fallback. A broken conditional in a branch you didn't test will surprise you in production.
Triple curly braces (`{{{ }}}`) skip HTML escaping. If user-submitted data contains HTML tags or scripts, it renders raw in the email. Only use triple braces with system-generated, trusted content.
Testing always with `name: 'Test User'` and `plan: 'pro'` misses edge cases. Vary your test data to cover missing fields, empty arrays, long strings, and unusual characters.
***
## Related Topics
Full reference for merge tags, conditionals, loops, and filters
Build and manage email templates with the Topol editor
Send to multiple recipients with per-recipient data
Manage and publish template versions
# Security Best Practices
Source: https://docs.lettr.com/knowledge-base/best-practices/security
Protect your Lettr account, API keys, and email data by storing keys in environment variables, securing webhooks, and limiting key permissions.
Email infrastructure handles sensitive data and has direct access to your recipients' inboxes. A compromised API key or insecure webhook endpoint can lead to unauthorized emails sent on your behalf, leaked recipient data, or abuse of your sending reputation. This guide covers the practical steps to lock down your Lettr integration.
***
## API Key Security
Your API key is the single credential that authorizes requests to the Lettr API. Treat it like a database password.
### Store Keys in Environment Variables
Never hardcode API keys in your source code. Use environment variables instead:
```bash theme={null}
# .env file (never committed to version control)
LETTR_API_KEY=lttr_xxxxxxxxxxxx
```
```javascript theme={null}
// Access via environment variable
const apiKey = process.env.LETTR_API_KEY;
```
```bash theme={null}
# Use in curl requests
curl -X POST https://app.lettr.com/api/emails \
-H "Authorization: Bearer $LETTR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to": "user@example.com", "subject": "Hello"}'
```
### Keep Keys Out of Version Control
Add your environment files to `.gitignore` before your first commit:
```bash theme={null}
# .gitignore
.env
.env.local
.env.production
```
If you've already committed a file containing an API key, adding it to `.gitignore` won't remove it from your git history. Rotate the key immediately in the Lettr dashboard and consider using a tool like `git filter-branch` or BFG Repo-Cleaner to purge the key from your history.
### Use the Right Permission Level
Lettr API keys have two permission levels:
| Permission Level | Use Case |
| ---------------- | ---------------------------------------------------------------------------------- |
| **Sending Only** | Application code that only needs to send emails — use this for production services |
| **Full Access** | Admin tasks like managing domains, templates, and account settings |
Default to **Sending Only** keys for any service that just sends email. This limits the damage if a key is ever exposed — an attacker could send emails, but couldn't access your templates, domains, or account settings.
See [API Key Permissions](/learn/api-keys/permissions) for details on what each level can access.
### Use Separate Keys Per Environment
Create distinct API keys for each environment:
* **Development** — a Sending Only key pointing to test recipients
* **Staging** — a Sending Only key for pre-production testing
* **Production** — a Sending Only key for live email sending
* **Admin** — a Full Access key used only for dashboard-level operations
If one environment is compromised, you only need to rotate that key without affecting other environments.
### Rotate Keys Regularly
Rotate your API keys periodically and immediately if you suspect exposure. You can create new keys and revoke old ones from the Lettr dashboard without downtime — create the new key first, update your environment variables, then revoke the old key.
***
## Webhook Security
Webhooks push event data to your server. Without verification, anyone who discovers your webhook URL could send fake events to your application.
### Verify Webhook Signatures
Every webhook request from Lettr includes a `lettr-signature` header. Verify this signature before processing any event:
```javascript theme={null}
const crypto = require('crypto');
const express = require('express');
const app = express();
// IMPORTANT: Use the raw body for signature verification
app.post('/webhooks/lettr', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['lettr-signature'];
const webhookSecret = process.env.LETTR_WEBHOOK_SECRET;
const expectedSignature = crypto
.createHmac('sha256', webhookSecret)
.update(req.body)
.digest('hex');
if (signature !== expectedSignature) {
console.error('Invalid webhook signature');
return res.sendStatus(401);
}
// Signature is valid — safe to process
const event = JSON.parse(req.body);
handleEvent(event);
res.sendStatus(200);
});
```
You must use the **raw request body** for signature verification, not a parsed JSON object. If your framework parses the body before your handler runs, the re-serialized JSON may differ from the original payload and the signature will not match.
### Use HTTPS for Webhook Endpoints
Always use an `https://` URL for your webhook endpoint. HTTP endpoints transmit event data — including recipient email addresses — in plain text across the network.
See [Webhook Authorization](/learn/webhooks/authorization) for the full signature verification reference.
***
## Account Security
### Enable Two-Factor Authentication
Enable 2FA for every team member in the Lettr dashboard under your account security settings. This protects against password compromise — even if an attacker obtains a password, they can't access the dashboard without the second factor.
2FA is configured per user in the dashboard. If you manage a team, require all members to enable it as part of your onboarding process.
### Review Team Access
Periodically review who has access to your Lettr account through the dashboard:
* Remove team members who no longer need access
* Verify that each member's role matches their current responsibilities
* Audit when new members were added and by whom
### Configure IP Restrictions
If your API requests originate from known IP addresses (such as production servers), configure IP restrictions in the Lettr dashboard to reject requests from unrecognized sources. This adds a layer of defense even if an API key is leaked.
***
## Data Protection
### Minimize Sensitive Data in Emails
Email is not a secure transport channel. Avoid including sensitive information directly in email content or metadata:
| Don't Include | Do Instead |
| ---------------------------- | --------------------------------------------- |
| Full credit card numbers | Last four digits only |
| Passwords or secrets | A link to securely reset or retrieve |
| Social security numbers | Reference an account number |
| Full API keys or tokens | A masked version with a link to the dashboard |
| Medical or financial details | A notification to log in and view securely |
### Be Careful with Metadata and Custom Headers
Any data you attach to an email — custom headers, metadata fields, tags — is stored by Lettr and may appear in logs, webhooks, and dashboard views. Don't use metadata fields to store passwords, tokens, or personally identifiable information that isn't necessary for email delivery.
If you need to correlate emails with internal records, use an opaque identifier (like a UUID) rather than embedding sensitive data directly.
***
## Monitoring and Incident Response
### Use Webhooks to Detect Unusual Activity
Set up webhook handlers to flag abnormal patterns:
```javascript theme={null}
const crypto = require('crypto');
const express = require('express');
const app = express();
app.post('/webhooks/lettr', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['lettr-signature'];
const webhookSecret = process.env.LETTR_WEBHOOK_SECRET;
const expectedSignature = crypto
.createHmac('sha256', webhookSecret)
.update(req.body)
.digest('hex');
if (signature !== expectedSignature) {
return res.sendStatus(401);
}
const event = JSON.parse(req.body);
if (event.type === 'email.bounced' && event.data.bounceType === 'hard') {
trackBounce(event.data.to);
// Alert if hard bounces spike — could indicate a compromised key
// sending to purchased or invalid lists
if (getRecentBounceCount() > BOUNCE_THRESHOLD) {
alertSecurityTeam('Unusual hard bounce spike detected');
}
}
res.sendStatus(200);
});
```
### Review Dashboard Logs Regularly
Check the Lettr dashboard periodically for:
* **Unexpected sending volume** — a spike could mean a compromised key
* **Emails to unfamiliar recipients** — could indicate unauthorized use
* **Failed authentication attempts** — someone may be trying stolen credentials
* **New API keys you didn't create** — another team member may need to verify, or an account may be compromised
If you discover any sign of unauthorized access, rotate all API keys immediately and contact [support@lettr.com](mailto:support@lettr.com).
***
## Security Checklist
Use this checklist when setting up a new Lettr integration or auditing an existing one:
Move all API keys out of source code and into environment variables. Verify your `.env` files are in `.gitignore`.
Check that production services use Sending Only keys, not Full Access keys. Reserve Full Access for admin operations only.
Create distinct keys for development, staging, and production so a compromise in one doesn't affect the others.
Confirm your webhook handler checks the `lettr-signature` header using the raw request body before processing any event.
Ensure your webhook URLs and any client-side requests use HTTPS, not HTTP.
Verify every user on your Lettr account has two-factor authentication enabled in the dashboard.
Review the team members list in the dashboard and remove anyone who no longer needs access.
Audit your email templates to ensure they don't contain passwords, full card numbers, or other sensitive data.
Configure webhook handlers to detect unusual bounce rates, sending volume, or other anomalies.
***
## Related Topics
Understand Full Access vs Sending Only permission levels
Full reference for webhook signature verification
Diagnose and fix API authentication errors
# Sending Reputation
Source: https://docs.lettr.com/knowledge-base/best-practices/sending-reputation
Build and protect sender reputation to maximize inbox placement, learn how ISPs judge bounces, complaints, engagement, and domain versus IP.
Your sender reputation is the single most important factor in whether your emails reach the inbox or get filtered to spam. Mailbox providers like Gmail, Outlook, and Yahoo assign a reputation to every sender based on observed behavior, and that reputation determines how your future emails are treated.
***
## What Is Sender Reputation
Every time you send an email, the receiving mail server evaluates your reputation before deciding what to do with the message. This evaluation happens in milliseconds and draws on data the provider has collected about your sending domain and the IP addresses your emails come from.
### How ISPs Evaluate Senders
Mailbox providers build a profile of each sender over time. They track:
* **Bounce rates** — How often your emails fail to deliver
* **Complaint rates** — How often recipients mark your emails as spam
* **Engagement signals** — Whether recipients open, click, or reply to your emails
* **Authentication results** — Whether your DKIM, SPF, and DMARC records pass
* **Sending patterns** — Whether your volume is consistent or erratic
* **Spam trap hits** — Whether you send to addresses that exist solely to catch spammers
### Domain vs IP Reputation
There are two distinct components to sender reputation:
| Component | What It Is | Who Controls It |
| ----------------- | ----------------------------------------------------------------- | ---------------------------------------------------------- |
| Domain reputation | Reputation tied to your sending domain (e.g., `mail.example.com`) | You — through your sending practices |
| IP reputation | Reputation tied to the IP address that delivers your email | Shared across all senders using the same IP infrastructure |
Lettr sends via shared IP infrastructure powered by SparkPost. This means your domain reputation is the primary lever you control. Domain reputation has become the dominant signal for most major mailbox providers, making it more important than IP reputation in most cases.
### Why It Matters
A strong reputation means your emails are delivered to the inbox quickly and reliably. A damaged reputation means your emails may be:
* Deferred (delayed by hours or days)
* Sent to the spam folder
* Silently dropped without any bounce notification
* Blocked outright by the receiving server
***
## Building Reputation from Scratch
New domains have no reputation history. Mailbox providers treat unknown senders with caution, so you need to build trust gradually through consistent, low-volume sending to engaged recipients.
### Warm-Up Schedule
| Week | Daily Volume | Who to Send To | What to Monitor |
| ---- | -------------------------- | ------------------------------------------------------------------------ | -------------------------------------- |
| 1 | 50–100 | Your most engaged recipients — users who have opened or clicked recently | Bounce rate, complaint rate |
| 2 | 200–500 | Expand to recipients who have engaged in the last 30 days | Bounce rate, complaint rate, deferrals |
| 3 | 500–2,000 | Include recipients who have engaged in the last 90 days | All metrics, inbox placement |
| 4 | 2,000–5,000 | Broader audience, still excluding long-dormant addresses | All metrics |
| 5+ | Scale toward target volume | Full list, excluding suppressed and unengaged addresses | All metrics |
Skipping the warm-up period and sending high volumes immediately from a new domain is one of the most common causes of long-term reputation damage. The damage can take weeks or months to recover from, and some providers may block your domain entirely.
### Key Principles During Warm-Up
* **Send to engaged users first.** Positive engagement signals (opens, clicks, replies) teach mailbox providers that recipients want your emails. Start with your most active subscribers and expand outward.
* **Be consistent.** Send every day during warm-up. Sporadic bursts of volume look suspicious to spam filters.
* **Monitor metrics after every send.** If your bounce rate exceeds 5% or spam complaint rate exceeds 0.3%, stop and investigate before continuing.
* **Use authentication from day one.** Ensure your CNAME, DKIM, and DMARC records are all verified and passing before you send a single email. See [Sending Domains](/learn/domains/sending-domains) for setup instructions.
***
## Protecting Established Reputation
Once you've built a solid reputation, maintaining it requires ongoing attention. Reputation can erode gradually or collapse suddenly depending on what goes wrong.
### Monitor Bounce and Complaint Rates
Check your sending metrics in the Lettr dashboard regularly. The two most critical numbers are:
* **Bounce rate** — Keep below 2%. Investigate immediately if it exceeds 5%.
* **Spam complaint rate** — Keep below 0.1%. Major providers like Gmail will throttle or block senders who exceed 0.3%.
Set up webhook endpoints for `email.bounced` and `email.complained` events to catch problems in real time rather than waiting to check the dashboard.
### Handle Bounces Immediately via Webhooks
Hard bounces indicate permanently invalid addresses. Every email you send to a hard-bounced address damages your reputation. Process bounces the moment they occur:
```javascript theme={null}
app.post('/webhooks/lettr', (req, res) => {
const event = req.body;
switch (event.type) {
case 'email.bounced': {
const { to, bounceType, bounceCode } = event.data;
if (bounceType === 'hard') {
// Permanently invalid — remove immediately
suppressRecipient(to, 'hard_bounce');
} else if (bounceType === 'soft') {
// Temporary issue — track consecutive soft bounces
incrementSoftBounceCount(to);
// Suppress after 3 consecutive soft bounces
if (getSoftBounceCount(to) >= 3) {
suppressRecipient(to, 'repeated_soft_bounce');
}
}
break;
}
case 'email.complained': {
const { to } = event.data;
// Recipient marked your email as spam — never send to them again
suppressRecipient(to, 'spam_complaint');
break;
}
}
res.sendStatus(200);
});
```
You can verify your webhook endpoint receives events correctly using curl:
```bash theme={null}
curl -X POST https://yourdomain.com/webhooks/lettr \
-H "Content-Type: application/json" \
-d '{
"type": "email.bounced",
"data": {
"to": "test@example.com",
"bounceType": "hard",
"bounceCode": "550"
}
}'
```
### Sunset Unengaged Subscribers
Recipients who haven't opened or clicked any of your emails in 6–12 months are hurting your reputation. Mailbox providers track whether recipients engage with your emails, and consistently low engagement tells them your emails aren't wanted.
Query your database for recipients who haven't opened or clicked any email in the last 6–12 months. Use `email.opened` and `email.clicked` webhook events to track engagement over time.
Send a targeted email asking if they still want to hear from you. Make it easy to confirm or unsubscribe.
Anyone who doesn't engage with the re-engagement email within 2 weeks should be removed from your active sending list.
***
## Reputation Signals ISPs Monitor
Mailbox providers weigh multiple signals when evaluating your reputation. Here's what they look at and what healthy values look like:
| Signal | What It Measures | Healthy Range | Danger Zone |
| ------------------------ | ----------------------------------------- | ----------------- | --------------------- |
| Bounce rate | Percentage of emails that fail to deliver | \< 2% | > 5% |
| Complaint rate | Percentage of recipients who report spam | \< 0.1% | > 0.3% |
| Spam trap hits | Emails sent to known trap addresses | 0 | Any hits |
| Open rate | Percentage of recipients who open | > 15% | \< 10% |
| Click rate | Percentage of recipients who click | > 2% | \< 1% |
| Authentication pass rate | Percentage of emails passing DKIM/DMARC | 100% | \< 95% |
| Sending consistency | Regularity and predictability of volume | Stable day-to-day | Sudden spikes or gaps |
You won't find a single "reputation score" in Lettr — no such API exists. Instead, monitor the individual signals above through your Lettr dashboard and webhook data. The combination of these metrics is what mailbox providers use to evaluate you.
***
## Domain Reputation vs IP Reputation
### Shared IP Infrastructure
Lettr sends emails through shared IP infrastructure powered by SparkPost. This means your emails share IP addresses with other Lettr customers. While SparkPost actively manages the reputation of these shared IPs, it also means your domain reputation is the factor you have the most control over.
### Domain Reputation Is What You Control
Major mailbox providers — especially Gmail — have shifted heavily toward domain-based reputation. This is actually advantageous for Lettr senders because:
* Your reputation is entirely in your hands, not affected by other senders on the same IP
* You can build reputation independently by following good sending practices
* Authentication (DKIM, DMARC) ties directly to your domain
### Why Subdomain Isolation Matters
If you send both transactional and marketing emails from the same domain, a reputation problem with your marketing sends can delay password resets, order confirmations, and other critical transactional emails. Using separate subdomains isolates these reputations from each other.
***
## Subdomain Strategy
Separating your email streams by subdomain is one of the most effective ways to protect your sender reputation. Each subdomain builds its own independent reputation with mailbox providers.
### Recommended Setup
| Email Type | Subdomain Example | Purpose |
| ---------------- | --------------------- | ---------------------------------------------------- |
| Transactional | `mail.example.com` | Password resets, order confirmations, account alerts |
| Marketing | `news.example.com` | Newsletters, promotions, product updates |
| Automated / Drip | `updates.example.com` | Onboarding sequences, re-engagement campaigns |
### How to Implement
1. Add each subdomain as a separate sending domain in Lettr
2. Configure CNAME, DKIM, and DMARC records for each subdomain
3. Wait for all domains to reach **approved** status before sending
4. Route each email type through its corresponding subdomain
At a minimum, separate transactional and marketing email onto different subdomains. If your marketing reputation takes a hit, your transactional emails (password resets, receipts) will still deliver reliably. See [Subdomain vs Root Domain](/knowledge-base/fundamentals/subdomain-vs-root) for more guidance.
***
## Recovery from Reputation Damage
If your reputation has been damaged — emails are going to spam, delivery rates have dropped, or you're seeing increased deferrals — you can recover, but it takes time and discipline.
Cut volume to 10–20% of your current level. Continuing to send at full volume while your reputation is damaged makes things worse with every send.
Determine what caused the damage. Common causes include:
* Sending to a purchased or scraped list
* Failing to process bounces, leading to repeated sends to invalid addresses
* A spike in spam complaints after a poorly targeted campaign
* Broken authentication (DKIM/DMARC failures)
Check your webhook logs for `email.bounced`, `email.complained`, and `email.deferred` events to pinpoint the issue.
Remove all hard-bounced addresses, all spam complainants, and anyone who hasn't engaged in the last 6 months. This is not the time for a generous re-engagement window.
Restrict sending to recipients who have opened or clicked within the last 30 days. Positive engagement signals are what will rebuild your reputation.
Follow the same warm-up schedule you would use for a new domain. Increase volume only when your metrics are healthy — bounce rate below 2%, complaint rate below 0.1%.
Check your dashboard and webhook data every day during recovery. It typically takes 2–4 weeks of consistently good behavior for reputation to recover meaningfully.
Recovery is not instant. Mailbox providers need to see sustained good behavior before they'll trust your domain again. Expect the process to take 2–6 weeks depending on the severity of the damage.
***
## Warning Signs
Watch for these indicators that your reputation may be slipping:
If you see a growing number of `email.deferred` webhook events, receiving servers are delaying your emails rather than accepting them immediately. This is often the first sign that a provider is losing trust in your domain. Check which providers are deferring and whether the pattern correlates with a recent volume increase or a change in your recipient list.
A sharp decline in open rates — especially at a specific provider like Gmail or Outlook — usually means your emails are being routed to spam. Open rates naturally fluctuate, but a drop of more than 20–30% over a few days is a red flag. Test by sending to a seed account at the affected provider to confirm inbox placement.
A gradually increasing bounce rate indicates your list is aging and accumulating invalid addresses. If you're not processing `email.bounced` webhook events in real time, stale addresses will pile up and accelerate reputation damage. Review your bounce handling code and confirm suppression is working correctly.
If your emails land in the inbox at most providers but consistently go to spam at one (commonly Gmail), that provider has flagged your domain. This often happens when your complaint rate exceeds their threshold. Reduce volume to that provider, send only to engaged recipients there, and ensure your DKIM and DMARC records are passing. Recovery at a single provider can take 1–4 weeks of improved behavior.
***
## Related Topics
Foundational practices for maximizing inbox placement
Maintain healthy, engaged recipient lists
Configure and verify your sending domains
Choose the right domain strategy for your emails
# Sending via SMTP vs API
Source: https://docs.lettr.com/knowledge-base/best-practices/smtp-vs-api
Choose between SMTP relay and REST API for sending email, with performance comparisons and migration guidance
Lettr supports two methods for sending email: SMTP relay and the REST API. Both deliver the same result — your email reaches the recipient — but they differ in how your application connects to Lettr, the features available, and the performance characteristics. This guide helps you choose the right method and migrate between them.
***
## How Each Method Works
### REST API
Your application sends an HTTP POST request to Lettr's API endpoint with the email content as a JSON payload. Lettr processes the request and returns a response immediately.
```javascript theme={null}
const response = await fetch('https://app.lettr.com/api/emails', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'notifications@mail.example.com',
to: 'recipient@example.com',
subject: 'Your order has shipped',
html: '
Order #1234 shipped
Track your package...
'
})
});
const data = await response.json();
console.log(data.id); // Email ID for tracking
```
### SMTP Relay
Your application connects to Lettr's SMTP server and sends the email using the SMTP protocol. This works with any language, framework, or tool that supports SMTP — including legacy systems, WordPress, and command-line utilities.
```bash theme={null}
# Example: Send via SMTP using curl
curl --url "smtp://smtp.lettr.com:587" \
--ssl-reqd \
--user "api:your-api-key" \
--mail-from "notifications@mail.example.com" \
--mail-rcpt "recipient@example.com" \
--upload-file email.eml
```
```javascript theme={null}
// Node.js with Nodemailer
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
host: 'smtp.lettr.com',
port: 587,
secure: false, // STARTTLS
auth: {
user: 'api',
pass: 'your-api-key'
}
});
await transporter.sendMail({
from: 'notifications@mail.example.com',
to: 'recipient@example.com',
subject: 'Your order has shipped',
html: '
Order #1234 shipped
Track your package...
'
});
```
***
## Feature Comparison
| Feature | REST API | SMTP |
| ------------------------------------ | -------------------------------------------------------- | ----------------------------------------------------- |
| **Template rendering** | Yes — pass template ID and variables in the request | No — you must render the email before sending |
| **Batch sending** | Yes — send to multiple recipients in one request | No — one connection per message (or per SMTP session) |
| **Immediate response with email ID** | Yes | No — SMTP returns only a queue acknowledgment |
| **Metadata and tags** | Yes — include custom metadata in the JSON payload | Limited — use custom headers (X-Lettr-Metadata) |
| **Scheduled sending** | Yes — set `scheduledAt` in the request | No |
| **Attachments** | Yes — base64-encoded in JSON | Yes — native MIME attachments |
| **Idempotency keys** | Yes — via `Idempotency-Key` header | No |
| **Works with legacy systems** | Requires HTTP client support | Works with any SMTP-capable system |
| **Connection overhead** | New HTTPS connection per request (or connection pooling) | Persistent TCP connection with reuse |
| **Firewall compatibility** | Port 443 (HTTPS) — rarely blocked | Port 587 — sometimes blocked in hosted environments |
***
## When to Use the REST API
The API is the recommended method for most use cases. Choose it when:
* **You're building a new integration.** The API provides the richest feature set and the most straightforward developer experience.
* **You use Lettr templates.** The API lets you pass a template ID and substitution variables — the rendering happens server-side.
* **You need batch sending.** Send to multiple recipients in a single API call.
* **You want immediate feedback.** The API response includes the email ID and any validation errors.
* **You're in a serverless environment.** Lambda, Cloud Functions, and similar platforms handle HTTP requests natively but may not support long-lived SMTP connections.
If you're starting fresh and have no existing email infrastructure, use the API. It's simpler to set up, easier to debug, and gives you access to all of Lettr's features.
***
## When to Use SMTP
SMTP is the right choice when:
* **You're migrating from another provider.** If your application already sends via SMTP, switching to Lettr requires only changing the SMTP host, port, and credentials — no code changes.
* **You use a platform that only supports SMTP.** WordPress, legacy CMS systems, and many enterprise applications expose SMTP settings but not HTTP API configuration.
* **You're sending from infrastructure tools.** Monitoring systems, CI/CD pipelines, and cron jobs often use SMTP for notifications.
* **Your environment blocks outbound HTTPS but allows SMTP.** Rare, but it happens in some corporate networks.
### SMTP Connection Settings
| Setting | Value |
| -------------- | --------------------------------------- |
| Host | `smtp.lettr.com` |
| Port | `587` (STARTTLS) or `465` (TLS) |
| Authentication | Username: `api`, Password: your API key |
| Encryption | Required (TLS or STARTTLS) |
Never use port 25 for sending through Lettr. Port 25 is unencrypted and is blocked by most cloud providers. Always use port 587 with STARTTLS or port 465 with implicit TLS.
***
## Performance Considerations
### Throughput
The REST API generally achieves higher throughput because:
* JSON payloads are smaller than full MIME messages
* Batch endpoints let you send multiple emails per request
* HTTP/2 connection multiplexing reduces overhead
SMTP throughput can be improved by reusing connections (sending multiple messages per session), but it still involves more protocol overhead per message (EHLO, AUTH, MAIL FROM, RCPT TO, DATA, QUIT).
### Latency
For a single email, the difference is negligible — both methods typically complete in under 200ms. For high-volume sending, the API's batch endpoint reduces the number of round trips.
### Error Handling
| Scenario | REST API | SMTP |
| ---------------------- | ----------------------------------------- | ----------------------------------- |
| Invalid recipient | Immediate 422 response with error details | 550 response during RCPT TO command |
| Rate limited | 429 response with Retry-After header | 421 response with retry guidance |
| Server error | 500 response | 451 temporary failure code |
| Authentication failure | 401 response | 535 authentication failed |
The API provides structured JSON errors that are easier to parse programmatically:
```json theme={null}
{
"error": {
"code": "validation_error",
"message": "The 'to' field must be a valid email address",
"field": "to"
}
}
```
SMTP errors are text-based status codes that require parsing:
```
550 5.1.1 : Recipient address rejected
```
***
## Migrating from SMTP to API
If you're currently using SMTP and want to switch to the API for more features, follow these steps:
Identify all places in your codebase that send email via SMTP. Look for SMTP configuration (host, port, credentials) and mail-sending calls.
Swap each SMTP send with an API call. If you use a framework like Laravel or Rails, update the mail driver configuration to use Lettr's API transport instead of SMTP.
If you're currently building HTML emails in your application, consider moving them to Lettr templates. This lets you update email content without redeploying your application.
SMTP and API errors have different formats. Update your error handling to parse JSON responses and handle HTTP status codes.
Send test emails through the API to verify everything works before switching production traffic.
***
## Common Mistakes
Serverless functions (AWS Lambda, Vercel Functions) have short execution timeouts and don't maintain persistent connections. SMTP's connection setup overhead makes it a poor fit. Use the REST API in serverless environments.
Opening a new SMTP connection for every email is wasteful. If you're sending multiple emails in sequence, keep the connection open and send them in the same session. Most SMTP libraries support connection pooling.
Store SMTP credentials (your API key) in environment variables, not in your codebase. This applies equally to API keys used with the REST API.
SMTP sends pre-built MIME messages — Lettr can't apply template rendering to them. If you want to use Lettr's template engine with merge tags and conditional content, you need the REST API.
***
## Related Topics
Complete REST API documentation
Send to multiple recipients in a single API call
Best practices for high-volume email sending
Understanding and handling rate limits
Send WordPress emails through Lettr
Stripe, Supabase, WordPress, and more
# Transactional vs Marketing Email
Source: https://docs.lettr.com/knowledge-base/best-practices/transactional-vs-marketing
Understand the differences between transactional and marketing email, why separating them matters, and how to manage both in Lettr
Not all email is created equal. The distinction between transactional and marketing email affects everything from legal compliance to deliverability to how recipients perceive your brand. Understanding and properly separating these two streams is one of the most impactful things you can do for your email program.
***
## Definitions
### Transactional Email
Transactional emails are triggered by a specific user action or event. They contain information the recipient expects or needs — a password reset link, an order confirmation, a shipping update. The recipient initiated the interaction, and the email is a direct response to that action.
### Marketing Email
Marketing emails are sent at the sender's initiative to promote products, share news, or drive engagement. Newsletters, promotional offers, product announcements, and re-engagement campaigns all fall into this category. The sender decides when and what to send, not the recipient.
***
## Why the Distinction Matters
The difference between transactional and marketing email is not just semantic. It has real consequences across three areas:
* **Legal requirements** — Most email regulations treat transactional and marketing email differently. Marketing email typically requires explicit consent and an unsubscribe mechanism. Transactional email has more lenient requirements because the recipient expects it.
* **User expectations** — A user waiting for a password reset link has zero tolerance for delay. A user receiving a weekly newsletter has different expectations entirely. Mixing the two degrades the experience for both.
* **Deliverability** — Mailbox providers evaluate sender reputation based on engagement signals. Marketing email naturally has lower open rates and higher complaint rates than transactional email. If both types share the same sending infrastructure, poor marketing metrics can drag down transactional delivery.
***
## Comparison Table
| | Transactional | Marketing |
| --------------------------- | -------------------------------------------------------- | ---------------------------------------------- |
| **Trigger** | User action or system event | Sender-initiated schedule or campaign |
| **Consent requirement** | Implied by the user's action (e.g., creating an account) | Explicit opt-in required in most jurisdictions |
| **Unsubscribe requirement** | Generally not required | Required by law (CAN-SPAM, GDPR, etc.) |
| **Timing** | Immediate or near-immediate | Scheduled or batched |
| **Examples** | Password resets, order confirmations, 2FA codes | Newsletters, promotions, product announcements |
| **Typical open rates** | 60–80% | 15–25% |
| **Legal basis** | Legitimate interest / contractual necessity | Consent |
***
## Common Examples of Each Type
### Transactional
* Password reset and account recovery emails
* Order confirmations and receipts
* Shipping and delivery notifications
* Account alerts (login from new device, payment failed)
* Two-factor authentication codes
* Subscription renewal confirmations
### Marketing
* Weekly or monthly newsletters
* Promotional offers and discounts
* Product announcements and feature updates
* Re-engagement campaigns for inactive users
* Event invitations and webinar reminders
* Seasonal or holiday campaigns
***
## Gray Areas
Some emails don't fit neatly into one category. These gray areas require careful judgment.
**When in doubt, treat it as marketing.** If an email contains any promotional content beyond what the user explicitly requested, apply marketing rules — include an unsubscribe link and ensure you have proper consent. It is always safer to over-comply than to risk a violation.
Common gray areas include:
* **Onboarding sequences** — Welcome emails triggered by sign-up are transactional in nature, but multi-step onboarding drip campaigns start to look like marketing. If the email is educating the user about the product they signed up for, it leans transactional. If it is upselling or promoting features they did not request, it leans marketing.
* **Review requests** — Asking for a product review after a purchase is related to a transaction, but the request itself is promotional. Most regulators consider these marketing emails.
* **Cross-sell content in transactional emails** — Adding a "You might also like..." section to an order confirmation blurs the line. CAN-SPAM allows some promotional content in transactional emails as long as the primary purpose remains transactional. GDPR is stricter. Keep promotional additions minimal and clearly secondary.
***
## Why Separate Your Sending Streams
Running transactional and marketing email through the same sending infrastructure is a common mistake. Here is why separation matters:
### Reputation Isolation
If a marketing campaign triggers a spike in spam complaints, that reputation damage stays contained to your marketing sending domain. Your transactional emails — the password resets and order confirmations your users depend on — continue to deliver reliably.
### Different Deliverability Profiles
Transactional emails should arrive instantly. Marketing emails are typically batched and can tolerate slight delays. Separating streams lets you optimize delivery speed for transactional email without being constrained by marketing volume.
### Different Compliance Rules
Transactional and marketing emails have different legal requirements. Separating them at the infrastructure level makes compliance easier to manage and audit. You can apply unsubscribe logic, consent checks, and suppression lists independently.
***
## How to Separate in Lettr
Lettr gives you several tools to cleanly separate your transactional and marketing email streams.
### Use Different Subdomains
Configure separate sending subdomains for each email type. This is the most important step for reputation isolation.
| Email Type | Subdomain Example |
| ------------- | -------------------------- |
| Transactional | `mail.yourdomain.com` |
| Marketing | `campaigns.yourdomain.com` |
Each subdomain builds its own sender reputation independently. See [Sending Domains](/learn/domains/sending-domains) for setup instructions.
### Use Different Templates and Projects
Organize your templates into separate [projects](/learn/templates/projects) — one for transactional templates, one for marketing templates. This keeps your template library clean and makes it easy to apply different design standards and review processes to each type.
### Use `tag` for Marketing Emails
When sending marketing emails through the API, include a `tag` to group related sends and track campaign-level metrics in the [Analytics dashboard](/learn/analytics/filtering-and-breakdowns):
```json theme={null}
POST /api/emails
Authorization: Bearer your-api-key
{
"from": "news@campaigns.yourdomain.com",
"to": "recipient@example.com",
"template_id": "tmpl_summer_sale",
"tag": "summer-sale-2025",
"merge_tags": {
"first_name": "Alex",
"offer_code": "SAVE20"
}
}
```
Transactional emails typically do not need a `tag` since they are triggered individually. See [Tags](/learn/sending/tags) for details.
### Use Metadata for Internal Tracking
Add metadata to your API calls to classify and filter emails in your internal systems:
```json theme={null}
{
"from": "no-reply@mail.yourdomain.com",
"to": "user@example.com",
"template_id": "tmpl_password_reset",
"metadata": {
"email_type": "transactional",
"triggered_by": "password_reset_request"
}
}
```
You can use [webhooks](/learn/sending/introduction) to receive delivery events and route them based on this metadata.
***
## Compliance Differences
Transactional and marketing emails face different regulatory requirements. Here is a summary for the two most common frameworks:
| Requirement | CAN-SPAM (Transactional) | CAN-SPAM (Marketing) | GDPR (Transactional) | GDPR (Marketing) |
| ------------------------ | ------------------------------------ | ------------------------------------------- | ---------------------------------------- | --------------------------- |
| **Consent** | Not required | Opt-out model (can send until unsubscribed) | Legitimate interest or contractual basis | Explicit opt-in required |
| **Unsubscribe link** | Not required | Required, must work within 10 days | Not required | Required, must be immediate |
| **Physical address** | Not required if purely transactional | Required | Not required | Required |
| **Accurate sender info** | Required | Required | Required | Required |
| **Honest subject lines** | Required | Required | Required | Required |
This table is a simplified overview, not legal advice. Email regulations vary by jurisdiction and are subject to change. Consult legal counsel for your specific situation.
***
## Best Practices
It is tempting to add a coupon code or product recommendation to an order confirmation. Resist the urge, or keep it minimal. If promotional content becomes the primary purpose of the email, regulators and mailbox providers will treat it as marketing — and your transactional sending reputation suffers.
This is the single most effective way to protect your transactional deliverability. A spam complaint spike on your marketing subdomain will not affect password reset delivery on your transactional subdomain. Configure each subdomain with its own DNS authentication records in Lettr.
Every marketing email must have a clear, functional unsubscribe link. Lettr supports one-click unsubscribe via the `List-Unsubscribe` header. Making it easy to unsubscribe reduces spam complaints, which protects your reputation far more than retaining a disengaged subscriber.
Transactional emails should contain exactly what the user needs — nothing more. A password reset email should have the reset link and minimal context. Every extra element adds load time, increases rendering complexity, and dilutes the purpose. Deliver them immediately via the API without batching.
Track deliverability metrics (bounce rate, complaint rate, open rate) separately for transactional and marketing email. A healthy transactional stream and a struggling marketing stream require very different responses. Use Lettr's webhook events and campaign tracking to maintain visibility into each stream.
***
## Related Topics
Understand CAN-SPAM requirements and how they apply to your emails.
Implement unsubscribe mechanisms that protect your reputation and comply with regulations.
Build and maintain a strong sender reputation across all your email streams.
Learn why subdomains are recommended for email sending and how to configure them.
# Acceptable Use Policy for Email
Source: https://docs.lettr.com/knowledge-base/compliance/acceptable-use-policy
What you can and cannot send through Lettr, covering permitted transactional and marketing use, prohibited content, and anti-abuse measures.
## Why an Acceptable Use Policy Exists
Email service providers maintain acceptable use policies (AUPs) to protect the platform's sending reputation, ensure reliable delivery for all users, and comply with legal obligations. When one sender abuses the platform, the resulting reputation damage affects every other sender sharing that infrastructure.
Lettr's acceptable use policy sets clear expectations for what you can send, how you should send it, and what is prohibited. Following these guidelines protects your deliverability and helps maintain a healthy sending environment for everyone.
Every major email service provider — including SendGrid, Postmark, Amazon SES, and Resend — enforces an acceptable use policy. These policies exist to protect the shared infrastructure that makes reliable email delivery possible.
***
## Permitted Use
Lettr is designed for legitimate transactional and commercial email. Permitted uses include:
| Category | Examples |
| ----------------------- | ------------------------------------------------------------------------------------------------------------- |
| **Transactional email** | Order confirmations, shipping notifications, password resets, account alerts, two-factor authentication codes |
| **Marketing email** | Newsletters, product announcements, promotional campaigns, event invitations |
| **Relationship email** | Onboarding sequences, feedback requests, renewal reminders, re-engagement campaigns |
| **Operational email** | System alerts, status updates, scheduled reports, usage notifications |
All permitted sending must comply with applicable laws (CAN-SPAM, GDPR, CASL) and follow email best practices regarding consent, identification, and unsubscribe mechanisms.
***
## Prohibited Content
The following types of content are prohibited and may result in immediate account suspension:
### Spam and Unsolicited Email
* Sending email to recipients who have not consented to receive it (where consent is required by law)
* Using purchased, rented, scraped, or harvested email lists
* Sending email to addresses collected through deceptive means
* Sending to lists that have not been mailed in over 12 months without re-consent
### Deceptive or Fraudulent Content
* Phishing emails or messages impersonating other organizations
* Emails with false or misleading header information
* Deceptive subject lines designed to trick recipients into opening
* Emails that disguise commercial content as personal messages
### Illegal Content
* Content that violates applicable laws in the sender's or recipient's jurisdiction
* Emails promoting illegal products, services, or activities
* Content that facilitates identity theft, financial fraud, or other crimes
### Malware and Harmful Content
* Emails containing viruses, malware, or malicious attachments
* Messages with links to malware distribution or phishing sites
* Emails designed to exploit software vulnerabilities
### Harmful or Abusive Content
* Threats, harassment, or intimidation
* Content promoting violence or self-harm
* Child exploitation material
Violations of the prohibited content policy may result in immediate account suspension without prior notice. Lettr reserves the right to review and take action on any content that poses a risk to platform reputation or violates applicable laws.
***
## Sending Practice Requirements
Beyond content restrictions, Lettr requires that all senders follow responsible sending practices:
### Authentication
All sending domains must be properly authenticated with SPF, DKIM, and DMARC. Unauthenticated sending is not permitted.
### Consent and Compliance
* Obtain appropriate consent before sending commercial email
* Include a functional unsubscribe mechanism in every commercial message
* Honor unsubscribe requests promptly
* Include accurate sender identification and a physical address in commercial emails
### List Quality
* Maintain clean recipient lists with valid, consented addresses
* Remove hard bounces immediately — do not re-send to addresses that have hard bounced
* Process spam complaints and unsubscribes without delay
* Do not send to suppressed addresses
### Volume and Reputation
* Warm up new domains and IPs gradually — do not send high volume from a new domain on day one
* Maintain a spam complaint rate below 0.1% (hard limit: 0.3%)
* Maintain a hard bounce rate below 2%
* Monitor your sending reputation through tools like Google Postmaster Tools
Lettr automatically adds hard bounces and spam complaints to your suppression list. Attempting to circumvent suppression lists by re-adding bounced or complained addresses is a policy violation.
***
## Monitoring and Enforcement
Lettr monitors sending activity to detect potential abuse and protect platform reputation. Monitoring includes:
| Signal | What It Indicates |
| ---------------------------- | ----------------------------------------- |
| **High bounce rate** | Poor list quality or stale addresses |
| **High spam complaint rate** | Unwanted email or poor consent practices |
| **Spam trap hits** | Use of purchased, scraped, or stale lists |
| **Sudden volume spikes** | Potential compromise or abuse |
| **Content pattern matching** | Phishing, scam, or prohibited content |
### Enforcement Actions
Depending on the severity and nature of the violation, Lettr may take one or more of the following actions:
For minor or first-time issues, you will receive a notification explaining the problem and what corrective action is needed.
Your sending rate may be temporarily reduced while the issue is investigated or resolved.
Your ability to send email may be temporarily suspended pending resolution of the issue.
For severe violations (phishing, malware, repeated policy violations), your account may be permanently terminated.
***
## What to Do If Your Account Is Flagged
If your sending is flagged or suspended:
1. **Check your email** — Lettr will send a notification explaining the issue
2. **Review your recent sending** — Identify the source of the problem (list quality, content, consent)
3. **Take corrective action** — Fix the root cause before requesting reinstatement
4. **Contact support** — Reach out to [support@lettr.com](mailto:support@lettr.com) with details of the corrective actions you have taken
Most flagged accounts are the result of list quality issues, not intentional abuse. Cleaning your list, removing unengaged recipients, and verifying consent records resolves the majority of cases.
***
## Common Mistakes
Lists that have not been mailed in 12 or more months are likely to contain invalid addresses, spam traps, and disengaged recipients. Sending to these lists will generate high bounce and complaint rates, triggering enforcement actions. Always re-verify or re-consent stale lists before importing.
High bounce and complaint rates are early warning signs. If you notice rates climbing, investigate immediately — do not continue sending at the same volume to the same list. Continuing to send into poor metrics will escalate enforcement actions.
Every commercial email must include a functional unsubscribe mechanism. Sending marketing email without one violates both the acceptable use policy and applicable laws (CAN-SPAM, GDPR, CASL).
While transactional email has lighter compliance requirements, it is still subject to the acceptable use policy. Transactional email must not contain deceptive content, must be sent to valid addresses, and must not be used as a vehicle for marketing content without proper consent and unsubscribe mechanisms.
Attempting to re-add addresses that have been suppressed due to bounces, complaints, or unsubscribes is a serious policy violation. Suppression lists exist to protect both recipients and your sending reputation.
***
## Related Topics
Maximize inbox placement and maintain sender reputation.
Build and protect your sender reputation.
Maintain clean, compliant recipient lists.
Gradually ramp up sending volume on new domains and IPs.
# CAN-SPAM Requirements
Source: https://docs.lettr.com/knowledge-base/compliance/can-spam
What the US CAN-SPAM Act requires for commercial email, who must comply, and the seven rules for headers, opt-out, and sender identification.
## What Is CAN-SPAM?
The **CAN-SPAM Act** (Controlling the Assault of Non-Solicited Pornography And Marketing Act) is a United States federal law enacted in 2003 that sets the rules for commercial email. It is enforced by the **Federal Trade Commission (FTC)** and establishes requirements for commercial messages, gives recipients the right to stop receiving emails, and spells out penalties for violations.
CAN-SPAM applies to **any commercial email sent to US recipients**, regardless of where the sender is located. If you send marketing emails to people in the United States, you must comply.
***
## Who Must Comply
CAN-SPAM applies to any sender of **"commercial electronic mail messages"** — any email whose primary purpose is the commercial advertisement or promotion of a product or service. This includes:
* Marketing and promotional emails
* Newsletters with commercial content
* Transactional emails that contain significant commercial content beyond the transaction itself
Even if your business is based outside the United States, CAN-SPAM applies to you if your emails reach US recipients.
***
## The Seven Requirements
Your **From**, **To**, **Reply-To**, and routing information must be accurate and identify the person or business that initiated the message. In Lettr, always send from a verified domain that belongs to your organization.
```html theme={null}
From: Sarah Johnson
Reply-To: support@yourcompany.com
From: Account Security
```
The subject line must accurately reflect the content of the message. Do not use misleading language to trick recipients into opening the email.
```
✓ "25% off all shoes this weekend"
✓ "Your monthly product newsletter"
✗ "Re: Your account has been compromised"
✗ "You have a new message from a friend"
```
If your email is commercial or promotional in nature, you must clearly and conspicuously disclose that the message is an advertisement. The law gives you flexibility in how to do this, but it must be clear.
```html theme={null}
This email is a promotional message from Your Company Name.
```
Every commercial email must include your valid **physical postal address**. This can be a street address, a PO Box registered with the US Postal Service, or a private mailbox registered with a commercial mail receiving agency.
```html theme={null}
```
You must provide a **clear and conspicuous** mechanism for recipients to opt out of future commercial emails. The opt-out process must be easy to find, easy to use, and available for at least 30 days after the message is sent.
```html theme={null}
```
Lettr handles unsubscribe processing automatically when you use the `data-msys-unsubscribe="1"` attribute on your unsubscribe link. The recipient is added to your suppression list and no further action is needed on your part.
Once a recipient opts out, you must stop sending them commercial email within **10 business days**. You cannot charge a fee, require any information beyond an email address, or make the recipient take any step other than sending a reply email or visiting a single web page.
When using Lettr's built-in unsubscribe mechanism, opt-outs are processed **immediately** — well within the 10-business-day requirement. You can monitor unsubscribe activity through the `unsubscribe` webhook event.
Even if you hire another company to handle your email marketing, **you are still legally responsible** for compliance. Both the company whose product is promoted and the company that sends the message can be held liable.
***
## Transactional vs Commercial Email
CAN-SPAM treats transactional and commercial emails differently. Transactional emails have lighter requirements but must still meet basic honesty standards.
| Requirement | Commercial Email | Transactional Email |
| --------------------------- | ---------------- | ------------------- |
| Accurate header information | Required | Required |
| Non-deceptive subject line | Required | Required |
| Identify as advertisement | Required | Not required |
| Physical postal address | Required | Not required |
| Unsubscribe mechanism | Required | Not required |
| Honor opt-out requests | Required | Not required |
A **transactional email** is one that facilitates an already agreed-upon transaction, provides warranty or product information, updates account status, or delivers goods or services. Examples include order confirmations, shipping notifications, and password resets. If a transactional email contains significant commercial content, it may be reclassified as commercial.
***
## Implementation in Lettr
### Physical Address in the Footer
Include your physical address in every commercial email template:
```html theme={null}
This email was sent by {{company_name or 'Your Company'}}
{{company_address or '123 Main Street, Suite 400, New York, NY 10001'}}
```
### Unsubscribe Link
Use the `data-msys-unsubscribe="1"` attribute on any link to enable Lettr's automatic unsubscribe processing:
```html theme={null}
Unsubscribe from these emails
```
When a recipient clicks this link, Lettr will:
1. Add the recipient to your suppression list
2. Fire an `unsubscribe` webhook event
3. Prevent future emails from being delivered to that address
### Accurate From Address
Always send from a verified domain in Lettr. Use a From address that clearly identifies your business:
```html theme={null}
From: Your Company
```
### Honest Subject Lines
Use Lettr's template variables to create dynamic but accurate subject lines:
```
{{if sale_active}}{{discount_percent}}% off — this weekend only{{end}}
{{if order_shipped}}Your order #{{order_id}} has shipped{{end}}
```
***
## Penalties
Violations of the CAN-SPAM Act can result in fines of up to **\$50,120 per email** per violation. Both the sender and the company whose product is promoted can be held liable. In severe cases, criminal penalties including imprisonment may apply.
Multiple parties can be held responsible for a single violation:
* The **company** whose product or service is promoted
* The **individual** who originated or transmitted the message
* Any **third party** that assists in the transmission
***
## Common Mistakes
Making the unsubscribe link tiny, low-contrast, or buried in dense text violates the requirement that the opt-out mechanism be "clear and conspicuous." Place the unsubscribe link in a visible location, typically the email footer, with legible text and adequate contrast.
CAN-SPAM requires opt-outs to be honored within 10 business days. Some senders use manual processes that cause delays. With Lettr's `data-msys-unsubscribe="1"` attribute, unsubscribes are processed instantly, eliminating this risk.
Every commercial email must include a valid physical postal address. This is one of the most commonly overlooked requirements. Add your address to your email templates and ensure it is present in every commercial send.
Using subject lines like "Re:" or "Fwd:" on emails that are not replies or forwards is deceptive. Similarly, implying urgency or personal familiarity that does not exist violates the Act. Keep subject lines honest and reflective of the email content.
CAN-SPAM does not require prior consent to send commercial email — it follows an **opt-out** model. However, purchased lists are still risky because they often contain invalid addresses, spam traps, and unengaged recipients, which will damage your deliverability. Even though sending to a purchased list may technically comply with CAN-SPAM, it is strongly discouraged.
***
## CAN-SPAM vs GDPR
If you send email to recipients in both the US and the EU/EEA, you need to understand the differences between these two frameworks.
| | CAN-SPAM (US) | GDPR (EU/EEA) |
| --------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------ |
| **Consent model** | Opt-out — you can email until they unsubscribe | Opt-in — you need explicit consent before sending |
| **Geographic scope** | Applies to emails sent to US recipients | Applies to emails sent to EU/EEA residents |
| **Consent standard** | No prior consent required for commercial email | Freely given, specific, informed, and unambiguous consent required |
| **Unsubscribe requirement** | Must provide opt-out mechanism in every email | Must provide opt-out, and consent must be as easy to withdraw as to give |
| **Record keeping** | No specific consent record requirements | Must maintain records proving valid consent |
| **Maximum penalties** | Up to \$50,120 per violation per email | Up to 4% of annual global turnover or €20 million |
If you send to both US and EU audiences, the simplest approach is to comply with GDPR for all recipients, since its requirements are stricter and encompass CAN-SPAM compliance.
***
## Related Topics
Understand GDPR requirements for email marketing to EU recipients.
Implement effective unsubscribe flows that keep you compliant and protect your reputation.
Meet the sender requirements enforced by major mailbox providers.
Optimize your sending practices for maximum inbox placement.
# CASL (Canadian Anti-Spam Law)
Source: https://docs.lettr.com/knowledge-base/compliance/casl
Requirements of Canada's Anti-Spam Legislation, consent types, and how CASL differs from CAN-SPAM and GDPR
## What Is CASL
**Canada's Anti-Spam Legislation (CASL)** is a federal law that took effect on July 1, 2014. It regulates commercial electronic messages (CEMs) sent to or from Canadian computer systems. CASL is enforced by the **Canadian Radio-television and Telecommunications Commission (CRTC)**, the **Competition Bureau**, and the **Office of the Privacy Commissioner of Canada**.
CASL is widely considered one of the strictest anti-spam laws in the world. Unlike the US CAN-SPAM Act, which follows an opt-out model, CASL requires **prior consent** before you can send a commercial electronic message.
CASL applies to any commercial electronic message sent to a **Canadian recipient** or routed through a **Canadian computer system**, regardless of where the sender is located. If you have Canadian recipients on your list, CASL applies to you.
***
## Who Must Comply
CASL applies to any person or organization that sends a **commercial electronic message (CEM)** — any electronic message that encourages participation in a commercial activity. This includes:
* Marketing and promotional emails
* Newsletters that promote products or services
* Emails containing offers, discounts, or upsells
* Messages that direct recipients to a website with commercial content
CASL also covers SMS, social media messages, and other electronic messages — not just email. However, for the purpose of email sending through Lettr, this article focuses on email-specific requirements.
***
## Consent Under CASL
CASL recognizes two types of consent: **express** and **implied**. You must have one or the other before sending a commercial email to a Canadian recipient.
### Express Consent
Express consent is an affirmative opt-in where the recipient explicitly agrees to receive your messages. It does not expire and remains valid until the recipient withdraws it.
To obtain valid express consent, you must clearly disclose:
1. **Who** is requesting consent (your name or organization name)
2. **Why** you are requesting consent (the purpose for sending messages)
3. **Contact information** — a mailing address and either a phone number, email address, or web address
4. **How to withdraw** — a statement that the recipient can unsubscribe at any time
```html theme={null}
```
Pre-checked boxes do **not** constitute express consent under CASL. The recipient must take an affirmative action to opt in.
### Implied Consent
Implied consent exists in certain business relationships without an explicit opt-in, but it is **time-limited**. The two most common forms are:
| Type | Duration | Example |
| -------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------- |
| **Existing business relationship** | 2 years from last purchase, contract, or transaction | A customer who bought from you 18 months ago |
| **Existing non-business relationship** | 6 months from the inquiry or application | A prospect who submitted a contact form 4 months ago |
| **Conspicuous publication** | No fixed expiry, but message must be relevant to the recipient's role | An email address listed on a business website or directory |
Implied consent is temporary. Use it as a window to convert the recipient to express consent. Include a clear opt-in mechanism in every email you send under implied consent.
***
## The Three Requirements for Every CEM
Every commercial electronic message sent under CASL must meet three requirements:
You must have valid consent before sending. Unlike CAN-SPAM, you cannot send first and offer an opt-out later.
Every message must clearly identify the sender, including your name (or the name of the person on whose behalf the message is sent), your mailing address, and a way to contact you (phone, email, or web URL).
Every message must include a functional unsubscribe mechanism that is free, easy to use, and works for at least 60 days after the message is sent. Unsubscribe requests must be processed within **10 business days**.
***
## Implementation in Lettr
### Consent Record Keeping
Maintain records of how and when consent was obtained. For express consent, store:
* The date and time of consent
* The method (signup form, checkbox, etc.)
* The exact text or disclosure presented
* The source (URL of the form, event name, etc.)
```javascript theme={null}
// Example: Storing consent data alongside a Lettr API call
const response = await fetch("https://app.lettr.com/api/emails", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "updates@yourcompany.com",
to: "recipient@example.ca",
subject: "Your weekly product update",
template_id: "weekly-update",
metadata: {
consent_type: "express",
consent_date: "2025-06-15T10:30:00Z",
consent_source: "signup_form_v3",
},
}),
});
```
### Unsubscribe Link
Use Lettr's built-in unsubscribe tracking to comply with the unsubscribe requirement:
```html theme={null}
Unsubscribe
```
Lettr processes unsubscribes immediately when using `data-msys-unsubscribe="1"`, which is well within CASL's 10-business-day requirement.
### Sender Identification
Include your organization name, mailing address, and contact information in every commercial email footer:
```html theme={null}
```
***
## Penalties
CASL penalties are among the highest in the world for anti-spam violations:
* Up to **\$1 million per violation** for individuals
* Up to **\$10 million per violation** for organizations
* Directors and officers can be held **personally liable**
The CRTC has levied multi-million-dollar fines against companies of all sizes.
***
## CASL vs CAN-SPAM vs GDPR
| Aspect | CASL (Canada) | CAN-SPAM (US) | GDPR (EU) |
| ------------------------------ | -------------------------------------- | --------------------------------------------- | -------------------------------------------------------- |
| **Consent model** | Opt-in required (express or implied) | Opt-out — you can send until they unsubscribe | Opt-in required (explicit consent) |
| **Pre-checked boxes** | Not valid consent | Not addressed (no consent required) | Not valid consent |
| **Implied consent** | Yes, time-limited (2 years / 6 months) | N/A — no consent required | No — consent must be explicit |
| **Unsubscribe processing** | Within 10 business days | Within 10 business days | Without undue delay |
| **Physical address required** | Yes | Yes | Not explicitly, but data controller must be identifiable |
| **Maximum penalties** | \$10M per violation (organizations) | \~\$50,120 per email | 4% of global revenue or €20M |
| **Transactional email exempt** | Largely exempt | Largely exempt | Requires lawful basis (contractual necessity) |
If you send email to recipients in Canada, the US, and the EU, the simplest compliance strategy is to obtain express consent from all recipients and honor all unsubscribe requests immediately. This satisfies the strictest requirements across all three frameworks.
***
## Common Mistakes
Implied consent expires — 2 years for existing business relationships and 6 months for inquiries. If you do not convert recipients to express consent before the implied consent window closes, you must stop emailing them.
CAN-SPAM is an opt-out law; CASL is an opt-in law. Complying with CAN-SPAM does not mean you comply with CASL. If you have Canadian recipients, you need express or implied consent before sending.
CASL places the burden of proof on the sender. If you cannot demonstrate that you had valid consent at the time of sending, you are presumed non-compliant. Store timestamps, form versions, and the disclosure text for every consent record.
Purchased lists almost never include valid CASL consent. Sending commercial email to purchased Canadian addresses without consent is a direct violation.
Every CEM must include your name, mailing address, and contact information. Missing any of these is a separate violation, even if you have valid consent and include an unsubscribe link.
***
## Related Topics
US commercial email law and how it compares to CASL.
EU data protection requirements for email communications.
Practical guidance for obtaining, recording, and managing email consent.
Implement effective unsubscribe mechanisms across all jurisdictions.
# Data Privacy in Email Metadata
Source: https://docs.lettr.com/knowledge-base/compliance/data-privacy-metadata
What data Lettr stores when you send an email, the difference between metadata and substitution data, and how to protect sensitive information.
When you send an email through Lettr, several pieces of data are stored to ensure reliable delivery, enable analytics, and support debugging. Understanding what is stored and how to keep sensitive information out of your email data is essential for maintaining compliance and protecting your users.
***
## What Data Lettr Stores
Every email sent through Lettr results in the following data being stored:
| Data | Description |
| ----------------- | ---------------------------------------------------------------------------- |
| Sender address | The `from` address used to send the email |
| Recipient address | The `to`, `cc`, and `bcc` addresses |
| Subject line | The subject of the email |
| Email content | The full HTML or text body of the email |
| Metadata | Custom key-value pairs you attach to the request |
| Delivery events | Timestamps for injection, delivery, bounces, opens, clicks, and other events |
| Tracking data | Open and click tracking information when enabled |
This data is visible in the Lettr dashboard under your email history and is used for analytics, debugging, and webhook delivery.
***
## Understanding Metadata vs Substitution Data
Lettr provides two distinct objects when sending an email, and it is important to understand the difference between them.
### `metadata`
Custom key-value pairs passed alongside the email for **your** tracking purposes. Metadata is not rendered into the email content. It is stored by Lettr and included in webhook event payloads so your systems can correlate events back to your internal records.
### `substitution_data`
Template variables that are rendered **into** the email content. These are used for personalization — things like the recipient's name, order details, or any dynamic content in your template.
Both `metadata` and `substitution_data` are stored by Lettr and visible in the dashboard. Treat both as data that will be persisted and accessible to your team members with dashboard access.
***
## What NOT to Include in Email Data
Never include the following in `metadata`, `substitution_data`, or email content:
* **Passwords, tokens, or credentials** — use secure, time-limited links instead
* **Social security numbers or national IDs**
* **Credit card numbers or financial account details**
* **Health information** (PHI under HIPAA)
* **Full API keys or secrets**
This data is stored by Lettr and visible in the dashboard. Including it creates a compliance risk and exposes sensitive information to anyone with account access.
***
## Safe Metadata Practices
Use opaque identifiers in metadata instead of personally identifiable information (PII). Your internal systems can resolve these identifiers when processing webhook events.
```bash theme={null}
# Bad — PII in metadata
curl -X POST https://app.lettr.com/api/emails \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "orders@shop.com",
"to": "customer@example.com",
"subject": "Your order confirmation",
"template_id": "order-confirmation",
"metadata": {
"customer_name": "Jane Smith",
"customer_email": "jane.smith@example.com",
"customer_ssn": "123-45-6789"
}
}'
# Good — opaque identifiers only
curl -X POST https://app.lettr.com/api/emails \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "orders@shop.com",
"to": "customer@example.com",
"subject": "Your order confirmation",
"template_id": "order-confirmation",
"metadata": {
"user_id": "usr_8a3f2b",
"order_id": "ord_19x7k4",
"campaign": "summer-sale-2025"
}
}'
```
Keep metadata minimal. Only include what you need for webhook processing and internal tracking. Every key-value pair is stored and delivered to all configured webhook endpoints.
***
## Safe Substitution Data Practices
Remember that `substitution_data` is rendered directly into the email content. Whatever you pass becomes part of the email body that is sent to the recipient and stored by Lettr.
Do not pass sensitive data through `substitution_data` that should not appear in the email itself.
```javascript theme={null}
// Safe personalization with substitution_data
const response = await fetch("https://app.lettr.com/api/emails", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "support@yourapp.com",
to: "user@example.com",
subject: "Your password reset request",
template_id: "password-reset",
substitution_data: {
first_name: "Jane",
reset_link: "https://yourapp.com/reset?token=abc123",
expiry_hours: "24",
},
metadata: {
user_id: "usr_8a3f2b",
request_id: "req_44fn29",
},
}),
});
```
Notice that the password reset token lives in a URL, not as a standalone value. The token itself is time-limited and single-use, so even if the email content is stored, the token expires and cannot be reused.
***
## Email Content Considerations
Email content — the full HTML or text body — is stored by Lettr to support delivery history and debugging. Keep this in mind when building your templates:
* **Do not embed sensitive data in HTML** that you would not want stored or visible in the dashboard.
* **Use secure links** for sensitive actions like password resets and account verification instead of embedding sensitive data directly in the email body.
* **Avoid including full account details** in transactional emails. Show partial or masked information (e.g., "card ending in 4242") rather than complete values.
***
## Data Retention
Lettr retains email data — including content, metadata, and delivery events — according to its data retention policy.
If you need to comply with data deletion requests, such as the GDPR right to erasure, contact [support@lettr.com](mailto:support@lettr.com) to discuss your requirements.
***
## Practical Guidelines
Your metadata should reference internal identifiers that only your systems can resolve. Instead of passing `customer_email` in metadata, pass a `user_id`. Your webhook consumers can look up the email address from your own database when needed.
Password resets, account verifications, and other sensitive actions should use tokens that expire. Even if the email content is stored indefinitely, an expired token poses no security risk. Set expiry times as short as practical — 24 hours or less for password resets.
It is tempting to encode useful information into identifiers, but values like `tag` are stored and visible across your team. Use opaque identifiers and resolve them in your own systems.
As your integration evolves, new fields may get added to metadata or substitution data without a privacy review. Schedule periodic audits of your API calls to ensure no sensitive data has crept into your payloads.
Metadata flows to all configured webhook endpoints. If you have multiple services consuming webhooks, every one of them receives the full metadata object. Only include data that all consumers are authorized to see.
***
## Related Topics
Understand GDPR requirements for email communications.
Learn how to use metadata when sending emails through Lettr.
Use substitution data effectively in your email templates.
Secure your Lettr integration and protect your sending infrastructure.
# Data Retention and Deletion
Source: https://docs.lettr.com/knowledge-base/compliance/data-retention
Learn how long Lettr retains email content, delivery events, tracking data, and suppression records, plus how to handle deletion requests.
## Why Data Retention Matters
Every email you send through Lettr generates data — recipient addresses, email content, delivery events, tracking data, and metadata. Understanding what is retained, for how long, and how to handle deletion requests is essential for compliance with GDPR, CASL, and other data protection regulations.
A clear data retention policy helps you:
* Respond to data subject access and deletion requests
* Minimize the personal data you store
* Meet regulatory expectations for data minimization
* Maintain a defensible compliance posture
Under GDPR's data minimization principle, personal data should be kept only for as long as necessary for the purposes for which it was collected. Retaining email data indefinitely without justification is a compliance risk.
***
## What Data Lettr Retains
When you send email through Lettr, the following data is stored:
| Data Type | Description | Retention Purpose |
| ---------------------------------- | ---------------------------------------------------------------- | ----------------------------------------------- |
| **Sender and recipient addresses** | From, To, CC, BCC addresses | Delivery, history, analytics |
| **Subject line** | The email subject | History, debugging |
| **Email content** | Full HTML or plain text body | History, preview, debugging |
| **Metadata** | Custom key-value pairs you attach via the API | Webhook delivery, your internal tracking |
| **Delivery events** | Injection, delivery, bounce, open, click, unsubscribe timestamps | Analytics, deliverability monitoring |
| **Tracking data** | Open and click tracking events with timestamps | Engagement analytics |
| **Suppression records** | Bounced, complained, and unsubscribed addresses | Preventing future sends to suppressed addresses |
Suppression records (bounces, complaints, unsubscribes) are retained separately from email history. Even when email data is deleted, suppression records are maintained to prevent re-sending to addresses that should not receive email.
***
## Retention Periods
Lettr retains different categories of data for different periods:
| Data Category | Retention Period | Notes |
| ---------------------------------- | -------------------------------------------- | -------------------------------------------------------- |
| **Email content and history** | 30 days | Full email body, subject, headers available in dashboard |
| **Delivery and engagement events** | 90 days | Open, click, bounce, delivery timestamps |
| **Aggregated analytics** | 12 months | Summary statistics without individual-level data |
| **Suppression lists** | Indefinite | Required to prevent sending to suppressed addresses |
| **API request logs** | 30 days | Request/response logs for debugging |
| **Account and billing data** | Duration of account + legal retention period | Required for billing and legal compliance |
If you need to retain email data longer than the default retention periods — for example, for your own compliance or audit requirements — export the data you need to your own systems using webhooks or the API before it is purged.
***
## Data Minimization Best Practices
Reduce the personal data flowing through your email infrastructure by following these practices:
### Use Opaque Identifiers in Metadata
Pass internal IDs instead of personally identifiable information in your API calls:
```bash theme={null}
# Avoid — PII in metadata
curl -X POST https://app.lettr.com/api/emails \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "orders@shop.com",
"to": "customer@example.com",
"subject": "Order confirmation",
"template_id": "order-confirm",
"metadata": {
"customer_name": "Jane Smith",
"customer_phone": "+1-555-0123"
}
}'
# Better — opaque identifiers only
curl -X POST https://app.lettr.com/api/emails \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type": "application/json" \
-d '{
"from": "orders@shop.com",
"to": "customer@example.com",
"subject": "Order confirmation",
"template_id": "order-confirm",
"metadata": {
"user_id": "usr_8a3f2b",
"order_id": "ord_19x7k4"
}
}'
```
### Limit Sensitive Data in Email Content
* Use masked or partial values (e.g., "card ending in 4242") instead of full account numbers
* Use time-limited, single-use tokens for sensitive actions like password resets
* Avoid embedding government IDs, health data, or financial details in email bodies
### Export What You Need, Delete What You Don't
Use Lettr's webhooks to capture delivery and engagement data in your own systems in real time. This way, you have the data you need for analysis without relying on Lettr's retention windows.
***
## Handling Deletion Requests
Under GDPR (right to erasure) and similar regulations, individuals can request that you delete their personal data. When a recipient makes a deletion request, you must address data held both in your own systems and in Lettr.
### What to Delete
Delete the recipient's email address and associated data from your own CRM, database, and mailing lists.
Add the address to your suppression list to ensure you do not accidentally re-add or re-send to this person. Maintaining a suppression record with the minimum necessary data (the email address) is permitted under GDPR.
Contact [support@lettr.com](mailto:support@lettr.com) to request deletion of a specific recipient's data from Lettr's systems. Include the email address and the sending domain(s) involved.
Once deletion is complete, confirm to the individual that their data has been removed.
GDPR requires you to respond to erasure requests within **one month**. Do not delay processing deletion requests. Establish an internal process so requests are handled promptly.
### What Is NOT Deleted
Certain data is retained even after a deletion request:
* **Suppression records** — The email address is retained in the suppression list to prevent future sends. This is permitted under GDPR as a legitimate interest to comply with the individual's request not to be contacted.
* **Aggregated analytics** — De-identified, aggregated statistics that cannot identify an individual are not subject to erasure requests.
* **Legal hold data** — Data subject to a legal hold, regulatory investigation, or ongoing dispute may be retained as required by law.
Suppression lists serve the recipient's interest by ensuring they are not contacted again. Regulators have confirmed that retaining the minimum data necessary for suppression purposes is compatible with the right to erasure.
***
## Data Subject Access Requests
Under GDPR, individuals can also request a copy of all personal data you hold about them (right of access). For email data, this may include:
* Email addresses and any associated profile data
* Sending history (dates, subjects, templates used)
* Engagement data (opens, clicks)
* Metadata attached to their emails
* Suppression status
You can retrieve much of this data from Lettr's dashboard or API. For data that is not accessible through self-service, contact [support@lettr.com](mailto:support@lettr.com).
Build internal tooling to generate data export reports from your own systems. This reduces your dependence on Lettr for access requests and speeds up your response time.
***
## Your Responsibilities as Data Controller
When you use Lettr to send email, you are the **data controller** and Lettr is the **data processor**. This means:
| Responsibility | Owner |
| ---------------------------------------------- | ----------------- |
| Determining what data to collect and process | You (controller) |
| Ensuring lawful basis for processing | You (controller) |
| Responding to data subject requests | You (controller) |
| Processing data according to your instructions | Lettr (processor) |
| Implementing appropriate security measures | Both |
| Maintaining a Data Processing Agreement (DPA) | Both |
As the data controller, you are ultimately responsible for compliance. Ensure you have a Data Processing Agreement (DPA) in place with Lettr. Contact [support@lettr.com](mailto:support@lettr.com) to request a DPA if you do not already have one.
***
## Common Mistakes
Keeping all email data forever "just in case" violates the data minimization principle under GDPR. Define clear retention periods based on your business needs and delete data that is no longer necessary.
If you delete a recipient's suppression record along with the rest of their data, you risk re-adding them to a list and sending to them again — which is the opposite of what they requested. Always maintain suppression records even after erasure.
As the data controller, you must understand what personal data your processors hold. Familiarize yourself with Lettr's data storage practices so you can accurately respond to access and deletion requests.
Metadata and substitution data are stored by Lettr and visible in the dashboard. If you pass PII in these fields, it becomes part of the data you must account for in access and deletion requests. Use opaque identifiers instead.
Without a defined internal process, deletion and access requests get delayed or lost. Designate a responsible person or team, define the steps, and document your procedures before a request arrives.
***
## Related Topics
EU data protection requirements for email communications.
What data is stored when sending emails and how to protect sensitive information.
Obtaining, recording, and managing email consent.
How suppression lists work and why they matter.
# Email Consent Best Practices
Source: https://docs.lettr.com/knowledge-base/compliance/email-consent
How to obtain, record, and manage email consent for compliance with GDPR, CASL, and other regulations
## Why Consent Matters
Consent is the foundation of compliant email sending. Under GDPR, CASL, and other privacy regulations, sending commercial email without valid consent can result in significant fines and damage to your sending reputation. Even where consent is not legally required (such as under CAN-SPAM's opt-out model), obtaining it is a best practice that improves engagement and reduces spam complaints.
Strong consent practices protect you legally, improve your deliverability, and build trust with your recipients. Lists built on genuine consent consistently outperform purchased or scraped lists.
***
## Single vs Double Opt-In
The two most common consent collection methods are single opt-in and double opt-in. Each has trade-offs.
### Single Opt-In
The recipient submits their email address through a form and is immediately added to your list. No confirmation step is required.
**Pros:** Lower friction, larger list growth, simpler to implement.
**Cons:** Higher risk of invalid addresses, typos, and bot signups. Weaker evidence of consent for GDPR compliance.
### Double Opt-In
After submitting the form, the recipient receives a confirmation email and must click a link to verify their address. Only confirmed addresses are added to the list.
**Pros:** Stronger consent evidence, cleaner lists, fewer spam complaints, better deliverability.
**Cons:** Some recipients never complete confirmation (expect 10–30% drop-off), slightly more complex to implement.
| Factor | Single Opt-In | Double Opt-In |
| ------------------------- | ------------------------------ | ------------------------------------- |
| **Consent strength** | Moderate | Strong |
| **List quality** | Lower (typos, bots) | Higher (verified addresses) |
| **GDPR compliance** | Acceptable but harder to prove | Recommended — clear audit trail |
| **CASL compliance** | Acceptable for express consent | Strongest evidence of express consent |
| **List growth rate** | Higher | Lower (10–30% drop-off) |
| **Deliverability impact** | Neutral to negative | Positive |
If you send to EU or Canadian recipients, double opt-in is strongly recommended. It provides the clearest evidence of consent and produces the highest-quality lists.
***
## Designing Compliant Consent Forms
A consent form must clearly communicate what the recipient is signing up for. Vague or bundled consent is not valid under GDPR or CASL.
### Required Elements
Tell recipients exactly what emails you will send — newsletters, product updates, promotional offers, etc. Do not use vague language like "we may contact you."
State how often you will send — weekly, monthly, or as applicable. Recipients should know what to expect.
Clearly identify your organization name so recipients know who will be emailing them.
If you send different types of email (e.g., product updates and partner offers), obtain separate consent for each. Bundling multiple purposes into a single checkbox is not valid under GDPR.
Inform recipients that they can withdraw consent at any time.
### Example: Compliant Signup Form
```html theme={null}
```
Never use pre-checked checkboxes. Under both GDPR and CASL, consent must be an affirmative action taken by the recipient. Pre-checked boxes do not count.
***
## Recording and Storing Consent
You must be able to demonstrate that valid consent was obtained if challenged by a regulator or a recipient. The burden of proof is on you as the sender.
### What to Record
For every consent record, store:
| Field | Description |
| ----------------- | ---------------------------------------------------------------------- |
| **Email address** | The address that was submitted |
| **Timestamp** | When consent was given (ISO 8601 format) |
| **Source** | Where consent was collected (URL, form name, event) |
| **Method** | How consent was collected (checkbox, double opt-in confirmation click) |
| **IP address** | The IP address of the person who submitted the form |
| **Consent text** | The exact wording presented at the time of consent |
| **Form version** | An identifier for the version of the form used |
```json theme={null}
{
"email": "recipient@example.com",
"consent_given_at": "2025-09-15T14:22:00Z",
"source": "https://yoursite.com/newsletter-signup",
"method": "double_opt_in",
"confirmed_at": "2025-09-15T14:25:12Z",
"ip_address": "198.51.100.42",
"consent_text": "Send me product updates and feature announcements (approximately twice a month)",
"form_version": "signup_v4"
}
```
Under GDPR, you must also record the specific purposes the recipient consented to. Generic "opted in to email" records are insufficient if you send multiple types of email.
***
## Managing Consent Over Time
Consent is not permanent. It must be managed as your relationship with the recipient evolves.
### Consent Decay
Even with valid consent, engagement declines over time. Recipients who signed up years ago and no longer open your emails are unlikely to still want them. Continuing to email disengaged recipients harms your deliverability and wastes resources.
Best practices for managing consent over time:
* **Re-engagement campaigns** — Send a targeted email to inactive recipients (e.g., no opens in 6+ months) asking if they still want to hear from you.
* **Sunset policies** — Automatically suppress recipients who have not engaged in a defined period (typically 6–12 months).
* **Periodic consent refresh** — For high-risk lists or long-inactive segments, ask recipients to reconfirm their subscription.
### When Consent Expires
Under CASL, implied consent has explicit expiry dates (2 years for business relationships, 6 months for inquiries). Under GDPR, consent does not technically expire, but regulators expect you to refresh consent periodically if there is no ongoing relationship.
Track the date of last engagement (open or click) alongside consent records. This helps you identify recipients whose consent may still be technically valid but whose interest has clearly lapsed.
***
## Consent for Third-Party Sharing
If you plan to share recipient data with third parties or send emails on behalf of partners, you need **separate, specific consent** for this purpose. Bundling third-party sharing into a general email consent is not valid under GDPR.
```html theme={null}
```
Never assume that consent to receive your emails also covers emails from your partners or affiliates. Each sender needs their own consent.
***
## Common Mistakes
A single checkbox that covers marketing emails, partner offers, and analytics consent is not valid under GDPR. Each distinct purpose must have its own consent mechanism. Recipients must be able to consent to one purpose without consenting to others.
"They signed up on our website" is not sufficient proof. You need timestamps, IP addresses, the exact text presented, and the form version. Without this evidence, you cannot demonstrate valid consent if challenged.
Under GDPR, consent must be freely given. You cannot make access to a service conditional on consenting to marketing emails (unless the emails are genuinely necessary for the service). A checkbox like "I agree to receive marketing emails" should not be required to complete a purchase.
When a recipient unsubscribes or withdraws consent, you must stop sending immediately. This includes all email types covered by that consent — not just the most recent campaign. Process withdrawals across all your systems, not just one mailing list.
Purchasing an email list does not transfer consent. The recipients consented to hear from the original collector, not from you. Sending to purchased lists without obtaining your own consent violates GDPR, CASL, and damages your deliverability.
***
## Related Topics
EU data protection requirements and consent standards for email.
Canadian consent requirements including express and implied consent.
Maintain healthy, engaged recipient lists.
Implement compliant unsubscribe mechanisms.
# GDPR and Email Sending
Source: https://docs.lettr.com/knowledge-base/compliance/gdpr-email
Understand how GDPR applies to email sending, the lawful bases and consent rules for marketing, and your duties handling EU recipient data.
## What Is GDPR
The **General Data Protection Regulation (GDPR)** is the European Union's comprehensive data protection law that took effect on May 25, 2018. It governs how organizations collect, store, process, and share personal data of individuals located in the EU and European Economic Area (EEA).
GDPR applies to **any organization** that processes personal data of EU/EEA residents, regardless of where the organization itself is located. If you send email to recipients in the EU, GDPR applies to you.
## How GDPR Applies to Email
Under GDPR, an email address is **personal data**. Sending an email to someone constitutes **processing** their personal data. This means every email you send through Lettr to an EU/EEA recipient falls within the scope of GDPR.
Specifically, the following activities are all considered data processing:
* Collecting email addresses
* Storing recipient lists
* Sending emails (marketing, transactional, or otherwise)
* Tracking opens, clicks, and other engagement events
* Retaining delivery logs and email history
You must have a **lawful basis** for each of these processing activities.
## Lawful Bases for Email
GDPR defines six lawful bases for processing personal data. Three are most relevant to email sending:
| Lawful Basis | When It Applies | Examples |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| **Consent** | Explicit opt-in for marketing email. Must be freely given, specific, informed, and unambiguous. | Newsletters, promotional campaigns, product announcements |
| **Legitimate Interest** | Some transactional or relationship emails where you can demonstrate a legitimate business reason. Must pass a balancing test against the individual's rights. | Account security alerts, product updates for active customers |
| **Contractual Necessity** | Emails required to fulfill a contract the recipient has entered into with you. | Order confirmations, shipping notifications, invoice delivery |
Consent is the **safest and most common** lawful basis for marketing email. If in doubt, obtain explicit consent.
## Consent Requirements
GDPR sets a high bar for what constitutes valid consent. All of the following must be met:
### Must Be Affirmative Action
The recipient must take a clear, positive action to opt in. Pre-checked boxes, silence, or inactivity do **not** count as consent.
### Must Be Specific
Consent must be obtained separately for different processing purposes. A single checkbox covering marketing emails, third-party data sharing, and analytics is not valid. Each purpose needs its own consent mechanism.
### Must Be Informed
At the point of collection, the recipient must clearly understand what they are consenting to — who will send the emails, what kind of content, and how often.
### Must Be Revocable
Recipients must be able to withdraw consent at any time, and it must be **as easy to withdraw as it was to give**. An unsubscribe link in every email is the minimum requirement.
### Must Be Documented
You must keep records of **when** and **how** consent was obtained. This includes timestamps, the version of the form used, and what information was presented at the time.
Store consent records with a timestamp, the source (e.g., signup form URL), the IP address, and the exact text the recipient agreed to. This evidence is critical if you ever need to demonstrate compliance.
## Data Subject Rights Relevant to Email
GDPR grants individuals a set of rights over their personal data. The following are most relevant to email operations:
| Right | What It Means | Your Obligation |
| ----------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Right to Access** | Individuals can request a copy of all personal data you hold about them. | Provide email addresses, sending history, engagement data, and any metadata you have stored. |
| **Right to Erasure** | Also known as the "right to be forgotten." Individuals can request deletion of their data. | Delete their data from your lists, CRM, and any other systems. Ensure they are added to a suppression list so you do not re-add them. |
| **Right to Object** | Individuals can object to processing for direct marketing at any time, with no exceptions. | Stop all marketing emails immediately upon request. |
| **Right to Data Portability** | Individuals can request their data in a structured, machine-readable format. | Provide their data in a common format such as CSV or JSON. |
The right to object to direct marketing is **absolute** under GDPR. There is no balancing test — you must stop immediately when someone objects.
## Practical Implementation
### Double Opt-In for EU Recipients
Double opt-in (confirmation email after signup) is the strongest evidence of consent. The recipient provides their email, receives a confirmation message, and clicks a link to verify. This creates a clear audit trail.
### Clear Privacy Notice at Point of Collection
Every signup form must include or link to a privacy notice that explains how you will use the email address, who the data controller is, and how the recipient can exercise their rights.
### Easy Unsubscribe Mechanism
Include a visible unsubscribe link in every marketing email. Process unsubscribe requests promptly. Lettr supports list-unsubscribe headers which enable one-click unsubscribe in supported email clients.
### Data Retention Policy
Do not keep email data indefinitely. Define how long you retain recipient data, delivery logs, and engagement events, and delete data that is no longer needed.
### Honor Erasure Requests
When a recipient requests erasure:
1. Remove them from all mailing lists
2. Delete their personal data from your systems
3. Add them to a suppression list to prevent future sends
4. Confirm the deletion to the requester
Suppression lists are permitted under GDPR even after an erasure request. You need to retain the minimum data necessary (the email address) to ensure you do not contact the person again.
## Data Processing with Lettr
When you send email through Lettr, Lettr acts as a **data processor** on your behalf. You remain the **data controller** and are responsible for ensuring lawful processing.
Lettr processes the following personal data for you:
* Recipient email addresses
* Email content (which may contain personal data)
* Delivery and engagement events (opens, clicks, bounces)
* Any custom data you pass via the `metadata` parameter
**Do not store sensitive personal data** in `substitution_data` or `metadata` fields. Avoid including information such as health data, financial account numbers, government IDs, or other special category data. Use opaque identifiers (such as internal user IDs) in metadata instead of directly including PII.
Instead of passing `"customer_name": "John Smith"` in metadata, use `"customer_id": "usr_48291"` and resolve the name in your own systems. This minimizes the personal data flowing through your email infrastructure.
## GDPR vs CAN-SPAM Key Differences
| Aspect | GDPR (EU) | CAN-SPAM (US) |
| ----------------------- | --------------------------------------------------------------------- | ------------------------------------------------- |
| **Consent Model** | Opt-in required before sending marketing email | Opt-out — you can send until someone unsubscribes |
| **Geographic Scope** | Applies to any organization processing EU resident data | Applies to commercial email sent to US recipients |
| **Penalties** | Up to €20 million or 4% of global annual revenue, whichever is higher | Up to \$51,744 per individual email violation |
| **Transactional Email** | Requires a lawful basis (usually contractual necessity) | Largely exempt from CAN-SPAM requirements |
| **Enforcement** | National Data Protection Authorities in each EU member state | Federal Trade Commission (FTC) |
## Common Mistakes
GDPR applies based on where the **recipient** is located, not where your organization is based. A US company sending email to EU residents must comply with GDPR.
Pre-checked boxes are explicitly prohibited under GDPR. Consent must be an affirmative action taken by the individual. Forms with pre-checked "Subscribe to our newsletter" boxes are non-compliant.
If you cannot demonstrate when and how consent was obtained, you effectively have no valid consent. Maintain detailed records including timestamps, form versions, and the text presented to the user.
Failing to respond to a data erasure request within the required timeframe (one month) is a GDPR violation. Establish a clear internal process for handling these requests promptly.
If you use any third-party service to send email (including Lettr), GDPR requires a Data Processing Agreement (DPA) between you (the controller) and the service (the processor). Ensure this is in place before processing EU recipient data.
## Related Topics
US email compliance requirements and how they compare to GDPR.
Implementing effective and compliant unsubscribe mechanisms.
How to handle personal data in email metadata and substitution variables.
Maintaining clean, compliant recipient lists.
# Google & Yahoo Sender Requirements
Source: https://docs.lettr.com/knowledge-base/compliance/google-yahoo-requirements
Meet the Google and Yahoo bulk sender rules enforced since 2024: SPF, DKIM, and DMARC, one-click unsubscribe, and low spam complaint rates.
In February 2024, Google and Yahoo began enforcing stricter requirements for bulk email senders. If you send 5,000 or more messages per day to Gmail or Yahoo addresses, you must comply with these rules or face delivery failures, spam filtering, and eventual blocking.
These requirements apply to all senders — not just marketers. Transactional email senders with high volume are equally affected.
***
## Who Is Affected
The bulk sender threshold is **5,000 messages per day** to Gmail or Yahoo recipients. This is measured per sending domain, not per account or IP address.
Even if you don't currently send at that volume, following these requirements is good practice. Google and Yahoo have stated they may lower the threshold over time, and the requirements align with industry best practices that benefit all senders.
Some requirements (like email authentication) apply to **all senders**, not just those above the 5,000/day threshold. Only the one-click unsubscribe requirement is specific to bulk senders.
***
## The Three Pillars
SPF, DKIM, and DMARC must all pass for your sending domain. This is no longer optional — it is a hard requirement.
Marketing and promotional emails must support one-click unsubscribe via the `List-Unsubscribe` header. Unsubscribe requests must be processed within 2 days.
Your spam complaint rate must stay below 0.3%. The target is below 0.1%. Consistently exceeding 0.3% will result in blocking.
***
## Authentication Requirements
All three authentication protocols must pass for your sending domain:
| Protocol | Requirement | Lettr Implementation |
| -------- | -------------------------------------- | --------------------------------------------------- |
| SPF | Must pass for your sending domain | Lettr handles SPF via the CNAME verification record |
| DKIM | Must pass with proper domain alignment | Lettr signs all emails with your domain's DKIM key |
| DMARC | Must have at least a `p=none` policy | You must add a DMARC TXT record to your DNS |
All three are required — passing just one or two is not sufficient. DMARC alignment means the domain in the `From` header must match (or be a subdomain of) the SPF or DKIM domain.
### Verifying Your Authentication
Check your DKIM record:
```bash theme={null}
dig TXT selector._domainkey.yourdomain.com +short
```
Check your DMARC record:
```bash theme={null}
dig TXT _dmarc.yourdomain.com +short
```
You should see output similar to:
```
"v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com"
```
If either command returns no results, the record is missing and needs to be added.
***
## Unsubscribe Requirements
For bulk senders, Google and Yahoo require:
| Requirement | Details |
| ------------------------------ | --------------------------------------------------------------------- |
| `List-Unsubscribe` header | Must include an HTTPS URL for unsubscribing |
| `List-Unsubscribe-Post` header | Must support one-click unsubscribe per RFC 8058 |
| Visible body link | An unsubscribe link must be visible in the email body |
| Processing time | Unsubscribes must be honored within **2 days** (not 10 like CAN-SPAM) |
### Implementation in Lettr
Add the `data-msys-unsubscribe="1"` attribute to your unsubscribe link to enable unsubscribe event tracking and proper header generation:
```html theme={null}
Unsubscribe
```
Click tracking must be enabled for the `data-msys-unsubscribe` attribute to generate unsubscribe events. Lettr will automatically add the appropriate `List-Unsubscribe` and `List-Unsubscribe-Post` headers when this attribute is present.
### Transactional Email Exception
One-click unsubscribe is only required for marketing and promotional emails. Purely transactional emails (order confirmations, password resets, account alerts) are exempt. However, if your transactional email contains promotional content, it may be classified as commercial and the requirement applies.
***
## Spam Rate Requirements
Google measures your spam complaint rate through Gmail's feedback mechanisms. You can monitor this through Google Postmaster Tools.
| Metric | Target | Hard Limit |
| ------------------- | ---------- | -------------------- |
| Spam complaint rate | Below 0.1% | Must stay under 0.3% |
### Monitoring with Google Postmaster Tools
1. Go to [Google Postmaster Tools](https://postmaster.google.com/)
2. Add and verify your sending domain
3. Monitor the **Spam Rate** dashboard regularly
4. Set up alerts if your rate approaches 0.1%
### Reducing Spam Complaints
* **Make unsubscribe easy** — A visible, one-click unsubscribe is the most effective way to reduce complaints. Recipients who can't find the unsubscribe link will use the spam button instead.
* **Send relevant content** — Segment your audience and send content they expect to receive.
* **Honor frequency expectations** — Don't email more often than subscribers signed up for.
* **Clean your lists** — Remove unengaged subscribers who haven't opened or clicked in 6+ months. See [List Hygiene](/knowledge-base/best-practices/list-hygiene).
* **Use double opt-in** — Confirm subscriptions to ensure recipients genuinely want your emails.
***
## Additional Requirements
Google and Yahoo also require:
| Requirement | Details | Lettr Handling |
| ----------------------------- | -------------------------------------------- | --------------------------------------- |
| Valid forward and reverse DNS | Sending IPs must have proper PTR records | Lettr manages this automatically |
| TLS encryption | Emails must be transmitted over TLS | Lettr uses TLS for all SMTP connections |
| RFC 5322 compliance | Messages must follow email format standards | Lettr constructs compliant messages |
| No Gmail impersonation | Don't use `@gmail.com` in your `From` header | Use your own verified domain |
Most of these infrastructure requirements are handled by Lettr automatically. Your primary responsibilities are domain authentication (DKIM + DMARC), unsubscribe implementation, and maintaining a low spam complaint rate.
***
## Compliance Checklist for Lettr Users
Add your sending domain and configure the CNAME and DKIM DNS records. Confirm both show as **valid** in the dashboard.
Add a TXT record for `_dmarc.yourdomain.com` with at least `v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com`. See [DMARC](/learn/domains/dmarc) for details.
Configure a custom tracking domain (e.g., `track.yourdomain.com`) to improve link reputation. See [Tracking Domains](/learn/domains/tracking-domains).
Add `data-msys-unsubscribe="1"` to the unsubscribe link in your email templates. Ensure the link is visible and functional.
Add your domain at [postmaster.google.com](https://postmaster.google.com/) and verify ownership to start monitoring spam rates and reputation.
Check Postmaster Tools regularly. If your rate approaches 0.1%, take immediate action to reduce complaints.
***
## What Happens If You Don't Comply
Gmail and Yahoo will outright reject emails from senders who fail authentication checks. You'll see `550 5.7.26` or similar errors indicating DMARC or DKIM failure. These rejections appear as hard bounces in Lettr.
Even if emails are accepted, they may be automatically placed in the spam folder if your spam complaint rate is too high or your authentication is incomplete.
Gmail may temporarily throttle your sending if you're borderline on compliance. You'll see increased `email.deferred` events as Gmail slows acceptance of your messages.
Persistent non-compliance — especially a consistently high spam complaint rate above 0.3% — can result in your domain being permanently blocked by Gmail or Yahoo. Recovery requires fixing the root cause, reducing volume, and gradually rebuilding reputation.
***
## Related Topics
Implement effective unsubscribe mechanisms
Understand email authentication protocols
Configure DMARC for your domain
Troubleshoot spam folder placement
# Unsubscribe Best Practices
Source: https://docs.lettr.com/knowledge-base/compliance/unsubscribe-best-practices
Implement one-click unsubscribe and List-Unsubscribe headers in Lettr to stay compliant with CAN-SPAM and GDPR and protect deliverability.
## Why Unsubscribe Matters
Providing a clear and functional unsubscribe mechanism is not optional — it is a legal requirement under CAN-SPAM, GDPR, and CASL. Beyond compliance, making it easy for recipients to unsubscribe directly benefits your sending reputation.
When recipients cannot find an unsubscribe link, they resort to marking your email as spam. Spam complaints are one of the strongest negative signals mailbox providers use when deciding whether to deliver your email to the inbox or the junk folder.
Since February 2024, Google and Yahoo require **one-click unsubscribe** support for bulk senders sending 5,000 or more emails per day. Failing to comply can result in your messages being blocked or sent to spam.
***
## One-Click Unsubscribe (RFC 8058)
One-click unsubscribe is defined by [RFC 8058](https://datatracker.ietf.org/doc/html/rfc8058). It uses the `List-Unsubscribe` and `List-Unsubscribe-Post` headers to allow email clients to display a native unsubscribe button directly in their interface — no need for the recipient to open a webpage.
### Why It Matters
Google and Yahoo enforce one-click unsubscribe for bulk senders. Messages that lack the required headers may be throttled, sent to spam, or rejected outright.
### Supported Email Clients
| Email Client | One-Click Unsubscribe Support |
| ----------------- | ----------------------------- |
| Gmail | Yes |
| Yahoo Mail | Yes |
| Apple Mail | Yes |
| Microsoft Outlook | Yes |
Lettr automatically includes the `List-Unsubscribe` and `List-Unsubscribe-Post` headers on messages sent through marketing streams when an unsubscribe link is present in the body.
***
## Implementing Unsubscribe in Lettr
Lettr has two unsubscribe mechanisms depending on how you're sending:
* **Marketing campaigns** built in the Lettr UI use the `{{unsubscribe_link}}` merge tag, which Lettr replaces with a unique per-recipient signed URL. The link is mandatory, and Lettr appends a default footer automatically if it's missing. See [Content & Design](/learn/campaigns/content-and-design#the-unsubscribe-link).
* **Transactional sends via the API** use a link you host on your own domain, marked with the `data-msys-unsubscribe="1"` attribute described below.
The rest of this article focuses on the API-level mechanism.
### In-Body Unsubscribe Link with Tracking
To track unsubscribe events in Lettr, add the `data-msys-unsubscribe="1"` attribute to your unsubscribe link. This tells Lettr to fire an unsubscribe event when the recipient clicks the link.
```html theme={null}
Unsubscribe from these emails
```
Click tracking must be **enabled** on the sending domain for the unsubscribe event to fire. If click tracking is disabled, Lettr cannot detect the click and no unsubscribe webhook event will be generated.
### Handling Unsubscribe Webhook Events
When a recipient clicks an unsubscribe link tagged with `data-msys-unsubscribe="1"`, Lettr sends a webhook event to your configured endpoint. Use this event to update your suppression list or database.
```json theme={null}
{
"event": "unsubscribe",
"recipient": "recipient@example.com",
"timestamp": "2025-03-15T14:22:00Z",
"message_id": "abc123",
"tag": "welcome_series"
}
```
You should process unsubscribe webhook events by immediately removing the recipient from future mailings. Do not delay this action.
***
## Unsubscribe Link Placement and Design
A compliant and user-friendly unsubscribe link follows these principles:
* **Visible** — Do not hide the link in tiny, low-contrast text.
* **In the footer** — Place the link in a consistent location recipients expect.
* **No login required** — The recipient must be able to unsubscribe without signing in.
* **Immediate processing** — CAN-SPAM allows up to 10 business days, but best practice is to process unsubscribes immediately.
### Example: Well-Designed Email Footer
```html theme={null}
You are receiving this email because you signed up at example.com.
```
***
## Preference Center vs Full Unsubscribe
A **preference center** lets recipients choose which categories of email they want to receive — for example, product updates but not promotional offers. This reduces unsubscribes by giving recipients control.
A **full unsubscribe** removes the recipient from all marketing communications.
Always offer a full unsubscribe option even if you provide a preference center. Regulations require that recipients can opt out of **all** commercial email, not just individual categories.
A common pattern is to link to a preference center first, with a full unsubscribe option clearly available on that page:
```html theme={null}
```
***
## What NOT to Do
Forcing recipients to log in creates friction and violates the spirit of CAN-SPAM. Many recipients will mark your email as spam instead of logging in. The unsubscribe process must work with a single click or a simple confirmation page.
Do not ask recipients to fill out surveys, confirm via email, or navigate multiple pages before they are unsubscribed. One click should be sufficient.
Using tiny fonts, low-contrast colors, or burying the link in dense text violates CAN-SPAM requirements and frustrates recipients. The link must be clearly visible.
Continuing to send email to recipients who have unsubscribed is a direct violation of CAN-SPAM and GDPR. Process every unsubscribe request promptly.
Never add unsubscribed recipients back to your mailing list without their explicit, affirmative consent. This includes importing old lists that contain previously unsubscribed addresses.
While offering frequency options is fine, you must always provide a way to fully unsubscribe. Offering only a "receive fewer emails" option without a complete opt-out does not satisfy legal requirements.
***
## Transactional Email Exception
Transactional emails — such as password resets, order confirmations, and account notifications — are generally exempt from unsubscribe requirements under CAN-SPAM because they are not commercial in nature.
However, if a transactional email contains promotional content (such as product recommendations or upsells), it may be reclassified as a commercial message and become subject to all CAN-SPAM requirements, including unsubscribe.
When in doubt, include an unsubscribe link. It does no harm in a transactional email, and it protects you if regulators determine the message has commercial intent.
***
## Compliance Summary
| Requirement | CAN-SPAM | GDPR | Google / Yahoo (Bulk Senders) |
| ------------------------------ | ---------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------- |
| Unsubscribe mechanism required | Yes — every commercial email | Yes — right to withdraw consent at any time | Yes — one-click unsubscribe via List-Unsubscribe header |
| Maximum processing time | 10 business days | Without undue delay (interpreted as immediately) | Unsubscribe must be processed within 2 days |
| One-click unsubscribe | Not explicitly required, but recommended | Not explicitly required | Required since February 2024 |
| List-Unsubscribe header | Not required | Not required | Required for bulk senders (5,000+ emails/day) |
| Preference center acceptable | Yes, if full opt-out is also available | Yes, if full withdrawal of consent is available | Yes, but one-click full unsubscribe must also be supported |
| Re-subscribing after opt-out | Only with new, affirmative consent | Only with new, freely given consent | Must honor unsubscribes; re-adding triggers spam filtering |
***
## Related Topics
Understand the full requirements of the CAN-SPAM Act for commercial email.
Meet the sender requirements enforced by major mailbox providers.
Improve inbox placement with proven deliverability strategies.
Configure click and open tracking for your sending domains.
# Dedicated vs Shared IPs
Source: https://docs.lettr.com/knowledge-base/concepts/dedicated-vs-shared-ips
Understand the differences between dedicated and shared IP addresses for email sending, when each is appropriate, and how IP warm-up works
When you send email through an ESP like Lettr, your messages are transmitted from an IP address that mailbox providers use to evaluate your sender reputation. That IP address is either **shared** with other senders on the platform or **dedicated** exclusively to your account.
This choice affects your deliverability, your control over reputation, and how much operational effort is required on your part. Neither option is universally better — the right choice depends on your sending volume, patterns, and tolerance for management overhead.
***
## How IP Reputation Works
Every IP address that sends email has a reputation score maintained by mailbox providers. This reputation is built over time based on the sending behavior observed from that IP:
* **Bounce rates** — How often emails from this IP are sent to invalid addresses
* **Complaint rates** — How often recipients mark emails from this IP as spam
* **Volume consistency** — Whether sending patterns are predictable or erratic
* **Spam trap hits** — Whether emails from this IP are sent to known spam trap addresses
* **Engagement signals** — Whether recipients open, click, and interact with emails from this IP
Mailbox providers use this reputation as a major factor in filtering decisions. A high-reputation IP gets its messages delivered to the inbox. A low-reputation IP gets its messages sent to spam or rejected outright.
***
## Shared IPs
With shared IPs, your emails are sent from IP addresses that are also used by other senders on the same ESP. Your reputation is pooled with theirs.
### How Shared IPs Work
The ESP manages a pool of IP addresses and distributes sending across them. Multiple customers send email from the same IPs. The reputation of those IPs reflects the aggregate behavior of all senders using them.
### Advantages
| Advantage | Detail |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **No warm-up required** | Shared IPs already have established reputation from ongoing use by multiple senders. You can start sending immediately. |
| **Lower cost** | Shared IPs are included in standard pricing. No additional fees. |
| **No maintenance** | The ESP manages the IP pool, monitors reputation, and removes bad actors. You do not need to manage IP health. |
| **Works at any volume** | Suitable for senders of all sizes, from a few hundred to tens of thousands of emails per month. |
### Disadvantages
| Disadvantage | Detail |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Shared reputation risk** | If another sender on the same IP engages in poor practices (sending to spam traps, high complaint rates), their behavior can affect your deliverability. |
| **Less control** | You cannot control the behavior of other senders sharing your IPs. You depend on the ESP to enforce quality standards. |
| **Reputation not portable** | The reputation belongs to the IP, not to you. If you switch ESPs, you start over on different IPs. |
Reputable ESPs mitigate shared IP risk by enforcing strict sending policies, monitoring for abuse, and quickly removing bad actors from shared pools. The shared IP risk is real but manageable with a well-run ESP.
***
## Dedicated IPs
With a dedicated IP, your emails are sent from an IP address used exclusively by your account. Your reputation is entirely your own — built by your sending behavior alone.
### How Dedicated IPs Work
The ESP assigns one or more IP addresses to your account. All email from your account is sent from those IPs and no one else's email uses them. Your reputation on those IPs is determined solely by your sending practices.
### Advantages
| Advantage | Detail |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **Full reputation control** | Your deliverability depends only on your own behavior. No other sender can damage your reputation. |
| **Reputation isolation** | Poor practices by other senders on the ESP do not affect you. |
| **Predictable deliverability** | Your inbox placement is a direct result of your sending quality, making troubleshooting straightforward. |
| **Reputation portability (domain-level)** | While IP reputation does not transfer between ESPs, domain reputation — which is increasingly important — does travel with you. |
### Disadvantages
| Disadvantage | Detail |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Requires warm-up** | A new dedicated IP has no reputation. You must gradually build it by slowly increasing volume over several weeks. Skipping warm-up will result in spam filtering and rejections. |
| **Requires sufficient volume** | Dedicated IPs need consistent daily volume to maintain reputation. If you send too infrequently, mailbox providers may treat the IP as inactive or suspicious. |
| **Higher cost** | Dedicated IPs are typically an add-on with additional fees. |
| **Your responsibility** | If your sending practices cause reputation damage, there is no shared pool to dilute the impact. The damage is concentrated on your IP. |
A dedicated IP is not inherently better for deliverability. If your sending volume is low or inconsistent, a dedicated IP will perform worse than a well-managed shared pool because it cannot maintain the steady sending patterns that mailbox providers expect.
***
## When to Use Each Option
### Use Shared IPs When
* You send fewer than **50,000 emails per month**
* Your sending volume fluctuates significantly (seasonal business, event-driven spikes)
* You are starting out and do not have the volume to sustain a dedicated IP
* You want to start sending immediately without a warm-up period
* You are a small to mid-size sender who wants the ESP to manage IP reputation
### Use Dedicated IPs When
* You consistently send more than **100,000 emails per month**
* You need full control over your sender reputation
* You operate in a regulated industry where reputation isolation is required
* You have the resources to manage IP warm-up and monitor reputation metrics
* Your deliverability requirements are strict (financial services, healthcare notifications)
### The Gray Zone: 50,000–100,000 Emails Per Month
Senders in this range can go either way. Consider a dedicated IP if:
* Your content or audience puts you at higher risk for complaints (e-commerce promotions, user-generated content notifications)
* You have experienced deliverability issues on shared IPs that you suspect are caused by other senders
* You want the ability to directly correlate your sending practices with your deliverability outcomes
Otherwise, a well-managed shared IP pool is likely sufficient and simpler to maintain.
***
## IP Warm-Up
If you move to a dedicated IP, you must warm it up before sending at full volume. A new IP has no reputation — mailbox providers do not know whether to trust it. Sending thousands of emails from an unknown IP will trigger spam filtering.
### Warm-Up Schedule
A typical warm-up schedule gradually increases daily volume over 4–6 weeks:
| Week | Daily Volume | Strategy |
| ---- | ------------- | ----------------------------------------------------------------------- |
| 1 | 50–200 | Send only to your most engaged recipients (recent openers and clickers) |
| 2 | 200–1,000 | Continue with engaged recipients, expand to recently active users |
| 3 | 1,000–5,000 | Broaden audience, monitor metrics closely |
| 4 | 5,000–20,000 | Continue expanding if metrics remain healthy |
| 5 | 20,000–50,000 | Approach target volume |
| 6+ | Full volume | Maintain consistent daily sending |
### Warm-Up Rules
During warm-up, send to recipients who have recently opened or clicked your emails. Their positive engagement sends strong trust signals to mailbox providers. Save less-engaged segments for later in the warm-up process.
Consistency matters during warm-up. Send every single day, even weekends. Gaps in sending can reset the reputation-building process or make the IP look inactive. If you do not have enough daily volume to fill the schedule naturally, consider supplementing with engaged segments from your list.
Watch your bounce rate (should stay below 2%) and complaint rate (should stay below 0.1%) at every volume step. If either metric spikes, pause volume increases and investigate before continuing. Pushing through bad metrics will damage the IP's reputation.
It is tempting to accelerate warm-up to reach full volume faster. Resist this. Mailbox providers need time to observe consistent, positive behavior. Jumping from 500 to 50,000 emails per day will trigger throttling and filtering that can take weeks to recover from.
Gmail, Outlook, and Yahoo each maintain independent reputation data. Your IP may warm up faster with one provider than another. If you see filtering from a specific provider, reduce volume to that provider's domains while continuing normal volume to others.
***
## Domain Reputation vs IP Reputation
IP reputation was historically the dominant factor in filtering decisions, but the industry has shifted significantly toward **domain reputation**. Major mailbox providers — especially Gmail — now weight domain reputation more heavily than IP reputation.
| Factor | IP Reputation | Domain Reputation |
| ----------------- | ------------------------------------------------------- | ------------------------------------ |
| **Tied to** | The sending IP address | Your sending domain (From address) |
| **Portable** | No — changes when you switch IPs or ESPs | Yes — follows your domain everywhere |
| **Influenced by** | All senders on that IP (shared) or only you (dedicated) | Only you, regardless of IP |
| **Trend** | Decreasing in weight | Increasing in weight |
Regardless of whether you use shared or dedicated IPs, invest in your domain reputation. Authenticate properly (SPF, DKIM, DMARC), maintain list hygiene, and monitor engagement metrics. Domain reputation travels with you across IPs and ESPs.
***
## Multiple Dedicated IPs
High-volume senders sometimes use multiple dedicated IPs to separate different email streams:
| IP | Purpose | Rationale |
| ---- | ----------------------- | ------------------------------------------------------------------------------ |
| IP 1 | Transactional email | Isolates critical emails (password resets, receipts) from marketing reputation |
| IP 2 | Marketing email | Marketing complaints and lower engagement do not affect transactional delivery |
| IP 3 | Re-engagement campaigns | Higher-risk sends to lapsed subscribers are isolated from both streams |
This approach provides maximum reputation isolation but adds operational complexity. Each IP needs its own warm-up, monitoring, and volume management. Only pursue this if your volume and deliverability requirements justify the overhead.
***
## Related Topics
How IP and domain reputation fit into the broader deliverability picture.
Build and protect your sender reputation across IPs and domains.
Practical strategies for maximizing inbox placement including warm-up guidance.
Domain strategy for isolating email streams and protecting reputation.
# What Is Email Deliverability?
Source: https://docs.lettr.com/knowledge-base/concepts/email-deliverability
Understand what email deliverability means, how it differs from delivery, and the factors that determine whether your emails reach the inbox
Email deliverability is the measure of how successfully your emails reach recipients' inboxes — not just whether they were accepted by a mail server, but whether they actually appeared in the inbox rather than the spam folder, promotions tab, or quarantine.
Deliverability is the single most important metric for any email program. An email that lands in spam is functionally the same as an email that was never sent.
***
## Delivery vs Deliverability
These two terms are frequently confused, but they describe fundamentally different outcomes.
| Term | What It Measures | Example |
| ------------------ | -------------------------------------------------------------------------- | -------------------------------------------------------------- |
| **Delivery** | Whether the receiving mail server accepted the message (it did not bounce) | Server returns a `250 OK` response — the message was delivered |
| **Deliverability** | Whether the message reached the recipient's **inbox** specifically | The message appears in the inbox, not the spam folder |
A 100% delivery rate does not mean a 100% inbox rate. You can have perfect delivery — every message accepted by the server — while half your emails sit in spam folders where no one reads them.
Think of it like postal mail. Delivery means the post office accepted the letter. Deliverability means it arrived in the recipient's mailbox rather than being redirected to a junk pile in the basement.
***
## Why Deliverability Matters
Poor deliverability has direct business consequences:
* **Password resets and 2FA codes don't arrive** — Users can't log in, contact support, and lose trust in your product.
* **Order confirmations go missing** — Customers assume their purchase failed and either repurchase or abandon your store.
* **Onboarding emails land in spam** — New users never activate, and your conversion funnel breaks at the first step.
* **Marketing campaigns underperform** — Open rates collapse, click rates vanish, and revenue from email drops.
Deliverability is not an email operations problem. It is a product reliability and revenue problem.
***
## The Five Factors That Determine Deliverability
Inbox placement is the result of five interconnected factors. Weakness in any one of them can send your emails to spam.
### 1. Authentication
Email authentication proves to receiving servers that you are who you claim to be and that your message has not been tampered with. Three protocols work together:
* **SPF** — Declares which IP addresses are authorized to send email for your domain.
* **DKIM** — Adds a cryptographic signature to each email, proving it was not modified in transit.
* **DMARC** — Ties SPF and DKIM together and tells receivers what to do when authentication fails.
Without proper authentication, mailbox providers have no reason to trust your messages. Since February 2024, Google and Yahoo require SPF, DKIM, and DMARC for all bulk senders.
Lettr configures DKIM signing automatically when you verify your domain. You need to add the DNS records Lettr provides — see [Sending Domains](/learn/domains/sending-domains) for the setup guide.
### 2. Sender Reputation
Mailbox providers assign a reputation score to your sending domain and IP address based on your historical sending behavior. This reputation acts as a trust signal that influences every filtering decision.
Reputation is built over time through:
* **Low bounce rates** — Sending to valid, active addresses
* **Low complaint rates** — Recipients not marking your emails as spam
* **Consistent volume** — Predictable sending patterns rather than sudden spikes
* **Positive engagement** — Recipients opening, reading, and clicking your emails
Reputation damage is easier to cause than to repair. A single bad campaign can take weeks to recover from.
### 3. List Quality
The health of your recipient list directly affects deliverability. Sending to invalid addresses, spam traps, or unengaged recipients generates the negative signals that destroy reputation.
Key list quality practices:
* **Remove hard bounces immediately** — Never retry a permanently invalid address
* **Use double opt-in** — Confirm that addresses are valid and that the owner wants your emails
* **Prune unengaged recipients** — Remove subscribers who haven't opened in 6–12 months
* **Never purchase email lists** — Purchased lists contain spam traps and uninterested recipients
### 4. Content Quality
The content of your email — subject line, body, HTML structure, links, and attachments — is analyzed by spam filters at the receiving server.
Content factors that affect deliverability:
| Helps Deliverability | Hurts Deliverability |
| ------------------------------- | ------------------------------------- |
| Clear, relevant subject lines | ALL CAPS, excessive punctuation |
| Balanced text-to-image ratio | Image-only emails with no text |
| Links to your own domain | URL shorteners or suspicious domains |
| Visible unsubscribe link | Hidden or missing unsubscribe option |
| Plain text alternative included | HTML-only with no plain text fallback |
### 5. Recipient Engagement
Modern mailbox providers — Gmail in particular — heavily weigh recipient engagement when making filtering decisions. If recipients consistently open, read, and interact with your emails, providers learn to trust your messages. If recipients ignore or delete them, providers learn to deprioritize them.
Engagement signals include:
* **Opens and reads** — Time spent viewing the message
* **Clicks** — Interacting with links in the email
* **Replies** — Responding to the sender
* **Moving to inbox** — Rescuing a message from spam
* **Marking as spam** — The strongest negative signal
Engagement is measured per sender, per recipient. A recipient who ignores your emails will increasingly see them filtered, even if other recipients engage well. This is why list hygiene matters — keeping unengaged recipients on your list drags down your aggregate metrics.
***
## How Mailbox Providers Make Filtering Decisions
Each mailbox provider (Gmail, Outlook, Yahoo, Apple Mail) uses its own proprietary filtering system. While the exact algorithms are not public, they all evaluate the same general categories:
Does the message pass SPF, DKIM, and DMARC? If authentication fails, the message is likely rejected or sent to spam immediately.
What is the sender's domain and IP reputation? Providers maintain internal reputation databases built from billions of messages. A poor reputation triggers stricter filtering.
Does the message content match known spam patterns? Filters scan for suspicious URLs, phishing indicators, spam trigger phrases, and structural anomalies.
How has this recipient interacted with this sender's previous emails? Positive engagement history biases toward inbox placement. Negative history biases toward spam.
Based on the combined signals, the provider places the message in the inbox, spam folder, promotions tab, or quarantine. This decision is per-recipient — the same message can land in the inbox for one recipient and spam for another.
***
## Measuring Deliverability
Deliverability is harder to measure than delivery because mailbox providers do not report inbox placement directly. You need to infer it from available signals.
| Metric | What It Tells You | Where to Find It |
| ----------------------- | -------------------------------------------------- | ---------------------------------- |
| **Delivery rate** | Percentage of emails accepted (not bounced) | Lettr dashboard |
| **Bounce rate** | Percentage of emails rejected | Lettr dashboard and webhooks |
| **Open rate** | Approximate inbox placement indicator | Lettr dashboard (with caveats) |
| **Spam complaint rate** | Percentage of recipients marking you as spam | Lettr dashboard via feedback loops |
| **Click rate** | Engagement level — higher is better for reputation | Lettr dashboard |
Open rates are increasingly unreliable due to Apple Mail Privacy Protection (which pre-fetches tracking pixels) and corporate email proxies. Use open rates as a directional indicator, not an exact measurement. Click rates are a more reliable engagement signal.
### Healthy Benchmarks
| Metric | Healthy | Warning | Critical |
| ------------------------- | ------- | ------- | -------- |
| Delivery rate | > 98% | \< 95% | \< 90% |
| Bounce rate | \< 2% | > 5% | > 10% |
| Spam complaint rate | \< 0.1% | > 0.3% | > 0.5% |
| Open rate (transactional) | > 50% | \< 30% | \< 15% |
| Open rate (marketing) | > 15% | \< 10% | \< 5% |
***
## Improving Deliverability
If your emails are not reaching the inbox, work through these areas in order:
1. **Verify authentication** — Confirm SPF, DKIM, and DMARC are all passing. Use Lettr's domain verification to check.
2. **Check your reputation** — Review bounce and complaint rates. If either is elevated, address the root cause before sending more.
3. **Clean your list** — Remove hard bounces, spam complainers, and long-term unengaged recipients.
4. **Review your content** — Check for spam trigger patterns, ensure you have a plain text version, and verify all links point to reputable domains.
5. **Warm up gradually** — If you are on a new domain or IP, increase volume slowly over several weeks.
Fix authentication and list quality first. Content optimization only matters if your emails are reaching the server and passing reputation checks.
***
## Common Deliverability Mistakes
A 99% delivery rate means almost nothing if 40% of those delivered emails land in spam. Delivery rate tells you that servers accepted your messages. It does not tell you where those messages ended up. Monitor open rates, click rates, and complaint rates alongside delivery rate.
Purchased lists contain spam traps — addresses specifically designed to catch senders with poor list practices. Hitting a spam trap can instantly blacklist your sending domain or IP. Only send to recipients who have explicitly opted in to receive your emails.
Every spam complaint damages your reputation. Make unsubscribing easy and immediate. Process complaints via webhook and suppress those addresses permanently. Fighting to retain uninterested subscribers hurts your deliverability far more than losing them.
Mailbox providers watch for sudden spikes in sending volume. If you normally send 1,000 emails per day and suddenly send 50,000, spam filters will intervene. Maintain consistent sending patterns and ramp up gradually when increasing volume.
Marketing email naturally has lower engagement and higher complaint rates than transactional email. If both share the same sending domain, marketing reputation problems will affect your transactional delivery — meaning password resets and order confirmations may land in spam.
***
## Related Topics
Actionable strategies for maximizing inbox placement rates.
How to build and protect your sender reputation.
Deep dive into email authentication protocols.
Step-by-step diagnosis when emails go to spam.
# What Is an Email Service Provider (ESP)?
Source: https://docs.lettr.com/knowledge-base/concepts/email-service-provider
What an email service provider does, how it differs from an ISP, and why sending through a dedicated provider like Lettr beats sending from your own server
An email service provider (ESP) is a platform that sends email on your behalf. Instead of running your own mail server and managing the infrastructure required for reliable email delivery, you send emails through an ESP's API or SMTP relay, and the ESP handles the rest — message delivery, authentication, reputation management, bounce processing, and compliance.
Lettr is an ESP built for developers sending transactional email. When your application needs to send a password reset, order confirmation, or any other email, it makes an API call to Lettr, and Lettr delivers the message to the recipient's mailbox provider.
***
## ESP vs ISP
These two acronyms are frequently confused, but they serve entirely different roles in the email ecosystem.
| | Email Service Provider (ESP) | Internet Service Provider (ISP) |
| ------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------ |
| **Role** | Sends email on behalf of businesses and applications | Provides internet connectivity and often operates mailbox services |
| **Examples** | Lettr, Resend, SendGrid, Postmark, Amazon SES | Gmail (Google), Outlook.com (Microsoft), Yahoo Mail, Comcast |
| **Relationship to email** | Sends and manages outbound email | Receives and stores inbound email for end users |
| **Also called** | Email sending platform, email API provider | Mailbox provider, inbox provider |
In the email industry, the term "ISP" is often used loosely to mean "mailbox provider" — the service that operates the recipient's inbox (Gmail, Outlook, Yahoo). This is technically imprecise (Gmail is not an internet service provider), but the usage is widespread in deliverability discussions.
***
## Why Use an ESP Instead of Sending Directly
It is technically possible to send email directly from your own server using an SMTP server like Postfix or Sendmail. For small-scale personal use, this can work. For any application sending email to real users at scale, direct sending creates serious problems that an ESP solves.
### IP Reputation
When you send from your own server, you are sending from an IP address with no email reputation. Mailbox providers treat unknown IPs with suspicion and are likely to filter or reject your messages. Building IP reputation from scratch requires weeks of careful volume ramp-up and consistent positive engagement.
An ESP like Lettr maintains pools of sending IPs with established, positive reputations. Your emails benefit from this reputation from day one.
### Authentication Infrastructure
Properly authenticating email requires generating DKIM key pairs, publishing SPF records, configuring DMARC policies, and rotating keys periodically. On your own server, you are responsible for all of this. If any component is misconfigured, your emails fail authentication checks and go to spam.
Lettr handles DKIM key generation and signing automatically. You publish the DNS records Lettr provides, and authentication works for every message.
### Bounce and Complaint Processing
When you send email directly, you need to:
* Parse SMTP bounce responses in dozens of formats
* Classify bounces as hard or soft
* Maintain a suppression list of invalid addresses
* Enroll in feedback loop programs with every major mailbox provider
* Process abuse reports and suppress complainers
An ESP handles all of this automatically. Lettr processes bounces, manages suppression lists, and receives feedback loop reports from major providers — surfacing the data to your application through webhooks and your dashboard.
### Deliverability Expertise
Mailbox providers constantly update their filtering algorithms. Staying current with sender requirements, authentication standards, and best practices is a specialized discipline. An ESP's deliverability infrastructure is maintained by people whose full-time job is ensuring emails reach the inbox.
### Compliance
Email regulations (CAN-SPAM, GDPR, CASL) impose requirements on commercial email — unsubscribe mechanisms, physical address inclusion, consent management. An ESP provides built-in tools to help you meet these requirements, including `List-Unsubscribe` header support and suppression list enforcement.
***
## What an ESP Does for You
Accepts your email via API or SMTP, assembles the full message with proper headers, signs it with DKIM, resolves the recipient's MX records, and delivers it over an encrypted SMTP connection.
Maintains sending IP reputation, monitors blocklists, processes feedback loops, and isolates your sending from other users on shared infrastructure.
Parses bounce responses, classifies them by type, automatically suppresses invalid addresses, and reports bounce events to your application via webhooks.
Tracks delivery, bounce, open, click, complaint, and unsubscribe events. Provides dashboards for monitoring and webhooks for real-time event processing.
Provides tools for designing, versioning, and managing email templates with dynamic content via merge tags — keeping email design out of your application code.
Enforces suppression lists, supports one-click unsubscribe headers, and provides the infrastructure needed to comply with email regulations.
***
## Types of ESPs
Not all ESPs serve the same purpose. The ESP landscape broadly splits into two categories:
### Transactional ESPs
Built for application-triggered, one-to-one emails — password resets, order confirmations, account notifications. These ESPs prioritize delivery speed, API reliability, and developer experience.
Lettr is a transactional ESP. Other examples include Postmark, Resend, and Amazon SES.
Key characteristics:
* API-first design with SDKs for major languages
* Sub-second delivery for time-sensitive messages
* Per-message event tracking (delivery, bounce, open, click)
* Template systems with merge tag support
* Webhook-based event delivery
### Marketing ESPs
Built for one-to-many campaigns — newsletters, promotions, product announcements. These ESPs prioritize audience management, campaign scheduling, and engagement analytics.
Examples include Mailchimp, Campaign Monitor, and HubSpot.
Key characteristics:
* Visual campaign builders and drag-and-drop editors
* Audience segmentation and list management
* A/B testing and campaign scheduling
* Subscription management and preference centers
* Aggregate campaign analytics
Many applications need both types. The recommended approach is to use a transactional ESP for triggered emails (where speed and reliability matter most) and either the same provider's marketing features or a separate marketing ESP for campaigns. Always use separate sending domains for each stream.
***
## Choosing an ESP
When evaluating an ESP for transactional email, consider these factors:
| Factor | What to Evaluate |
| -------------------- | ----------------------------------------------------------------------------------------- |
| **API design** | Is the API well-documented and intuitive? Are there SDKs for your language? |
| **Delivery speed** | How quickly do messages arrive after an API call? Sub-second matters for auth codes. |
| **Deliverability** | Does the provider maintain strong IP reputation and support all authentication protocols? |
| **Event tracking** | Can you track delivery, bounces, opens, clicks, and complaints via webhooks? |
| **Template support** | Can you manage templates outside your codebase with dynamic content support? |
| **Pricing model** | Per-email pricing vs volume tiers? Are there overages or hidden fees? |
| **Compliance** | Does the provider handle suppression lists, feedback loops, and unsubscribe headers? |
| **Support** | Is deliverability support available when you have inbox placement issues? |
***
## Common Mistakes
Running your own SMTP server (Postfix, Sendmail) and sending directly to recipients might work for a handful of test emails, but it will fail at scale. Your IP has no reputation, you have no bounce processing, you are not enrolled in feedback loops, and mailbox providers will likely reject or spam-folder your messages. Use an ESP.
Marketing ESPs are optimized for campaigns, not triggered messages. They may batch-process sends (adding latency), lack per-message event tracking, or not support the API patterns needed for real-time triggering. Use a transactional ESP for transactional email.
Sending application email through Google Workspace or Microsoft 365 is not a sustainable approach. These services are designed for person-to-person email, have strict sending limits, and are not built for API-driven transactional use cases. They will rate-limit you quickly.
An ESP provides authentication, bounce handling, suppression lists, and feedback loop processing. If you do not set up your DNS records, do not configure webhooks, and do not monitor your metrics, you lose most of the value of using an ESP. Take the time to configure these features properly.
***
## Related Topics
End-to-end overview of the email delivery pipeline.
Understand the factors that determine inbox placement.
Get started sending email through the Lettr API.
Configure authentication for your sending domain.
# What Are Feedback Loops?
Source: https://docs.lettr.com/knowledge-base/concepts/feedback-loops
How mailbox providers report spam complaints back to senders and how Lettr processes feedback loop data to protect your reputation
A feedback loop (FBL) is a mechanism that mailbox providers use to notify senders when a recipient marks their email as spam. When a user clicks "Report Spam" or "Mark as Junk" in their email client, the mailbox provider sends a complaint report back to the sender — or in most cases, to the sender's email service provider.
Feedback loops are one of the most important signals in email deliverability. They tell you directly that a recipient does not want your emails, and they give you the opportunity to stop sending to that person before further complaints damage your reputation.
***
## How Feedback Loops Work
A recipient clicks "Report Spam," "Mark as Junk," or a similar button in their email client (Gmail, Outlook, Yahoo Mail, Apple Mail). This registers a complaint with the mailbox provider.
The mailbox provider creates a complaint report in a standardized format — typically ARF (Abuse Reporting Format, defined in RFC 5965). The report includes the original message headers (or a redacted version) and identifies the complaint type.
The mailbox provider sends the ARF report to the email address registered in their feedback loop program. For emails sent through Lettr, these reports are sent to Lettr's feedback loop processing infrastructure.
Lettr receives the complaint, identifies the original message and recipient, and records the event. The recipient is automatically added to the suppression list to prevent further sends. The complaint event is fired to your configured webhooks.
Your application receives the complaint webhook and can take additional action — updating the recipient's status in your database, triggering an internal review, or adjusting your sending practices if complaint rates are elevated.
***
## Which Providers Offer Feedback Loops
Not all mailbox providers operate feedback loop programs, and those that do have varying levels of detail in their reports.
| Provider | FBL Available | Format | Notes |
| -------------------------- | ------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Yahoo / AOL** | Yes | ARF | One of the original FBL programs. Reports include full message headers. |
| **Outlook.com / Hotmail** | Yes | ARF via JMRP/SNDS | Microsoft's Junk Mail Reporting Program. Also offers Smart Network Data Services (SNDS) for IP-level reputation data. |
| **Gmail** | Partial | Not traditional ARF | Gmail does not offer a traditional FBL. Instead, it requires senders to implement a `List-Unsubscribe` header and uses aggregate reputation data via Google Postmaster Tools. |
| **Apple Mail / iCloud** | Limited | Varies | Apple processes complaints but does not offer a public FBL enrollment program. |
| **Corporate / Enterprise** | Varies | Varies | Many enterprise email systems (Exchange, Google Workspace) have internal complaint mechanisms that do not generate external FBL reports. |
Gmail's approach is different from traditional feedback loops. Instead of sending individual complaint reports, Gmail expects senders to monitor aggregate data through [Google Postmaster Tools](https://postmaster.google.com/) and respond to reputation changes at the domain or IP level.
***
## How Lettr Handles Feedback Loops
Lettr is enrolled in feedback loop programs with major mailbox providers. When a complaint is received, Lettr processes it automatically.
### Automatic Suppression
When a recipient files a spam complaint, Lettr immediately adds their address to your account's suppression list. This prevents your application from sending further emails to that address, even if your application explicitly requests it.
This automatic suppression is critical for protecting your sending reputation. Continuing to send to recipients who have complained is one of the fastest ways to get your domain or IP blocklisted.
### Webhook Events
Lettr fires a `email.complained` webhook event for every complaint received. Your application can listen for this event to update its own records:
```javascript theme={null}
app.post('/webhooks/lettr', (req, res) => {
const event = req.body;
if (event.type === 'email.complained') {
const { to, complaint_type, timestamp } = event.data;
// Update your database
markAsComplained(to, timestamp);
// Optional: trigger internal review if complaints spike
checkComplaintRate();
}
res.sendStatus(200);
});
```
### Dashboard Visibility
Complaint events are visible in your Lettr dashboard under email event history. You can filter by complaint events to see which messages generated complaints and identify patterns.
***
## Complaint Rate and Reputation
Your complaint rate — the percentage of delivered emails that generate spam complaints — is one of the most heavily weighted signals in sender reputation scoring.
### Benchmarks
| Complaint Rate | Assessment | Action |
| -------------- | ---------- | ------------------------------------------------ |
| \< 0.1% | Healthy | Continue current practices |
| 0.1% – 0.3% | Warning | Review recent sends, check content and targeting |
| 0.3% – 0.5% | Dangerous | Stop non-essential sends, investigate root cause |
| > 0.5% | Critical | Sending reputation is being actively damaged |
Google requires bulk senders to maintain a spam complaint rate below 0.3%, and recommends staying below 0.1%. Exceeding this threshold can result in emails being sent to spam or rejected entirely. See [Google & Yahoo Sender Requirements](/knowledge-base/compliance/google-yahoo-requirements).
### Why Complaints Matter More Than Unsubscribes
An unsubscribe is a neutral signal — the recipient used the proper mechanism to stop receiving emails. A complaint is a negative signal — the recipient told their mailbox provider that your email is spam. From a reputation perspective, complaints are far more damaging than unsubscribes.
This is why making it easy to unsubscribe is a deliverability strategy, not a subscriber retention risk. Every recipient who unsubscribes instead of complaining is protecting your reputation.
***
## Reducing Complaint Rates
If the unsubscribe link is buried at the bottom of your email in small gray text, recipients will use the more visible "Report Spam" button instead. Place your unsubscribe link prominently. Implement one-click unsubscribe via the `List-Unsubscribe` header — Lettr supports this automatically.
The most common cause of high complaint rates is sending to people who did not explicitly agree to receive your emails. Never add recipients without their consent. Use double opt-in to confirm that the address is valid and the owner wants your messages.
Tell subscribers what kind of emails they will receive and how often. If someone signs up expecting a single welcome email and receives weekly promotions, they will complain. Align your sending behavior with what you promised.
Sending irrelevant content increases complaint rates. Segment your audience and send content that matches their interests and engagement level. A user who signed up for product updates does not necessarily want marketing promotions.
Process unsubscribe requests in real time. If a recipient unsubscribes and receives another email the next day because of processing delays, they will often file a spam complaint. Lettr processes `List-Unsubscribe` requests immediately.
***
## The ARF Format
For technical readers, the Abuse Reporting Format (ARF) defined in RFC 5965 is the standard format for feedback loop reports. An ARF message is a MIME multipart message containing three parts:
1. **Human-readable description** — A plain text summary of the complaint
2. **Machine-readable report** — Structured fields including `Feedback-Type`, `User-Agent`, `Version`, and `Arrival-Date`
3. **Original message** — The original email (or its headers) that was reported
Common `Feedback-Type` values:
| Type | Meaning |
| ---------- | -------------------------------------------------- |
| `abuse` | Recipient reported the message as spam |
| `fraud` | Message is suspected phishing or fraud |
| `not-spam` | Recipient indicated the message is not spam (rare) |
| `other` | Other complaint type |
You do not need to parse ARF reports yourself. Lettr processes all incoming feedback loop reports and translates them into structured webhook events and dashboard data.
***
## Related Topics
How feedback loops fit into the broader deliverability picture.
How complaint rates affect your sender reputation and what to do about it.
Implement unsubscribe mechanisms that reduce complaints and protect reputation.
How Lettr manages suppressed addresses from bounces and complaints.
# What Is Transactional Email?
Source: https://docs.lettr.com/knowledge-base/concepts/transactional-email
Learn what transactional email is, how it differs from marketing email, and why it requires a different approach to sending and deliverability
Transactional email is email sent to an individual recipient in response to a specific action they took or an event that directly affects them. Password resets, order confirmations, shipping notifications, and login alerts are all transactional emails. The recipient expects them, often needs them immediately, and did not need to subscribe to receive them.
Transactional email is the backbone of every modern application. When it fails, users cannot log in, do not know their order shipped, and lose trust in your product.
***
## What Makes Email Transactional
An email is transactional when it meets two criteria:
1. **Triggered by a user action or system event** — The recipient did something (placed an order, requested a password reset, logged in from a new device) or something happened to their account (payment failed, subscription renewed).
2. **Contains information the recipient expects or needs** — The email delivers information directly related to that action or event. It is not promotional in nature.
The key distinction is who initiated the interaction. With transactional email, the recipient triggered it. With marketing email, the sender initiated it.
***
## Common Types of Transactional Email
| Category | Examples |
| -------------------- | ------------------------------------------------------------------------------------------------------ |
| **Authentication** | Password reset links, two-factor authentication codes, magic login links |
| **Account activity** | Welcome confirmation, email verification, account settings changes, login from new device alerts |
| **Commerce** | Order confirmations, payment receipts, shipping notifications, refund confirmations |
| **Billing** | Invoice emails, payment failure notices, subscription renewal confirmations, plan change confirmations |
| **Notifications** | Comment replies, mentions, shared document alerts, collaboration invitations |
| **System alerts** | Usage limit warnings, security alerts, scheduled maintenance notices |
***
## Transactional vs Marketing Email
| | Transactional | Marketing |
| ------------------------- | ------------------------------------ | -------------------------- |
| **Initiated by** | Recipient's action or a system event | Sender's decision |
| **Timing** | Immediate or near-immediate | Scheduled or batched |
| **Consent** | Implied by the user's action | Explicit opt-in required |
| **Unsubscribe link** | Generally not required | Required by law |
| **Typical open rate** | 60–80% | 15–25% |
| **Recipient expectation** | Expected and often urgent | Optional and interruptive |
| **Volume pattern** | Steady, driven by user activity | Spiky, driven by campaigns |
Some emails fall into a gray area. Onboarding sequences, review requests, and order confirmations with product recommendations can blur the line. When in doubt, treat the email as marketing — include an unsubscribe link and ensure you have consent. See [Transactional vs Marketing Email](/knowledge-base/best-practices/transactional-vs-marketing) for a detailed guide on handling gray areas.
***
## Why Transactional Email Needs Special Treatment
Transactional email has unique requirements that make it fundamentally different from marketing email in how it should be sent, managed, and monitored.
### Speed Is Critical
A password reset link that arrives five minutes late is a failed product experience. A two-factor authentication code that takes thirty seconds is barely acceptable. Transactional emails must be sent and delivered as close to instantly as possible.
This means:
* Sending through a dedicated API rather than batching through a queue
* Using infrastructure optimized for low-latency delivery
* Not throttling transactional sends the way you might throttle marketing campaigns
### Deliverability Cannot Fail
Marketing emails that land in spam are a missed opportunity. Transactional emails that land in spam are a product outage. If a user cannot receive their password reset email, they are locked out of your product entirely.
This is why transactional and marketing email should use separate sending domains. Marketing reputation problems should never affect transactional delivery.
### Content Must Be Focused
Transactional emails should contain exactly what the recipient needs — the reset link, the order details, the shipping tracking number — and nothing else. Adding promotional content to transactional emails risks reclassification by mailbox providers and regulators.
Adding a "You might also like..." section to an order confirmation can cause mailbox providers to treat the entire email as marketing, applying stricter filtering. It can also create legal complications under GDPR and similar regulations. Keep transactional emails focused on their purpose.
***
## How to Send Transactional Email with Lettr
### Via the API
The most common approach is sending transactional email through Lettr's REST API, triggered by your application logic:
```javascript theme={null}
const response = await fetch('https://app.lettr.com/api/emails', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: 'no-reply@mail.yourdomain.com',
to: 'user@example.com',
subject: 'Reset your password',
template_id: 'tmpl_password_reset',
merge_tags: {
reset_link: 'https://yourdomain.com/reset?token=abc123',
expiry_minutes: '30',
},
}),
});
```
### Via SMTP
If your application sends email through SMTP (common with legacy systems and frameworks like Laravel, Rails, or Django), Lettr supports SMTP relay:
```
Host: smtp.lettr.com
Port: 587
Username: your-api-key
Password: your-api-key
Encryption: STARTTLS
```
### Using Templates
Lettr's template system lets you design your transactional emails once and send them with dynamic data via merge tags. This keeps your email content out of your application code and allows non-developers to update email designs without deploying code changes.
See [Templates](/learn/templates/introduction) for the full guide.
***
## Best Practices for Transactional Email
Send transactional email from a subdomain like `mail.yourdomain.com` rather than your root domain. This isolates transactional reputation from marketing reputation and from your website's domain reputation. If you also send marketing email, use a separate subdomain like `campaigns.yourdomain.com`.
Transactional emails are time-sensitive. Send each one as soon as the triggering event occurs. Do not queue transactional emails for batch processing — a password reset link that arrives an hour late is useless.
A password reset email needs the reset link, an expiry notice, and a note about what to do if the user didn't request it. It does not need your company's full header, a product announcement, or social media links. Every extra element adds rendering time and dilutes the purpose.
Always provide a plain text alternative alongside your HTML email. Some email clients render plain text only, and spam filters view HTML-only emails with more suspicion. Lettr's template system generates plain text versions automatically.
Track transactional email metrics independently from marketing email. Transactional email should maintain open rates above 50% and bounce rates below 1%. If metrics deviate, investigate immediately — it likely indicates a delivery or authentication problem.
Implement webhook handlers that respond to delivery failures. If a password reset email bounces, your application should surface an alternative recovery flow. If a 2FA code is deferred, your application should allow the user to request a new one.
***
## Common Mistakes
Many teams invest heavily in marketing email campaigns while treating transactional email as a simple utility. In reality, transactional email is a product feature. When it fails, users experience a product failure. Invest in monitoring, testing, and reliability for transactional email with the same rigor you apply to any critical system.
This is the most common and most damaging mistake. A marketing campaign that generates spam complaints will drag down the reputation of your transactional sending domain, causing password resets and order confirmations to land in spam. Always use separate subdomains.
Transactional email without proper SPF, DKIM, and DMARC authentication is likely to be filtered or rejected by major mailbox providers. Authentication is not optional — it is the foundation of deliverability.
Adding product recommendations, upsells, or promotional banners to transactional emails risks reclassification by mailbox providers and violates regulations in some jurisdictions. Keep transactional emails focused on the information the recipient needs.
***
## Related Topics
Detailed comparison and guidance on separating email streams.
Understand the factors that determine whether your emails reach the inbox.
Get started sending transactional email through the Lettr API.
Design and manage reusable email templates for your transactional emails.
# AWS Route 53
Source: https://docs.lettr.com/knowledge-base/dns-guides/aws-route53
Add the DNS records Lettr needs in AWS Route 53 hosted zones to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using AWS Route 53. Route 53 is Amazon Web Services' scalable Domain Name System (DNS) web service, managed through the [AWS Management Console](https://console.aws.amazon.com/route53/). Route 53 organizes DNS records into **hosted zones**, where each hosted zone corresponds to a domain.
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list. This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Route 53 DNS
Log in to the [AWS Route 53 Dashboard](https://console.aws.amazon.com/route53/). In the left sidebar, click **Hosted zones** and select the Hosted zone (domain) you want to configure, or create a new one.
This will open the Hosted zone details page, where you can manage your DNS records.
If your domain was purchased through AWS Route 53 or your nameservers already point to AWS Route 53, skip nameserver
configuration entirely. Your domain is already using AWS Route 53's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on AWS Route 53, you must first **update the nameservers**
at your registrar to AWS Route 53's nameservers shown in the domain configuration.
Until the nameservers are updated, any records you add in AWS Route 53 will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Route 53:
1. Click **Create record** in your Hosted zone.
2. Copy the **Hostname** from Lettr and paste it into the **Record name** field in Route 53.
3. Select **CNAME** from the **Record type** dropdown.
4. Copy the **Value** from Lettr and paste it into the **Value** field in Route 53.
5. Leave **TTL** set to 300 (Route 53 default).
6. Ensure **Routing policy** is set to **Simple routing**.
7. Click **Create records**.
Omit your domain suffix from the Hostname when pasting into Route 53. For example, instead of `mailing.lettr-demo.com`, paste only `mailing`. Route 53 displays the hosted zone domain as a greyed-out suffix next to the Record name field.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Route 53:
1. Click **Create record** in your hosted zone.
2. Copy the **Hostname** from Lettr and paste it into the **Record name** field in Route 53.
3. Select **TXT** from the **Record type** dropdown.
4. Copy the **Value** from Lettr and paste it into the **Value** field in Route 53. Enclose the value in double quotes (e.g. `"v=DKIM1; ..."`).
5. Leave **TTL** set to 300 or adjust as needed.
6. Ensure **Routing policy** is set to **Simple routing**.
7. Click **Create records**.
Route 53 requires TXT record values to be enclosed in double quotes. If you paste the value without quotes, the record will fail to save or will be stored incorrectly.
Omit your domain suffix from the Hostname when pasting into Route 53. For example, instead of `scph0126._domainkey.mailing.lettr-demo.com`, paste only `scph0126._domainkey.mailing`.
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Route 53:
1. Click **Create record** in your hosted zone.
2. Copy the **Hostname** from Lettr and paste it into the **Record name** field in Route 53.
3. Select **TXT** from the **Record type** dropdown.
4. Copy the **Value** from Lettr and paste it into the **Value** field in Route 53. Enclose the value in double quotes.
5. Leave **TTL** set to 300 or adjust as needed.
6. Ensure **Routing policy** is set to **Simple routing**.
7. Click **Create records**.
Omit your domain suffix from the Hostname when pasting into Route 53. For example, instead of `_dmarc.mailing.lettr-demo.com`, paste only `_dmarc.mailing`.
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**
Click on your new domain in the Inbound Domains list. This will display the MX records that need to be configured. Keep this page open — you will need these values in the next steps.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Route 53:
1. Click **Create record** in your hosted zone.
2. Copy the **Hostname** from Lettr and paste it into the **Record name** field in Route 53.
3. Select **MX** from the **Record type** dropdown.
4. In the **Value** field, enter all three MX records, each on a separate line, in the format `priority mailserver`. For example:
```
10 rx1.sparkpostmail.com
10 rx2.sparkpostmail.com
10 rx3.sparkpostmail.com
```
5. Leave **TTL** set to 300 or adjust as needed.
6. Ensure **Routing policy** is set to **Simple routing**.
7. Click **Create records**.
Route 53 combines all MX records for the same name into a single record set. Enter each MX record on a separate line within the same Value field, with the priority number before the mail server address.
Omit your domain suffix from the Hostname when pasting into Route 53. For example, instead of `inbound.lettr-demo.com`, paste only `inbound`.
### Verify Your Inbound Domain
After adding the MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
In the Lettr dashboard, select **Domains** in the navigation panel, then select **Tracking Domains** and click **Create Tracking Domain**. Enter your desired tracking subdomain (e.g. `track.company.com`) and click **Create Tracking Domain**.
Click on the name of your new tracking domain in the Tracking Domains list. This will display the CNAME records that need to be configured. Keep this page open — you will need these values in the next steps.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Route 53:
1. Click **Create record** in your hosted zone.
2. Copy the **Hostname** from Lettr and paste it into the **Record name** field in Route 53.
3. Select **CNAME** from the **Record type** dropdown.
4. Copy the **Value** from Lettr and paste it into the **Value** field in Route 53.
5. Leave **TTL** set to 300 or adjust as needed.
6. Ensure **Routing policy** is set to **Simple routing**.
7. Click **Create records**.
Omit your domain suffix from the Hostname when pasting into Route 53. For example, instead of `track.lettr-demo.com`, paste only `track`.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Route 53:
1. Click **Create record** in your hosted zone.
2. Copy the **Hostname** from Lettr and paste it into the **Record name** field in Route 53.
3. Select **CNAME** from the **Record type** dropdown.
4. Copy the **Value** from Lettr and paste it into the **Value** field in Route 53.
5. Leave **TTL** set to 300 or adjust as needed.
6. Ensure **Routing policy** is set to **Simple routing**.
7. Click **Create records**.
Omit your domain suffix from the Hostname when pasting into Route 53. For example, instead of `track.lettr-demo.com`, paste only `track`.
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
In the Lettr dashboard, select **Domains** in the navigation panel, then select **Storage Domains** and click **Create Storage Domain**. Enter your desired storage subdomain (e.g. `assets.company.com`) and click **Create Storage Domain**.
Click on your new domain in the Storage Domains list. This will display the TXT and CNAME records that need to be configured. Keep this page open — you will need these values in the next steps.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Route 53:
1. Click **Create record** in your hosted zone.
2. Copy the **Hostname** from Lettr and paste it into the **Record name** field in Route 53.
3. Select **TXT** from the **Record type** dropdown.
4. Copy the **Value** from Lettr and paste it into the **Value** field in Route 53. Enclose the value in double quotes.
5. Leave **TTL** set to 300 or adjust as needed.
6. Ensure **Routing policy** is set to **Simple routing**.
7. Click **Create records**.
Omit your domain suffix from the Hostname when pasting into Route 53. For example, instead of `assets.lettr-demo.com`, paste only `assets`.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Route 53:
1. Click **Create record** in your hosted zone.
2. Copy the **Hostname** from Lettr and paste it into the **Record name** field in Route 53.
3. Select **TXT** from the **Record type** dropdown.
4. Copy the **Value** from Lettr and paste it into the **Value** field in Route 53. Enclose the value in double quotes.
5. Leave **TTL** set to 300 or adjust as needed.
6. Ensure **Routing policy** is set to **Simple routing**.
7. Click **Create records**.
If the Record name is the same as the Certificate Validation TXT record above, Route 53 will not allow two separate TXT record sets with the same name. Instead, edit the existing TXT record and add the new value on a separate line, with each value enclosed in its own double quotes.
Omit your domain suffix from the Hostname when pasting into Route 53. For example, instead of `assets.lettr-demo.com`, paste only `assets`.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Route 53:
1. Click **Create record** in your hosted zone.
2. Copy the **Hostname** from Lettr and paste it into the **Record name** field in Route 53.
3. Select **CNAME** from the **Record type** dropdown.
4. Copy the **Value** from Lettr and paste it into the **Value** field in Route 53.
5. Leave **TTL** set to 300 or adjust as needed.
6. Ensure **Routing policy** is set to **Simple routing**.
7. Click **Create records**.
Omit your domain suffix from the Hostname when pasting into Route 53. For example, instead of `assets.lettr-demo.com`, paste only `assets`.
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Route 53 requires all TXT record values to be enclosed in double quotes. If you paste a value without quotes, the record may fail to save or resolve incorrectly. Edit the record and ensure the value is wrapped like `"v=DKIM1; ..."`.
Route 53 does not allow two separate record sets of the same type with the same name. If you need to add multiple TXT values for the same hostname (e.g. both storage TXT records share a name), add them as separate lines within a single TXT record set, each enclosed in its own double quotes:
```
"certificate-validation-value-here"
"hostname-prevalidation-value-here"
```
Route 53 displays the hosted zone domain as a greyed-out suffix next to the Record name field. If you paste the full hostname (e.g. `mailing.lettr-demo.com`), the resulting record will be `mailing.lettr-demo.com.lettr-demo.com`, which will fail verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
If verification fails after adding records, check the following:
* **Wait at least 30 minutes** before your first verification attempt. Most records propagate within 1–2 hours.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
A common mistake is selecting the wrong type in Route 53's Record type dropdown:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. After saving the record in Route 53, click the record to confirm the full value was stored. If it appears truncated, edit the record and try pasting the value again. Remember to enclose the entire value in double quotes.
Route 53 does not support CNAME records at the zone apex (root domain). For example, you cannot create a CNAME record for `company.com` itself — only for subdomains like `mailing.company.com`. Use a subdomain for your sending domain to avoid this limitation.
If you need to use the root domain, consider using Route 53's **Alias** record type, which works at the zone apex. However, Alias records only support routing to specific AWS resources and may not work for Lettr's CNAME targets. Using a subdomain is the recommended approach.
If your records are saved in Route 53 but not resolving, confirm that your domain registrar is pointing to Route 53's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include the four nameservers listed in your Route 53 hosted zone (e.g. `ns-123.awsdns-45.com`, `ns-456.awsdns-67.net`). If it shows a different provider's nameservers, update them at your domain registrar.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after 48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Azure DNS
Source: https://docs.lettr.com/knowledge-base/dns-guides/azure-dns
Add the DNS records Lettr needs in Microsoft Azure DNS to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using Microsoft Azure DNS. Azure DNS is a reliable, fast DNS service built on Microsoft's global network of name servers, managed through the [Azure Portal](https://portal.azure.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list. This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Azure DNS
Log in to the [Azure Portal](https://portal.azure.com) and navigate to **All services** in the left-hand menu. Search for **DNS zones** to view your zones, and select the zone that matches your domain.
If your domain was purchased through Azure or your nameservers already point to Azure DNS, skip nameserver
configuration entirely. Your domain is already using Azure DNS's nameservers by default — proceed directly to adding
the DNS records below.
If you registered your domain elsewhere but want to manage DNS on Azure, you must first create a DNS zone in Azure DNS
and then **update the nameservers** at your registrar to Azure's nameservers shown in the zone overview.
Until the nameservers are updated, any records you add in Azure DNS will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Add the record in Azure DNS:
1. Click **+ Add** in your DNS zone.
2. Enter the **Hostname** from Lettr (without your domain suffix) into the **Name** field. For example, paste only `mailing`, not `mailing.company.com`.
3. Set **Type** to **CNAME**.
4. Leave **TTL** and **TTL unit** at their defaults (1 Hour).
5. Enter the **Value** from Lettr into the **Alias** field.
6. Click **Add**.
Azure DNS automatically appends your zone name to the record name. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`).
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Add the record in Azure DNS:
1. Click **+ Add** in your DNS zone.
2. Enter the **Hostname** from Lettr (without your domain suffix) into the **Name** field. For example, paste only `scph0126._domainkey.mailing`.
3. Set **Type** to **TXT**.
4. Leave **TTL** and **TTL unit** at their defaults (1 Hour).
5. Enter the **Value** from Lettr into the **Value** field.
6. Click **Add**.
Azure DNS automatically appends your zone name to the record name. Always paste only the subdomain portion (e.g.
`scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
DKIM values are long strings. After saving, re-open the record set to confirm the full value was stored correctly. If
it appears truncated, delete and re-add the record.
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Add the record in Azure DNS:
1. Click **+ Add** in your DNS zone.
2. Enter the **Hostname** from Lettr (without your domain suffix) into the **Name** field. For example, paste only `_dmarc.mailing`.
3. Set **Type** to **TXT**.
4. Leave **TTL** and **TTL unit** at their defaults (1 Hour).
5. Enter the **Value** from Lettr into the **Value** field.
6. Click **Add**.
Azure DNS automatically appends your zone name to the record name. Always paste only the subdomain portion (e.g.
`_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list. This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Add the MX record set in Azure DNS:
1. Click **+ Add** in your DNS zone.
2. Enter the **Hostname** from Lettr (without your domain suffix) into the **Name** field. For example, paste only `inbound`.
3. Set **Type** to **MX**.
4. Leave **TTL** and **TTL unit** at their defaults (1 Hour).
5. Under **MX Records**, enter `10` for **Preference** and `rx1.sparkpostmail.com` for **Mail exchange**.
6. Add two more rows: `10` / `rx2.sparkpostmail.com` and `10` / `rx3.sparkpostmail.com`.
7. Click **Add**.
Azure DNS automatically appends your zone name to the record name. Always paste only the subdomain portion (e.g.
`inbound`, not `inbound.company.com`).
Adding MX records to a domain or subdomain will route all incoming email for that address to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list. This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Azure DNS:
1. Click **+ Add** in your DNS zone.
2. Enter the **Hostname** from Lettr (without your domain suffix) into the **Name** field.
3. Set **Type** to **CNAME**.
4. Leave **TTL** and **TTL unit** at their defaults (1 Hour).
5. Enter the **Value** from Lettr into the **Alias** field.
6. Click **Add**.
Azure DNS automatically appends your zone name to the record name. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Azure DNS:
1. Click **+ Add** in your DNS zone.
2. Enter the **Hostname** from Lettr (without your domain suffix) into the **Name** field.
3. Set **Type** to **CNAME**.
4. Leave **TTL** and **TTL unit** at their defaults (1 Hour).
5. Enter the **Value** from Lettr into the **Alias** field.
6. Click **Add**.
Azure DNS automatically appends your zone name to the record name. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list. This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Azure DNS:
1. Click **+ Add** in your DNS zone.
2. Enter the **Hostname** from Lettr (without your domain suffix) into the **Name** field.
3. Set **Type** to **TXT**.
4. Leave **TTL** and **TTL unit** at their defaults (1 Hour).
5. Enter the **Value** from Lettr into the **Value** field.
6. Click **Add**.
Azure DNS automatically appends your zone name to the record name. Always paste only the subdomain portion (e.g.
`storage`, not `storage.company.com`).
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Azure DNS:
1. Click **+ Add** in your DNS zone.
2. Enter the **Hostname** from Lettr (without your domain suffix) into the **Name** field.
3. Set **Type** to **TXT**.
4. Leave **TTL** and **TTL unit** at their defaults (1 Hour).
5. Enter the **Value** from Lettr into the **Value** field.
6. Click **Add**.
Azure DNS automatically appends your zone name to the record name. Always paste only the subdomain portion (e.g.
`storage`, not `storage.company.com`).
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Azure DNS:
1. Click **+ Add** in your DNS zone.
2. Enter the **Hostname** from Lettr (without your domain suffix) into the **Name** field.
3. Set **Type** to **CNAME**.
4. Leave **TTL** and **TTL unit** at their defaults (1 Hour).
5. Enter the **Value** from Lettr into the **Alias** field.
6. Click **Add**.
Azure DNS automatically appends your zone name to the record name. Always paste only the subdomain portion (e.g.
`storage`, not `storage.company.com`).
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Using Azure CLI
You can also add records using the Azure CLI. Replace `` and `` with your own values.
```bash theme={null}
# Add CNAME record for sending domain verification
az network dns record-set cname set-record \
--resource-group \
--zone-name example.com \
--record-set-name mailing \
--ttl 3600 \
--cname
# Add TXT record for DKIM
az network dns record-set txt add-record \
--resource-group \
--zone-name example.com \
--record-set-name "scph0126._domainkey.mailing" \
--value "v=DKIM1;k=rsa;h=sha256;p=MIGf..."
# Add TXT record for DMARC
az network dns record-set txt add-record \
--resource-group \
--zone-name example.com \
--record-set-name "_dmarc.mailing" \
--value "v=DMARC1;p=none;"
# Add MX records for inbound (run once per exchange)
az network dns record-set mx add-record \
--resource-group \
--zone-name example.com \
--record-set-name inbound \
--exchange rx1.sparkpostmail.com \
--preference 10
az network dns record-set mx add-record \
--resource-group \
--zone-name example.com \
--record-set-name inbound \
--exchange rx2.sparkpostmail.com \
--preference 10
az network dns record-set mx add-record \
--resource-group \
--zone-name example.com \
--record-set-name inbound \
--exchange rx3.sparkpostmail.com \
--preference 10
# Add CNAME records for tracking domain
az network dns record-set cname set-record \
--resource-group \
--zone-name example.com \
--record-set-name \
--ttl 3600 \
--cname
az network dns record-set cname set-record \
--resource-group \
--zone-name example.com \
--record-set-name tracking \
--ttl 3600 \
--cname
# Add TXT and CNAME records for storage domain
az network dns record-set txt add-record \
--resource-group \
--zone-name example.com \
--record-set-name \
--value ""
az network dns record-set txt add-record \
--resource-group \
--zone-name example.com \
--record-set-name \
--value ""
az network dns record-set cname set-record \
--resource-group \
--zone-name example.com \
--record-set-name assets \
--ttl 3600 \
--cname
```
***
## Troubleshooting
Ensure you have the **DNS Zone Contributor** role or equivalent permissions on the DNS zone resource in Azure.
Azure DNS typically propagates within minutes, but in some cases it can take longer. If verification fails after adding
records, check the following:
* **Wait at least 30 minutes** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
Alternatively, you can use the Azure CLI to verify records directly:
```bash theme={null}
az network dns record-set list \
--resource-group \
--zone-name yourdomain.com \
--output table
```
If your records are saved in Azure DNS but not resolving, confirm that your domain registrar is pointing to Azure's
nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include the four Azure nameservers shown in your DNS zone overview (e.g. `ns1-xx.azuredns.com`). If it
shows a different provider's nameservers, update them at your domain registrar.
A common mistake is selecting the wrong type when creating the record set:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. After saving the record set in Azure, re-open it to confirm the full value was
stored. If it appears truncated, delete the record and re-add it, pasting the full value carefully.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after
48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the
output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Cloudflare
Source: https://docs.lettr.com/knowledge-base/dns-guides/cloudflare
Configure the DNS records Lettr needs in Cloudflare, using automatic Domain Connect setup or manual records for your sending and other domains.
This guide walks you through adding the required DNS records for Lettr using Cloudflare's DNS management. Cloudflare is a web infrastructure and security company that provides DNS hosting, CDN, and DDoS protection for domains managed through its dashboard at [dash.cloudflare.com](https://dash.cloudflare.com).
Because Cloudflare supports the Domain Connect protocol, you have two ways to set up your DNS records: **automatic setup**, which configures everything in one click directly from the Lettr dashboard, or **manual setup**, where you copy each record value into Cloudflare yourself. Automatic setup is the recommended approach — it's faster, eliminates copy-paste errors, and handles all the Cloudflare-specific details (like disabling proxy mode on CNAME records) for you.
***
## Automatic Setup with Domain Connect (Recommended)
Cloudflare is the first DNS provider to support Lettr's Domain Connect integration, which means you can configure all required DNS records without leaving the Lettr dashboard or touching Cloudflare's DNS settings directly. Instead of manually creating each CNAME, TXT, and MX record, Lettr generates a signed link that tells Cloudflare exactly which records to add. You review the proposed changes on Cloudflare's end, click **Apply**, and the records appear in your DNS zone within seconds.
This works for all domain types — sending, tracking, and inbound. The specific records configured depend on the domain type:
| Domain Type | Records Configured Automatically |
| ------------------------- | -------------------------------------------------------------------------- |
| **Sending** (subdomain) | CNAME for domain verification, TXT for DKIM signing, TXT for DMARC policy |
| **Sending** (root domain) | TXT for SPF authorization, TXT for DKIM signing, TXT for DMARC policy |
| **Tracking** | CNAME for SSL certificate provisioning, CNAME for tracking traffic routing |
| **Inbound** | 3 MX records directing incoming mail to Lettr's servers |
### How to Use Automatic Setup
The process is the same regardless of which domain type you're configuring. The example below uses a sending domain, but the steps are identical for tracking and inbound domains — only the button location and the records shown on Cloudflare's review page will differ.
Navigate to **Domains** in the sidebar, then select the appropriate domain section — **Sending Domains**, **Tracking Domains**, or **Inbound Domains**. Click the **Create** button, enter your domain name, and create the domain. This is the same step you'd take for manual setup.
On the domain's detail page, you'll see a **Configure with Cloudflare** button alongside the usual DNS record table. Click it. Lettr generates a cryptographically signed URL that encodes every DNS record your domain needs, then redirects you to Cloudflare.
Cloudflare's Domain Connect page displays a summary of the DNS records that will be added to your zone. Take a moment to review them — you'll see the record types, names, and values that match what Lettr's detail page shows. Nothing is applied until you explicitly approve.
Click **Apply** to have Cloudflare add all the records to your DNS zone. This happens instantly through Cloudflare's API. CNAME records are automatically created in **DNS only** mode (grey cloud), so you don't need to worry about proxy mode causing verification failures.
After applying, Cloudflare redirects you back to your domain's detail page in Lettr. Click **Verify DNS Records** to confirm that the records are resolving. Propagation typically completes within a few seconds for Cloudflare-hosted domains, though in rare cases it may take a minute or two.
Domain Connect checks your existing DNS configuration before applying records. If you already have a valid DMARC or SPF record in place, it skips those records to avoid creating conflicts or duplicates. This means you can safely use automatic setup even if you've already partially configured your domain by hand.
Domain Connect handles all the complexity of DNS configuration automatically, making it the fastest way to set up Lettr domains on Cloudflare.
### When to Use Manual Setup Instead
Automatic setup covers the most common configurations, but there are situations where manual setup is the better choice:
* **DNS not hosted on Cloudflare** — If your domain's nameservers point to a different provider (even if you have a Cloudflare account), Domain Connect won't be available. Follow the manual steps below, or consult the [DNS guides](/knowledge-base/introduction) for your provider.
* **Storage domains** — Domain Connect currently supports sending, tracking, and inbound domains. Storage domain records need to be added manually.
* **Authorization issues** — If clicking **Configure with Cloudflare** results in an error or you can't authorize the changes on Cloudflare's side, you can always fall back to copying the records manually. The domain detail page in Lettr shows every record you need.
* **Preference for manual control** — Some teams prefer to review and add each record individually, especially if they maintain strict change control over their DNS zones.
If any of these apply, the manual setup sections below walk you through adding each record type step by step.
***
## Manual Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Cloudflare DNS
Log in to the [Cloudflare dashboard](https://dash.cloudflare.com), click **Domains** in the left-hand sidebar to view a list of your domains. Select the domain you want to configure, or create a new one.
This will open the domain details page, where you can manage your DNS records.
If your domain was purchased through Cloudflare or your nameservers already point to Cloudflare, skip nameserver
configuration entirely. Your domain is already using Cloudflare's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on Cloudflare, you must first **update the nameservers**
at your registrar to Cloudflare's nameservers shown in the domain configuration. Click on your domain in the list, then follow the instructions.
Until the nameservers are updated, any records you add in Cloudflare will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Cloudflare:
1. Click **Add record** on the Cloudflare DNS page.
2. Select **CNAME** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in Cloudflare.
4. Copy the **Value** from Lettr and paste it into the **Target** field in Cloudflare.
5. Set **Proxy status** to **DNS only** (grey cloud). Click the orange cloud icon to toggle it off.
6. Leave **TTL** set to Auto.
7. Click **Save**.
Cloudflare's proxy mode (orange cloud) rewrites DNS responses and will cause CNAME verification to fail. All CNAME records for Lettr **must** use **DNS only** (grey cloud) mode.
Omit your domain suffix from the Hostname when pasting into Cloudflare. For example, instead of `mailing.lettr-demo.com`, paste only `mailing`.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Cloudflare:
1. Click **Add record** on the Cloudflare DNS page.
2. Select **TXT** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in Cloudflare.
4. Copy the **Value** from Lettr and paste it into the **Content** field in Cloudflare.
5. Leave **TTL** set to Auto.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into Cloudflare. For example, instead of `scph0126._domainkey.mailing.lettr-demo.com`, paste only `scph0126._domainkey.mailing`.
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Cloudflare:
1. Click **Add record** on the Cloudflare DNS page.
2. Select **TXT** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in Cloudflare.
4. Copy the **Value** from Lettr and paste it into the **Content** field in Cloudflare.
5. Leave **TTL** set to Auto.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into Cloudflare. For example, instead of `_dmarc.mailing.lettr-demo.com`, paste only `_dmarc.mailing`.
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Manual Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Cloudflare:
1. Click **Add record** on the Cloudflare DNS page.
2. Select **MX** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in Cloudflare.
4. Copy the first **Required MX Record** value (without the priority number) from Lettr and paste it into the **Mail server** field in Cloudflare.
5. Copy the **Priority** number (e.g. `10`) from Lettr and paste it into the **Priority** field in Cloudflare.
6. Leave **TTL** set to Auto.
7. Click **Save**.
8. Repeat this process for the second (rx2.sparkpostmail.com) and third (rx3.sparkpostmail.com) MX records.
Omit your domain suffix from the Hostname when pasting into Cloudflare. For example, instead of `inbound.lettr-demo.com`, paste only `inbound`.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Manual Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Cloudflare:
1. Click **Add record** on the Cloudflare DNS page.
2. Select **CNAME** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in Cloudflare.
4. Copy the **Value** from Lettr and paste it into the **Target** field in Cloudflare.
5. Set **Proxy status** to **DNS only** (grey cloud).
6. Leave **TTL** set to Auto.
7. Click **Save**.
Omit your domain suffix from the Hostname when pasting into Cloudflare. For example, instead of `track.lettr-demo.com`, paste only `track`.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Cloudflare:
1. Click **Add record** on the Cloudflare DNS page.
2. Select **CNAME** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in Cloudflare.
4. Copy the **Value** from Lettr and paste it into the **Target** field in Cloudflare.
5. Set **Proxy status** to **DNS only** (grey cloud).
6. Leave **TTL** set to Auto.
7. Click **Save**.
Omit your domain suffix from the Hostname when pasting into Cloudflare. For example, instead of `track.lettr-demo.com`, paste only `track`.
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Manual Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Cloudflare:
1. Click **Add record** on the Cloudflare DNS page.
2. Select **TXT** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in Cloudflare.
4. Copy the **Value** from Lettr and paste it into the **Content** field in Cloudflare.
5. Leave **TTL** set to Auto.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into Cloudflare, just as with the CNAME record above.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Cloudflare:
1. Click **Add record** on the Cloudflare DNS page.
2. Select **TXT** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in Cloudflare.
4. Copy the **Value** from Lettr and paste it into the **Content** field in Cloudflare.
5. Leave **TTL** set to Auto.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into Cloudflare, just as with the CNAME record above.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Cloudflare:
1. Click **Add record** on the Cloudflare DNS page.
2. Select **CNAME** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in Cloudflare.
4. Copy the **Value** from Lettr and paste it into the **Target** field in Cloudflare.
5. Set **Proxy status** to **DNS only** (grey cloud).
6. Leave **TTL** set to Auto.
7. Click **Save**.
Omit your domain suffix from the Hostname when pasting into Cloudflare. For example, instead of `assets.lettr-demo.com`, paste only `assets`.
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
This is the most common issue when using Cloudflare with Lettr. Cloudflare's proxy mode (orange cloud icon) intercepts and rewrites DNS responses, which causes CNAME verification to fail because Lettr cannot see the original CNAME target.
**How to fix:**
1. Go to your domain in the [Cloudflare dashboard](https://dash.cloudflare.com).
2. Open the **DNS** tab.
3. Find each CNAME record you added for Lettr.
4. Click the orange cloud icon next to the record to toggle it to **DNS only** (grey cloud).
5. Wait a few minutes for the change to propagate, then re-verify in Lettr.
All CNAME records for Lettr (sending verification, tracking SSL, tracking traffic, and storage domain routing) must be set to **DNS only** (grey cloud). TXT and MX records are not affected by proxy mode.
Cloudflare automatically appends your domain to the record name. If you paste the full hostname (e.g. `mailing.lettr-demo.com`), the resulting record will be `mailing.lettr-demo.com.lettr-demo.com`, which will fail verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
If verification fails after adding records, check the following:
* **Wait at least 30 minutes** before your first verification attempt. Most records propagate within 1–2 hours.
* **Confirm proxy mode is off** for all CNAME records (see above).
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
If a `dig CNAME` query returns an IP address instead of a hostname, the record is still proxied (orange cloud). Toggle it to DNS only and check again.
A common mistake is selecting the wrong type in Cloudflare's dropdown:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. Cloudflare handles long TXT values well, but copying errors can occasionally cut off the string. After saving the record, click **Edit** on the record to confirm the full value was stored. If it appears truncated, try pasting the value again.
If your records are saved in Cloudflare but not resolving, confirm that your domain registrar is pointing to Cloudflare's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include the two Cloudflare nameservers assigned to your domain (e.g. `anna.ns.cloudflare.com`, `bob.ns.cloudflare.com`). These are displayed on the domain overview page in the Cloudflare dashboard. If the output shows a different provider's nameservers, update them at your domain registrar.
If you are adding a CNAME record at the root of your domain (e.g. `company.com` instead of `mailing.company.com`), Cloudflare will automatically apply CNAME flattening. This resolves the CNAME to an A record, which can cause verification to fail. Use a subdomain for your sending domain to avoid this issue.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org), proxy mode is disabled for all CNAME records, and verification still fails after 48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
How automatic DNS setup works under the hood.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# DigitalOcean
Source: https://docs.lettr.com/knowledge-base/dns-guides/digitalocean
Add the DNS records Lettr needs in the DigitalOcean control panel to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using DigitalOcean's DNS management. DigitalOcean is a cloud infrastructure provider that offers DNS hosting as part of its platform, managed through the [DigitalOcean Control Panel](https://cloud.digitalocean.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list. This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure DigitalOcean DNS
Log in to the [DigitalOcean Control Panel](https://cloud.digitalocean.com) and navigate to **Networking** → **Domains**. Select the domain you want to configure.
If your domain was purchased through DigitalOcean or your nameservers already point to DigitalOcean, skip nameserver
configuration entirely. Your domain is already using DigitalOcean's nameservers by default — proceed directly to
adding the DNS records below.
If you registered your domain elsewhere but want to manage DNS on DigitalOcean, you must first add the domain to
DigitalOcean and then **update the nameservers** at your registrar to DigitalOcean's nameservers. More information
in [DigitalOcean docs](https://docs.digitalocean.com/products/networking/dns/getting-started/dns-registrars/).
Until the nameservers are updated, any records you add in DigitalOcean will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to DigitalOcean:
1. Click **Create a record** in the domain's DNS settings.
2. Select **CNAME** from the record type dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Hostname** field in DigitalOcean (without your domain suffix). For example, paste only `mailing`.
4. Copy the **Value** from Lettr and paste it into the **Is an alias of** field in DigitalOcean.
5. Leave **TTL** to **43200** (default).
6. Click **Create Record**.
DigitalOcean automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`).
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to DigitalOcean:
1. Click **Create a record** in the domain's DNS settings.
2. Select **TXT** from the record type dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Hostname** field in DigitalOcean (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
4. Copy the **Value** from Lettr and paste it into the **TXT Value** field in DigitalOcean.
5. Leave **TTL** at the default (43200).
6. Click **Create Record**.
DigitalOcean automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to DigitalOcean:
1. Click **Create a record** in the domain's DNS settings.
2. Select **TXT** from the record type dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Hostname** field in DigitalOcean (without your domain suffix). For example, paste only `_dmarc.mailing`.
4. Copy the **Value** from Lettr and paste it into the **TXT Value** field in DigitalOcean.
5. Leave **TTL** at the default (43200).
6. Click **Create Record**.
DigitalOcean automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list. This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to DigitalOcean:
1. Click **Create a record** in the domain's DNS settings.
2. Select **MX** from the record type dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Hostname** field in DigitalOcean (without your domain suffix). For example, paste only `inbound`.
4. Copy the first **Required MX Record** value (without the priority number) from Lettr and paste it into the **Mail providers mail server** field in DigitalOcean.
5. Set **Priority** to `10`.
6. Leave **TTL** on 14400 (default).
7. Click **Create Record**.
8. Repeat this process for the second (`rx2.sparkpostmail.com`) and third (`rx3.sparkpostmail.com`) MX records.
DigitalOcean automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`inbound`, not `inbound.company.com`).
Adding MX records to a domain or subdomain will route all incoming email for that address to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list. This will display the CNAME records that need to be configured.
### Add CNAME Record (SSL Certificate)
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in DigitalOcean:
1. Click **Create a record** in the domain's DNS settings.
2. Select **CNAME** from the record type dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Hostname** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Is an alias of** field.
5. Leave **TTL** at the default (43200).
6. Click **Create Record**.
DigitalOcean automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Add CNAME Record (Traffic)
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in DigitalOcean:
1. Click **Create a record** in the domain's DNS settings.
2. Select **CNAME** from the record type dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Hostname** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Is an alias of** field.
5. Leave **TTL** at the default (43200).
6. Click **Create Record**.
DigitalOcean automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in DigitalOcean:
1. Click **Create a record** in the domain's DNS settings.
2. Select **TXT** from the record type dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Hostname** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **TXT Value** field.
5. Leave **TTL** at the default (3600).
6. Click **Create Record**.
DigitalOcean automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in DigitalOcean:
1. Click **Create a record** in the domain's DNS settings.
2. Select **TXT** from the record type dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Hostname** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **TXT Value** field.
5. Leave **TTL** at the default (3600).
6. Click **Create Record**.
DigitalOcean automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in DigitalOcean:
1. Click **Create a record** in the domain's DNS settings.
2. Select **CNAME** from the record type dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Hostname** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Is an alias of** field.
5. Leave **TTL** at the default (43200).
6. Click **Create Record**.
DigitalOcean automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Troubleshooting
DNS propagation on DigitalOcean typically takes 5–30 minutes, but can occasionally take longer. If verification fails
after adding records, check the following:
* **Wait at least 30 minutes** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
DigitalOcean does not allow CNAME records at the root of a domain (e.g. `company.com`). You must use a subdomain for
your sending domain (e.g. `mailing.company.com`). This is also a DNS protocol limitation — CNAME records cannot coexist
with other record types at the same name.
A common mistake is selecting the wrong type in the record type dropdown:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
DigitalOcean supports multiple TXT records on the same hostname. Add each record separately (e.g. SPF and DKIM
records can coexist on related hostnames without conflict).
The DKIM TXT value is a long string. After saving the record, click **Edit** to confirm the full value was stored. If
it appears truncated, delete the record and re-add it, pasting the full value carefully.
If your records are saved in DigitalOcean but not resolving, confirm that your domain registrar is pointing to
DigitalOcean's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include DigitalOcean nameservers (e.g. `ns1.digitalocean.com`, `ns2.digitalocean.com`,
`ns3.digitalocean.com`). If it shows a different provider's nameservers, update them at your domain registrar.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after
48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the
output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# DreamHost
Source: https://docs.lettr.com/knowledge-base/dns-guides/dreamhost
Add the DNS records Lettr needs in the DreamHost panel to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using DreamHost's DNS management. DreamHost is a web hosting provider that offers DNS hosting for domains registered or managed through its [DreamHost Panel](https://panel.dreamhost.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list. This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure DreamHost DNS
Log in to the [DreamHost Panel](https://panel.dreamhost.com) and navigate to **Websites** → **Manage Websites**. Find your domain and click the **⋮** (three-dot) button to the right of it, then select **DNS Settings** from the menu.
If your domain was registered through DreamHost or your nameservers already point to DreamHost, skip nameserver
configuration entirely — proceed directly to adding the DNS records below.
If you registered your domain elsewhere but want to manage DNS on DreamHost, you must first add the domain to your
DreamHost account (set to **DNS Only** mode) and then **update the nameservers** at your registrar to DreamHost's
nameservers:
```
ns1.dreamhost.com
ns2.dreamhost.com
ns3.dreamhost.com
```
Until the nameservers are updated at your registrar, any records you add in DreamHost will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to DreamHost:
1. Click **Add Record** on the DNS Settings page.
2. Select **CNAME** as the record type.
3. Set **Host** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `mailing`.
4. Set **Points to** to the **Value** from Lettr.
5. Click **Add Record**.
DreamHost automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`). DreamHost does not expose a TTL field — it defaults to 5 minutes internally.
Do not add a CNAME record at the root of your domain (e.g. `company.com`). DreamHost does not support CNAME records
at the root, and attempting to do so will produce an error. Always use a subdomain for your sending domain.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to DreamHost:
1. Click **Add Record** on the DNS Settings page.
2. Select **TXT** as the record type.
3. Set **Host** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
4. Set **TXT Value** to the **Value** from Lettr.
5. Click **Add Record**.
DreamHost automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to DreamHost:
1. Click **Add Record** on the DNS Settings page.
2. Select **TXT** as the record type.
3. Set **Host** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `_dmarc.mailing`.
4. Set **TXT Value** to the **Value** from Lettr.
5. Click **Add Record**.
DreamHost automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation typically completes within a few hours on DreamHost, though it can take up to 48 hours for external resolvers to pick up the changes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list. This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to DreamHost:
1. Click **Add Record** on the DNS Settings page.
2. Select **MX** as the record type.
3. Set **Host** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `inbound`.
4. Set **Points to** to `rx1.sparkpostmail.com`.
5. Set **Priority** to `10`.
6. Click **Add Record**.
7. Repeat this process for the second (`rx2.sparkpostmail.com`) and third (`rx3.sparkpostmail.com`) MX records, each with priority `10`.
DreamHost automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`inbound`, not `inbound.company.com`). Do not add a trailing period to the MX values — DreamHost handles this automatically.
Adding MX records to a subdomain will route all incoming email for that address to Lettr. Use a dedicated subdomain
(e.g. `inbound.company.com`) to avoid interfering with DreamHost's own email services or your existing mail setup.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation typically completes within a few hours, though it can take up to 48 hours for external resolvers.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list. This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in DreamHost:
1. Click **Add Record** on the DNS Settings page.
2. Select **CNAME** as the record type.
3. Set **Host** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Points to** to the **Value** from Lettr.
5. Click **Add Record**.
DreamHost automatically appends your domain to the Host field. Always paste only the subdomain portion.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in DreamHost:
1. Click **Add Record** on the DNS Settings page.
2. Select **CNAME** as the record type.
3. Set **Host** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Points to** to the **Value** from Lettr.
5. Click **Add Record**.
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list. This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in DreamHost:
1. Click **Add Record** on the DNS Settings page.
2. Select **TXT** as the record type.
3. Set **Host** to the **Hostname** from Lettr (without your domain suffix).
4. Set **TXT Value** to the **Value** from Lettr.
5. Click **Add Record**.
DreamHost automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in DreamHost:
1. Click **Add Record** on the DNS Settings page.
2. Select **TXT** as the record type.
3. Set **Host** to the **Hostname** from Lettr (without your domain suffix).
4. Set **TXT Value** to the **Value** from Lettr.
5. Click **Add Record**.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in DreamHost:
1. Click **Add Record** on the DNS Settings page.
2. Select **CNAME** as the record type.
3. Set **Host** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Points to** to the **Value** from Lettr.
5. Click **Add Record**.
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
DreamHost automatically appends your domain to the **Host** field. If you paste the full hostname (e.g.
`mailing.company.com`), the resulting record will resolve as `mailing.company.com.company.com`, which will fail
verification.
Always paste only the subdomain portion:
* Sending CNAME: `mailing`
* DKIM: `scph0126._domainkey.mailing`
* DMARC: `_dmarc.mailing`
* Inbound: `inbound`
DreamHost DNS changes are applied quickly within their own infrastructure (default TTL is 5 minutes), but external
resolvers that have already cached a record will hold their own TTL before refreshing. Propagation typically completes
within a few hours but can take up to 48 hours.
If verification fails after adding records, check the following:
* **Wait at least 1–2 hours** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
If your records are saved in DreamHost but not resolving, confirm that your domain registrar is pointing to
DreamHost's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include DreamHost's nameservers:
```
ns1.dreamhost.com
ns2.dreamhost.com
ns3.dreamhost.com
```
If it shows a different provider's nameservers, update them at your domain registrar. Nameserver changes can take
4–72 hours to propagate globally.
DreamHost does not support CNAME records at the root of a domain (e.g. `company.com`). You must use a subdomain for
your sending, tracking, and storage domains. This is also a DNS protocol constraint — CNAME records cannot coexist
with any other record type at the same name.
If DreamHost shows a conflict error when adding a CNAME, check whether an existing A record or another CNAME is
already present for that subdomain and remove it first.
A common mistake is selecting the wrong record type when clicking **Add Record**:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. After saving the record, navigate back to the DNS Settings page for your domain
and locate the record to confirm the full value was stored. If it appears truncated, delete the record and re-add it,
pasting the complete value from Lettr. DreamHost's DNS panel handles long TXT values without chunking — paste the
value as a single string.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails
after 48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name
and the output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Dynadot
Source: https://docs.lettr.com/knowledge-base/dns-guides/dynadot
Add the DNS records Lettr needs in your Dynadot account to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using Dynadot's DNS management. Dynadot is a domain registrar that offers DNS hosting for domains registered through its [Dynadot account](https://www.dynadot.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list. This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Dynadot DNS
Log in to your [Dynadot account](https://www.dynadot.com) and navigate to **My Domains** → **Manage Domains**. Check the box next to your domain, click the **Action** button above the domain list, and select **DNS Settings** from the dropdown. On the DNS settings page, select **Dynadot DNS** from the top dropdown menu if it is not already selected.
If your domain was registered through Dynadot or your nameservers already point to Dynadot (`ns1.dyna-ns.net` and
`ns2.dyna-ns.net`), skip nameserver configuration entirely — proceed directly to adding the DNS records below.
If you registered your domain elsewhere but want to manage DNS on Dynadot, you must first **update the nameservers**
at your registrar to Dynadot's nameservers:
```
ns1.dyna-ns.net
ns2.dyna-ns.net
```
Until the nameservers are updated at your registrar, any records you add in Dynadot will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Dynadot:
1. On the DNS Settings page, scroll down to the **Subdomain Records (optional)** section.
2. In an empty row, enter the **Hostname** from Lettr into the **Subdomain** field (without your domain suffix). For example, paste only `mailing`.
3. Set the **Record Type** dropdown to **CNAME**.
4. Paste the **Value** from Lettr into the **IP Address or Target Host** field.
5. Click **Save DNS**.
Dynadot automatically appends your domain to the Subdomain field. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`).
Do not add a CNAME record at the root of your domain (e.g. `company.com`). Like all standard DNS providers, Dynadot
does not support CNAME records at the root because they conflict with the NS and SOA records required for DNS to
function. Always use a subdomain for your sending, tracking, and storage domains.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Dynadot:
1. On the DNS Settings page, scroll down to the **Subdomain Records (optional)** section.
2. In an empty row, enter the **Hostname** from Lettr into the **Subdomain** field (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
3. Set the **Record Type** dropdown to **TXT**.
4. Paste the **Value** from Lettr into the **IP Address or Target Host** field.
5. Click **Save DNS**.
Dynadot automatically appends your domain to the Subdomain field. Always paste only the subdomain portion (e.g.
`scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Dynadot:
1. On the DNS Settings page, scroll down to the **Subdomain Records (optional)** section.
2. In an empty row, enter the **Hostname** from Lettr into the **Subdomain** field (without your domain suffix). For example, paste only `_dmarc.mailing`.
3. Set the **Record Type** dropdown to **TXT**.
4. Paste the **Value** from Lettr into the **IP Address or Target Host** field.
5. Click **Save DNS**.
Dynadot automatically appends your domain to the Subdomain field. Always paste only the subdomain portion (e.g.
`_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS changes on Dynadot propagate in as little as 5 minutes, though it can take up to 48 hours for external resolvers to pick up the changes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list. This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Dynadot:
1. On the DNS Settings page, scroll down to the **Subdomain Records (optional)** section.
2. In an empty row, enter the **Hostname** from Lettr into the **Subdomain** field (without your domain suffix). For example, paste only `inbound`.
3. Set the **Record Type** dropdown to **MX**.
4. Enter `rx1.sparkpostmail.com` into the **IP Address or Target Host** field.
5. Set the **Distance** field to `10`. (Dynadot uses "Distance" instead of "Priority" — they are equivalent.)
6. Click **Save DNS**.
7. Repeat this process for the second (`rx2.sparkpostmail.com`) and third (`rx3.sparkpostmail.com`) MX records, each with Distance `10`.
Dynadot labels the MX priority field **Distance** rather than **Priority**. Set it to `10` for all three records, as
Lettr's MX records are equal-priority. Do not add a trailing period to the MX values — Dynadot handles this
automatically.
Adding MX records to a domain or subdomain will route all incoming email for that address to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS changes on Dynadot propagate in as little as 5 minutes, though it can take up to 48 hours for external resolvers.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list. This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Dynadot:
1. On the DNS Settings page, scroll down to the **Subdomain Records (optional)** section.
2. In an empty row, enter the **Hostname** from Lettr into the **Subdomain** field (without your domain suffix).
3. Set the **Record Type** dropdown to **CNAME**.
4. Paste the **Value** from Lettr into the **IP Address or Target Host** field.
5. Click **Save DNS**.
Dynadot automatically appends your domain to the Subdomain field. Always paste only the subdomain portion.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Dynadot:
1. On the DNS Settings page, scroll down to the **Subdomain Records (optional)** section.
2. In an empty row, enter the **Hostname** from Lettr into the **Subdomain** field (without your domain suffix).
3. Set the **Record Type** dropdown to **CNAME**.
4. Paste the **Value** from Lettr into the **IP Address or Target Host** field.
5. Click **Save DNS**.
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list. This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Dynadot:
1. On the DNS Settings page, scroll down to the **Subdomain Records (optional)** section.
2. In an empty row, enter the **Hostname** from Lettr into the **Subdomain** field (without your domain suffix).
3. Set the **Record Type** dropdown to **TXT**.
4. Paste the **Value** from Lettr into the **IP Address or Target Host** field.
5. Click **Save DNS**.
Dynadot automatically appends your domain to the Subdomain field. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Dynadot:
1. On the DNS Settings page, scroll down to the **Subdomain Records (optional)** section.
2. In an empty row, enter the **Hostname** from Lettr into the **Subdomain** field (without your domain suffix).
3. Set the **Record Type** dropdown to **TXT**.
4. Paste the **Value** from Lettr into the **IP Address or Target Host** field.
5. Click **Save DNS**.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Dynadot:
1. On the DNS Settings page, scroll down to the **Subdomain Records (optional)** section.
2. In an empty row, enter the **Hostname** from Lettr into the **Subdomain** field (without your domain suffix).
3. Set the **Record Type** dropdown to **CNAME**.
4. Paste the **Value** from Lettr into the **IP Address or Target Host** field.
5. Click **Save DNS**.
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Dynadot automatically appends your domain to the **Subdomain** field. If you paste the full hostname (e.g.
`mailing.company.com`), the resulting record will resolve as `mailing.company.com.company.com`, which will fail
verification.
Always paste only the subdomain portion:
* Sending CNAME: `mailing`
* DKIM: `scph0126._domainkey.mailing`
* DMARC: `_dmarc.mailing`
* Inbound: `inbound`
Dynadot's default TTL is 300 seconds (5 minutes). Changes typically propagate within minutes on Dynadot's own
nameservers, but external resolvers that have already cached a record will hold their own TTL before refreshing.
Propagation can take up to 48 hours globally.
If verification fails after adding records, check the following:
* **Wait at least 15–30 minutes** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
If your records are saved in Dynadot but not resolving, confirm that your domain is using Dynadot's nameservers. You
can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include Dynadot's nameservers:
```
ns1.dyna-ns.net
ns2.dyna-ns.net
```
If it shows a different provider's nameservers, update them at your domain registrar. Nameserver changes can take
4–72 hours to propagate globally.
A common mistake in Dynadot is either selecting the wrong **Record Type** in the dropdown or entering a record in
the **Domain Record** section (intended for root-level records) instead of the **Subdomain Records** section.
All Lettr records should be entered in the **Subdomain Records (optional)** section using these types:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string (256+ characters). After clicking **Save DNS**, navigate back to the DNS Settings
page and confirm the full value is stored in the **IP Address or Target Host** field. If it appears truncated, delete
the record and re-add it, pasting the complete value from Lettr in one operation. Dynadot's DNS interface does not
impose a UI character limit beyond the DNS protocol standard, so paste the value as a single unbroken string.
Dynadot labels the MX priority field **Distance** instead of the more common term **Priority**. These are
equivalent — set **Distance** to `10` for all three Lettr MX records. Using equal distance values (10/10/10) allows
mail servers to distribute load evenly across all three Lettr inbound servers.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails
after 48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name
and the output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Gandi DNS Setup
Source: https://docs.lettr.com/knowledge-base/dns-guides/gandi
Add the DNS records Lettr needs in the Gandi LiveDNS interface to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using Gandi's DNS management. Gandi is a domain registrar that offers DNS hosting through its [LiveDNS interface](https://admin.gandi.net).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list. This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Gandi DNS
Log in to your [Gandi account](https://admin.gandi.net) and click **Domain** in the left sidebar. Select the domain you want to configure, then click the **DNS Records** tab at the top of the domain settings page.
If your domain was registered through Gandi or your nameservers already point to Gandi LiveDNS, skip nameserver
configuration entirely — proceed directly to adding the DNS records below.
If you registered your domain elsewhere but want to manage DNS on Gandi, you must first **update the nameservers**
at your registrar to Gandi's LiveDNS nameservers. Gandi assigns unique LiveDNS nameservers per domain in the format
`ns-{numbers}-{letters}.gandi.net`. You can find your domain's specific nameservers under the **Nameservers** tab
in your Gandi domain settings.
Until the nameservers are updated at your registrar, any records you add in Gandi will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Gandi:
1. Click the green **Add** button above the DNS records table.
2. Set **Type** to **CNAME**.
3. Set **Name** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `mailing`.
4. Set **Hostname** to the **Value** from Lettr, ensuring it ends with a trailing period (e.g. `sparkpostmail.com.`).
5. Leave **TTL** at the default (**10800**).
6. Click **Create**.
Gandi requires a trailing period on CNAME target values. When pasting the value from Lettr into the **Hostname**
field, ensure it ends with a period (e.g. `sparkpostmail.com.`). Without it, Gandi will append your domain to the
target, producing an incorrect address.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Gandi:
1. Click the green **Add** button above the DNS records table.
2. Set **Type** to **TXT**.
3. Set **Name** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
4. Set **Text Value** to the **Value** from Lettr.
5. Leave **TTL** at the default (**10800**).
6. Click **Create**.
The DKIM value is a long string that may exceed 255 characters. Gandi's interface accepts the value as a single
string for standard records. If the interface requires chunking for very long values, split the value into 255-character
segments and wrap each in double quotes adjacent to one another: `"first255chars""next255chars"`.
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Gandi:
1. Click the green **Add** button above the DNS records table.
2. Set **Type** to **TXT**.
3. Set **Name** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `_dmarc.mailing`.
4. Set **Text Value** to the **Value** from Lettr (e.g. `v=DMARC1; p=none;`).
5. Leave **TTL** at the default (**10800**).
6. Click **Create**.
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few hours with Gandi LiveDNS.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list. This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Gandi:
1. Click the green **Add** button above the DNS records table.
2. Set **Type** to **MX**.
3. Set **Name** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `inbound`.
4. Set **Hostname** to `rx1.sparkpostmail.com.` (with a trailing period).
5. Set **Priority** to `10`.
6. Leave **TTL** at the default (**10800**).
7. Click **Create**.
8. Repeat this process for the second (`rx2.sparkpostmail.com.`) and third (`rx3.sparkpostmail.com.`) MX records, each with priority `10`.
Gandi requires a trailing period on MX target hostnames. Enter each mail server address with a trailing period
(e.g. `rx1.sparkpostmail.com.`) to ensure the record resolves correctly.
Adding MX records to a domain or subdomain will route all incoming email for that address to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few hours.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list. This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Gandi:
1. Click the green **Add** button above the DNS records table.
2. Set **Type** to **CNAME**.
3. Set **Name** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Hostname** to the **Value** from Lettr, ensuring it ends with a trailing period.
5. Leave **TTL** at the default (**10800**).
6. Click **Create**.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Gandi:
1. Click the green **Add** button above the DNS records table.
2. Set **Type** to **CNAME**.
3. Set **Name** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Hostname** to the **Value** from Lettr, ensuring it ends with a trailing period.
5. Leave **TTL** at the default (**10800**).
6. Click **Create**.
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list. This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Gandi:
1. Click the green **Add** button above the DNS records table.
2. Set **Type** to **TXT**.
3. Set **Name** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Text Value** to the **Value** from Lettr.
5. Leave **TTL** at the default (**10800**).
6. Click **Create**.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Gandi:
1. Click the green **Add** button above the DNS records table.
2. Set **Type** to **TXT**.
3. Set **Name** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Text Value** to the **Value** from Lettr.
5. Leave **TTL** at the default (**10800**).
6. Click **Create**.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Gandi:
1. Click the green **Add** button above the DNS records table.
2. Set **Type** to **CNAME**.
3. Set **Name** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Hostname** to the **Value** from Lettr, ensuring it ends with a trailing period.
5. Leave **TTL** at the default (**10800**).
6. Click **Create**.
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
The most common mistake when adding records in Gandi is omitting the trailing period from CNAME and MX target
values. Without it, Gandi appends your domain name to the target, resulting in an incorrect address (e.g.
`sparkpostmail.com.company.com` instead of `sparkpostmail.com`).
Always ensure the **Hostname** field for CNAME and MX records ends with a period:
* Sending verification CNAME: `sparkpostmail.com.`
* Inbound MX records: `rx1.sparkpostmail.com.`, `rx2.sparkpostmail.com.`, `rx3.sparkpostmail.com.`
* Tracking and storage CNAME targets: append `.` to the end of the value from Lettr
To fix an existing record, click the **pencil icon** to the right of the record, correct the **Hostname** field,
and click **Update**.
Gandi LiveDNS applies changes within milliseconds to its own servers, but external resolvers that have cached
previous records can take longer to refresh. Propagation typically completes within a few hours but can take up
to 72 hours in some regions.
If verification fails after adding records, check the following:
* **Wait at least 1–2 hours** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [WhatsMyDNS](https://www.whatsmydns.net) or [dnschecker.org](https://dnschecker.org)
to verify propagation across multiple DNS servers worldwide.
If your records are saved in Gandi but not resolving, confirm that your domain registrar is pointing to Gandi's
LiveDNS nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include Gandi's LiveDNS nameservers (in the format `ns-{numbers}-{letters}.gandi.net`). You
can find your domain's exact assigned nameservers under the **Nameservers** tab in your Gandi domain settings.
If the output shows a different provider's nameservers, update them at your domain registrar. Nameserver changes
can take 4–72 hours to propagate globally.
Gandi does not support CNAME records at the apex of a domain (e.g. `company.com`). The **Name** field does not
accept `@` for CNAME records — only subdomains work. This is a DNS protocol constraint: CNAME records cannot
coexist with other record types (like SOA or NS) that are required at the root.
Always use a subdomain for your sending, tracking, and storage domains (e.g. `mailing.company.com`). If you need
to point your bare domain to another hostname, Gandi offers an **ALIAS** record type for that purpose.
If Gandi shows a conflict error when adding a CNAME, check whether an existing A or CNAME record is already
present for that subdomain and remove it first.
A common mistake is selecting the wrong type from the **Type** dropdown when clicking **Add**:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string that often exceeds 255 characters. After saving the record, click the
**pencil icon** to re-open it and confirm the full value was stored. If it appears truncated, delete the record
and re-add it.
If Gandi's interface requires chunking for values longer than 255 characters, split the DKIM value into
255-character segments and wrap each in double quotes directly adjacent: `"first255chars""next255chars"`. Paste
this combined string into the **Text Value** field.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still
fails after 48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your
domain name and the output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# GoDaddy
Source: https://docs.lettr.com/knowledge-base/dns-guides/godaddy
Add the DNS records Lettr needs in your GoDaddy account to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using GoDaddy's DNS management. GoDaddy is a domain registrar and web hosting provider that offers DNS management through its account dashboard at [dcc.godaddy.com](https://dcc.godaddy.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure GoDaddy DNS
Log in to your [GoDaddy account](https://dcc.godaddy.com), make sure the **DNS** in the left-hand menu is selected, and select the domain for which you want to manage DNS records from the dropdown. Scroll down for DNS management.
If your domain was purchased through GoDaddy or your nameservers already point to GoDaddy, skip nameserver
configuration entirely. Your domain is already using GoDaddy's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on GoDaddy, you must first transfer the domain to GoDaddy. Select **Transfer** in the left-hand menu and follow the instructions.
Then, select DNS in the left-hand menu, select your domain, and **update the nameservers**
at your registrar to GoDaddy's nameservers shown in the domain configuration.
Until the nameservers are updated, any records you add in GoDaddy will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to GoDaddy:
1. Click **Add New Record** on the DNS Management page.
2. Select **CNAME** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in GoDaddy.
4. Copy the **Value** from Lettr and paste it into the **Value** field in GoDaddy.
5. Leave **TTL** set to the default (typically 1 Hour).
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into GoDaddy. For example, instead of `mailing.lettr-demo.com`, paste only `mailing`. GoDaddy automatically appends your domain to the record name.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to GoDaddy:
1. Click **Add New Record** on the DNS Management page.
2. Select **TXT** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in GoDaddy.
4. Copy the **Value** from Lettr and paste it into the **Value** field in GoDaddy.
5. Leave **TTL** set to the default.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into GoDaddy. For example, instead of `scph0126._domainkey.mailing.lettr-demo.com`, paste only `scph0126._domainkey.mailing`.
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to GoDaddy:
1. Click **Add New Record** on the DNS Management page.
2. Select **TXT** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in GoDaddy.
4. Copy the **Value** from Lettr and paste it into the **Value** field in GoDaddy.
5. Leave **TTL** set to the default.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into GoDaddy. For example, instead of `_dmarc.mailing.lettr-demo.com`, paste only `_dmarc.mailing`.
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to GoDaddy:
1. Click **Add New Record** on the DNS Management page.
2. Select **MX** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in GoDaddy.
4. Copy the **Priority** number (e.g. `10`) from Lettr and paste it into the **Priority** field in GoDaddy.
5. Copy the first **Required MX Record** value (without the priority number) from Lettr and paste it into the **Value** field in GoDaddy.
6. Leave **TTL** set to the default.
7. Click **Save**.
8. Repeat this process for the second (rx2.sparkpostmail.com) and third (rx3.sparkpostmail.com) MX records.
GoDaddy may have default MX records (e.g. pointing to GoDaddy's own mail servers). If you are not using GoDaddy email, delete or update these existing MX records before adding the Lettr MX records to avoid mail delivery conflicts.
Omit your domain suffix from the Hostname when pasting into GoDaddy. For example, instead of `inbound.lettr-demo.com`, paste only `inbound`.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in GoDaddy:
1. Click **Add New Record** on the DNS Management page.
2. Select **CNAME** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in GoDaddy.
4. Copy the **Value** from Lettr and paste it into the **Value** field in GoDaddy.
5. Leave **TTL** set to the default.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into GoDaddy. For example, instead of `track.lettr-demo.com`, paste only `track`.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in GoDaddy:
1. Click **Add New Record** on the DNS Management page.
2. Select **CNAME** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in GoDaddy.
4. Copy the **Value** from Lettr and paste it into the **Value** field in GoDaddy.
5. Leave **TTL** set to the default.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into GoDaddy. For example, instead of `track.lettr-demo.com`, paste only `track`.
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in GoDaddy:
1. Click **Add New Record** on the DNS Management page.
2. Select **TXT** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in GoDaddy.
4. Copy the **Value** from Lettr and paste it into the **Value** field in GoDaddy.
5. Leave **TTL** set to the default.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into GoDaddy, just as with the CNAME record above.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in GoDaddy:
1. Click **Add New Record** on the DNS Management page.
2. Select **TXT** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in GoDaddy.
4. Copy the **Value** from Lettr and paste it into the **Value** field in GoDaddy.
5. Leave **TTL** set to the default.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into GoDaddy, just as with the CNAME record above.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in GoDaddy:
1. Click **Add New Record** on the DNS Management page.
2. Select **CNAME** from the **Type** dropdown.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field in GoDaddy.
4. Copy the **Value** from Lettr and paste it into the **Value** field in GoDaddy.
5. Leave **TTL** set to the default.
6. Click **Save**.
Omit your domain suffix from the Hostname when pasting into GoDaddy. For example, instead of `assets.lettr-demo.com`, paste only `assets`.
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
GoDaddy automatically appends your domain to the record name. If you paste the full hostname (e.g. `mailing.lettr-demo.com`), the resulting record will be `mailing.lettr-demo.com.lettr-demo.com`, which will fail verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
GoDaddy often includes default MX records pointing to its own mail servers (e.g. `mailstore1.secureserver.net`). If these remain alongside the Lettr MX records, mail delivery may be unpredictable. If you are using a subdomain for inbound email (e.g. `inbound.company.com`), the default MX records on the root domain will not conflict. If you are using the root domain, delete the default GoDaddy MX records before adding the Lettr records.
GoDaddy has a 1024-character limit for individual TXT record values in some configurations. DKIM values can exceed this limit. If GoDaddy truncates the value or shows an error when saving, try the following:
* Split the value into two quoted strings separated by a space (e.g. `"first-half" "second-half"`). GoDaddy may concatenate them automatically.
* If splitting does not work, contact GoDaddy support to increase the TXT record value limit for your domain.
If GoDaddy truncates your DKIM TXT value, DKIM verification will fail. Always confirm the full value was saved by editing the record after creation.
If verification fails after adding records, check the following:
* **Wait at least 30 minutes** before your first verification attempt. Most records propagate within 1–2 hours.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
A common mistake is selecting the wrong type in GoDaddy's Type dropdown:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. After saving the record in GoDaddy, click the pencil icon to edit the record and confirm the full value was stored. If it appears truncated, see the TXT Record Character Limit section above.
If your domain has GoDaddy's domain forwarding or parking enabled, it may add extra DNS records (such as A records or CNAME records for `@`) that interfere with your Lettr configuration. Disable domain forwarding and parking in GoDaddy's domain settings before adding Lettr DNS records.
If your domain is registered with GoDaddy but you have previously changed the nameservers to another provider, your DNS records in GoDaddy will not resolve. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include GoDaddy nameservers (e.g. `ns51.domaincontrol.com`, `ns52.domaincontrol.com`). If it shows a different provider's nameservers, either update them back to GoDaddy or add the Lettr DNS records at your current DNS provider instead.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after 48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Google Cloud DNS
Source: https://docs.lettr.com/knowledge-base/dns-guides/google-cloud-dns
Add the DNS records Lettr needs in Google Cloud DNS to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using Google Cloud DNS. Google Cloud DNS is a fast, reliable, and cost-effective domain name system managed through the [Google Cloud Console](https://console.cloud.google.com).
This guide is for Google Cloud DNS. If you registered your domain through Google Domains (now part of Squarespace),
see the [Squarespace guide](/knowledge-base/dns-guides/squarespace) instead.
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
**Google Cloud DNS requires a trailing period (`.`) on all FQDN values** in the **Canonical name** and **Mail server**
fields. For example, enter `sparkpostmail.com.` not `sparkpostmail.com`. The **DNS name** field is different — you
enter only the subdomain label (e.g. `mailing`), and the console automatically appends the zone's domain and the
trailing period.
**TXT record values must be enclosed in double quotes** in Google Cloud DNS. Unlike most other DNS providers, Google
Cloud DNS does not add quotes automatically. Always wrap the value in double quotes when entering it into the
**TXT data** field (e.g. `"v=DMARC1;p=none;"`).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list. This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Google Cloud DNS
Log in to the [Google Cloud Console](https://console.cloud.google.com) and navigate to **Network Services** → **Cloud DNS** in the left-hand menu. Click the name of the managed zone that corresponds to your domain to open the zone details page.
If your domain was registered through Google Cloud Domains or your nameservers already point to Google Cloud DNS,
skip nameserver configuration entirely. Your domain is already using Google Cloud DNS's nameservers by default —
proceed directly to adding the DNS records below.
If you registered your domain elsewhere but want to manage DNS on Google Cloud DNS, you must first create a managed
public zone in Google Cloud DNS and then **update the nameservers** at your registrar to the four nameservers
assigned to your managed zone.
To find your zone's nameservers, open the zone details page in Cloud DNS. The four nameservers are listed in the
**NS record** at the top of the records list. They follow the format:
```
ns-cloud-a1.googledomains.com
ns-cloud-a2.googledomains.com
ns-cloud-a3.googledomains.com
ns-cloud-a4.googledomains.com
```
The shard letter (`a`–`e`) is randomly assigned per zone — copy the exact values shown in your zone, not the
example above.
Until all four nameservers are updated at your registrar, any records you add in Google Cloud DNS will not
resolve. Nameserver propagation can take up to 48 hours.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Google Cloud DNS:
1. Click **Add standard** on the zone details page.
2. Set **DNS name** to the **Hostname** from Lettr, omitting your domain suffix. For example, paste only `mailing`.
3. Set **Resource record type** to **CNAME**.
4. Set **TTL** to `300` and select **seconds** from the TTL unit dropdown.
5. Set **Canonical name** to the **Value** from Lettr, with a trailing period. For example, `sparkpostmail.com.`
6. Click **Create**.
Google Cloud DNS automatically appends your zone's domain and a trailing period to the **DNS name** field. Always
paste only the subdomain portion (e.g. `mailing`, not `mailing.company.com`). The **Canonical name** target,
however, requires a trailing period that you must add manually.
Do not add a CNAME record at the root of your domain (e.g. `company.com`). Google Cloud DNS does not support CNAME
records at the zone apex — the root already has required SOA and NS records, and a CNAME cannot coexist with any
other record type at the same name. Always use a subdomain for your sending domain.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Google Cloud DNS:
1. Click **Add standard** on the zone details page.
2. Set **DNS name** to the **Hostname** from Lettr, omitting your domain suffix. For example, paste only `scph0126._domainkey.mailing`.
3. Set **Resource record type** to **TXT**.
4. Set **TTL** to `300` and select **seconds** from the TTL unit dropdown.
5. Set **TXT data** to the **Value** from Lettr, enclosed in double quotes. For example, `"v=DKIM1;k=rsa;h=sha256;p=MIGfMA0..."`
6. Click **Create**.
Google Cloud DNS automatically appends your zone's domain to the **DNS name** field. Always paste only the subdomain
portion (e.g. `scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
**DKIM keys are longer than 255 characters.** Google Cloud DNS does NOT automatically split long TXT values — it
returns an "Invalid record data" error if you paste a single unquoted string over 255 characters. You must manually
split the value into 255-character segments, wrapping each segment in double quotes, and enter them as a single
string in the **TXT data** field:
```
"first255characters..." "remainingcharacters..."
```
Do not add separate **Add item** entries for each segment — all segments must be in one TXT data entry, separated by
a space. Google Cloud DNS concatenates the quoted strings automatically when the record is queried.
To split a DKIM key using the `gcloud` CLI, wrap the full value in single outer quotes and use double-quoted
segments:
```bash theme={null}
gcloud dns record-sets create scph0126._domainkey.mailing.example.com. \
--zone="my-zone" \
--type="TXT" \
--ttl="300" \
--rrdatas='"v=DKIM1;k=rsa;h=sha256;p=first255chars..." "remainingchars..."'
```
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Google Cloud DNS:
1. Click **Add standard** on the zone details page.
2. Set **DNS name** to the **Hostname** from Lettr, omitting your domain suffix. For example, paste only `_dmarc.mailing`.
3. Set **Resource record type** to **TXT**.
4. Set **TTL** to `300` and select **seconds** from the TTL unit dropdown.
5. Set **TXT data** to the **Value** from Lettr, enclosed in double quotes. For example, `"v=DMARC1;p=none;"`
6. Click **Create**.
Google Cloud DNS automatically appends your zone's domain to the **DNS name** field. Always paste only the subdomain
portion (e.g. `_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. With the default 300-second TTL, record changes propagate globally within minutes. Click **Verify DNS Records** in Lettr once propagation is complete.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list. This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Google Cloud DNS:
1. Click **Add standard** on the zone details page.
2. Set **DNS name** to the **Hostname** from Lettr, omitting your domain suffix. For example, paste only `inbound`.
3. Set **Resource record type** to **MX**.
4. Set **TTL** to `300` and select **seconds** from the TTL unit dropdown.
5. In the first **Priority** field, enter `10`. In the adjacent **Mail server** field, enter `rx1.sparkpostmail.com.` (with trailing period).
6. Click **Add item** to add a second row. Enter priority `10` and mail server `rx2.sparkpostmail.com.`
7. Click **Add item** again for a third row. Enter priority `10` and mail server `rx3.sparkpostmail.com.`
8. Click **Create**.
Google Cloud DNS automatically appends your zone's domain to the **DNS name** field. Always paste only the subdomain
portion (e.g. `inbound`, not `inbound.company.com`). The **Mail server** values require a trailing period — add it
manually (e.g. `rx1.sparkpostmail.com.`).
Adding MX records to a domain or subdomain will route all incoming email for that address to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. With the default 300-second TTL, changes propagate within minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list. This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Google Cloud DNS:
1. Click **Add standard** on the zone details page.
2. Set **DNS name** to the **Hostname** from Lettr, omitting your domain suffix.
3. Set **Resource record type** to **CNAME**.
4. Set **TTL** to `300` and select **seconds** from the TTL unit dropdown.
5. Set **Canonical name** to the **Value** from Lettr, with a trailing period.
6. Click **Create**.
Google Cloud DNS automatically appends your zone's domain to the **DNS name** field. Always paste only the subdomain
portion. The **Canonical name** requires a trailing period — add it manually.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Google Cloud DNS:
1. Click **Add standard** on the zone details page.
2. Set **DNS name** to the **Hostname** from Lettr, omitting your domain suffix.
3. Set **Resource record type** to **CNAME**.
4. Set **TTL** to `300` and select **seconds** from the TTL unit dropdown.
5. Set **Canonical name** to the **Value** from Lettr, with a trailing period.
6. Click **Create**.
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list. This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Google Cloud DNS:
1. Click **Add standard** on the zone details page.
2. Set **DNS name** to the **Hostname** from Lettr, omitting your domain suffix.
3. Set **Resource record type** to **TXT**.
4. Set **TTL** to `300` and select **seconds** from the TTL unit dropdown.
5. Set **TXT data** to the **Value** from Lettr, enclosed in double quotes.
6. Click **Create**.
Google Cloud DNS automatically appends your zone's domain to the **DNS name** field. Always paste only the subdomain
portion (e.g. `assets`, not `assets.company.com`). Remember to wrap the value in double quotes.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Google Cloud DNS:
1. Click **Add standard** on the zone details page.
2. Set **DNS name** to the **Hostname** from Lettr, omitting your domain suffix.
3. Set **Resource record type** to **TXT**.
4. Set **TTL** to `300` and select **seconds** from the TTL unit dropdown.
5. Set **TXT data** to the **Value** from Lettr, enclosed in double quotes.
6. Click **Create**.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Google Cloud DNS:
1. Click **Add standard** on the zone details page.
2. Set **DNS name** to the **Hostname** from Lettr, omitting your domain suffix.
3. Set **Resource record type** to **CNAME**.
4. Set **TTL** to `300` and select **seconds** from the TTL unit dropdown.
5. Set **Canonical name** to the **Value** from Lettr, with a trailing period.
6. Click **Create**.
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Using gcloud CLI
If you prefer the command line, you can add records using the `gcloud` CLI. Replace `my-zone` with your zone name and `example.com` with your domain.
CLI management requires the `roles/dns.admin` role on your Google Cloud project or zone. You can grant it in the
IAM section of the Google Cloud Console.
```bash theme={null}
# Add CNAME record for sending domain verification
gcloud dns record-sets create mailing.example.com. \
--zone="my-zone" \
--type="CNAME" \
--ttl="300" \
--rrdatas="sparkpostmail.com."
# Add TXT record for DKIM (split values at 255 characters)
gcloud dns record-sets create scph0126._domainkey.mailing.example.com. \
--zone="my-zone" \
--type="TXT" \
--ttl="300" \
--rrdatas='"v=DKIM1;k=rsa;h=sha256;p=first255chars..." "remainingchars..."'
# Add TXT record for DMARC
gcloud dns record-sets create _dmarc.mailing.example.com. \
--zone="my-zone" \
--type="TXT" \
--ttl="300" \
--rrdatas='"v=DMARC1;p=none;"'
# Add MX records for inbound (all three in one command)
gcloud dns record-sets create inbound.example.com. \
--zone="my-zone" \
--type="MX" \
--ttl="300" \
--rrdatas="10 rx1.sparkpostmail.com.","10 rx2.sparkpostmail.com.","10 rx3.sparkpostmail.com."
```
***
## Troubleshooting
Google Cloud DNS requires trailing periods on all FQDN values in the **Canonical name** and **Mail server** fields.
If a record resolves to the wrong hostname or fails verification, check that each target value ends with a period
(e.g. `sparkpostmail.com.` not `sparkpostmail.com`). Open the record set, click **Edit**, and add the trailing
period if it is missing.
The **DNS name** field is different — you enter only the subdomain label (e.g. `mailing`), and the console appends
the zone's domain and trailing period automatically. Do not add a trailing period there.
Google Cloud DNS requires TXT record values to be wrapped in double quotes. Unlike most DNS providers, it does not
add quotes automatically.
* Correct: `"v=DMARC1;p=none;"`
* Incorrect: `v=DMARC1;p=none;`
If you submitted the value without quotes, edit the record set and add double quotes around the value. If the
record is not resolving, run `dig TXT _dmarc.yourdomain.com +short` to confirm how the value is stored — a
correctly stored TXT record will include the quotes in the output.
DKIM public keys are typically 256+ characters long. Google Cloud DNS will return an "Invalid record data" error if
you paste the full key as a single unquoted string.
You must split the key into segments of 255 characters or fewer and wrap each segment in its own double quotes.
Enter all quoted segments as a single string in the **TXT data** field, separated by a space:
```
"first255characters..." "remainingcharacters..."
```
Do not use **Add item** to create separate entries for each segment — all segments must be in one entry. Google
Cloud DNS concatenates them automatically when the record is queried.
If you use the `gcloud` CLI:
```bash theme={null}
gcloud dns record-sets create scph0126._domainkey.mailing.example.com. \
--zone="my-zone" \
--type="TXT" \
--ttl="300" \
--rrdatas='"v=DKIM1;k=rsa;h=sha256;p=first255..." "remaining..."'
```
If your records are saved in Google Cloud DNS but not resolving, confirm that your domain registrar is pointing to
the nameservers assigned to your managed zone. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include the four nameservers shown in your zone's NS record (format:
`ns-cloud-{a–e}{1–4}.googledomains.com`). If it shows a different provider's nameservers, log in to your registrar
and update the nameservers to match the four shown in your Cloud DNS zone.
To find your zone's nameservers in the console, open the zone details page — the NS record at the top of the
records list contains all four nameservers for your zone. Nameserver changes can take up to 48 hours to propagate
globally.
Google Cloud DNS publishes changes within seconds to its global anycast network. With the default TTL of 300
seconds, record changes become visible to most resolvers within 5 minutes. However, resolvers that cached the
previous record will hold it for its full TTL before refreshing.
If verification fails after adding records:
* **Wait at least 10–15 minutes** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
* **Verify records in the CLI**: `gcloud dns record-sets list YOUR_ZONE_NAME` to confirm the records are saved correctly.
If nameservers were recently changed at your registrar, propagation can take up to 48 hours regardless of TTL.
If you cannot add or edit records in Google Cloud DNS, your Google account may lack the required permissions on the
project or zone.
To create, update, or delete DNS records, you need the **`roles/dns.admin`** role, which grants:
* `dns.resourceRecordSets.create`
* `dns.resourceRecordSets.update`
* `dns.resourceRecordSets.delete`
* `dns.changes.create`
Ask a project owner to grant you the **DNS Administrator** (`roles/dns.admin`) role in the IAM section of the
Google Cloud Console, scoped to either the project or the specific managed zone.
There is no separate `roles/dns.resourceRecordSetsEditor` predefined role — `roles/dns.admin` is the correct
predefined role for managing records.
Google Cloud DNS does not support CNAME records at the zone apex (the root domain, e.g. `company.com`). The zone
apex is required to hold SOA and NS records, and a CNAME cannot coexist with any other record type at the same
name. This is a DNS protocol constraint enforced by Google Cloud DNS.
Always use a subdomain for your sending, tracking, and storage domains (e.g. `mailing.company.com`,
`tracking.company.com`, `assets.company.com`). If you need a root-domain alias (pointing `company.com` to another
hostname), Google Cloud DNS supports an **ALIAS** record type at the apex for A/AAAA lookups only.
A common mistake is selecting the wrong record type in the **Resource record type** dropdown:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after
48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the
output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Hetzner
Source: https://docs.lettr.com/knowledge-base/dns-guides/hetzner
Add the DNS records Lettr needs in the Hetzner DNS Console to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using Hetzner's DNS Console. Hetzner is a European hosting provider that offers DNS management through its DNS Console at [dns.hetzner.com](https://dns.hetzner.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Hetzner DNS
Log in to your [Hetzner account](https://console.hetzner.com/projects) and select one of your projects. In your project dashboard, click on **DNS** in the left-hand menu and select the DNS Zone you want to configure.
This will open the domain details page, where you can manage your DNS records.
If your domain was purchased through Hetzner or your nameservers already point to Hetzner, skip nameserver
configuration entirely. Your domain is already using Hetzner's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on Hetzner, you must first **update the nameservers**
at your registrar to Hetzner's nameservers shown in the domain configuration.
Until the nameservers are updated, any records you add in Hetzner will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Hetzner:
1. Expand the **Type** dropdown in Hetzner and select **CNAME**.
2. Copy the **Hostname** from Lettr and paste it into the **Name** field in Hetzner.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Hetzner.
4. Leave **TTL** empty (Hetzner will default to 3600).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Hetzner. For example, instead of `mailing.lettr-demo.com`,
paste only `mailing`.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Hetzner:
1. Expand the **Type** dropdown in Hetzner and select **TXT**.
2. Copy the **Hostname** from Lettr and paste it into the **Name** field in Hetzner.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Hetzner.
4. Leave **TTL** empty (Hetzner will default to 3600).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Hetzner. For example, instead of
`scph0126._domainkey.mailing.lettr-demo.com`, paste only `scph0126._domainkey.mailing`.
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Hetzner:
1. Expand the **Type** dropdown in Hetzner and select **TXT**.
2. Copy the **Hostname** from Lettr and paste it into the **Name** field in Hetzner.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Hetzner.
4. Leave **TTL** empty (Hetzner will default to 3600).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Hetzner. For example, instead of
`_dmarc.mailing.lettr-demo.com`, paste only `_dmarc.mailing`.
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Hetzner:
1. Expand the **Type** dropdown in Hetzner and select **MX**.
2. Copy the **Hostname** from Lettr and paste it into the **Name** field in Hetzner.
3. Copy the **Priority** number (e.g. `10`) from Lettr and paste it into the **Priority** field in Hetzner.
4. Copy the **Required MX Record** value (without the priority number) from Lettr and paste it into the **Value** field in Hetzner.
5. Leave **TTL** empty (Hetzner will default to 3600).
6. Click **Add**.
7. Repeat this process for the second (rx2.sparkpostmail.com) and third (rx3.sparkpostmail.com) MX records.
Omit your domain suffix from the Hostname when pasting into Hetzner. For example, instead of `inbound.lettr-demo.com`,
paste only `inbound`.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Hetzner:
1. Expand the **Type** dropdown in Hetzner and select **CNAME**.
2. Copy the **Hostname** from Lettr and paste it into the **Name** field in Hetzner.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Hetzner.
4. Leave **TTL** empty (Hetzner will default to 3600).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Hetzner. For example, instead of `track.lettr-demo.com`,
paste only `track`.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Hetzner:
1. Expand the **Type** dropdown in Hetzner and select **CNAME**.
2. Copy the **Hostname** from Lettr and paste it into the **Name** field in Hetzner.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Hetzner.
4. Leave **TTL** empty (Hetzner will default to 3600).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Hetzner. For example, instead of `track.lettr-demo.com`,
paste only `track`.
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Hetzner:
1. Expand the **Type** dropdown in Hetzner and select **TXT**.
2. Copy the **Hostname** from Lettr and paste it into the **Name** field in Hetzner.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Hetzner.
4. Leave **TTL** empty (Hetzner will default to 3600).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Hetzner, just as with the CNAME record above.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Hetzner:
1. Expand the **Type** dropdown in Hetzner and select **TXT**.
2. Copy the **Hostname** from Lettr and paste it into the **Name** field in Hetzner.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Hetzner.
4. Leave **TTL** empty (Hetzner will default to 3600).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Hetzner, just as with the CNAME record above.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Hetzner:
1. Expand the **Type** dropdown in Hetzner and select **CNAME**.
2. Copy the **Hostname** from Lettr and paste it into the **Name** field in Hetzner.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Hetzner.
4. Leave **TTL** empty (Hetzner will default to 3600).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Hetzner. For example, instead of `assets.lettr-demo.com`,
paste only `assets`.
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Hetzner automatically appends your zone's domain to the record name. If you paste the full hostname (e.g. `mailing.lettr-demo.com`), the resulting record will be `mailing.lettr-demo.com.lettr-demo.com`, which will fail verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
If verification fails after adding records, check the following:
* **Wait at least 30 minutes** before your first verification attempt. Most records propagate within 1–2 hours.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
A common mistake is selecting the wrong type in Hetzner's record type selector:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
Hetzner may require a trailing period on MX values (e.g. `rx1.sparkpostmail.com.`). Try adding it if verification
fails.
The DKIM TXT value is a long string. After saving the record in Hetzner, re-open it to confirm the full value was stored. If it appears truncated, try pasting the value again. Hetzner's DNS Console supports long TXT values, but copying errors can occasionally cut off the string.
If your records are saved in Hetzner but not resolving, confirm that your domain registrar is pointing to Hetzner's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include Hetzner nameservers (e.g. `hydrogen.ns.hetzner.com`, `oxygen.ns.hetzner.com`, `helium.ns.hetzner.de`). If it shows a different provider's nameservers, update them at your domain registrar.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after 48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Hostinger
Source: https://docs.lettr.com/knowledge-base/dns-guides/hostinger
Add the DNS records Lettr needs in the Hostinger hPanel to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using Hostinger's DNS management. Hostinger is a web hosting provider that offers DNS hosting for domains managed through its [hPanel dashboard](https://hpanel.hostinger.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Hostinger DNS
Log in to your [Hostinger hPanel](https://hpanel.hostinger.com) and navigate to **Domains** → **Domain Portfolio**. Click **Manage** next to the domain you want to configure, then open the **DNS / Nameservers** tab and select **DNS records**.
If your domain was purchased through Hostinger or your nameservers already point to Hostinger, skip nameserver
configuration entirely. Your domain is already using Hostinger's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on Hostinger, you must first **update the nameservers**
at your registrar to Hostinger's nameservers. Your assigned nameservers are shown in your hPanel under **Websites** →
**Dashboard** → **Plan Details**. They typically follow the format `ns1.dns-parking.com` and `ns2.dns-parking.com`,
but the exact values vary by account — always use what your panel shows.
Until the nameservers are updated, any records you add in Hostinger will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Hostinger:
1. In the **DNS records** tab, select **CNAME** from the **Type** dropdown.
2. Set **Name (Host)** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `mailing`.
3. Set **Target (Points to)** to the **Value** from Lettr.
4. Leave **TTL** at the default (14400).
5. Click **Add Record**.
Hostinger automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`). If you paste the full hostname, the resulting record will resolve as
`mailing.company.com.company.com`, which will fail verification.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Hostinger:
1. In the **DNS records** tab, select **TXT** from the **Type** dropdown.
2. Set **Name (Host)** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
3. Set **TXT Value** to the **Value** from Lettr.
4. Leave **TTL** at the default (14400).
5. Click **Add Record**.
Hostinger automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Hostinger:
1. In the **DNS records** tab, select **TXT** from the **Type** dropdown.
2. Set **Name (Host)** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `_dmarc.mailing`.
3. Set **TXT Value** to the **Value** from Lettr (e.g. `v=DMARC1;p=none;`).
4. Leave **TTL** at the default (14400).
5. Click **Add Record**.
Hostinger automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Hostinger:
1. In the **DNS records** tab, select **MX** from the **Type** dropdown.
2. Set **Name (Host)** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `inbound`.
3. Set **Mail server (Points to)** to `rx1.sparkpostmail.com`.
4. Set **Priority** to `10`.
5. Leave **TTL** at the default (14400).
6. Click **Add Record**.
7. Repeat this process for the second (`rx2.sparkpostmail.com`) and third (`rx3.sparkpostmail.com`) MX records, each with priority `10`.
Hostinger automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`inbound`, not `inbound.company.com`).
All emails sent to the domain or subdomain where MX records are configured will be routed to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Hostinger:
1. In the **DNS records** tab, select **CNAME** from the **Type** dropdown.
2. Set **Name (Host)** to the **Hostname** from Lettr (without your domain suffix).
3. Set **Target (Points to)** to the **Value** from Lettr.
4. Leave **TTL** at the default (14400).
5. Click **Add Record**.
Hostinger automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Hostinger:
1. In the **DNS records** tab, select **CNAME** from the **Type** dropdown.
2. Set **Name (Host)** to the **Hostname** from Lettr (without your domain suffix).
3. Set **Target (Points to)** to the **Value** from Lettr.
4. Leave **TTL** at the default (14400).
5. Click **Add Record**.
Hostinger automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Hostinger:
1. In the **DNS records** tab, select **TXT** from the **Type** dropdown.
2. Set **Name (Host)** to the **Hostname** from Lettr (without your domain suffix).
3. Set **TXT Value** to the **Value** from Lettr.
4. Leave **TTL** at the default (14400).
5. Click **Add Record**.
Hostinger automatically appends your domain to the record name. Always paste only the subdomain portion, just as with the CNAME record above.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Hostinger:
1. In the **DNS records** tab, select **TXT** from the **Type** dropdown.
2. Set **Name (Host)** to the **Hostname** from Lettr (without your domain suffix).
3. Set **TXT Value** to the **Value** from Lettr.
4. Leave **TTL** at the default (14400).
5. Click **Add Record**.
Hostinger automatically appends your domain to the record name. Always paste only the subdomain portion, just as with the CNAME record above.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Hostinger:
1. In the **DNS records** tab, select **CNAME** from the **Type** dropdown.
2. Set **Name (Host)** to the **Hostname** from Lettr (without your domain suffix).
3. Set **Target (Points to)** to the **Value** from Lettr.
4. Leave **TTL** at the default (14400).
5. Click **Add Record**.
Hostinger automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Hostinger automatically appends your domain to the **Name (Host)** field. If you paste the full hostname (e.g.
`mailing.company.com`), the resulting record will resolve as `mailing.company.com.company.com`, which will fail
verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
Hostinger DNS changes are typically applied within minutes, but external resolvers may take longer to pick up the
changes. If verification fails after adding records, check the following:
* **Wait at least 30 minutes** before your first verification attempt. Most records propagate within 1–2 hours.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
If your records are saved in Hostinger but not resolving, confirm that your domain registrar is pointing to
Hostinger's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include your assigned Hostinger nameservers (e.g. `ns1.dns-parking.com`, `ns2.dns-parking.com`).
Your exact nameservers are shown in hPanel under **Websites** → **Dashboard** → **Plan Details**. If the output shows
a different provider's nameservers, update them at your domain registrar.
Standard CNAME records cannot be used at the root of a domain (e.g. `company.com`). If you enter `@` as the name for
a CNAME record, Hostinger will silently convert it to an ALIAS record on save — it will not appear as CNAME in the
list. Always use a subdomain (e.g. `mailing.company.com`) for your sending, tracking, and storage domains.
A common mistake is selecting the wrong type from the **Type** dropdown in Hostinger's DNS records tab:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
Remove any existing A or CNAME records for the same hostname before adding new CNAME records. Hostinger does not
automatically remove conflicting records. Duplicate or conflicting records on the same hostname will cause
verification failures.
The DKIM TXT value is a long string. After saving the record, re-open the DNS records tab and locate the record to
confirm the full value is displayed in the **TXT Value** column. If it appears truncated, delete the record and
re-add it, pasting the full value carefully into the **TXT Value** field.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after
48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the
output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# IONOS DNS Setup
Source: https://docs.lettr.com/knowledge-base/dns-guides/ionos
Add the DNS records Lettr needs in the IONOS Control Panel to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using IONOS's DNS management. IONOS is a web hosting and domain provider that offers DNS hosting for domains managed through its [IONOS Control Panel](https://my.ionos.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure IONOS DNS
Log in to the [IONOS Control Panel](https://my.ionos.com) and click the **Domains & SSL** tile on the dashboard. Find the domain you want to configure, click the **three-dot menu** in the Actions column next to it, and select **DNS**.
If your domain was purchased through IONOS or your nameservers already point to IONOS, skip nameserver
configuration entirely. Your domain is already using IONOS's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on IONOS, you must first **update the nameservers**
at your registrar to the IONOS nameservers shown in your domain's DNS settings. IONOS assigns four nameservers per
account in the format `ns1045.ui-dns.org`, `ns1045.ui-dns.de`, `ns1045.ui-dns.biz`, and `ns1045.ui-dns.com` — the
number prefix (e.g. `1045`) varies by account. Use the exact values shown in your IONOS control panel.
Until the nameservers are updated, any records you add in IONOS will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to IONOS:
1. Click **Add record** in the DNS management page.
2. Select **CNAME** from the record type dropdown.
3. Set **Hostname** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `mailing`.
4. Set **Point to** to the **Value** from Lettr.
5. Leave **TTL** at the default (3600).
6. Click **Save**.
IONOS automatically appends your domain to the hostname. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`). If you paste the full hostname, the resulting record will resolve as
`mailing.company.com.company.com`, which will fail verification.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to IONOS:
1. Click **Add record** in the DNS management page.
2. Select **TXT** from the record type dropdown.
3. Set **Host name** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
4. Set **Value** to the **Value** from Lettr.
5. Leave **TTL** at the default (3600).
6. Click **Save**.
IONOS automatically appends your domain to the hostname. Always paste only the subdomain portion (e.g.
`scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to IONOS:
1. Click **Add record** in the DNS management page.
2. Select **TXT** from the record type dropdown.
3. Set **Host name** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `_dmarc.mailing`.
4. Set **Value** to the **Value** from Lettr (e.g. `v=DMARC1;p=none;`).
5. Leave **TTL** at the default (3600).
6. Click **Save**.
IONOS automatically appends your domain to the hostname. Always paste only the subdomain portion (e.g.
`_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS changes on IONOS propagate within about 1 hour in most cases, though external resolvers may take longer.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to IONOS:
1. Click **Add record** in the DNS management page.
2. Select **MX** from the record type dropdown.
3. Set **Host name** to the **Hostname** value from Lettr (without your domain suffix). For example, paste only `inbound`.
4. Set **Points to** to `rx1.sparkpostmail.com`.
5. Set **Priority** to `10`.
6. Leave **TTL** at the default (3600).
7. Click **Save**.
8. Repeat this process for the second (`rx2.sparkpostmail.com`) and third (`rx3.sparkpostmail.com`) MX records, each with priority `10`.
IONOS automatically appends your domain to the hostname. Always paste only the subdomain portion (e.g.
`inbound`, not `inbound.company.com`).
All emails sent to the domain or subdomain where MX records are configured will be routed to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS changes on IONOS propagate within about 1 hour in most cases, though external resolvers may take longer.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in IONOS:
1. Click **Add record** in the DNS management page.
2. Select **CNAME** from the record type dropdown.
3. Set **Hostname** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Point to** to the **Value** from Lettr.
5. Leave **TTL** at the default (3600).
6. Click **Save**.
IONOS automatically appends your domain to the hostname. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in IONOS:
1. Click **Add record** in the DNS management page.
2. Select **CNAME** from the record type dropdown.
3. Set **Hostname** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Point to** to the **Value** from Lettr.
5. Leave **TTL** at the default (3600).
6. Click **Save**.
IONOS automatically appends your domain to the hostname. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in IONOS:
1. Click **Add record** in the DNS management page.
2. Select **TXT** from the record type dropdown.
3. Set **Host name** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Value** to the **Value** from Lettr.
5. Leave **TTL** at the default (3600).
6. Click **Save**.
IONOS automatically appends your domain to the hostname. Always paste only the subdomain portion, just as with the CNAME record above.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in IONOS:
1. Click **Add record** in the DNS management page.
2. Select **TXT** from the record type dropdown.
3. Set **Host name** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Value** to the **Value** from Lettr.
5. Leave **TTL** at the default (3600).
6. Click **Save**.
IONOS automatically appends your domain to the hostname. Always paste only the subdomain portion, just as with the CNAME record above.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in IONOS:
1. Click **Add record** in the DNS management page.
2. Select **CNAME** from the record type dropdown.
3. Set **Hostname** to the **Hostname** from Lettr (without your domain suffix).
4. Set **Point to** to the **Value** from Lettr.
5. Leave **TTL** at the default (3600).
6. Click **Save**.
IONOS automatically appends your domain to the hostname. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
IONOS automatically appends your domain to the **Hostname** / **Host name** field. If you paste the full hostname
(e.g. `mailing.company.com`), the resulting record will resolve as `mailing.company.com.company.com`, which will
fail verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
IONOS applies DNS changes immediately on their side, but external resolvers may take up to 1 hour to pick up the
changes (and in rare cases, ISPs with long cache times may take longer). If verification fails after adding records,
check the following:
* **Wait at least 1 hour** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
If your records are saved in IONOS but not resolving, confirm that your domain is using IONOS's nameservers. You can
check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include IONOS nameservers in the format `ns####.ui-dns.org`, `ns####.ui-dns.de`,
`ns####.ui-dns.biz`, and `ns####.ui-dns.com` (where `####` is a number unique to your account). Your exact
nameservers are shown in the IONOS Control Panel under **Domains & SSL** → your domain's DNS settings. If the output
shows a different provider's nameservers, update them at your domain registrar.
IONOS does not allow CNAME records at the root of a domain (e.g. `company.com`). You must use a subdomain for your
sending domain (e.g. `mailing.company.com`). This is also a DNS protocol limitation — CNAME records cannot coexist
with other record types at the same name.
If you have IONOS-hosted services active on your domain (e.g. Microsoft 365, IONOS webmail, WordPress hosting),
IONOS manages some DNS records automatically. Adding records that conflict with service-managed entries may cause
errors or silent overwrites. Check for existing A, CNAME, or MX records on the same hostname before adding new ones,
and remove any conflicting entries first.
A common mistake is selecting the wrong type from the record type dropdown:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. After saving the record, re-open the DNS management page and confirm the full
value is displayed. If it appears truncated, delete the record and re-add it, pasting the full value carefully into
the **Value** field.
If IONOS rejects the value due to length, try splitting the `p=` portion into two quoted strings separated by a
space: `"v=DKIM1; k=rsa; p=firsthalf" "secondhalf"`. Paste both quoted strings together into the **Value** field.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after
48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the
output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Linode DNS Setup
Source: https://docs.lettr.com/knowledge-base/dns-guides/linode
Add the DNS records Lettr needs in Linode DNS Manager to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using Linode DNS Manager (now part of Akamai). Linode is a cloud infrastructure provider that offers DNS hosting through the [Linode Cloud Manager](https://cloud.linode.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Linode DNS
Log in to the [Linode Cloud Manager](https://cloud.linode.com) and click **Domains** in the left sidebar. Select your domain from the list to open the DNS records management page.
If your domain was purchased through Linode or your nameservers already point to Linode, skip nameserver
configuration entirely. Your domain is already using Linode's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on Linode, you must first **update the nameservers**
at your registrar to Linode's nameservers (`ns1.linode.com` through `ns5.linode.com`).
Until the nameservers are updated, any records you add in Linode will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Linode:
1. Click **Add a CNAME Record**.
2. Copy the **Hostname** from Lettr and paste it into the **Hostname** field in Linode (without your domain suffix). For example, paste only `mailing`.
3. Copy the **Value** from Lettr and paste it into the **Alias to** field in Linode.
4. Leave **TTL** set to **Default**.
5. Click **Save**.
Linode automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`). If you paste the full hostname, the resulting record will resolve as
`mailing.company.com.company.com`, which will fail verification.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Linode:
1. Click **Add a TXT Record**.
2. Copy the **Hostname** from Lettr and paste it into the **Hostname** field in Linode (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Linode.
4. Leave **TTL** set to **Default**.
5. Click **Save**.
Linode automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Linode:
1. Click **Add a TXT Record**.
2. Copy the **Hostname** from Lettr and paste it into the **Hostname** field in Linode (without your domain suffix). For example, paste only `_dmarc.mailing`.
3. Copy the **Value** from Lettr (e.g. `v=DMARC1;p=none;`) and paste it into the **Value** field in Linode.
4. Leave **TTL** set to **Default**.
5. Click **Save**.
Linode automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within 5–30 minutes for Linode.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Linode:
1. Click **Add a MX Record**.
2. Copy the first **Required MX Record** value (e.g. `rx1.sparkpostmail.com`) from Lettr and paste it into the **Mail Server** field in Linode.
3. Set **Preference** to `10`.
4. Copy the **Hostname** from Lettr and paste it into the **Subdomain** field in Linode (without your domain suffix). For example, paste only `inbound`.
5. Leave **TTL** set to **Default**.
6. Click **Save**.
7. Repeat this process for the second (`rx2.sparkpostmail.com`) and third (`rx3.sparkpostmail.com`) MX records, each with preference `10`.
Linode automatically appends your domain to the subdomain field. Always paste only the subdomain portion (e.g.
`inbound`, not `inbound.company.com`).
Adding MX records to a domain or subdomain will route all incoming email for that address to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within 5–30 minutes for Linode.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Linode:
1. Click **Add a CNAME Record**.
2. Copy the **Hostname** from Lettr and paste it into the **Hostname** field (without your domain suffix).
3. Copy the **Value** from Lettr and paste it into the **Alias to** field.
4. Leave **TTL** set to **Default**.
5. Click **Save**.
Linode automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Linode:
1. Click **Add a CNAME Record**.
2. Copy the **Hostname** from Lettr and paste it into the **Hostname** field (without your domain suffix).
3. Copy the **Value** from Lettr and paste it into the **Alias to** field.
4. Leave **TTL** set to **Default**.
5. Click **Save**.
Linode automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Linode:
1. Click **Add a TXT Record**.
2. Copy the **Hostname** from Lettr and paste it into the **Hostname** field (without your domain suffix).
3. Copy the **Value** from Lettr and paste it into the **Value** field.
4. Leave **TTL** set to **Default**.
5. Click **Save**.
Linode automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Linode:
1. Click **Add a TXT Record**.
2. Copy the **Hostname** from Lettr and paste it into the **Hostname** field (without your domain suffix).
3. Copy the **Value** from Lettr and paste it into the **Value** field.
4. Leave **TTL** set to **Default**.
5. Click **Save**.
Linode automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Linode:
1. Click **Add a CNAME Record**.
2. Copy the **Hostname** from Lettr and paste it into the **Hostname** field (without your domain suffix).
3. Copy the **Value** from Lettr and paste it into the **Alias to** field.
4. Leave **TTL** set to **Default**.
5. Click **Save**.
Linode automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Linode automatically appends your domain to the **Hostname** field. If you paste the full hostname (e.g.
`mailing.company.com`), the resulting record will resolve as `mailing.company.com.company.com`, which will fail
verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
Linode DNS typically propagates within 5–30 minutes. If verification fails after adding records, check the
following:
* **Wait at least 30 minutes** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [WhatsMyDNS](https://www.whatsmydns.net) or [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
Linode doesn't support CNAME records at the root domain. Use a subdomain for your sending domain
(e.g. `mailing.company.com`). This is also a DNS protocol limitation — CNAME records cannot coexist with other
record types at the same name.
If your records are saved in Linode but not resolving, confirm that your domain registrar is pointing to Linode's
nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include Linode nameservers (`ns1.linode.com` through `ns5.linode.com`). If it shows a different
provider's nameservers, update them at your domain registrar.
A common mistake is selecting the wrong record type:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. After saving the record, re-open it to confirm the full value was stored. If
it appears truncated, delete the record and re-add it, pasting the full value carefully. Do not wrap the value in
quotation marks — Linode handles long TXT records automatically, and manually adding quotes will cause them to be
stored as literal characters, breaking the record.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails
after 48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name
and the output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Namecheap
Source: https://docs.lettr.com/knowledge-base/dns-guides/namecheap
Add the DNS records Lettr needs in your Namecheap account to verify your sending, inbound, tracking, and storage domains with DKIM and DMARC.
This guide walks you through adding the required DNS records for Lettr using Namecheap's DNS management. Namecheap is a popular domain registrar that offers DNS hosting for domains registered through its [Namecheap Account Panel](https://www.namecheap.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Namecheap DNS
Log in to your [Namecheap Account Panel](https://www.namecheap.com) and navigate to **Domain List**. Click **Manage** next to your domain, then select the **Advanced DNS** tab.
If your domain was purchased through Namecheap or your nameservers already point to Namecheap, skip nameserver
configuration entirely. Your domain is already using Namecheap's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on Namecheap, you must first transfer the domain to
Namecheap or **update the nameservers** at your registrar to Namecheap's nameservers.
Until the nameservers are updated, any records you add in Namecheap will not resolve.
Namecheap automatically appends your domain to the host value. When entering hostnames, paste only the subdomain portion
(e.g. `mailing`, not `mailing.company.com`). If you paste the full hostname, the resulting record will be
`mailing.company.com.company.com`, which will fail verification.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Namecheap:
1. Click **ADD NEW RECORD** in the Advanced DNS tab.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `mailing`.
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Leave **TTL** set to the default (Automatic).
6. Click the **checkmark** to save.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Namecheap:
1. Click **ADD NEW RECORD** in the Advanced DNS tab.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Leave **TTL** set to the default (Automatic).
6. Click the **checkmark** to save.
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Namecheap:
1. Click **ADD NEW RECORD** in the Advanced DNS tab.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `_dmarc.mailing`.
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Leave **TTL** set to the default (Automatic).
6. Click the **checkmark** to save.
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Before adding MX records, ensure that Namecheap's mail settings are configured correctly. In the **Advanced DNS** tab, scroll down to the **MAIL SETTINGS** section. Open the **Email Forwarding** drop-down and select **Custom MX** — otherwise Namecheap's default mail settings will take precedence over any custom MX records you add.
Copy the MX values from Lettr to Namecheap:
1. Click **ADD NEW RECORD** in the Advanced DNS tab.
2. Set **Type** to **MX**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `inbound`.
4. Copy the first MX record value from Lettr (e.g. `rx1.sparkpostmail.com`) and paste it into the **Value** field.
5. Set **Priority** to `10`.
6. Leave **TTL** set to the default (Automatic).
7. Click the **checkmark** to save.
8. Repeat this process for the second (`rx2.sparkpostmail.com`) and third (`rx3.sparkpostmail.com`) MX records, each with priority `10`.
All emails sent to the domain or subdomain where MX records are configured will be routed to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Namecheap:
1. Click **ADD NEW RECORD** in the Advanced DNS tab.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Leave **TTL** set to the default (Automatic).
6. Click the **checkmark** to save.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Namecheap:
1. Click **ADD NEW RECORD** in the Advanced DNS tab.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Leave **TTL** set to the default (Automatic).
6. Click the **checkmark** to save.
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Namecheap:
1. Click **ADD NEW RECORD** in the Advanced DNS tab.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Leave **TTL** set to the default (Automatic).
6. Click the **checkmark** to save.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Namecheap:
1. Click **ADD NEW RECORD** in the Advanced DNS tab.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Leave **TTL** set to the default (Automatic).
6. Click the **checkmark** to save.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Namecheap:
1. Click **ADD NEW RECORD** in the Advanced DNS tab.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Leave **TTL** set to the default (Automatic).
6. Click the **checkmark** to save.
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Namecheap automatically appends your domain to the Host field. If you paste the full hostname (e.g.
`mailing.company.com`), the resulting record will be `mailing.company.com.company.com`, which will fail verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`). If you made
this mistake, delete the incorrect record and re-add it with only the subdomain.
If your inbound MX records are not resolving, confirm that Namecheap's mail settings are configured for custom
records. In the **Advanced DNS** tab, scroll down to the **MAIL SETTINGS** section. Open the **Email Forwarding**
drop-down and select **Custom MX**. The default setting will override any custom MX records you add.
Namecheap DNS propagation typically takes up to 72 hours but is often much faster. If verification fails after adding
records, check the following:
* **Wait at least 1–2 hours** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
If your records are saved in Namecheap but not resolving, confirm that your domain registrar is pointing to
Namecheap's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include Namecheap's nameservers (e.g. `dns1.registrar-servers.com`, `dns2.registrar-servers.com`).
If the output shows a different provider's nameservers, update them at your domain registrar to point to Namecheap.
Standard CNAME records cannot be used at the root of a domain (e.g. `company.com`). Namecheap does not allow CNAME
records at the apex (`@`) — attempting to add one will fail. Always use a subdomain (e.g. `mailing.company.com`) for
your sending, tracking, and storage domains. Namecheap does offer ALIAS records at the root as an alternative, but
Lettr's verification requires a standard CNAME, so a subdomain is required.
A common mistake is selecting the wrong type from the dropdown:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
If a CNAME record fails to save or resolve, check whether an existing A or CNAME record already uses the same
hostname. Namecheap does not automatically remove conflicting records. Delete any duplicate or conflicting records for
the same hostname before adding the new CNAME.
The DKIM TXT value is a long string (often 400+ characters). After saving the record, click the **Edit** pencil icon
next to it and confirm the full value is present in the **Value** field. If it appears cut off, delete the record and
re-add it, pasting the complete value carefully. Namecheap supports up to 2500 characters in the Value field, so the
full DKIM key fits without splitting.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after
48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the
output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Netlify
Source: https://docs.lettr.com/knowledge-base/dns-guides/netlify
Configure Netlify DNS for Lettr: add CNAME, DKIM, DMARC, and MX records to set up sending, inbound, tracking, and storage domains.
This guide walks you through adding the required DNS records for Lettr using Netlify's DNS management. Netlify is a platform for deploying and hosting web applications that also provides DNS hosting for domains connected to your Netlify account, managed through the [Netlify dashboard](https://app.netlify.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Netlify DNS
Netlify DNS is managed at the team level, not per site. Log in to the [Netlify dashboard](https://app.netlify.com) and select **DNS** from the left sidebar in your team dashboard. Select the domain you want to configure to open its DNS records panel.
If your domain was purchased through Netlify or your nameservers already point to Netlify, skip nameserver
configuration entirely. Your domain is already using Netlify's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on Netlify, you must first add the domain to Netlify
DNS and then **update the nameservers** at your registrar to Netlify's nameservers. Your domain's assigned
nameservers are displayed in the **Name servers** panel on the domain's DNS page — they follow the format
`dns1.p0X.nsone.net` through `dns4.p0X.nsone.net`, where the partition number is unique to your domain.
Until the nameservers are updated, any records you add in Netlify will not resolve.
If you have existing Netlify sites using subdomains that overlap with the subdomains you are configuring for Lettr
(e.g. `mailing.company.com`), Netlify may have automatically created NETLIFY records for those subdomains. Remove
or reconfigure those site assignments before adding the DNS records below.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Netlify:
1. Click **Add new record** in the DNS records section.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field (without your domain suffix). For example, paste only `mailing`.
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Click **Save**.
Netlify automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`).
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Netlify:
1. Click **Add new record** in the DNS records section.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Click **Save**.
Netlify automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Netlify:
1. Click **Add new record** in the DNS records section.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field (without your domain suffix). For example, paste only `_dmarc.mailing`.
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Click **Save**.
Netlify automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few hours on Netlify.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Netlify:
1. Click **Add new record** in the DNS records section.
2. Set **Type** to **MX**.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field (without your domain suffix). For example, paste only `inbound`.
4. Copy the first **Required MX Record** value (e.g. `rx1.sparkpostmail.com`) from Lettr and paste it into the **Value** field.
5. Set **Priority** to `10`.
6. Click **Save**.
7. Repeat this process for the second (`rx2.sparkpostmail.com`) and third (`rx3.sparkpostmail.com`) MX records, each with priority `10`.
Netlify automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`inbound`, not `inbound.company.com`).
Adding MX records to a domain or subdomain will route all incoming email for that address to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few hours on Netlify.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Netlify:
1. Click **Add new record** in the DNS records section.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Click **Save**.
Netlify automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Netlify:
1. Click **Add new record** in the DNS records section.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Click **Save**.
Netlify automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Netlify:
1. Click **Add new record** in the DNS records section.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Click **Save**.
Netlify automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Netlify:
1. Click **Add new record** in the DNS records section.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Click **Save**.
Netlify automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Netlify:
1. Click **Add new record** in the DNS records section.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Name** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Value** field.
5. Click **Save**.
Netlify automatically appends your domain to the record name. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Netlify automatically appends your domain to the record name. If you paste the full hostname (e.g.
`mailing.company.com`), the resulting record will resolve as `mailing.company.com.company.com`, which will fail
verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
When you assign a domain to a Netlify site, Netlify automatically creates proprietary NETLIFY or NETLIFYv6 records
for that subdomain. If a subdomain you want to use for Lettr (e.g. `mailing.company.com`) is already assigned to a
Netlify site, you may need to disconnect the site from that domain before adding DNS records for Lettr. Remove the
site assignment first, or use a different subdomain.
DNS propagation on Netlify typically takes a few hours, but can occasionally take longer. If verification fails
after adding records, check the following:
* **Wait at least 30 minutes** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
A common mistake is selecting the wrong record type:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. After saving the record, click on it in the DNS records list to confirm the
full value was stored. If it appears truncated, note that Netlify does not support in-place record editing — add
a new record with the correct full value, then delete the old one.
If your records are saved in Netlify but not resolving, confirm that your domain registrar is pointing to
Netlify's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include Netlify's nameservers in the format `dns1.p0X.nsone.net` through `dns4.p0X.nsone.net`.
Your domain's exact nameservers are shown in the **Name servers** panel on the domain's DNS page in the Netlify
dashboard. If the output shows a different provider's nameservers, update them at your domain registrar.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails
after 48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain
name and the output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Porkbun
Source: https://docs.lettr.com/knowledge-base/dns-guides/porkbun
Configure Porkbun DNS for Lettr: add CNAME, DKIM, DMARC, and MX records to set up sending, inbound, tracking, and storage domains.
This guide walks you through adding the required DNS records for Lettr using Porkbun's DNS management. Porkbun is an affordable domain registrar that offers DNS hosting for domains registered through its [Porkbun dashboard](https://porkbun.com).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Porkbun DNS
Log in to your [Porkbun dashboard](https://porkbun.com) and navigate to **Domain Management**. Hover over your domain name and click the **DNS** link that appears inline to access the DNS record management page.
If your domain was purchased through Porkbun or your nameservers already point to Porkbun, skip nameserver
configuration entirely. Your domain is already using Porkbun's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on Porkbun, you must first **update the nameservers**
at your registrar to Porkbun's nameservers shown in your domain settings.
Until the nameservers are updated, any records you add in Porkbun will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Porkbun:
1. In the DNS management page, select **CNAME** from the **Type** dropdown.
2. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `mailing`.
3. Copy the **Value** from Lettr and paste it into the **Answer** field.
4. Leave **TTL** at the default.
5. Click **Save**.
Porkbun automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`).
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Porkbun:
1. In the DNS management page, select **TXT** from the **Type** dropdown.
2. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
3. Copy the **Value** from Lettr and paste it into the **Answer** field.
4. Leave **TTL** at the default.
5. Click **Save**.
Porkbun automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Porkbun:
1. In the DNS management page, select **TXT** from the **Type** dropdown.
2. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `_dmarc.mailing`.
3. Copy the **Value** from Lettr and paste it into the **Answer** field.
4. Leave **TTL** at the default.
5. Click **Save**.
Porkbun automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Porkbun:
1. In the DNS management page, select **MX** from the **Type** dropdown.
2. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `inbound`.
3. Copy the first **Required MX Record** value (without the priority number) from Lettr (e.g. `rx1.sparkpostmail.com`) and paste it into the **Answer** field.
4. Set **Priority** to `10`.
5. Leave **TTL** at the default.
6. Click **Save**.
7. Repeat this process for the second (`rx2.sparkpostmail.com`) and third (`rx3.sparkpostmail.com`) MX records, each with priority `10`.
Porkbun automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`inbound`, not `inbound.company.com`).
Adding MX records to a domain or subdomain will route all incoming email for that address to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Porkbun:
1. In the DNS management page, select **CNAME** from the **Type** dropdown.
2. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
3. Copy the **Value** from Lettr and paste it into the **Answer** field.
4. Leave **TTL** at the default.
5. Click **Save**.
Porkbun automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Porkbun:
1. In the DNS management page, select **CNAME** from the **Type** dropdown.
2. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
3. Copy the **Value** from Lettr and paste it into the **Answer** field.
4. Leave **TTL** at the default.
5. Click **Save**.
Porkbun automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Porkbun:
1. In the DNS management page, select **TXT** from the **Type** dropdown.
2. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
3. Copy the **Value** from Lettr and paste it into the **Answer** field.
4. Leave **TTL** at the default.
5. Click **Save**.
Porkbun automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Porkbun:
1. In the DNS management page, select **TXT** from the **Type** dropdown.
2. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
3. Copy the **Value** from Lettr and paste it into the **Answer** field.
4. Leave **TTL** at the default.
5. Click **Save**.
Porkbun automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Porkbun:
1. In the DNS management page, select **CNAME** from the **Type** dropdown.
2. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
3. Copy the **Value** from Lettr and paste it into the **Answer** field.
4. Leave **TTL** at the default.
5. Click **Save**.
Porkbun automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Porkbun automatically appends your domain name to whatever you enter in the **Host** field. If you paste the full hostname (e.g. `mailing.company.com`), the resulting record will be `mailing.company.com.company.com`, which will fail verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
Porkbun's DNS is powered by Cloudflare's infrastructure, so records typically propagate within minutes. If verification fails after adding records, check the following:
* **Wait at least 30 minutes** before your first verification attempt. Most records propagate within 1–2 hours.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [WhatsMyDNS](https://www.whatsmydns.net) or [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
A common mistake is selecting the wrong record type from the **Type** dropdown:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. After saving the record, re-open the DNS management page and confirm the full value is displayed in the **Answer** field. If it appears truncated, delete the record and re-add it, pasting the full value carefully.
If Porkbun rejects the value due to length, you may need to split the DKIM key into two quoted strings within the same TXT record. For example:
```
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOC..." "AQ8AMIIBCgKCAQEA..."
```
Each quoted segment must be 255 characters or fewer. Paste both quoted strings as a single value in the **Answer** field.
If your records are saved in Porkbun but not resolving, confirm that your domain is using Porkbun's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include Porkbun nameservers. If it shows a different provider's nameservers, update them in your domain registrar settings.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after
48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the
output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Squarespace
Source: https://docs.lettr.com/knowledge-base/dns-guides/squarespace
Configure Squarespace DNS for Lettr: add CNAME, DKIM, DMARC, and MX records to set up sending, inbound, tracking, and storage domains.
This guide walks you through adding the required DNS records for Lettr using Squarespace's DNS management. Squarespace is a website builder and hosting platform that also offers DNS hosting for domains managed through its [Squarespace Domains panel](https://account.squarespace.com/domains).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Squarespace DNS
Log in to your [Squarespace account](https://account.squarespace.com/domains), click the domain you want to configure, then click **DNS** in the side panel, followed by **DNS Settings**.
Squarespace only allows custom DNS records for domains purchased or managed through Squarespace. If your domain is
registered elsewhere, you may need to transfer it to Squarespace or update your nameservers before adding records.
If your domain was purchased through Squarespace or your nameservers already point to Squarespace, skip nameserver
configuration entirely. Your domain is already using Squarespace's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on Squarespace, you must first transfer the domain to
Squarespace or **update the nameservers** at your registrar to Squarespace's nameservers (`ns1.squarespace-dns.com`
and `ns2.squarespace-dns.com`).
Until the nameservers are updated, any records you add in Squarespace will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Squarespace:
1. Click **Add record** in the DNS Settings panel.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `mailing`.
4. Copy the **Value** from Lettr and paste it into the **Alias Data** field.
5. Click **Save**.
Squarespace automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`).
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Squarespace:
1. Click **Add record** in the DNS Settings panel.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `scph0126._domainkey.mailing`.
4. Copy the **Value** from Lettr and paste it into the **Text** field.
5. Click **Save**.
Squarespace automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`scph0126._domainkey.mailing`, not `scph0126._domainkey.mailing.company.com`).
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Squarespace:
1. Click **Add record** in the DNS Settings panel.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `_dmarc.mailing`.
4. Copy the **Value** from Lettr and paste it into the **Text** field (e.g. `v=DMARC1;p=none;`).
5. Click **Save**.
Squarespace automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`_dmarc.mailing`, not `_dmarc.mailing.company.com`).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Squarespace:
1. Click **Add record** in the DNS Settings panel.
2. Set **Type** to **MX**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix). For example, paste only `inbound`.
4. Copy the first MX record value from Lettr (e.g. `rx1.sparkpostmail.com`) and paste it into the **Mail Server** field.
5. Set **Priority** to `10`.
6. Click **Save**.
7. Repeat this process for the second (`rx2.sparkpostmail.com`) and third (`rx3.sparkpostmail.com`) MX records, each with priority `10`.
Squarespace automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`inbound`, not `inbound.company.com`).
Adding MX records to a domain or subdomain will route all incoming email for that address to Lettr. Use a dedicated
subdomain (e.g. `inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Squarespace:
1. Click **Add record** in the DNS Settings panel.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Alias Data** field.
5. Click **Save**.
Squarespace automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Squarespace:
1. Click **Add record** in the DNS Settings panel.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Alias Data** field.
5. Click **Save**.
Squarespace automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Squarespace:
1. Click **Add record** in the DNS Settings panel.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Text** field.
5. Click **Save**.
Squarespace automatically appends your domain to the Host field. Always paste only the subdomain portion, just as with the CNAME record above.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Squarespace:
1. Click **Add record** in the DNS Settings panel.
2. Set **Type** to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Text** field.
5. Click **Save**.
Squarespace automatically appends your domain to the Host field. Always paste only the subdomain portion, just as with the CNAME record above.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Squarespace:
1. Click **Add record** in the DNS Settings panel.
2. Set **Type** to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Host** field (without your domain suffix).
4. Copy the **Value** from Lettr and paste it into the **Alias Data** field.
5. Click **Save**.
Squarespace automatically appends your domain to the Host field. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Squarespace automatically appends your domain to the Host field. If you paste the full hostname (e.g. `mailing.company.com`), the resulting record will be `mailing.company.com.company.com`, which will fail verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
Squarespace DNS propagation can take up to 24–48 hours. If verification fails after adding records, check the following:
* **Wait at least 2–4 hours** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [WhatsMyDNS](https://www.whatsmydns.net) or [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
Squarespace only supports custom DNS records for domains purchased or managed through Squarespace. If you are unable to
add records, confirm that your domain is managed by Squarespace. If it is registered elsewhere, consider transferring it
to Squarespace or pointing your nameservers to Squarespace before adding records.
Squarespace will display a **"This host is already in use"** error if you attempt to add a second TXT record with an
identical Host value. Each hostname can only hold one TXT record in Squarespace's DNS panel (with the exception of
SPF records, which Squarespace merges automatically).
If you need to add multiple TXT records for the same subdomain, consider managing DNS with a provider that supports
multiple TXT records on the same hostname, such as Cloudflare or DigitalOcean.
A common mistake is selecting the wrong record type:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. After saving the record, re-open the DNS Settings panel and confirm the full
value is displayed. If it appears truncated, delete the record and re-add it, pasting the full value carefully.
If your records are saved in Squarespace but not resolving, confirm that your domain registrar is pointing to
Squarespace's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include Squarespace nameservers (e.g. `ns1.squarespace-dns.com`, `ns2.squarespace-dns.com`). If it
shows a different provider's nameservers, update them at your domain registrar.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after
48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the
output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Strato DNS Setup
Source: https://docs.lettr.com/knowledge-base/dns-guides/strato
Configure Strato DNS for Lettr: add CNAME, DKIM, DMARC, and MX records to set up sending, inbound, tracking, and storage domains.
This guide walks you through adding the required DNS records for Lettr using Strato's DNS management. Strato is a German web hosting and domain provider that offers DNS hosting for domains managed through its [Strato Control Panel](https://www.strato.de/apps/CustomerService).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Strato DNS
Log in to the [Strato Control Panel](https://www.strato.de/apps/CustomerService) and navigate to **Domains** → **Domainverwaltung** (Domain Management). Click the gear icon next to your domain and select the **DNS** tab to open the DNS editor.
If your domain was purchased through Strato or your nameservers already point to Strato, skip nameserver
configuration entirely. Your domain is already using Strato's nameservers by default — proceed directly to adding the
DNS records below.
If you registered your domain elsewhere but want to manage DNS on Strato, you must first **update the nameservers**
at your registrar to Strato's nameservers:
* `ns1.strato.de`
* `ns2.strato.de`
* `ns4.strato.de`
Until the nameservers are updated, any records you add in Strato will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Strato:
1. In the DNS editor, click **+ Weiteren Record erstellen** (Create another record).
2. Set **Typ** (Type) to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Präfix** (Prefix) field — without your domain suffix. For example, paste only `mailing`.
4. Copy the **Value** from Lettr and paste it into the **Wert** (Value) field.
5. Click **Einstellungen übernehmen** (Apply settings).
Strato automatically appends your domain to the Präfix field. Always paste only the subdomain portion (e.g.
`mailing`, not `mailing.company.com`).
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Strato:
1. In the DNS editor, click **+ Weiteren Record erstellen** (Create another record).
2. Set **Typ** (Type) to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Präfix** (Prefix) field — without your domain suffix. For example, paste only `scph0126._domainkey.mailing`.
4. Copy the **Value** from Lettr and paste it into the **Wert** (Value) field.
5. Click **Einstellungen übernehmen** (Apply settings).
DKIM records are case-sensitive. Copy the value exactly using the copy icon in your Lettr dashboard. Strato supports
multiple TXT records on the same hostname, so this record will not conflict with existing TXT records.
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Strato:
1. In the DNS editor, click **+ Weiteren Record erstellen** (Create another record).
2. Set **Typ** (Type) to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Präfix** (Prefix) field — without your domain suffix. For example, paste only `_dmarc.mailing`.
4. Copy the **Value** from Lettr and paste it into the **Wert** (Value) field (e.g. `v=DMARC1;p=none;`).
5. Click **Einstellungen übernehmen** (Apply settings).
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation on Strato can take up to 24 hours, though it typically completes within a few minutes to a few hours.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Strato uses a dedicated MX configuration dialog. In the DNS tab, click **verwalten** (manage) next to the MX record row, then enable **Eigener Mailserver** (Own mail server) to configure custom MX entries.
Add the MX records for your inbound subdomain:
1. In the MX configuration dialog, enable **Eigener Mailserver** (Own mail server).
2. Enter `rx1.sparkpostmail.com.` (with trailing dot) as the mail server hostname.
3. Set **Priorität** (Priority) to `10`.
4. Click **+ Weiteren Record erstellen** (Create another record) and repeat for `rx2.sparkpostmail.com.` and `rx3.sparkpostmail.com.`, each with priority `10`.
5. Click **Einstellungen übernehmen** (Apply settings).
Strato requires a trailing dot on MX record hostnames (e.g. `rx1.sparkpostmail.com.`). Without it, the record may
not resolve correctly.
Adding MX records to a domain or subdomain will route all incoming email for that address to Lettr. Enabling
**Eigener Mailserver** disables Strato's mail handling for that subdomain. Use a dedicated subdomain (e.g.
`inbound.company.com`) to avoid affecting your primary email.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation on Strato can take up to 24 hours, though it typically completes within a few minutes to a few hours.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Strato:
1. In the DNS editor, click **+ Weiteren Record erstellen** (Create another record).
2. Set **Typ** (Type) to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Präfix** (Prefix) field — without your domain suffix.
4. Copy the **Value** from Lettr and paste it into the **Wert** (Value) field.
5. Click **Einstellungen übernehmen** (Apply settings).
Strato automatically appends your domain to the Präfix field. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
Strato does not allow a CNAME record to coexist with other record types (A, MX, TXT) on the same hostname. If the
subdomain already has other records, you may need to remove them or use a different subdomain.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Strato:
1. In the DNS editor, click **+ Weiteren Record erstellen** (Create another record).
2. Set **Typ** (Type) to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Präfix** (Prefix) field — without your domain suffix.
4. Copy the **Value** from Lettr and paste it into the **Wert** (Value) field.
5. Click **Einstellungen übernehmen** (Apply settings).
Strato automatically appends your domain to the Präfix field. Always paste only the subdomain portion (e.g.
`tracking`, not `tracking.company.com`).
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Strato:
1. In the DNS editor, click **+ Weiteren Record erstellen** (Create another record).
2. Set **Typ** (Type) to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Präfix** (Prefix) field — without your domain suffix.
4. Copy the **Value** from Lettr and paste it into the **Wert** (Value) field.
5. Click **Einstellungen übernehmen** (Apply settings).
Strato automatically appends your domain to the Präfix field. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Strato:
1. In the DNS editor, click **+ Weiteren Record erstellen** (Create another record).
2. Set **Typ** (Type) to **TXT**.
3. Copy the **Hostname** from Lettr and paste it into the **Präfix** (Prefix) field — without your domain suffix.
4. Copy the **Value** from Lettr and paste it into the **Wert** (Value) field.
5. Click **Einstellungen übernehmen** (Apply settings).
Strato supports multiple TXT records on the same hostname — add each record separately using the **+ Weiteren Record
erstellen** button.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Strato:
1. In the DNS editor, click **+ Weiteren Record erstellen** (Create another record).
2. Set **Typ** (Type) to **CNAME**.
3. Copy the **Hostname** from Lettr and paste it into the **Präfix** (Prefix) field — without your domain suffix.
4. Copy the **Value** from Lettr and paste it into the **Wert** (Value) field.
5. Click **Einstellungen übernehmen** (Apply settings).
Strato automatically appends your domain to the Präfix field. Always paste only the subdomain portion (e.g.
`assets`, not `assets.company.com`).
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Strato automatically appends your domain to the Präfix (Prefix) field. If you paste the full hostname (e.g.
`mailing.company.com`), the resulting record will resolve as `mailing.company.com.company.com`, which will fail
verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
DNS propagation on Strato can take up to 24 hours. If verification fails after adding records, check the following:
* **Wait at least 2–4 hours** before your first verification attempt.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
If your records are saved in Strato but not resolving, confirm that your domain is using Strato's nameservers. You can
check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include Strato nameservers (e.g. `ns1.strato.de`, `ns2.strato.de`, `ns4.strato.de`). If it shows a
different provider's nameservers, update them at your domain registrar.
Strato does not allow a CNAME record to coexist with other record types (A, MX, TXT) on the same hostname. Adding
a CNAME will deactivate all other DNS settings for that exact subdomain. If you need CNAME records for Lettr on a
subdomain that already has other records, use a different subdomain or remove the conflicting records first.
Additionally, CNAME records are not available at the root domain (e.g. `company.com`) in Strato — you must always
use a subdomain.
A common mistake is selecting the wrong record type in the **Typ** dropdown:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
Strato configures its own mail server for domains by default. To add custom MX records, navigate to the MX
configuration dialog (click **verwalten** next to MX records in the DNS tab) and enable **Eigener Mailserver**
(Own mail server). Without this step, Strato will not allow custom MX entries.
Also ensure that mail server hostnames include a trailing dot (e.g. `rx1.sparkpostmail.com.`).
The DKIM TXT value is a long string. After saving the record, re-open the DNS editor and confirm the full value is
displayed. If it appears truncated, delete the record and re-add it, pasting the full value carefully.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after
48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the
output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# Vercel DNS Setup
Source: https://docs.lettr.com/knowledge-base/dns-guides/vercel
Configure Vercel DNS for Lettr: add CNAME, DKIM, DMARC, and MX records to set up sending, inbound, tracking, and storage domains.
This guide walks you through adding the required DNS records for Lettr using Vercel's DNS management. Vercel is a cloud platform for frontend frameworks and static sites that also provides DNS hosting for domains connected to your [Vercel projects](https://vercel.com/login).
You will configure a **sending domain** (CNAME, DKIM TXT, and DMARC TXT records) and, optionally, an **inbound domain** (MX records), **tracking domain** (two CNAME records), and **storage domain** (CNAME and two TXT records).
***
## Sending Domain Setup
A sending domain authenticates your outgoing emails with DKIM and DMARC, ensuring they are delivered reliably and not marked as spam. This requires a CNAME record for domain verification, a TXT record for DKIM signing, and a TXT record for DMARC policy.
To create a sending domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Sending Domains**
3. Click **Create Sending Domain**
4. Enter your desired sending subdomain (e.g. `mailing.company.com`)
5. Click **Create Domain**
Use a subdomain (e.g. `mailing.company.com`) instead of the root domain (`company.com`). A subdomain provides proper
reputation segmentation and is required if you also plan to receive emails with Lettr.
Click your new domain in the Sending Domains list.
This will display a list of DNS records that need to be configured. Keep this page open — you will need these values soon.
### Configure Vercel DNS
Log in to your [Vercel account](https://vercel.com/login) and select the **Domains** tab in your project dashboard. Find the domain you want to configure, then click the three vertical dots and select **Configure**.
In the Domain configuration, click **Enable Vercel DNS**. This allows you to manage your domain's DNS records directly in Vercel.
If your domain was purchased through Vercel or your nameservers already point to Vercel, skip nameserver configuration
entirely. Your domain is already using Vercel's nameservers by default — proceed directly to adding the DNS records
below.
If you registered your domain elsewhere but want to manage DNS on Vercel, you must first **update the nameservers**
at your registrar to Vercel's nameservers shown in the domain configuration.
Until the nameservers are updated, any records you add in Vercel will not resolve.
### Add CNAME Record
The CNAME record verifies domain ownership with Lettr's email infrastructure.
Copy the CNAME values from Lettr to Vercel:
1. Copy the **Hostname** from Lettr and paste it into the **Name** field in Vercel.
2. Expand the **Type** dropdown in Vercel and select **CNAME**.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Vercel.
4. Leave **TTL** set to 60 (Vercel default).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Vercel. For example, instead of `mailing.lettr-demo.com`,
paste only `mailing`.
### Add TXT Record (DKIM)
The DKIM record adds a cryptographic signature to your outgoing emails, allowing recipients to verify they were sent by an authorized sender.
Copy the TXT values from Lettr to Vercel:
1. Copy the **Hostname** from Lettr and paste it into the **Name** field in Vercel.
2. Expand the **Type** dropdown in Vercel and select **TXT**.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Vercel.
4. Leave **TTL** set to 60 (Vercel default).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Vercel. For example, instead of
`scph0126._domainkey.mailing.lettr-demo.com`, paste only `scph0126._domainkey.mailing`.
### Add TXT Record (DMARC)
The DMARC record tells receiving mail servers how to handle emails that fail authentication checks, protecting your domain from spoofing.
Copy the TXT values from Lettr to Vercel:
1. Copy the **Hostname** from Lettr and paste it into the **Name** field in Vercel.
2. Expand the **Type** dropdown in Vercel and select **TXT**.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Vercel.
4. Leave **TTL** set to 60 (Vercel default).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Vercel. For example, instead of
`_dmarc.mailing.lettr-demo.com`, paste only `_dmarc.mailing`.
### Verify Your Sending Domain
After adding all three DNS records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
Stuck on verification? If [Adamko](/learn/ai-assistant/troubleshooting-and-diagnostics#domain-verification-problems), Lettr's AI assistant, is enabled in your account, ask him *"why isn't my domain verifying?"* — he runs live DNS lookups, compares each record against what Lettr expects, and pinpoints exactly which record needs fixing.
***
## Inbound Domain Setup
An inbound domain allows Lettr to receive emails on your behalf. This requires three MX records that direct incoming mail to Lettr's mail servers.
### Add Inbound Domain to Lettr
To create an Inbound domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Inbound Domains**
3. Click **Create Inbound Domain**
4. Enter your desired inbound subdomain (e.g. `inbound.company.com`)
5. Click **Create Domain**.
Click on your new domain in the Inbound Domains list.
This will display the MX records that need to be configured.
### Add MX Records
MX records tell other mail servers where to deliver emails addressed to your domain.
Copy the MX values from Lettr to Vercel:
1. Copy the **Hostname** from Lettr and paste it into the **Name** field in Vercel.
2. Expand the **Type** dropdown in Vercel and select **MX**.
3. Copy the **Required MX Record** value (without the priority number) from Lettr and paste it into the **Value** field in Vercel.
4. Copy the **Priority** number (e.g. `10`) from Lettr and paste it into the **Priority** field in Vercel.
5. Leave **TTL** set to 60 (Vercel default).
6. Click **Add**.
7. Repeat this process for the second (rx2.sparkpostmail.com) and third (rx3.sparkpostmail.com) MX records.
Omit your domain suffix from the Hostname when pasting into Vercel. For example, instead of `inbound.lettr-demo.com`,
paste only `inbound`.
### Verify Your Inbound Domain
After adding all three MX records, go back to Lettr and click **Verify DNS Records**. DNS propagation can take up to 24–48 hours, though it typically completes within a few minutes.
***
## Tracking Domain Setup
A tracking domain allows Lettr to track email opens and link clicks using your own custom domain instead of the default Lettr tracking domain. This requires two CNAME records: one for the SSL certificate and one for routing tracking traffic to Lettr's infrastructure.
### Add Tracking Domain to Lettr
To create a Tracking domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Tracking Domains**
3. Click **Create Tracking Domain**
4. Enter your desired tracking subdomain (e.g. `tracking.company.com`)
5. Click **Create Domain**
Click on your new domain in the Tracking Domains list.
This will display the CNAME records that need to be configured.
### Add SSL Certificate CNAME Record
The SSL Certificate CNAME record provisions an SSL certificate for your custom tracking domain, enabling secure HTTPS connections for tracked links.
Add the record in Vercel:
1. Copy the **Hostname** from Lettr and paste it into the **Name** field in Vercel.
2. Expand the **Type** dropdown in Vercel and select **CNAME**.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Vercel.
4. Leave **TTL** set to 60 (Vercel default).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Vercel. For example, instead of `track.lettr-demo.com`,
paste only `track`.
### Add Traffic CNAME Record
The Traffic CNAME record routes click and open tracking requests from your custom domain to Lettr's tracking servers.
Add the record in Vercel:
1. Copy the **Hostname** from Lettr and paste it into the **Name** field in Vercel.
2. Expand the **Type** dropdown in Vercel and select **CNAME**.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Vercel.
4. Leave **TTL** set to 60 (Vercel default).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Vercel. For example, instead of `track.lettr-demo.com`,
paste only `track`.
### Verify Your Tracking Domain
After adding both CNAME records, go back to Lettr and click **Verify DNS Records**.
***
## Storage Domain Setup
A storage domain lets you serve email assets (images, attachments) from your own custom domain instead of the default Lettr storage URL. This requires two TXT records for certificate validation and ownership verification, and a CNAME record for routing asset requests to Lettr's storage infrastructure.
### Add Storage Domain to Lettr
To create a Storage domain in Lettr:
1. Select **Domains** in the navigation panel
2. Select **Storage Domains**
3. Click **Create Storage Domain**
4. Enter your desired storage subdomain (e.g. `assets.company.com`)
5. Click **Create Domain**
Click on your new domain in the Storage Domains list.
This will display the TXT and CNAME records that need to be configured.
### Add TXT Record (Certificate Validation)
The Certificate Validation TXT record provisions an SSL certificate for your custom storage domain, enabling secure HTTPS delivery of email assets.
Add the record in Vercel:
1. Copy the **Hostname** from Lettr and paste it into the **Name** field in Vercel.
2. Expand the **Type** dropdown in Vercel and select **TXT**.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Vercel.
4. Leave **TTL** set to 60 (Vercel default).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Vercel, just as with the CNAME record above.
### Add TXT Record (Hostname Pre-validation)
The Hostname Pre-validation TXT record verifies ownership of the storage domain before Lettr provisions a custom hostname for it.
Add the record in Vercel:
1. Copy the **Hostname** from Lettr and paste it into the **Name** field in Vercel.
2. Expand the **Type** dropdown in Vercel and select **TXT**.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Vercel.
4. Leave **TTL** set to 60 (Vercel default).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Vercel, just as with the CNAME record above.
### Add CNAME Record (Domain Routing)
The Domain Routing CNAME record routes asset requests from your custom domain to Lettr's storage infrastructure.
Add the record in Vercel:
1. Copy the **Hostname** from Lettr and paste it into the **Name** field in Vercel.
2. Expand the **Type** dropdown in Vercel and select **CNAME**.
3. Copy the **Value** from Lettr and paste it into the **Value** field in Vercel.
4. Leave **TTL** set to 60 (Vercel default).
5. Click **Add**.
Omit your domain suffix from the Hostname when pasting into Vercel. For example, instead of `assets.lettr-demo.com`,
paste only `assets`.
### Verify Your Storage Domain
After adding all three records, go back to Lettr and click **Verify DNS Records**.
***
## Troubleshooting
Vercel automatically appends your domain to the record name. If you paste the full hostname (e.g. `mailing.lettr-demo.com`), the resulting record will be `mailing.lettr-demo.com.lettr-demo.com`, which will fail verification.
Always paste only the subdomain portion (e.g. `mailing`, `scph0126._domainkey.mailing`, `_dmarc.mailing`).
If verification fails after adding records, check the following:
* **Wait at least 30 minutes** before your first verification attempt. Most records propagate within 1–2 hours.
* **Confirm the records exist** using command-line tools:
```bash theme={null}
# Check CNAME record
dig CNAME mailing.yourdomain.com +short
# Check DKIM record
dig TXT scph0126._domainkey.mailing.yourdomain.com +short
# Check DMARC record
dig TXT _dmarc.mailing.yourdomain.com +short
# Check MX records (inbound)
dig MX inbound.yourdomain.com +short
# Check tracking domain CNAME
dig CNAME track.yourdomain.com +short
# Check storage domain CNAME
dig CNAME assets.yourdomain.com +short
```
* **Use a web tool** like [dnschecker.org](https://dnschecker.org) to verify propagation across multiple DNS servers worldwide.
A common mistake is selecting the wrong type in Vercel's dropdown:
| Record | Correct Type |
| ------------------------------- | ------------ |
| Sending verification | CNAME |
| DKIM | TXT |
| DMARC | TXT |
| Inbound mail | MX |
| Tracking SSL certificate | CNAME |
| Tracking traffic | CNAME |
| Storage certificate validation | TXT |
| Storage hostname pre-validation | TXT |
| Storage domain routing | CNAME |
The DKIM TXT value is a long string. After saving the record in Vercel, re-open it to confirm the full value was stored. If it appears truncated, try pasting the value again.
If your records are saved in Vercel but not resolving, confirm that your domain registrar is pointing to Vercel's nameservers. You can check this with:
```bash theme={null}
dig NS yourdomain.com +short
```
The output should include Vercel nameservers (e.g. `ns1.vercel-dns.com`, `ns2.vercel-dns.com`). If it shows a different provider's nameservers, update them at your domain registrar. You can find the correct Vercel nameservers in your domain's configuration page under **Nameservers**.
If you do not see the option to add DNS records, make sure you clicked **Enable Vercel DNS** in the domain configuration. Without this step, Vercel only manages domain routing, not DNS records.
If your DNS records are correctly configured (confirmed with `dig` or dnschecker.org) and verification still fails after 48 hours, contact Lettr support at **[support@lettr.com](mailto:support@lettr.com)** or through the in-app chat. Include your domain name and the output of the `dig` commands above.
***
## Related Topics
Learn about sending domain setup, SPF, DKIM, and DMARC.
Configure MX records to receive emails with Lettr.
Set up a custom tracking domain for click and open tracking.
Serve email assets from your own custom domain.
Understand domain types and how they work in Lettr.
Troubleshoot common DNS configuration and propagation issues.
# BIMI: Brand Indicators for Message Identification
Source: https://docs.lettr.com/knowledge-base/fundamentals/bimi
How BIMI displays your verified brand logo in recipient inboxes, plus the DMARC enforcement and VMC certificate requirements it needs.
BIMI (Brand Indicators for Message Identification) is an email standard that lets you display your brand's logo next to your messages in recipient inboxes. Instead of a generic avatar or the recipient's initials, your verified logo appears — increasing brand recognition and signaling authenticity.
BIMI builds on top of existing email authentication. It requires a fully enforced [DMARC policy](/knowledge-base/fundamentals/spf-dkim-dmarc) and, for most mailbox providers, a Verified Mark Certificate (VMC) that proves you own the logo's trademark.
***
## How BIMI Works
BIMI uses a DNS TXT record to point mailbox providers to your brand's logo. When a message arrives, the receiving server checks whether the email passes DMARC authentication and then looks up the BIMI record to find and display the logo.
The receiving mail server authenticates the message using SPF, DKIM, and DMARC. BIMI only applies if DMARC passes with a policy of `p=quarantine` or `p=reject`. A `p=none` policy is not sufficient.
The receiving server queries DNS for a BIMI record at `default._bimi.yourdomain.com`. This TXT record contains the URL of your logo file and, optionally, a URL to your VMC certificate.
```
default._bimi.yourdomain.com TXT "v=BIMI1; l=https://example.com/logo.svg; a=https://example.com/cert.pem"
```
The server fetches the logo file and, if a VMC is provided, validates the certificate to confirm the logo is trademarked and the certificate is issued by an authorized Certificate Authority.
If all checks pass, the mailbox provider displays your logo in the inbox alongside your message. The exact placement varies by provider — Gmail shows it as the sender avatar, Apple Mail displays it as a verified brand indicator.
***
## Requirements
BIMI has several prerequisites that must be in place before your logo will appear.
### Authentication Requirements
| Requirement | Detail |
| ----------- | ---------------------------------------------------------------------------- |
| **SPF** | Must pass for your sending domain |
| **DKIM** | Must pass with alignment to your From domain |
| **DMARC** | Must be published with `p=quarantine` or `p=reject` — `p=none` is not enough |
BIMI will not work if your DMARC policy is set to `p=none`. You must enforce at least `p=quarantine` before mailbox providers will look up your BIMI record. See the [SPF, DKIM & DMARC guide](/knowledge-base/fundamentals/spf-dkim-dmarc) for how to progress your DMARC policy safely.
### Logo Requirements
Your logo must meet specific format requirements:
| Specification | Requirement |
| -------------- | ------------------------------------------------------------------------------ |
| **Format** | SVG Tiny PS (Portable/Secure profile) — not standard SVG |
| **Shape** | Square — the logo is displayed in a circle, so keep important content centered |
| **Background** | Non-transparent — must have a solid background color |
| **File size** | Under 32 KB |
| **Hosted at** | An HTTPS URL accessible to mailbox providers |
SVG Tiny PS is a restricted subset of SVG designed for security. It does not allow JavaScript, external references, or animations. Standard SVG files from design tools will need to be converted. Tools like the BIMI Group's SVG converter can help: [bimigroup.org](https://bimigroup.org/implementation-guide).
### Verified Mark Certificate (VMC)
A VMC is a digital certificate that proves your logo is a registered trademark and that you have the right to use it. VMCs are issued by authorized Certificate Authorities.
| Detail | Information |
| --------------------------- | ------------------------------------------------------------------------------------------- |
| **Required by** | Gmail (required), Apple Mail (required for blue checkmark) |
| **Not required by** | Yahoo Mail, Fastmail (will display logo without VMC) |
| **Trademark requirement** | Your logo must be registered with a recognized trademark office (e.g., USPTO, EUIPO, UKIPO) |
| **Certificate Authorities** | DigiCert and Entrust are the current authorized VMC issuers |
| **Validity period** | Typically 1 year — must be renewed |
| **Cost** | VMCs are a paid product — check with DigiCert or Entrust for current pricing |
***
## Setting Up BIMI
Verify that your domain has a DMARC record with `p=quarantine` or `p=reject` and that your emails are passing DMARC consistently. Check your DMARC record:
```bash theme={null}
dig TXT _dmarc.yourdomain.com
```
The response should show a policy of `quarantine` or `reject`:
```
v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.com
```
Create an SVG Tiny PS version of your logo:
1. Start with your brand logo in SVG format
2. Convert it to SVG Tiny PS profile (remove scripts, external references, animations)
3. Ensure it is square with a solid background
4. Keep the file under 32 KB
5. Host the file at a publicly accessible HTTPS URL
```
https://yourdomain.com/brand/logo.svg
```
If you want your logo to appear in Gmail:
1. Ensure your logo is a registered trademark
2. Contact DigiCert or Entrust to apply for a VMC
3. Complete the validation process (trademark verification, domain ownership)
4. Receive your VMC certificate file (PEM format)
5. Host the certificate at a publicly accessible HTTPS URL
```
https://yourdomain.com/brand/vmc.pem
```
Add a TXT record at `default._bimi.yourdomain.com`:
```
default._bimi.yourdomain.com TXT "v=BIMI1; l=https://yourdomain.com/brand/logo.svg; a=https://yourdomain.com/brand/vmc.pem"
```
If you do not have a VMC, you can omit the `a=` parameter:
```
default._bimi.yourdomain.com TXT "v=BIMI1; l=https://yourdomain.com/brand/logo.svg; a="
```
Confirm the DNS record is published:
```bash theme={null}
dig TXT default._bimi.yourdomain.com
```
You should see your BIMI record in the response.
***
## Mailbox Provider Support
BIMI adoption is growing but not yet universal. Here is the current state of support among major providers.
| Provider | BIMI Support | VMC Required? | Notes |
| --------------------------- | ------------ | ------------------- | ------------------------------------------------------------------ |
| **Gmail** | Yes | Yes | Displays logo as sender avatar. Shows a blue verified checkmark. |
| **Apple Mail** | Yes | Yes (for checkmark) | Displays logo in macOS and iOS Mail. Blue checkmark with VMC. |
| **Yahoo Mail** | Yes | No | Displays logo without VMC. One of the earliest BIMI adopters. |
| **Fastmail** | Yes | No | Displays logo without VMC. |
| **Outlook / Microsoft 365** | Limited | — | Microsoft has its own brand verification program (not BIMI-based). |
| **Thunderbird** | No | — | Does not support BIMI. |
***
## BIMI Record Syntax
The BIMI TXT record has a straightforward syntax:
```
v=BIMI1; l=; a=
```
| Tag | Required | Description |
| --------- | -------- | ------------------------------------------------------------------------------------------------------ |
| `v=BIMI1` | Yes | Version identifier |
| `l=` | Yes | HTTPS URL pointing to your SVG Tiny PS logo file |
| `a=` | No | HTTPS URL pointing to your VMC certificate in PEM format. Set to empty (`a=`) if you don't have a VMC. |
### Selector-Based BIMI
By default, the BIMI record is published at `default._bimi.yourdomain.com`. You can use different selectors for different email streams by changing the subdomain prefix. For example, `marketing._bimi.yourdomain.com` could display a different logo for marketing emails — though this is rarely used in practice.
***
## Common Mistakes
BIMI requires DMARC enforcement. If your DMARC policy is `p=none`, mailbox providers will not look up your BIMI record regardless of whether it exists. Progress your DMARC policy to at least `p=quarantine` — and ideally `p=reject` — before implementing BIMI.
A regular SVG file exported from Figma, Illustrator, or Inkscape will not work. BIMI requires the SVG Tiny PS (Portable/Secure) profile, which strips out scripts, external references, and other elements that pose security risks. Use a BIMI-specific SVG converter to produce a compliant file.
BIMI logos are displayed in a circular frame by most providers. If your logo is not centered within a square canvas, important parts may be clipped. Design your logo with padding so the key visual element is centered and visible within a circle crop.
The logo URL in your BIMI record must use HTTPS. HTTP URLs will be rejected. Ensure the URL is publicly accessible — mailbox providers need to fetch the file from their servers.
After publishing your BIMI record, it may take days or weeks before logos start appearing consistently. DNS propagation, provider caching, and the provider's own processing timeline all contribute to the delay. BIMI is not instant.
***
## Related Topics
BIMI requires DMARC enforcement — understand the authentication stack first.
Set up and verify your sending domain in Lettr.
How your domain and IP reputation affect inbox placement.
Comprehensive guide to securing your email sending infrastructure.
# Bounce Codes Reference
Source: https://docs.lettr.com/knowledge-base/fundamentals/bounce-codes-reference
Reference for SMTP response and enhanced status codes, covering soft versus hard bounces and the recommended action for each in Lettr.
Every time an email is sent, the receiving mail server responds with an SMTP status code indicating whether the message was accepted, temporarily deferred, or permanently rejected. Lettr surfaces these codes in your **dashboard** and via **`email.bounced` webhook events**, so understanding them helps you diagnose delivery issues quickly.
***
## How SMTP Response Codes Work
SMTP response codes are three-digit numbers returned by a receiving mail server during or after the message transfer. The **first digit** determines the overall class of the response:
| First Digit | Class | Meaning |
| ----------- | ----------------- | ------------------------------------------------------------------------------------------------------------ |
| **2xx** | Success | The server accepted the message for delivery. |
| **4xx** | Temporary Failure | The server could not process the message right now but may accept it later. These generate **soft bounces**. |
| **5xx** | Permanent Failure | The server will never accept this message. These generate **hard bounces**. |
Modern mail servers also return **Enhanced Status Codes** (defined in RFC 3463) in the format `x.y.z`, such as `5.1.1`. These provide more granular detail about the failure and are explained in a [later section](#enhanced-status-code-structure).
***
## Success Codes
These codes indicate the message was accepted by the receiving server.
| Code | Meaning |
| ------- | ---------------------------------------------------------------------------- |
| **250** | Message accepted for delivery. This is the standard success response. |
| **251** | User not local; the server is forwarding the message to another destination. |
A `250` response means the receiving server accepted the message — it does not guarantee inbox placement. The server may still filter the message to spam or reject it at a later stage.
***
## Temporary Failure Codes — Soft Bounces
Soft bounces are transient failures. Lettr automatically retries delivery for soft bounces according to its retry schedule. If retries are exhausted without success, the bounce may be reclassified as a hard bounce.
| Code | Enhanced Code | Meaning | Recommended Action |
| ------- | ------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| **421** | 4.7.0 | Server temporarily unavailable or rate limiting | Auto-retry. Lettr handles this automatically. |
| **450** | 4.2.1 | Mailbox temporarily unavailable | Auto-retry. The mailbox may be locked or temporarily offline. |
| **451** | 4.3.0 | Server configuration issue on the receiving end | Auto-retry. Usually resolves on its own. |
| **452** | 4.2.2 | Mailbox full or over quota | Auto-retry. If the mailbox remains full across multiple attempts, this may be promoted to a hard bounce. |
| **454** | 4.7.0 | TLS negotiation failed; TLS not available | Retry without TLS if your sending policy allows opportunistic encryption. |
Lettr retries soft bounces automatically with exponential backoff. You do not need to resend these messages manually. Monitor the **Activity Log** in your dashboard to track retry progress.
***
## Permanent Failure Codes — Hard Bounces
Hard bounces are definitive rejections. The receiving server will not accept this message regardless of how many times it is sent. Lettr automatically adds hard-bounced addresses to your suppression list to protect your sender reputation.
| Code | Enhanced Code | Meaning | Recommended Action |
| ------- | ------------- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
| **550** | 5.1.1 | User unknown — mailbox does not exist | Remove the address from your list. |
| **550** | 5.1.2 | Bad destination domain — domain does not exist or has no MX records | Remove the address from your list. |
| **550** | 5.2.1 | Mailbox disabled or deactivated | Remove the address from your list. |
| **550** | 5.7.1 | Message rejected by policy (spam filter, blocklist, or authentication failure) | Check your content, authentication records (SPF/DKIM/DMARC), and sender reputation. |
| **551** | 5.1.6 | User not local and server will not forward | Remove the address from your list. |
| **552** | 5.2.3 | Message exceeds size limits | Reduce the message size (compress images, remove large attachments). |
| **553** | 5.1.3 | Invalid mailbox name syntax | Fix the email address format (check for typos or illegal characters). |
| **554** | 5.7.1 | Transaction failed — general rejection | Investigate the full bounce message for details. May indicate blocklisting or content issues. |
Continuing to send to hard-bounced addresses damages your sender reputation and can lead to your IP or domain being blocklisted. Lettr suppresses these addresses automatically — do not remove them from your suppression list unless you have confirmed the address is valid again.
***
## Enhanced Status Code Structure
Enhanced Status Codes follow the format **`x.y.z`** where each component has a specific meaning:
* **x** — Class (matches the first digit of the basic SMTP code)
* `2` = Success
* `4` = Temporary failure
* `5` = Permanent failure
* **y** — Subject category (what part of the system the issue relates to)
* **z** — Detail (specific condition within that category)
### Subject Categories
| Subject (y) | Category | Description |
| ----------- | ----------------- | ------------------------------------------------------------------------- |
| **0** | Other / Undefined | Status does not fit other categories. |
| **1** | Addressing | Problems with the recipient or sender address. |
| **2** | Mailbox | Issues with the destination mailbox (full, disabled, not found). |
| **3** | Mail System | Problems with the destination mail system. |
| **4** | Network | Network-level issues (DNS, routing, connection). |
| **5** | Protocol | Protocol-related failures during the SMTP transaction. |
| **6** | Content | The message content triggered a rejection (encoding, media type). |
| **7** | Security | Security or policy violations (authentication, encryption, blocklisting). |
For example, `5.1.1` means: **permanent failure** (`5`) related to **addressing** (`.1.`) with detail code **1** (mailbox does not exist).
***
## Provider-Specific Codes
Major mailbox providers often return custom error messages alongside standard SMTP codes. Below are common patterns you may encounter.
| Error Message Pattern | Meaning | What to Do |
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `550 5.1.1 The email account that you tried to reach does not exist` | The Gmail address is invalid or has been deleted. | Remove the address from your list. |
| `421 4.7.28 ... rate limited` | Gmail is throttling your sending due to volume or reputation. | Reduce sending speed. Lettr retries automatically. |
| `550 5.7.1 Our system has detected that this message is likely unsolicited mail` | Gmail's spam filters flagged your message. | Review your content, authentication, and list hygiene. |
| `550 5.7.26 Unauthenticated email ... is not accepted due to domain's DMARC policy` | Your message fails DMARC alignment. | Ensure SPF and DKIM are properly configured and aligned with your From domain. |
| Error Message Pattern | Meaning | What to Do |
| -------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------ |
| `550 5.1.1 User unknown` | The Outlook/Hotmail address does not exist. | Remove the address from your list. |
| `550 5.7.1 Service unavailable, client host [x.x.x.x] blocked` | Your sending IP is on a Microsoft blocklist. | Check your IP against the Outlook SNDS portal and request delisting if needed. |
| `451 4.7.500 Server busy. Please try again later` | Microsoft is rate limiting connections. | Lettr retries automatically. |
| `550 5.5.0 Requested action not taken: mailbox unavailable` | Mailbox is disabled or deleted. | Remove the address from your list. |
| Error Message Pattern | Meaning | What to Do |
| --------------------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------- |
| `553 5.1.3 Invalid address` | The Yahoo/AOL address is malformed or does not exist. | Remove the address or fix formatting. |
| `421 4.7.0 [TS01] ... temporarily deferred` | Yahoo is throttling your messages due to sending patterns or reputation. | Reduce volume. Lettr retries automatically. |
| `554 5.7.9 Message not accepted for policy reasons` | Your message was rejected due to Yahoo's content or authentication policies. | Review DKIM/SPF configuration and message content. |
| `421 4.7.1 [TS03] ... too many connections` | Too many simultaneous connections from your IP. | Lettr manages connection pooling automatically. |
***
## How Lettr Categorizes Bounces
Lettr maps raw SMTP response codes to standardized bounce categories that appear in your dashboard and in `email.bounced` webhook payloads. This makes it easier to take action without interpreting SMTP codes directly.
| Lettr Category | SMTP Codes / Conditions | Description |
| ------------------ | -------------------------------------- | -------------------------------------------------------------------------------- |
| `invalid_address` | 550 5.1.1, 553 5.1.3 | The recipient address does not exist or is malformed. |
| `domain_not_found` | 550 5.1.2 | The recipient domain does not exist or has no MX records. |
| `mailbox_full` | 452 4.2.2, 552 5.2.2 | The recipient mailbox is over its storage quota. |
| `blocked` | 550 5.7.1 (IP/domain block), 554 5.7.1 | The receiving server blocked delivery due to reputation or blocklisting. |
| `spam_related` | 550 5.7.1 (content rejection) | The message was flagged as spam by the receiving server. |
| `policy_related` | 550 5.7.1 (authentication), 551 5.1.6 | Rejected due to authentication failure, DMARC policy, or other sending policies. |
| `server_error` | 451 4.3.0, 421 4.7.0 | A temporary server-side issue on the receiving end. |
| `protocol_error` | 454 4.7.0, 552 5.2.3 | A protocol-level failure such as TLS negotiation or message size limits. |
| `unknown` | Any unrecognized or ambiguous response | The bounce could not be classified into a specific category. |
You can filter bounces by category in the **Activity** section of your dashboard, or use the `category` field in `email.bounced` webhook events to automate list management in your application.
***
## Related Topics
Step-by-step guide to investigating and resolving bounce issues.
How Lettr manages bounced addresses and suppression lists.
Understand the full email delivery pipeline from send to inbox.
Reference for all webhook events including email.bounced payloads.
# Email Content Types: HTML, Plain Text, and AMP
Source: https://docs.lettr.com/knowledge-base/fundamentals/content-types
When to use HTML, plain text, and AMP email content types in Lettr, what each supports, and how email clients render them.
Every email you send through Lettr contains content in one or more formats. The three supported content types are **HTML** for rich formatting, **plain text** for universal compatibility, and **AMP HTML** for interactive experiences. Understanding when and how to use each format directly affects how your emails render, how accessible they are, and how mailbox providers evaluate them.
Lettr's API accepts three corresponding parameters: `html`, `text`, and `amp_html`. At least one of `html` or `text` is required for every send.
***
## HTML Email
HTML is the most common email content format. It allows you to include styling, images, links, buttons, and structured layouts that make emails visually engaging.
### What HTML Email Supports
* Custom fonts, colors, and spacing
* Images and background images referenced from a public URL
* Clickable buttons and hyperlinks
* Multi-column layouts using tables
* Open and click tracking via tracking pixels and link wrapping
### Limitations Compared to Web HTML
HTML email is not the same as HTML on the web. Email clients strip or ignore many features that browsers handle without issue:
| Feature | Web HTML | Email HTML |
| ----------------------- | --------------- | ------------------------ |
| JavaScript | Fully supported | Completely stripped |
| External CSS (``) | Supported | Ignored by most clients |
| CSS Flexbox / Grid | Supported | Unreliable — use tables |
| `