Code samples
Edit in CMSEach task below is shown three ways: with the TypeScript package, with the letterhead command line, and as a plain HTTP request with curl. To set up the package or the command line, see Installing the TypeScript SDK and CLI. For every parameter, see the API reference.
The TypeScript examples assume a client created like this:
import { createLetterheadClient } from '@tryletterhead/sdk';
const letterhead = createLetterheadClient({ apiKey: process.env.LETTERHEAD_API_KEY! });The curl examples use $LETTERHEAD_API_KEY for your key and https://acme.api.tryletterhead.com for your API address; swap in your own (see Getting started with the Letterhead API). Where a newsletter is named, use its slug, such as my-newsletter.
Add a contact and subscribe them to a newsletter
Section titled “Add a contact and subscribe them to a newsletter”Adding a contact puts them in your company audience, or updates them if a contact with that email already exists. Subscribing them to a newsletter is a second step. A subscription status of 1 means subscribed.
await letterhead.contacts.createASubscription({ body: { channel: 'my-newsletter', status: 1 },});letterhead contacts create-a-subscription --email [email protected] --channel my-newsletter --status 1curl -X POST "https://acme.api.tryletterhead.com/api/v3/contacts" \ -H "Authorization: Bearer $LETTERHEAD_API_KEY" \ -H "Content-Type: application/json" \
curl -X POST "https://acme.api.tryletterhead.com/api/v3/contacts/person%40example.org/subscriptions" \ -H "Authorization: Bearer $LETTERHEAD_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api": true, "channel": "my-newsletter", "status": 1}'Tags you name are applied to the contact. Custom field values go in customFields, keyed by a field name that already exists for your company.
Curate a story
Section titled “Curate a story”Curating a story adds it to your company’s curation library, ready to drop into a newsletter. Letterhead saves exactly the fields you send and doesn’t read the page for you, so pass the title, excerpt and image yourself. Name newsletters in channels[] to share the story with only those; leave it out to share it with every newsletter. Sending the same url again updates the story rather than adding a second copy.
const { items } = await letterhead.curations.curateOrUpdateContent({ body: { url: 'https://example.org/stories/spring-openings', title: 'Spring openings', excerpt: 'Two new galleries open downtown this weekend.', image: 'https://example.org/images/spring.jpg', 'channels[]': ['my-newsletter'], },});letterhead curations curate-or-update-content \ --url https://example.org/stories/spring-openings \ --title "Spring openings" \ --excerpt "Two new galleries open downtown this weekend." \ --image https://example.org/images/spring.jpg \ --channels my-newslettercurl -X POST "https://acme.api.tryletterhead.com/api/v3/curations" \ -H "Authorization: Bearer $LETTERHEAD_API_KEY" \ -F "api=true" \ -F "url=https://example.org/stories/spring-openings" \ -F "title=Spring openings" \ -F "excerpt=Two new galleries open downtown this weekend." \ -F "image=https://example.org/images/spring.jpg" \ -F "channels[]=my-newsletter"The response’s items.uniqueId identifies the story for the other curation endpoints. To add many stories in one request, see Adding curations in bulk.
Send a newsletter
Section titled “Send a newsletter”You can send a newsletter from your own HTML. It’s queued as soon as the request succeeds and goes out within about a minute, so send to yourself first. A segment of 0 sends to every subscriber of the newsletter.
const html = `<!DOCTYPE html><html><body> <h1>Spring openings</h1> <p>Two new galleries open downtown this weekend. <a href="https://example.org/stories/spring-openings">Read more</a></p> <p><a href="{{ unsubscribe }}">Unsubscribe</a></p></body></html>`;
await letterhead.letters.sendALetter({ body: { channel: 'my-newsletter', subject: 'Spring openings', subtitle: 'Two new galleries this weekend', html, segment: 0 },});letterhead letters send-a-letter --body @letter.jsonwhere letter.json holds the same fields:
{ "channel": "my-newsletter", "subject": "Spring openings", "subtitle": "Two new galleries this weekend", "segment": 0, "html": "<!DOCTYPE html><html><body><h1>Spring openings</h1><p><a href=\"{{ unsubscribe }}\">Unsubscribe</a></p></body></html>"}curl -X POST "https://acme.api.tryletterhead.com/api/v3/letters/actions/send" \ -H "Authorization: Bearer $LETTERHEAD_API_KEY" \ -H "Content-Type: application/json" \ -d @letter.jsonFor curl, add "api": true to letter.json; the package and the command line add it for you.
Before you send, know these:
- Add your own unsubscribe link. Sending your own HTML never adds one for you. Use the
{{ unsubscribe }}merge tag, as above. - The newsletter must send through Letterhead. If it sends through another email service, the request is refused. Create a draft instead with
createADraft(letterhead letters create-a-draft), which takes the same fields, then test, schedule or send it from Letterhead. - Opens and clicks are tracked for you, with a few limits, and some HTML is rejected.
Sending your own HTML covers tracking, merge tags and what can get a send refused.
If a request fails in a way the error message doesn’t explain, contact support.
Still can’t find what you need? Contact support.