$ features
Everything a transactional email needs. Nothing it doesn't.
Pharos does one job: get a receipt, a password reset or an alert from your application into somebody's inbox. Every capability below exists to serve that, and every one of them is on every plan.
01 Two ways in, one pipeline
Post JSON from new code, or point an existing mailer at the relay. They are not two products with different behaviour — the same queue, the same signing, the same alignment checks, the same event log.
curl -X POST https://api.pharos.email/v1/send \
-H "Authorization: Bearer $PHAROS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "receipts@yourapp.com",
"to": "customer@example.com",
"subject": "Your receipt from Acme",
"html": "<p>Thanks for your order.</p>"
}' # change the host, change nothing else
MAIL_HOST=smtp.pharosinfra.net
MAIL_PORT=587
MAIL_ENCRYPTION=tls
MAIL_USERNAME=$PHAROS_SMTP_USER
MAIL_PASSWORD=$PHAROS_SMTP_PASS
# 250 2.0.0 Ok — signed, aligned, queued -
idempotent
A retried request with the same key sends once. A network timeout never doubles a receipt.
-
no SDK required
Plain HTTP and plain SMTP. Nothing to install, nothing to keep up to date, nothing to audit.
-
same events either way
An SMTP send produces the same webhooks and the same log entries as an API send.
02 Sender domains
Add a domain, add four records, and Pharos verifies every one before it will send from it. Verified domains are re-checked daily, because a DKIM key that was correct in March is not evidence about today.
- → As many domains and subdomains as you need, on every plan
- → Separate API keys and webhooks per domain
- → A domain that fails verification cannot send — no silent unsigned mail
- TXT v=spf1 include:pharosinfra.net ~all SPF OK
- TXT ph1._domainkey v=DKIM1; k=rsa; p=MIIBIj… DKIM OK
- TXT _dmarc v=DMARC1; p=quarantine; adkim=s ALIGNED
- CNAME bounce → bounce.pharosinfra.net RETURN-PATH
Subject: Your receipt from {{ company }}
Hi {{ first_name }},
Order {{ order_id }} is confirmed.
Total: {{ total }}
{% if tracking_url %}
Track it: {{ tracking_url }}
{% endif %} 03 Templates
Keep the copy out of your codebase. Send a template name and a set of variables instead of a rendered body, and change the wording without shipping a release.
- → Versioned — every edit is a new version, and you can roll back
- → Variables and conditionals, so one template covers the variants
- → Preview against real variable values before it goes live
- → Plain-text alternative generated alongside the HTML
04 Events, webhooks and the log
Every message produces the same event stream whether you sent it over the API or the relay. Read it in the dashboard, or have it posted to your endpoint and verify the signature.
- delivered The receiving server accepted the message.
- bounced It refused, with its own reason code attached.
- complained The recipient marked it as spam.
- deferred Temporarily rejected; Pharos retries on a backoff.
- opened Tracking pixel loaded, where tracking is on.
- clicked A tracked link in the message was followed.
// every webhook carries a signature header
const expected = crypto
.createHmac("sha256", PHAROS_WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
if (!crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(req.headers["x-pharos-signature"])
)) return res.status(401).end(); 05 Suppression
A hard bounce or a spam complaint adds that address to your suppression list, and Pharos will not attempt it again. This is not a courtesy — repeatedly mailing addresses that reject you is the fastest way to lose a sending reputation.
- → Per account, visible and exportable
- → Remove an address yourself when you know it is fixed
- → Suppressed sends do not count against your monthly volume
06 API keys
Issue one key per application, per environment, or per agent. Revoking the key your staging box uses should never take production down with it, so each one stands alone.
- → Scoped to a domain, revoked individually
- → Last-used timestamp, so dead keys are findable
- → Shown once at creation and never again
The specifics.
The details you would otherwise have to open a support ticket to find out.
- Send protocols
- HTTPS · SMTP (587, STARTTLS)
- Body formats
- HTML · plain text · both
- Authentication applied
- SPF · DKIM · DMARC (strict)
- Return path
- Pharos-managed, per domain
- Sender domains
- unlimited, every plan
- Event log retention
- 120 days, every plan
- Max message size
- 50 MB including attachments
- Rate limit
- 5 messages/second
The rate limit is a steady-state ceiling, not a monthly cap — 5 messages a second is roughly 430,000 a day, comfortably above every plan's allowance. A burst above it is queued and drained rather than rejected.
All of it, on the free plan.
3,000 emails a month, every feature on this page, no card required.
start free