FAQ

Questions, answered properly

The things people actually ask about Posthaste, with real answers rather than a sentence that avoids the question.

Is this the right thing for me?

The questions people ask before they read any documentation.

I just need an email service to send emails from my app. Is this it?

Yes, as long as the emails are ones your application sends to a person because that person did something — signing up, resetting a password, placing an order, being invited. That is what transactional email means, and it is all this does.

If what you need is to send the same message to a list of people at once, that is marketing email and we do not accept it. Everything else about sending is one HTTPS request.

How do I send emails from my website?

Your website’s server-side code makes the request; the browser never does. Verify the domain you want to send from, create an API key, and POST the message to /v1/emails.

Keep the key on the server. An API key in front-end JavaScript is readable by anyone who opens the page, and can then be used to send mail as you.

Is this an alternative to SendGrid, Mailgun, Resend or Amazon SES?

It does the same job: your application makes one HTTPS request and a transactional email — a password reset, a receipt, a verification code — arrives.

The difference worth comparing is who runs the mail servers. We run ours: the message is signed and delivered by our own infrastructure straight to the recipient, and we keep the entire SMTP conversation so you can read back exactly what the receiving server said. When a provider sends through a third party, the answer to "what happened to this message" can only be as detailed as what that third party passes back.

Why are my emails going to spam?

Usually one of four things: the sending domain is not authenticated, the sending IP has no reputation, the reverse DNS does not match the name the server introduces itself with, or the content looks like bulk mail.

We sign every message with DKIM from a domain you have verified, the sending IP’s reverse DNS and HELO name agree by design, and volume ramps gradually rather than starting at full speed — a brand-new IP sending thousands on day one is the fastest way to be filtered. What we cannot do is make a domain trusted overnight. Nobody can.

Why did my email bounce, and how do I find out?

Every message keeps the receiving server’s own words. Not a category, not a code we invented — the actual response its mail server gave, stored against the message.

That is the difference between "delivery failed" and knowing the recipient’s server said the mailbox is full, or that it does not exist, or that it wants you to slow down. The first tells you nothing you can act on.

My emails are not arriving and I do not know why. Where do I start?

Read the delivery record for the message. It holds the whole conversation with the recipient’s server, so the question becomes what the far end actually said rather than what we guessed it meant.

The common causes are a domain that is not verified, an address on your suppression list from an earlier bounce, or a message accepted and then deferred by the recipient. All three look identical from the outside and are told apart immediately by the record.

Do I need to run my own mail server?

No. Running the mail servers is the part we do. You make one HTTPS request.

The reason it is worth knowing we run them is that it determines what we can tell you afterwards, and who your mail’s reputation depends on.

Can I use SMTP instead of the API?

Not today — sending is over the HTTPS API only. If you have an existing application that only speaks SMTP, this will not drop in as-is, and it is better to know that now than after an afternoon of configuration.

The mail server we run does listen on port 25, but that is for receiving bounces from the wider internet, not for accepting your mail.

How do I send email from a Node, Next.js or serverless app?

One POST to /v1/emails with an API key. There is no SDK to install and no connection to keep open, so it works anywhere that can make an HTTPS request — a server, a container, a serverless function, an edge runtime.

The quickstart in the documentation is a complete working request in Node and curl.

Is there a free tier?

Yes — 5,000 emails a month at $0, across up to 3 domains, with 30 days of delivery records.

Webhooks and delivery records are not charged for on any plan, including this one.

What is the difference between an email API and an SMTP relay?

An SMTP relay accepts mail from your application over the same protocol mail servers use between themselves, and forwards it. An email API accepts an HTTPS request describing the message and builds it for you.

In practice the API is easier to call from modern application code and from environments where holding an SMTP connection is awkward, and it makes per-message status straightforward to report back. We are the second kind.

Can I send newsletters or marketing campaigns?

No, and the refusal is deliberate. Bulk campaigns carry a different complaint profile from transactional mail, and on shared infrastructure one bad list damages inbox placement for every other sender on it.

Turning the category away is worth more to your password resets than the revenue would be.

Getting started

What it takes to send your first message.

What do I actually need to set up?

One DNS record. You add a domain, we generate a DKIM key pair for it, and you publish the public half as a TXT record. Once we can see it, the domain is verified and you can send.

We deliberately do not ask you to change your SPF record. A domain may publish only one SPF record, and replacing yours with ours would break every other system that sends as you — your CRM, your helpdesk, your invoicing tool.

Why is SPF not required?

DMARC passes when either SPF or DKIM aligns with the visible sender domain. We sign every message with a key belonging to your domain, so DKIM alignment on its own satisfies DMARC.

The envelope sender on our mail is our own bounce domain, which is what lets us attribute a bounce to an exact send. SPF is evaluated against that envelope domain, which is ours — so an SPF record on your domain would not be doing the work people assume it does.

How long does domain verification take?

As long as your DNS takes to propagate — usually minutes, occasionally up to an hour. You can re-check on demand rather than waiting for a polling cycle.

If the record is wrong we tell you what we found instead of just saying "not verified", because the usual causes are a provider appending your domain to the record name twice, or splitting a long TXT value incorrectly.

Can I try it without a domain?

Not for real sending, no. Sending from an unverified domain is how a platform becomes a spoofing service, so it is refused outright rather than queued and quietly failed.

Sending and delivery

What happens between your API call and the recipient.

What happens when I call the API?

We run the cheap checks first — address shape, whether your domain is verified, whether the recipient is suppressed — and refuse immediately with a reason if any fail. Nothing is queued that we already know will not be sent.

If it passes, the message, its content, its delivery job and its first event are written in a single database transaction, then acknowledged. There is no window where a message is accepted but its job is missing, so a crash after acknowledgement cannot lose it.

What does "we run our own mail servers" actually mean?

We operate the mail transfer agent and the IP it sends from. When your message goes out, our software looks up the recipient domain’s MX records, opens an SMTP connection to their server, negotiates TLS, and conducts the conversation itself.

Most providers hand that step to Amazon SES or similar. That is the difference behind everything else on this site: you can only give somebody the receiving server’s own words if you were the one talking to it.

Is mail encrypted in transit?

We negotiate STARTTLS with the receiving server whenever it offers it, which is the overwhelming majority of mail today.

Where a receiver offers no TLS at all, the alternative to sending in the clear is not delivering — so we deliver and record exactly what the connection was. The details are in that message’s record rather than hidden behind a summary.

What if I send the same request twice?

Pass an idempotency key and we deliver once. The second call returns the original message id rather than an error, so a client can retry blindly after a timeout without worrying about double-sending a receipt.

Do you support attachments, HTML, and custom headers?

HTML and plain text alternatives, custom headers, reply-to and List-Unsubscribe, yes. Attachments are on the list but not shipped — see the changelog rather than trusting this page to stay current.

Bounces and suppression

What happens when a message does not get through.

How do you know which message a bounce belongs to?

Every message goes out with a unique, signed return path. When a bounce comes back it addresses that return path, so attribution is exact rather than a guess based on the recipient address.

This matters more than it sounds: the same address may have received five messages from you this week, and "which one bounced" is the difference between a useful record and a shrug.

What is the difference between a bounce and a deferral?

A permanent refusal (a 5xx response — no such mailbox, domain does not exist) is a bounce. We stop, record it, and suppress the address immediately.

A temporary refusal (a 4xx — greylisting, rate limits, a full mailbox) is a deferral. We retry on a backoff and we never suppress, because suppressing on a transient error would make a perfectly good address unreachable forever.

Can I remove an address from the suppression list?

You can remove a suppression you created yourself, or one caused by a bounce you know has been fixed. You cannot remove a complaint suppression — somebody marked your mail as spam, and sending to them again is what gets an IP blocklisted.

Do you handle complaints from feedback loops?

Yes. Complaint reports are parsed, attributed to the exact message, and the address is suppressed. Your complaint rate also feeds the warmup governor, which will lower your daily cap before a receiver starts acting on it.

Limits and deliverability

Why your cap is what it is, and how it moves.

Why can I only send 200 emails on my first day?

Because a new sending IP has no reputation, and volume that appears out of nothing looks exactly like a compromised host. Ramping gradually is what the receiving side expects from a legitimate sender.

The cap climbs one rung at a time — 200, 500, 1,000, 2,500, 5,000 and upward — after each day where you used at least 80% of it with complaints at or under 0.1% and bounces at or under 5%.

What happens if I hit the cap?

The API returns 429 with the limit, how much of it you have used, and a Retry-After header pointing at the reset, which is midnight UTC. Nothing is silently queued for tomorrow — a refused message was never accepted, so you decide what to do with it.

You can also check where you stand at any time without hitting a refusal: GET /v1/me reports your daily limit, what you have sent today and what remains.

Can I pay to skip the warmup?

No. The cap protects every other customer sharing the infrastructure, so it is not for sale. A dedicated IP changes the shape of the ramp because the reputation being built is yours alone, but there is still a ramp.

Will my email land in the inbox?

We cannot promise that, and neither can anyone else honestly. Placement is decided by the receiving provider based on your domain reputation, your content and our IP reputation.

What we can promise is that you will see exactly what happened, including the receiving server’s own diagnostic text when something went wrong — which is what lets you fix it rather than file a ticket.

Webhooks and records

Getting events out of Posthaste and into your systems.

How do I know a webhook really came from you?

Every delivery carries a timestamped HMAC signature over the raw request body. Verify it with a constant-time comparison and reject anything outside your tolerance window.

One trap worth naming: verify the raw bytes before parsing the JSON. A body that has been parsed and re-serialised will not match the signature, and the resulting bug looks like an intermittent signature failure.

What happens if my endpoint is down?

We retry with backoff — seconds, then minutes, then hours — and each retry carries the same idempotency key, so a redelivery can never be mistaken for a second event.

A 410 or 404 stops delivery immediately rather than retrying for twelve hours into an endpoint that has told us it no longer exists.

What is in the delivery record?

The actual conversation: the receiving server’s response codes, its diagnostic text, which MX we connected to, how many attempts were made and why each retry was scheduled.

It is append-only and hash-linked, so entries cannot be quietly rewritten after the fact. You can verify the chain yourself instead of taking our word for it.

Security and data

What we hold and how it is protected.

Who can see my message content?

Tenant isolation is enforced by PostgreSQL row-level security with FORCE enabled, and the application connects as a role that cannot bypass it. A query that forgets to filter by account returns nothing rather than somebody else’s data.

Message bodies are stored separately from delivery records and deleted after 30 days, because the record of what happened needs to outlive the contents of the message.

Where is my DKIM private key?

Encrypted at rest with AES-256-GCM, under a key held outside the database and mounted at runtime. A database dump on its own does not let anyone sign mail as your domain — which would be worse than leaking the data, since it would let them send DMARC-passing mail we vouch for.

Are you SOC 2 or ISO 27001 certified?

No, and we are not going to imply otherwise. If you need an audited provider today we are not it yet. The specific measures we do take are listed on the security page so you can judge them directly.

Do you read or train on my email?

No. Your message content is processed to deliver it and for nothing else. It is not used to train anything, and it is not shared with any third party — there is no email provider in our sub-processor list, because we do the sending ourselves.

Pricing and the product

What it costs and what stage this is at.

How can you charge $9 a month for this?

Because we own the pipe. A provider built on top of another sending service pays for that service plus their own margin, and both come out of your bill. Running our own infrastructure means one cost instead of two.

Starter is $9 a month for 100,000 emails, and there is no charge for webhooks or delivery records.

Why will you not accept marketing email?

Bulk campaigns carry a different complaint profile from transactional mail, and on shared infrastructure one bad list damages placement for everyone. Refusing the category outright is worth more to your password resets than the revenue would be.

Is Posthaste production-ready?

It is in private testing. The sending path, bounce handling, signed webhooks and the delivery record are built and tested. The dashboard is not built yet, and the sending IP is new, so placement is still being established.

We would rather tell you that now than during your incident review. If you need years of IP reputation today, use Postmark and come back later.

What happens to my data if you shut down?

You can export your delivery records through the API at any time, and we would give notice rather than disappearing. It is a fair question to ask a young company, and the honest answer is that your records are exportable by design precisely so you are never locked in.