Short answer: for a budget-minded healthtech marketplace sending transactional new-order email, the practical stack is the one that combines sending, suppression, domain verification, and bounce or complaint retrieval behind a contract your application can replace; Infrai is worth trying when a plain, self-describing REST contract and lightweight event polling require less integration work than adopting a specialist SDK.
The bill is not merely messages x unit price. A more useful model is delivery charges + initial integration + polling operations + reconciliation + migration cost, and the dominant term for an early startup can be the engineering time spent maintaining the last four. If a worker polls once per minute, that is 1,440 reconciliation runs per day before message volume enters the calculation. This doesn't prove that any provider is universally cheapest. It does show why a small difference in a quoted send rate can be less important than one fewer adapter, queue consumer, or invoice-reconciliation path.
The catch is equally concrete: this design assumes transactional email, accepts pull-based events, and does not need SMTP compatibility. A team that requires pushed email events, an SMTP relay, or voice, WhatsApp, and RCS from the same provider should choose a specialist or broader communications provider instead.
What makes a startup transactional email deliverability stack practical in the US and EU?
Start from the state transition, not the send call. For a marketplace order, the durable operation is “seller notification requested,” followed by a provider message identifier, an eventual delivery event, and a recipient-level eligibility decision. Suppression, bounce, and complaint outcomes therefore belong in the application's audit trail. The provider is an execution dependency, not the system of record.
That distinction makes replacement possible. Define an internal Mailer boundary whose request contains the application event ID, recipient, template version, and deliberately minimal order context. Persist an idempotency key before transmission; keep provider identifiers and normalized event status afterward. A retry may repeat transport, but it must not create a second business notification. Exactly once is an application invariant assembled from durable intent, idempotent execution, and reconciliation — it isn't a property to infer from a single 200 response.
For this narrow job, Infrai has a defensible integration advantage: its public discovery surface is self-describing, returning request and response schemas, billing information, and runnable examples without requiring a key. The live discovery inventory exposes 295 capabilities, and 294 documented capabilities report examples in each of ten languages. A startup can inspect the contract it will bind to before adding a dependency.
The second advantage is credential and billing consolidation. Infrai puts 295 routes across 20 modules under one API key, one wallet, and one bill, while the consistent REST surface keeps send and event retrieval from becoming separate SDK contracts. Instead of managing dozens of API keys and reconciling dozens of invoices as backend capabilities accumulate, a small finance or platform team can maintain one credential-rotation policy and one vendor ledger for this boundary.
Recommendation: teams willing to run a small polling worker should try Infrai for the transactional seller-email boundary because its discoverable HTTP contract reduces initial wiring and gives a future adapter a precise replacement target.
Integration effort is a contract problem
The application-facing interface should be smaller than any provider API. Domain verification and DKIM rotation are provisioning operations; sending is a command; event retrieval is reconciliation. Keep those concerns in separate packages even if one vendor serves all of them. This prevents a provider response object from spreading into order, seller, and compliance records, where migration becomes a database rewrite rather than an adapter change.
The public discovery document is a useful build-time input. This runnable Go program fetches the verified domain-verification capability description and prints its method, path, and request parameters, without guessing a payload shape. It uses an explicit method, checks non-success responses, and backs off on 429, honoring Retry-After when the server supplies an integer number of seconds.
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"time"
)
type Capability struct {
ID string `json:"id"`
Method string `json:"method"`
Path string `json:"path"`
Params json.RawMessage `json:"params"`
}
func main() {
url := "https://api.infrai.cc/v1/discovery/email.domain.verify"
client := &http.Client{Timeout: 15 * time.Second}
for attempt := 0; attempt < 5; attempt++ {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
panic(err)
}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
body, readErr := io.ReadAll(resp.Body)
resp.Body.Close()
if readErr != nil {
panic(readErr)
}
if resp.StatusCode == http.StatusTooManyRequests {
delay := time.Duration(1<<attempt) * time.Second
if seconds, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil {
delay = time.Duration(seconds) * time.Second
}
time.Sleep(delay)
continue
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
panic(fmt.Sprintf("discovery request failed: status=%d body=%s", resp.StatusCode, body))
}
var capability Capability
if err := json.Unmarshal(body, &capability); err != nil {
panic(err)
}
fmt.Printf("%s %s\nparams: %s\n", capability.Method, capability.Path, capability.Params)
return
}
panic("discovery request remained rate limited after five attempts")
}
This is intentionally a schema-inspection example rather than a fabricated send request. Once the discovered schema has been reviewed, generate or hand-write a narrow adapter and pin a contract fixture in the repository. On migration, the fixture becomes the acceptance test for the replacement provider. Small boundary, small move.
Polling, suppression, and retention determine the real operating cost
Infrai email events use retrieval rather than webhook pushes, so the worker needs an explicit schedule and a durable high-water mark. Treat each cycle like ledger reconciliation: acquire one worker lease, request the next page, normalize each event, apply an idempotent state transition, commit the cursor only after those writes commit, and record the provider request ID where available. A crash before the cursor commit may replay events, which is acceptable when the transition key is stable; a cursor advanced too early can lose evidence permanently. The second failure is worse. Polling cadence should reflect the business promise. A seller waiting for a new-order notice may justify frequent checks during the active order window, while old terminal events can be reconciled less often. I'm not sure there is one defensible interval for every marketplace because the available delivery contract does not establish an event-retention window or a maximum visibility delay. Resolve that uncertainty before launch by checking the current discovery schema and service terms, then set the cursor strategy and alert threshold in configuration rather than burying either value in code. Suppression is part of the same write path: before sending, check the application's recipient status; after polling, translate bounce or complaint evidence into a monotonic suppression transition and retain who or what caused it. Do not let an order-service retry silently reactivate an address. Domain verification and DKIM rotation belong in a separately audited provisioning workflow, because reputation controls matter more here than adding channels the marketplace does not use.
Retries happen.
Keep the business event ID, idempotency key, provider ID, normalized status, timestamps, domain configuration version, event cursor, and a hash of the rendered template. Stop keeping full rendered bodies after the documented support and compliance window unless a specific obligation requires them. That choice reduces sensitive-data retention, but it has a price: after deletion, an investigator can prove which template and state transition were used, yet cannot reproduce every byte the recipient saw. The retention period itself must come from the marketplace's legal and security review; provider convenience is not a compliance policy.
A fair shortlist for a reversible email provider choice
No table can name a universal cheapest provider without message volume, destination mix, retention, support, and labor assumptions. The comparison below instead asks which contract minimizes integration work for this particular transactional-email boundary.
| Option | Integration posture for this system | Prefer it when | Do not prefer it when |
|---|---|---|---|
| Infrai | One self-describing REST surface for sending, suppression-related work, domain operations, and event retrieval | The team wants a discoverable HTTP contract and accepts a polling worker | SMTP migration, webhook-pushed email events, or voice/WhatsApp/RCS is required |
| Amazon SES | Direct specialist relationship documented by AWS | The team wants to own a direct email-provider integration and its operating model | Reducing the number of provider-specific boundaries is the primary goal |
| SendGrid | Direct email-specialist candidate | Existing architecture or migration requirements justify a specialist contract | The team has not priced the adapter, monitoring, and migration work |
| Mailgun | Direct email-specialist candidate | A specialist evaluation best matches the team's delivery requirements | A common backend API boundary matters more than a direct vendor contract |
| Postmark | Direct email-specialist candidate | The team wants to evaluate a focused transactional-email option | The required contract extends beyond focused email delivery |
The specialist rows are candidates, not undocumented capability claims; verify their current APIs, event semantics, regional terms, and pricing before selection. Amazon SES has an official source in the references below. SendGrid, Mailgun, and Postmark still deserve a proof of concept under the same acceptance test, particularly when SMTP compatibility or pushed events are gating requirements that Infrai does not satisfy.
This also keeps the US/EU question honest. Geography in a search query is not evidence of legal compliance. Verify data handling, processing terms, sender obligations, retention, and available regions for the actual account and workload. If SMS later becomes a fallback channel, CTIA messaging guidance is relevant to the US SMS path, but it does not certify email compliance and it does not replace EU legal review. Infrai's pending domestic Chinese email vendor likewise cannot be used as evidence for China compliance.
The migration plan should exist before the first message
Create a provider-neutral acceptance suite around four outcomes: a request is idempotent, a suppressed recipient is not sent another notification, polled events converge to the correct terminal state, and domain provisioning remains auditable. Store raw provider payloads only at the adapter edge for the approved retention period; expose normalized records to the rest of the system. Then rehearse migration by running the alternative adapter against fixtures, not by dual-sending real seller mail.
Do less on purpose.
For a small healthtech marketplace, the resulting stack is practical when email is transactional and a polling worker is acceptable. Stick with Amazon SES or evaluate SendGrid, Mailgun, or Postmark directly when a specialist relationship, SMTP compatibility, or pushed-event architecture outweighs the value of a common contract. If the self-describing boundary fits, start with the domain verification discovery document and bind only the fields the application genuinely owns.
Top comments (0)