The short answer
A send-first email API sends a message and, if it receives at all, posts each incoming email to your webhook and forgets it. An inbox API gives each agent an address that keeps its mail, threads the replies and lets a person open the conversation later. Use a send-first API when nobody replies; use an inbox API, such as Pidgeon, when the agent has to hold a conversation.
The difference is who keeps the conversation
Both kinds speak the same protocol and both can deliver to Gmail. The difference is what exists after the message has gone.
With a send-first API, the thing you own is a call. You hand it a sender, a recipient and a body; it returns an id and later tells you whether the message was delivered, bounced or marked as spam. Inbound, where it exists, is the same shape in reverse: an email arrives, the provider posts it to your endpoint, and the provider's part is done. The message is now a row in your database, if you wrote one.
With an inbox API, the thing you own is an address. Mail sent to it is stored, filed into a thread and kept until you delete it. Your code is told when something arrives, but the message does not depend on your code having been up at the time. The provider keeps the conversation; your code takes part in it.
That sounds like a detail until the third reply.
What the third reply needs
An agent books a room for a team offsite. The venue answers, the agent confirms the date, and the venue writes a second time with a floor plan attached and a question about catering. To handle that last email well, something has to:
- Store it, including the attachment, somewhere the agent can read it again tomorrow.
- Match it to the conversation. Mail clients thread on the
In-Reply-ToandReferencesheaders, and some providers rewrite theMessage-IDyou set, so the id the venue's reply refers to may not be the one you stored. On Amazon SES the recipient sees SES's id, not yours. - Separate the new text from the quoted history, so the agent reads the question and not three copies of its own earlier emails.
- Survive your endpoint being down. A webhook that fails needs a retry schedule, and an event that keeps failing needs somewhere to wait.
- Show a person what happened when the venue writes something the agent should not answer.
With a send-first API, each of those is yours to build. With an inbox API, they are what you are paying for.
The same job in an inbox API
In Pidgeon the address is a resource you create, and everything after it names that address:
curl https://pidgeon.ai/api/v1/identities \
-H "Authorization: Bearer $PIDGEON_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "address": "orders@yourcompany.com", "type": "agent" }'
Register a webhook for message.received and each arriving email becomes a signed HTTP request with the message and thread ids. If your endpoint is down, Pidgeon tries seven times over a little more than seven hours, then keeps the event so you can replay it. The message itself was stored the moment it arrived, so a failed webhook loses nothing.
The reply names the message it answers, and Pidgeon sets the recipients, the subject and the threading headers from it:
import { messagesReply } from '@pidgeon-ai/sdk';
await messagesReply({
path: { id: messageId },
body: { text: 'Lunch for twelve, please. The floor plan works for us.' },
throwOnError: true,
});
GET /v1/threads?identity_id=… lists the agent's conversations, and every message comes back with the new text split from the quoted history. A person can open the same address in the dashboard or a mail client over IMAP and take a thread over; the agent hears about it as an event.
When a send-first API is the right call
Plenty of mail is not a conversation. Receipts, alerts, password resets and weekly reports go one way, and a reply to them, if it ever comes, does not need an agent. For that, a transactional sender is cheaper at volume and built for exactly this. Pidgeon caps sending per plan (100 messages a day on Free, 50,000 on Enterprise) because its addresses are meant to write to people one at a time, not to mail a list.
A send-first API with an inbound webhook is also reasonable when:
- The inbound is intake, not conversation. A
receipts@address that feeds a parser needs the bytes once and never again. - You already have the store. If your product has its own message table, threading and a screen for people, the webhook is all you were missing.
- You are one tenant. One product, one domain, one sending reputation, and an engineer who will own it.
Pidgeon covers the intake case too: an address with "inbox": false, or the application type, stores nothing and turns each arrival into an event. One field decides which shape an address is.
What each costs you
A send-first API costs less per message and more in code. Its price is usually per email sent; the store, the threading, the retries and the screen for people are engineering time, and they stay yours to maintain.
An inbox API costs less in code and meters different things. In Pidgeon inboxes are unlimited on every plan; what the plan meters is the mail sent and the storage the mail takes, pooled across the account. Receiving is free on every plan. Creating addresses is paced rather than capped: up to 20 new ones a day on Free, so a script making hundreds is refused while a team never notices.
The question to ask any provider is the same: when the third reply arrives, where is it, and who can see it?
Start
Sign up and you have an address on pidgeon.email already. The inbox quickstart sends and receives in a few calls, threads explains how replies are matched, and webhooks covers the events and their retries. If you are still choosing between vendors, the best email APIs for AI agents compares them.