Skip to content

Herald

Gets the message there.

One API and SMTP for every email Mentor, Sidekick and Hallelo send, from sign-in codes and receipts to launches and newsletters. Each project is kept apart from every other, and every email goes out under the product’s own name.

Already set up? Open Console

 

How it works

The life of an email

From your app to the inbox, and the news back to you, in five steps. Every one of them is a standard you can check.

01

Accept

Your app calls the API or speaks SMTP. Herald checks the key, that the sender’s domain is verified and yours, the day’s quota and who’s suppressed, then answers in milliseconds. An idempotency key makes a retry safe: the same key, the same answer, one email.

import { Herald } from '@heraldmail/sdk'

const herald = new Herald(process.env.HERALD_API_KEY)

const { data, error } = await herald.emails.send(
  {
    from: 'Mentor <hello@mentor.app>',
    to: 'ada@example.com',
    subject: 'Your sign-in link',
    html: '<p>Sign in to Mentor: <a href="https://mentor.app/s/8Fq2">continue</a></p>',
  },
  { idempotencyKey: 'sign-in/8Fq2' },
)

02

Compose

Each recipient gets their own copy: a Message-ID, and a return path only Herald can read back, so a bounce or complaint finds its way to the right person in the right project. Proclamations carry one-click unsubscribe.

The headers Herald writes
From: Mentor <hello@mentor.app>
To: ada@example.com
Subject: Your sign-in link
Message-ID: <emq7xk2rd4f5.0.ab3d@mentor.app>
Return-Path: <b-5hssj.k3mxq7v2rd.2c4a9f@send.mentor.app>
Feedback-ID: signin:mentor:transactional:herald
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="--h1"

03

Sign

Two DKIM signatures: your domain’s, so your mail is aligned with DMARC, and Herald’s own, so complaint loops and Gmail’s Postmaster Tools can report back. The private keys never leave Herald’s keyring.

DKIM-Signature
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mentor.app;
  s=herald; h=from:from:to:to:subject:subject:date:date:message-id:message-id;
  bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; b=JmYw9q…
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=heraldmail.email;
  s=herald; h=from:from:to:to:subject:subject:date:date:message-id:message-id;
  bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; b=Wq81Hc…

04

Deliver

KumoMTA delivers it at each provider’s pace, from the project’s own pool of addresses. It always tries TLS, and enforces MTA-STS and DANE where a domain asks for them.

SMTP, to the recipient’s server
S: 220 mx.google.com ESMTP
C: EHLO mta-1.heraldmail.email
S: 250-STARTTLS
C: STARTTLS
   … TLS 1.3, certificate checked against MTA-STS …
C: MAIL FROM:<b-5hssj.k3mxq7v2rd.2c4a9f@send.mentor.app>
C: RCPT TO:<ada@example.com>
C: DATA
S: 250 2.0.0 OK 1793648712 x7si2215204wmb.142 - gsmtp

05

Report

Deliveries, bounces and complaints come back and are matched by the token in the return path, never by an address someone could forge. Your webhook hears about each one, signed, and retried for three days if it doesn’t answer.

A signed webhook
POST https://mentor.app/webhooks/herald
webhook-id: msg_2c4a9f6e1d0b
webhook-timestamp: 1793648713
webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=

{
  "type": "email.delivered",
  "created_at": "2026-11-02T20:31:53.204Z",
  "data": {
    "email_id": "01a19dcd-361c-7342-ab15-8ef7fe4529a1",
    "from": "Mentor <hello@mentor.app>",
    "to": ["ada@example.com"],
    "subject": "Your sign-in link"
  }
}

Isolation

Each project on its own

Mentor can’t read Sidekick’s mail, reach its contacts, or send from its domain, even by mistake. Isolation isn’t a filter in the code: the database, the keys and the mail servers all enforce it.

  • Row-level security on every table

    Postgres answers only for the project in the request’s context, live or test.

  • A key for each project

    Its mail and secrets are sealed under its own data key, which only the keyring can open.

  • Its own queues

    The mail servers queue and pause each project apart: stopping one stops nobody else.

  • Tokens that can’t be reused

    Every link and return path is signed for its project; another project’s token resolves nothing.

How Herald keeps mail safe
Mentor
  • Domains and keys
  • Contacts and lists
  • Templates
  • Suppression list
  • Webhooks
  • Data key
  • Queues and pool
Sidekick
  • Domains and keys
  • Contacts and lists
  • Templates
  • Suppression list
  • Webhooks
  • Data key
  • Queues and pool
Hallelo
  • Domains and keys
  • Contacts and lists
  • Templates
  • Suppression list
  • Webhooks
  • Data key
  • Queues and pool

Domains

Four records, and you’re sending

Add a domain and Herald gives you its records: DKIM for your signature, a return path for bounces (your own SPF is left alone), and DMARC. Each one turns green as it’s found, and Herald keeps checking: Console shows you if one goes missing.

The DNS guide
mentor.appNot found

Add these at your DNS provider, then check. A demonstration: nothing is looked up.

PurposeTypeHostValueStatus
DKIMTXTherald._domainkeyv=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1o…Not found
SPFTXTsendv=spf1 include:_spf.heraldmail.email -allNot found
Return pathMXsend10 mx.heraldmail.emailNot found
DMARCTXT_dmarcv=DMARC1; p=none;Not found

Guardrails

Stopped before it costs you

A bought list or an unwanted newsletter can ruin a domain’s reputation in an afternoon. Herald watches every broadcast at every mailbox provider, starts with a canary, and stops before Gmail’s and Yahoo’s lines, not after.

  • Broadcasts to 200 people or more send a 5% canary first; the rest waits for it.
  • Imports prove themselves: a sample goes first, and a list that bounces is held.

A Proclamation to 5,000 people at one provider. Move the sliders.

Sending

Inside every line. It goes on, batch by batch.

Standards

Built on the standards, not around them

  • RFC 5321 · SMTP
  • RFC 6376 · DKIM
  • RFC 8463 · Ed25519 DKIM
  • RFC 7208 · SPF
  • RFC 7489 · DMARC
  • RFC 8461 · MTA-STS
  • RFC 7672 · DANE
  • RFC 8058 · One-click unsubscribe
  • RFC 3464 · Delivery status
  • RFC 5965 · Complaint reports
  • RFC 9457 · Problem details
  • Standard Webhooks · Signed webhooks
Every standard Herald implements

Send your first email in five minutes

An API key from Console, a verified domain, and one call. Test keys never send to anyone: their mail lands in Console’s Test inbox.

The quickstart