Send a letter
const url = 'https://api.tryletterhead.com/api/v3/letters/actions/send';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"api":true,"channel":"an-example-channels","html":"<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title>Test</title></head><body><h1>Hello from Postman</h1><p>This is a test letter sent via the <strong>/api/v3/letters/actions/send</strong> endpoint.</p><p><a href=\"https://letterhead.co\">Visit Letterhead</a></p></body></html>","segment":0,"subject":"Who doesn\'t love a good movie?","subtitle":"A new exhibition, two openings, and a closer look at this season\'s residency.","tags":["a-tag-of-my-choosing"]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.tryletterhead.com/api/v3/letters/actions/send \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "api": true, "channel": "an-example-channels", "html": "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title>Test</title></head><body><h1>Hello from Postman</h1><p>This is a test letter sent via the <strong>/api/v3/letters/actions/send</strong> endpoint.</p><p><a href=\"https://letterhead.co\">Visit Letterhead</a></p></body></html>", "segment": 0, "subject": "Who doesn'\''t love a good movie?", "subtitle": "A new exhibition, two openings, and a closer look at this season'\''s residency.", "tags": [ "a-tag-of-my-choosing" ] }'Send a letter from the HTML you provide. The edition is queued as soon as the request succeeds and goes out within about a minute. Note that because you are providing your own HTML, you will not be able to edit this edition with our composer.
Opens and clicks are tracked automatically with no markup required on your part, subject to a few limits, and the channel must resolve to Letterhead’s own sending path or the request is rejected. See Sending your own HTML: what’s tracked and what’s required for the full detail, including the HTML validation rules that can get a request rejected.
-
api: Boolean flag indicating the request is being made via the API. -
channel: Channel slug to associate the draft with. -
html: Full HTML content for the letter body. -
segment: Segment identifier to target a subset of the channel audience;0applies to all subscribers. -
subject: Draft subject/title. -
suppress(optional): Array of channel slugs used to suppress recipients who are also subscribed to those channels. -
subtitle(optional): Populates the email preview text shown in inbox previews after the subject, so the Letterhead UI only needs the send date filled in. Max 191 chars. -
tags(optional): Newsletter tags applied to the created letter. Use this to label a send with your own internal identifier; tags are reused across sends and listed underGET /api/v3/letters/tags. Max 20 items, each ≤ 60 chars. Names are trimmed and deduped case-insensitively.
Tracking: Opens and clicks are tracked automatically — there’s nothing to add to your HTML for either. Only <a href=""> links are tracked; a bare URL in the body text is not. A link whose href still contains a {{ }} merge tag or a [[ ]] data-feed expression is left untouched and won’t be tracked, since rewriting it would break the expression — resolve those in your HTML before sending if you want the link tracked.
Unsubscribe: This endpoint never inserts an unsubscribe link into your HTML — include a working one yourself.
Requirements: The channel must be on Letterhead’s own sending infrastructure — if it’s connected to a third-party ESP, the request is rejected with a 400 (use createADraft instead, then test, schedule, or send the draft from Letterhead). Your HTML is also validated before sending: <iframe>, <form>, <input>, <embed>, <object>, <applet>, <frame>, and <frameset> tags are rejected, along with onclick/onload attributes and any {{ }} merge tag Letterhead doesn’t recognize. Markup that can’t be parsed is also rejected — a common cause is a literal & that should be &, including inside link query strings. A request that fails any of these checks returns 400 with a message describing what to fix.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
Required. Set to true to authenticate with an API key.
The channel you are targeting.
This endpoint is designed for you to use your own HTML.
Identify a specific subset of your channel’s list. Pass 0 to send to every subscriber.
The subject line. Max 191 chars, and it must contain at least one non-whitespace character.
(optional) Email preview text shown in inbox previews after the subject. Max 191 chars.
(optional) Channel slugs whose subscribers should be left out of this send, so someone subscribed to both channels only hears from you once. Every slug must belong to a channel your company owns.
(optional) Newsletter tags applied to the created letter. Max 20 items, each ≤ 60 chars. Names are trimmed and deduped case-insensitively.
Example
{ "api": true, "channel": "an-example-channels", "html": "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title>Test</title></head><body><h1>Hello from Postman</h1><p>This is a test letter sent via the <strong>/api/v3/letters/actions/send</strong> endpoint.</p><p><a href=\"https://letterhead.co\">Visit Letterhead</a></p></body></html>", "segment": 0, "subject": "Who doesn't love a good movie?", "subtitle": "A new exhibition, two openings, and a closer look at this season's residency.", "tags": [ "a-tag-of-my-choosing" ]}Responses
Section titled “ Responses ”Send
object
object
Example
{ "items": { "uniqueId": "ludctamgd6", "publicationDate": "2026-05-06 05:53:05" }, "message": "Your html letter will be sent shortly.", "total": 0}400 Validation Error — returned when the request body fails validation, when the submitted HTML is rejected (a disallowed tag or attribute, an unrecognized merge tag, or markup that can’t be parsed), or when the channel isn’t on Letterhead’s own sending infrastructure. data carries the individual validation error strings when there are any.
object
object
Example
{ "data": [], "items": [], "message": "The html send endpoint is only available on channels that resolve to Letterhead's native email service provider; channel an-example-channel resolves to a third-party ESP. Create the letter as a draft instead, then test, schedule, or send it from Letterhead.", "total": 0}Still can’t find what you need? Contact support.