Skip to content

Email

Lettr
API integration

Ship Email features without building the integration. Full Lettr API access via Proxy and 70+ MCP-ready tools for AI agents — extend models and mappings to fit your product.

Talk to us
Lettr

Use Cases

Why integrate with Lettr

Common scenarios for SaaS companies building Lettr integrations for their customers.

01

Embed Lettr as your native email engine

Let your users connect their Lettr account to power both marketing campaigns and transactional sends directly from your SaaS, without making them context-switch into Lettr's dashboard.

02

Sync customer data into Lettr audiences

Keep your SaaS's contact records continuously in sync with Lettr audience lists, topics, and segments so marketers always send to accurate, up-to-date subscriber states.

03

Trigger lifecycle and transactional emails

Fire scheduled or immediate emails from product events — onboarding, order shipped, appointment reminders — and safely cancel them if conditions change before send time.

04

Pipe engagement events back into your product

Pull open, click, bounce, and delivery events from Lettr into your CRM timeline, lead scoring engine, or analytics dashboard to close the loop on email performance.

05

Offer white-label domain provisioning

Programmatically create and verify sending domains on behalf of your users so they can start sending from their own domain without ever logging into Lettr.

What You Can Build

Ship these features with Truto + Lettr

Concrete product features your team can ship faster by leveraging Truto’s Lettr integration instead of building from scratch.

01

Bulk contact sync

Use bulk contact creation and bulk topic/list assignment to push thousands of subscribers into Lettr in a single pass during initial onboarding or scheduled CDP syncs.

02

Template-aware email composer

Fetch a user's Lettr templates and their required merge tags to auto-generate a mapping UI where your SaaS fields are bound to Lettr template variables.

03

Scheduled send with cancellation

Queue emails up to 30 days in advance via scheduled emails and cancel them by ID if a downstream event (purchase, cancellation, status change) makes the send obsolete.

04

Campaign dispatch from your UI

Create a Lettr campaign, target it to a segment or list, and trigger send — all from inside your own product's campaign builder.

05

Engagement event ingestion

Register Lettr webhooks or poll email and campaign event endpoints to stream opens, clicks, and bounces into your contact timelines in near real time.

06

Domain onboarding wizard

Guide users through adding a sending domain, then call the verify endpoint to confirm DNS setup without leaving your onboarding flow.

SuperAI

Lettr AI agent tools

Comprehensive AI agent toolset with fine-grained control. Integrates with MCP clients like Cursor and Claude, or frameworks like LangChain.

lettr_audience_contact_lists_bulk_create

Bulk attach contacts to lists (POST /api/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. Required: contact_ids, list_ids.

lettr_audience_contact_lists_bulk_delete

Bulk detach contacts from lists (DELETE /api/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. Required: contact_ids, list_ids.

create_a_lettr_audience_contact_list

Attach contact to list (POST /api/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. Required: contact_id, list_id.

delete_a_lettr_audience_contact_list_by_id

Detach contact from list (DELETE /api/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. Lettr answers 204 with no body. Required: id, contact_id.

lettr_audience_contact_topics_bulk_create

Bulk subscribe contacts to topics (POST /api/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. Required: contact_ids, topic_ids.

lettr_audience_contact_topics_bulk_delete

Bulk unsubscribe contacts from topics (DELETE /api/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. Required: contact_ids, topic_ids.

create_a_lettr_audience_contact_topic

Subscribe contact to topic (POST /api/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. Required: contact_id, topic_id.

delete_a_lettr_audience_contact_topic_by_id

Unsubscribe contact from topic (DELETE /api/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. Lettr answers 204 with no body. Required: id, contact_id.

list_all_lettr_audience_contacts

List audience contacts (GET /api/audience/contacts). List contacts with pagination and filtering. Requires the `audience:read` scope. Truto pages with page / per_page (limit = page size, at most 100) until the last page.

create_a_lettr_audience_contact

Create a contact (POST /api/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. Required: email.

lettr_audience_contacts_bulk_create

Bulk create contacts (POST /api/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.

get_single_lettr_audience_contact_by_id

Show a contact (GET /api/audience/contacts/{contactId}). Retrieve a single contact. Requires the `audience:read` scope. Required: id.

update_a_lettr_audience_contact_by_id

Update a contact (PATCH /api/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. Required: id.

delete_a_lettr_audience_contact_by_id

Delete a contact (DELETE /api/audience/contacts/{contactId}). Permanently delete a contact. Requires the `audience:write` scope and is blocked for sandbox API keys. Lettr answers 204 with no body. Required: id.

list_all_lettr_audience_lists

List audience lists (GET /api/audience/lists). Returns all audience lists for the authenticated team. Requires the `audience:read` scope. Truto pages with page / per_page (limit = page size, at most 100) until the last page.

create_a_lettr_audience_list

Create an audience list (POST /api/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. Required: name.

lettr_audience_lists_bulk_delete

Bulk delete audience lists (DELETE /api/audience/lists/bulk). Delete up to 50 lists in a single request. All `list_ids` must belong to the authenticated team. If any list has segments restricted to it, nothing is deleted and the response is `409` `list_in_use`. Requires the `audience:write` scope and is blocked for sandbox API keys. Required: list_ids.

get_single_lettr_audience_list_by_id

Show an audience list (GET /api/audience/lists/{listId}). Retrieve a single audience list. Requires the `audience:read` scope. Required: id.

update_a_lettr_audience_list_by_id

Update an audience list (PATCH /api/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. Required: id.

delete_a_lettr_audience_list_by_id

Delete an audience list (DELETE /api/audience/lists/{listId}). Permanently delete an audience list. A list that segments are restricted to cannot be deleted (`409` `list_in_use`): remove the restriction from those segments or delete them first. Requires the `audience:write` scope and is blocked for sandbox API keys. Lettr answers 204 with no body. Required: id.

list_all_lettr_audience_properties

List audience properties (GET /api/audience/properties). List the team's custom contact properties. Requires the `audience:read` scope. Truto pages with page / per_page (limit = page size, at most 100) until the last page.

create_a_lettr_audience_property

Create a property (POST /api/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. Required: name, type.

get_single_lettr_audience_property_by_id

Show a property (GET /api/audience/properties/{propertyId}). Retrieve a single property. Requires the `audience:read` scope. Required: id.

update_a_lettr_audience_property_by_id

Update a property (PATCH /api/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. Required: id.

delete_a_lettr_audience_property_by_id

Delete a property (DELETE /api/audience/properties/{propertyId}). Permanently delete a property. Requires the `audience:write` scope and is blocked for sandbox API keys. Lettr answers 204 with no body. Required: id.

list_all_lettr_audience_segments

List audience segments (GET /api/audience/segments). List segments with pagination. Requires the `audience:read` scope. Truto pages with page / per_page (limit = page size, at most 100) until the last page.

create_a_lettr_audience_segment

Create a segment (POST /api/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. Required: name, conditions.

get_single_lettr_audience_segment_by_id

Show a segment (GET /api/audience/segments/{segmentId}). Retrieve a single segment. Requires the `audience:read` scope. Required: id.

update_a_lettr_audience_segment_by_id

Update a segment (PATCH /api/audience/segments/{segmentId}). Partially update a segment. Requires the `audience:write` scope and is blocked for sandbox API keys. Required: id.

delete_a_lettr_audience_segment_by_id

Delete a segment (DELETE /api/audience/segments/{segmentId}). Permanently delete a segment. Requires the `audience:write` scope and is blocked for sandbox API keys. Lettr answers 204 with no body. Required: id.

list_all_lettr_audience_topics

List audience topics (GET /api/audience/topics). List topics with pagination. Requires the `audience:read` scope. Truto pages with page / per_page (limit = page size, at most 100) until the last page.

create_a_lettr_audience_topic

Create a topic (POST /api/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. Required: name.

get_single_lettr_audience_topic_by_id

Show a topic (GET /api/audience/topics/{topicId}). Retrieve a single topic. Requires the `audience:read` scope. Required: id.

update_a_lettr_audience_topic_by_id

Update a topic (PATCH /api/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. Required: id.

delete_a_lettr_audience_topic_by_id

Delete a topic (DELETE /api/audience/topics/{topicId}). Permanently delete a topic. Requires the `audience:write` scope and is blocked for sandbox API keys. Lettr answers 204 with no body. Required: id.

list_all_lettr_auth_check

Validate API Key (GET /api/auth/check). Validate the provided API key and return associated team information. Use this endpoint to verify API key validity in client libraries.

list_all_lettr_campaign_events

List campaign engagement events (GET /api/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`. Truto pages with the cursor (limit = page size, at most 100) until next_cursor is null. Required: campaign_id.

create_a_lettr_campaign_schedule

Schedule a campaign (POST /api/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. Required: campaign_id, scheduled_at.

lettr_campaign_schedules_cancel

Unschedule a campaign (POST /api/campaigns/{campaignId}/unschedule). Cancels a scheduled send, returning the campaign to `draft`. Also clears a delivery time staged on a `draft` in the web editor, so the draft can then be sent with the send endpoint. The campaign must be `scheduled`, or a `draft` with a staged delivery time. Requires the `campaigns:write` scope. Not available to sandbox keys. Required: campaign_id.

list_all_lettr_campaigns

List campaigns (GET /api/campaigns). Returns a paginated list of campaigns for the authenticated team, each with embedded engagement stats. Requires the `campaigns:read` scope. Truto pages with page / per_page (limit = page size, at most 100) until the last page.

create_a_lettr_campaign

Create a campaign (POST /api/campaigns). Creates a draft campaign. Give the content as `html_content` (optionally with the editor's `json_content`) or as a `template_id`, whose HTML is copied onto the campaign. Every list, segment, topic and template must belong to your team. The sender domain is checked when the campaign is sent, not here; language override senders are checked here and must use a verified sending domain. idempotency_key is sent as the Idempotency-Key header.

get_single_lettr_campaign_by_id

Show a campaign (GET /api/campaigns/{campaignId}). Retrieve a single campaign with embedded stats and rendered HTML content. Requires the `campaigns:read` scope. Required: id.

lettr_campaigns_send

Send a campaign now (POST /api/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. Required: campaign_id.

list_all_lettr_domains

List Domains (GET /api/domains). Retrieve all sending domains registered with your account. Returns domains with their current status, verification state, and timestamps.

create_a_lettr_domain

Create Domain (POST /api/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. Adding a domain your team already has returns `409` and leaves its DNS records and verification status unchanged. Required: domain.

get_single_lettr_domain_by_id

Get Domain (GET /api/domains/{domain}). Retrieve details of a single sending domain including DNS records and tracking domain configuration. Required: id.

delete_a_lettr_domain_by_id

Delete Domain (DELETE /api/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. Lettr answers 204 with no body. Required: id.

lettr_domains_verify

Verify Domain (POST /api/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. Required: domain.

list_all_lettr_email_events

List Email Events (GET /api/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. Truto pages with the cursor (limit = page size, at most 100) until next_cursor is null. Lists (events, recipients) are sent comma-separated.

create_a_lettr_email

Send Email (POST /api/emails). Send a transactional email with optional attachments, tracking, and personalization. At least one of `html` or `text` content must be provided. Supply `Idempotency-Key` for safe retries using SparkPost native transmission idempotency. Keys are namespaced per Lettr API key and retained by SparkPost for 24 hours. idempotency_key is sent as the Idempotency-Key header. Required: from, to.

list_all_lettr_emails

List Sent Emails (GET /api/emails). Retrieve a paginated list of sent emails. Supports filtering by recipient email and date range. Uses cursor-based pagination. Truto pages with the cursor (limit = page size, at most 100) until next_cursor is null.

get_single_lettr_email_by_id

Get Email Detail (GET /api/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. Required: id.

list_all_lettr_folders

List Folders (GET /api/folders). Retrieve a paginated list of the folders in a project, so a template can be filed into the right one. Truto pages with page / per_page (limit = page size, at most 100) until the last page.

list_all_lettr_health

Health Check (GET /api/health). Check the health status of the API. This endpoint does not require authentication.

list_all_lettr_projects

List Projects (GET /api/projects). Retrieve a paginated list of projects for the authenticated team. Truto pages with page / per_page (limit = page size, at most 100) until the last page.

create_a_lettr_scheduled_email

Schedule Email (POST /api/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 30 days. Required: from, to, scheduled_at.

list_all_lettr_scheduled_emails

List Scheduled Emails (GET /api/emails/scheduled). List the scheduled emails of your team, newest first. Requires the `emails:read` scope. Truto pages with page / per_page (limit = page size, at most 100) until the last page.

get_single_lettr_scheduled_email_by_id

Get Scheduled Email (GET /api/emails/scheduled/{transmissionId}). Retrieve a scheduled email by the `request_id` returned when it was scheduled (`sch_...`). Required: id.

delete_a_lettr_scheduled_email_by_id

Cancel Scheduled Email (DELETE /api/emails/scheduled/{transmissionId}). Cancel a scheduled email before it is injected into SparkPost, and return the cancelled email. Required: id.

list_all_lettr_template_html

Get Template HTML (GET /api/templates/html). Retrieve the HTML content and merge tags for a template's active version. Requires `project_id` and template `slug` as query parameters. Required: project_id, slug.

list_all_lettr_template_merge_tags

Get Template Merge Tags (GET /api/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. Required: slug.

list_all_lettr_templates

List Templates (GET /api/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. Truto pages with page / per_page (limit = page size, at most 100) until the last page.

create_a_lettr_template

Create Template (POST /api/templates). Create a new email template with HTML or Topol editor JSON content. Automatically creates and publishes a template version with extracted merge tags. Required: name.

get_single_lettr_template_by_id

Get Template (GET /api/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. Required: id.

delete_a_lettr_template_by_id

Delete Template (DELETE /api/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. Required: id.

update_a_lettr_template_by_id

Update Template (PUT /api/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. Required: id.

list_all_lettr_webhooks

List Webhooks (GET /api/webhooks). Retrieve all webhooks configured for your account. Returns webhooks with their current status, event types, and delivery information.

create_a_lettr_webhook

Create Webhook (POST /api/webhooks). Create a new webhook to receive event notifications at the specified URL. Required: name, url, auth_type, events_mode.

get_single_lettr_webhook_by_id

Get Webhook (GET /api/webhooks/{webhookId}). Retrieve details of a single webhook including its status, event types, and delivery information. Required: id.

update_a_lettr_webhook_by_id

Update Webhook (PUT /api/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. Required: id.

delete_a_lettr_webhook_by_id

Delete Webhook (DELETE /api/webhooks/{webhookId}). Delete a webhook. This removes the webhook from SparkPost and it will no longer receive event notifications. Required: id.

Why Truto

Why use Truto’s MCP server for Lettr

Other MCP servers give you a static tool list for one app. Truto gives you a managed, multi-tenant MCP infrastructure across 1050+ integrations.

01

Auto-generated, always up to date

Tools are dynamically generated from curated documentation — not hand-coded. As integrations evolve, tools stay current without manual maintenance.

02

Fine-grained access control

Scope each MCP server to read-only, write-only, specific methods, or tagged tool groups. Expose only what your AI agent needs — nothing more.

03

Multi-tenant by design

Each MCP server is scoped to a single connected account with its own credentials. The URL itself is the auth token — no shared secrets, no credential leaking across tenants.

04

Works with every MCP client

Standard JSON-RPC 2.0 protocol. Paste the URL into Claude, ChatGPT, Cursor, or any MCP-compatible agent framework — tools are discovered automatically.

05

Built-in auth, rate limits, and error handling

Tool calls execute through Truto’s proxy layer with automatic OAuth refresh, rate-limit handling, and normalized error responses. No raw API plumbing in your agent.

06

Expiring and auditable servers

Create time-limited MCP servers for contractors or automated workflows. Optional dual-auth requires both the URL and a Truto API token for high-security environments.

How It Works

From zero to integrated

Start with Lettr in a free sandbox, usually ready within one business day. No boilerplate, no maintenance burden.

01

Link your customer’s Lettr account

Use Truto’s frontend SDK to connect your customer’s Lettr account. We handle all OAuth and API key flows — you don’t need to create the OAuth app.

02

We handle authentication

Don’t spend time refreshing access tokens or figuring out secure storage. We handle it and inject credentials into every API request.

03

Call our API, we call Lettr

Truto’s Proxy API is a 1-to-1 mapping of the Lettr API. You call us, we call Lettr, and pass the response back in the same cycle.

04

Unified response format

Every response follows a single format across all integrations. We translate Lettr’s pagination into unified cursor-based pagination. Data is always in the result attribute.

FAQs

Common questions about Lettr on Truto

Authentication, rate limits, data freshness, and everything else you need to know before you integrate.

How do end users authenticate their Lettr account?

Users connect their Lettr account via Truto's managed auth flow. Truto handles credential storage and token lifecycle so you never touch the raw API keys in your application code.

Can I sync large audiences without hitting rate limits?

Yes. Lettr exposes bulk endpoints for contacts, contact lists, and contact topics, letting you create or delete records in batches rather than one call per contact, which is the recommended path for initial syncs and large daily updates.

How do I know which variables a Lettr template needs?

You can list a template's merge tags via the template merge tags endpoint. This lets you dynamically render a mapping UI so users can bind your SaaS data fields to the exact variables their Lettr template expects.

Can I cancel a scheduled email before it sends?

Yes. Scheduled emails can be retrieved and deleted by ID before they're dispatched, which is useful for cart recovery, appointment reminders, or any workflow where the triggering condition may reverse.

How fresh is engagement data (opens, clicks, bounces)?

You can either register a webhook to receive events as they happen, or poll the email events and campaign events endpoints on a schedule. Both endpoints support cursor-based pagination for reliable incremental ingestion.

Does the integration support provisioning sending domains for my users?

Yes. You can create a domain, fetch its DNS requirements, and trigger verification programmatically, so users can complete domain setup inside your product rather than logging into Lettr directly.

Lettr

Get Lettr integrated into your app

Our team understands what it takes to make a Lettr integration successful. A short, crisp 30 minute call with folks who understand the problem.