Skip to content
Letterhead Letterhead Letterhead Help Center
Admin Tools

Coming from Sailthru

Edit in CMS

If you’re moving to Letterhead from Sailthru and you have reporting built on its API, this article maps what you’re calling today onto the Letterhead API, field by field.

What’s covered here: the three reads teams most often depend on — list statistics, per-campaign statistics, and profile data. Sailthru’s other APIs, such as those for sending, templates, or purchase events, aren’t mapped yet. If you rely on one of those, tell us which and we’ll extend this guide.

This is about reading data. If you’d rather keep Sailthru as your sending provider for now and use Letterhead only to build newsletters, that’s a different setup — see Create newsletters in Letterhead while sending through your own ESP.

Most field-level questions answer themselves once the nouns match up.

In SailthruIn LetterheadWhat changes
SiteCompanyAn API key is scoped to a company and covers every newsletter in it.
List — the newsletter itselfNewsletter (channel)Identified by a short text slug rather than a numeric ID.
List — a saved querySegmentA live query over your audience, not a stored copy of it. Defined once for the whole company.
BlastNewsletter editionIdentified by a unique ID rather than a numeric one.
ProfileContactIdentified by the email address itself.

There’s no export job to request and poll. Sailthru’s pattern of requesting an export, polling until it’s ready, then downloading a CSV has no counterpart, because there’s nothing to wait for. Newsletter and audience statistics are ordinary requests that answer immediately, and bulk contact reads page through results with a cursor. Letterhead does offer emailed CSV exports, covered at the end, but none of the reporting below needs one.

Email addresses come back in the clear. Contact records carry the actual address. If your Sailthru exports request hashed addresses, you can drop the hashing parameter and whatever you do downstream to match those hashes against your own records — Letterhead identifies a contact by the address itself.

Sailthru needs three calls per list — inventory, last send time, statistics. In Letterhead each of these answers for every newsletter at once.

GET /api/v3/channels returns every newsletter in your company. Each one carries the slug you’ll use everywhere else, its title, and its type.

The newsletter’s creation date isn’t part of this response.

There’s no “last send” field on a newsletter. Read it from the editions list instead, which covers every newsletter in one request rather than one request per list:

GET /api/v3/letters?allChannels=true&orderBy=publicationDate&asc=false

Each edition carries its publication date, title, newsletter, unique ID, and status. Add channels[]=<slug> to narrow to particular newsletters.

Two endpoints cover what stat=list returns, and between them they go further:

  • GET /api/v3/metrics/portfolio-health — the latest snapshot for every newsletter: total subscribers, new subscribers, unsubscribes, net growth, cleaned addresses, and the five engagement groups described below.
  • POST /api/v3/metrics/audience — the same audience over a date range you choose, with a daily series and a comparison against the previous period. Pass groupBy: "channel" for a per-newsletter breakdown.
Sailthru statisticLetterhead
email_counttotalSubscribers, or totalAudienceMembers for everyone including unsubscribed
active_countactiveSubscribers
engaged_countloyalistsCount plus newAndEngagedCount
passive_countcasualCount
disengaged_countfadingCount, or totalDisengaged if you want the status rather than the behavior
dormant_countghostsCount
new_countnewSubscribers
optout_countunsubscribes for a chosen window, totalUnsubscribes for all time
hardbounce_countHard-bounced addresses move to a cleaned state, so totalCleaned is the newsletter-level figure. Exact bounce counts are per edition — see below.
lists_countsingleNewsletterCount is the inverse: subscribers who read only this newsletter. For genuine cross-newsletter membership, use GET /api/v3/contacts/overlap.

Two more rollups have no Sailthru equivalent and may save you some assembly: GET /api/v3/contacts/overview returns company-wide totals plus how many newsletters are growing, holding steady, or need attention, and GET /api/v3/contacts/metrics/groups breaks subscribers down by group and newsletter with growth and health for each.

Where a Sailthru list is really a saved query, the equivalent is a segment. Segments are defined once at company level and evaluated live, so “engaged openers” is one segment you ask about per newsletter rather than a query you maintain separately on every list. Add ?channel=<slug> to any read below to scope it to a single newsletter.

What you wantEndpoint
The segments that exist, and which newsletters they apply toGET /api/v3/contacts/segments
One segment, including its live definitionGET /api/v3/contacts/segments/{segmentId}
How many contacts are in it right nowGET /api/v3/contacts/segments/{segmentId}/count
Who’s in it, pagedPOST /api/v3/contacts/segments/{segmentId}/preview
Its engagement over timeGET /api/v3/contacts/segments/{segmentId}/engagement-timeline
The same figures for your whole audience, as a baselineGET /api/v3/contacts/engagement-timeline

The engagement timelines return, for each day, how many contacts were delivered to, how many opened, how many clicked, and how many bounced, along with the rates those imply. Append /csv to either timeline endpoint for the same data as a file.

Reading a segment’s definition alongside its count is worth doing: it lets you record what a number actually counted, which is something a stored list membership can’t tell you later.

Letterhead classifies subscribers by how they’ve engaged with recent editions, without anyone having to define a rule. These groups are the closest equivalent to Sailthru’s engagement levels, and you can use them anywhere a segment is accepted.

GroupWho’s in it
LoyalistsOpened at least three of the last five editions
New & EngagedJoined in the last 30 days and engaging
CasualOpens intermittently — also where subscribers sit when a newsletter is too new to judge
FadingEngagement declining across recent editions
GhostsHasn’t opened any of the last ten editions

Counts for these come from GET /api/v3/metrics/portfolio-health, which returns them for every newsletter in a single request. GET /api/v3/contacts/metrics/groups gives each group as a share of the newsletter’s audience, with an up, down, or steady trend.

Older accounts may also see a newsletter-level segment list at /api/v3/audience/segments. That one exists for setups that send through an outside provider — if you’re sending with Letterhead, build against the company-level segment endpoints above.

This is where the most work disappears. Sailthru makes you list campaigns and then fetch statistics one campaign at a time; Letterhead returns identity and performance in the same rows.

POST /api/v3/letters/metrics takes a page number, a sort direction, a date range, and an optional list of newsletters. The envelope’s total is the number of published editions matching your filter, so paging is straightforward. If you only care about one newsletter, POST /api/v3/letters/metrics-by-channel does the same with a single authorization step.

Sailthru fieldLetterhead
blasts[].blast_iduniqueId
blasts[].nametitle
blasts[].listchannel, plus segmentNames and suppressedSegmentNames when the edition was sent to particular segments
blasts[].start_timepublicationDate
countaccepted, with delivered alongside it
open_totalopens, with opensUnique and opensUniqueConfirmed
confirmed_opensopensUniqueConfirmed
beaconprefetchedOpensLegacy
estopensprojectedOpenRate — a rate rather than a count
click_totalclicks, with clicksUnique, realClickRate, and nhiClicks
hardbouncehardBounces, with hardBounceRate
softbouncesoftBounces, with softBounceRate
optoutunsubscribed
subjecttitle is the edition’s title. For subject-line performance specifically, use GET /api/v3/letters/subject-line-performances.

Two counts you may be used to seeing folded together

Section titled “Two counts you may be used to seeing folded together”

Letterhead separates two populations that most providers mix into their totals, so you can report on real readers if you want to:

  • prefetchedOpensLegacy is opens recorded because a mail app fetched the tracking image on the reader’s behalf, rather than because a person opened the message.
  • nhiClicks is clicks from security scanners and other automated systems rather than people.

Both are reported separately instead of being rolled into opens and clicks, so your open and click rates can be computed either way.

A few reads have no equivalent in what you’re replacing:

  • POST /api/v3/metrics — company-wide totals with a daily series and a previous-period comparison.
  • GET /api/v3/letters/{uniqueId}/links and GET /api/v3/letters/{uniqueId}/click-links — per-link click detail for a single edition.
  • POST /api/v3/metrics/clicks/topics and POST /api/v3/metrics/clicks/topic-share — clicks grouped by subject, and how much you publish on a subject against how much readers click it.
  • GET /api/v3/links — every link you’ve sent, deduplicated across editions.
  • GET /api/v3/letters/{uniqueId}/opens-by-hour — the open curve for one edition.
  • GET /api/v3/health/insights — deliverability signals and recommendations per newsletter.

Sailthru’s request, poll, download, aggregate sequence becomes a single loop.

POST /api/v3/contacts/browse pages through your audience with a cursor: make the request, use the cursor it returns to ask for the next page, and repeat until it’s exhausted. You can filter by newsletter, subscription status, tag, custom field, segment, date added, or an explicit list of addresses, and sort by name, email, status, or date added. POST /api/v3/contacts/search is the lighter keyword-and-tag search over the same data.

These are the columns most Sailthru profile exports carry. If yours includes something not listed, it’s most likely a custom variable, which maps to a custom field.

Sailthru columnLetterhead
Profile IdThe email address is the identifier; there’s no separate profile ID
Email Hashemail, unhashed
DomainSplit it from the email address — it isn’t stored separately
Profile Created DatecreatedAt
SignupEach subscription carries its own createdAt, so you get one per newsletter rather than one per profile
EngagementNot a field on the contact. GET /api/v3/contacts/{email}/engagement returns that contact’s deliveries, unique opens, unique clicks, bounces, and the rates those imply. For whole cohorts, use the engagement groups above.
Custom variables such as date of birth, gender, or sourcecustomFields, which you can also filter on when browsing

Each contact also carries first and last name, tags, and a list of subscriptions, each with its newsletter, status, and dates.

  • GET /api/v3/contacts/{email} — the full record.
  • GET /api/v3/contacts/{email}/activity — that contact’s event history: opens, clicks, bounces with a reason, and more.
  • GET /api/v3/contacts/{email}/last-active — when they last engaged.
  • GET /api/v3/contacts/{email}/suppressions — why they’re being held back, if they are.

POST /api/v3/contacts/export accepts the same filters as browsing, runs in the background, and emails you a CSV: first and last name, email, your custom fields, tags, and one column per newsletter showing membership. It doesn’t include engagement or date-added columns — browse for those.

POST /api/v3/reports/export emails a clicks, engagement, or growth report across the newsletters and date range you choose.

Sailthru fieldWhere it stands
pvLetterhead reports on the email itself, so there’s no on-site pageview figure.
spam per campaignNot returned by the edition statistics endpoint.
spam_count per listNot available as a per-newsletter figure over the API. Deliverability signals per newsletter come from GET /api/v3/health/insights.
source_countSource isn’t a built-in dimension. Store it as a custom field, then filter and count on it when browsing contacts.
DomainDerive it from the email address.
List creation dateNot part of the newsletter list response.
Per-list last send timeDerive it from the editions list — one request covers every newsletter.

Still can’t find what you need? Contact support.