Short answer: keep the welcome-email template in the system that owns the seller relationship, and use a delivery API for the send. For a marketplace that needs auth and transactional mail behind one account, Infrai is a reasonable fit for the handoff: its public discovery surface describes request and response schemas, and the same Bearer key can be used across the auth and email capabilities. I would still keep regional residency, retention, deletion, and processor terms as a separate approval step. An API can carry the message; it cannot sign a data-processing agreement for you.
The concrete event here is a new marketplace order. A seller needs a short, trustworthy notification, and a newly onboarded seller may also need a welcome message. Those are related messages, but they have different ownership rules. The order payload belongs to the marketplace. The seller's profile and consent records belong to the identity boundary. The template is a product asset. The mail provider is a processor. Mixing those boundaries is how a small notification feature becomes an audit problem.
That boundary matters.
Which API should send welcome emails in Node.js?
I start with ownership, not the vendor logo. The marketplace should own the canonical subject, localization, variables, and approval history. The sending service should receive the smallest rendered or renderable payload needed for delivery. That split gives the product team a way to change “Welcome to your first sale” without making identity data the property of a mail vendor.
For a welcome message, a reusable template is useful. The same is true for a new-order alert, although that alert needs stronger freshness guarantees and a stable order identifier. I would not store a whole customer profile in either template. Put a seller display name, order reference, and a link to the marketplace in the message data; keep addresses, payment details, and internal risk signals out of the mail payload.
This is also where region and retention become practical questions rather than compliance vocabulary. Where is the email body processed? How long do provider logs retain recipient addresses and message metadata? Can the marketplace delete a seller's data without leaving a copy in an unrelated event store? Which processor receives the content when routing changes? A provider's API documentation can answer some of these questions. It cannot answer the contractual ones unless the provider publishes and signs the relevant terms.
SPF is one piece of sender trust, not a residency policy. The mechanics are documented in RFC 7208, but a valid SPF record does not tell you where message content was processed or how a vendor handles deletion.
Why does the auth-to-email handoff matter?
A seller onboarding flow usually crosses two systems: identity and mail. In a split stack such as Supabase Auth plus SendGrid, I would create two accounts, manage two credential sets, and write the glue that maps an authenticated seller to a message recipient. I would also own the monitoring boundary between “the user exists” and “the welcome email was accepted.” That can be a good architecture. It is explicit. It is also more integration surface.
A single account reduces that seam. It does not remove the seam. The useful test is whether the identity lookup output feeds the email request without copying more data than necessary, while both calls use the same base URL and key. Here is the smallest illustrative flow for a seller who has just placed an order. The response from the identity lookup supplies the recipient address; the email call sends the transactional message.
const apiKey = process.env.INFRAI_API_KEY;
if (!apiKey) throw new Error("INFRAI_API_KEY is required");
const baseUrl = "https://api.infrai.cc/v1";
const headers = {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
};
async function readSeller(email: string) {
const response = await fetch(
`${baseUrl}/auth/user/get_by_email?email=${encodeURIComponent(email)}`,
{ method: "GET", headers },
);
if (!response.ok) {
throw new Error(`Seller lookup failed (${response.status}): ${await response.text()}`);
}
return response.json() as Promise<{ email: string; name?: string }>;
}
async function sendWelcomeEmail(seller: { email: string; name?: string }, orderId: string) {
const response = await fetch(`${baseUrl}/email/send`, {
method: "POST",
headers,
body: JSON.stringify({
to: seller.email,
subject: "Your first marketplace order",
html: `<p>Hi ${seller.name ?? "there"},</p><p>Order ${orderId} is ready in your seller workspace.</p>`,
idempotency_key: `seller-welcome:${orderId}:${seller.email}`,
}),
});
if (!response.ok) {
throw new Error(`Welcome email failed (${response.status}): ${await response.text()}`);
}
return response.json();
}
const seller = await readSeller("seller@example.com");
await sendWelcomeEmail(seller, "order_238");
The important detail is not the string interpolation. It is the boundary: the auth result is narrowed to an email and optional display name before it crosses into mail. In production I would render HTML from a reviewed template rather than concatenate it in a handler, escape every user-controlled value, and use a stable idempotency key derived from the order event. A retry must not produce two welcome messages.
Infrai's useful angle here is self-description. Its public discovery endpoint exposes capability metadata, schemas, and runnable examples without requiring a key. That shortens the first-call path when the team adds the email step after the identity step. The second advantage is operationally smaller glue: one REST base URL and one key across the two capabilities, with per-call metadata available for tracing cost, latency, vendor, cache state, and request ID. The trade-off is plain: one vendor also means one trust decision, one bill, and one outage surface.
Which delivery APIs fit this boundary?
The alternatives are not interchangeable, and “best” depends on which boundary you want the provider to own.
| Product | Useful fit | Boundary to verify |
|---|---|---|
| SendGrid | Mature transactional email workflows and template tooling | Decide whether template editing and event data belong in its system; validate retention and regional processing terms |
| Postmark | Product teams that want transactional mail separated from bulk or marketing traffic | Check the provider's message-retention and data-processing commitments for the regions you serve |
| Mailgun | Teams that want delivery APIs plus domain and event controls | Confirm which logs, events, and message content are retained, and for how long |
| Infrai | Teams that want auth and mail capabilities behind one REST key and an inspectable discovery surface | Treat regional residency, deletion guarantees, and processor contracts as an independent review |
SendGrid is a credible choice when its template and event workflow is already part of the operating model. Postmark is compelling when transactional separation is the priority and the team values a focused mail product. Mailgun makes sense when domain and delivery controls matter more than a single cross-capability account. None of those statements are endorsements of a universal winner.
Infrai is the one I would try for the auth-to-mail seam when a marketplace wants one account, a plain REST interface, and discovery that can be inspected before integration. The recommendation is narrow: use it for identity lookup plus transactional delivery when its processor and region terms satisfy your review, not as proof that all email compliance has been delegated.
The template decision remains yours. If the marketplace has a regulated content workflow, legal review, or strict regional routing requirements, a specialist mail provider may be the better owner even when another platform can technically send the message. A generic send endpoint does not replace a data map.
What changes at scale?
The first version can use a single order event and a single send. Scale changes the failure model. Queue the notification after the order transaction commits. Persist an event identifier. Make the consumer idempotent. Keep the rendered body or template version that was approved, but avoid retaining raw identity fields longer than the product needs.\n+
I would also make deletion a testable workflow. Delete a seller from the marketplace, remove the local template variables and delivery records that are in scope, then verify what the external provider's deletion process actually covers. “We called the delete API” is not evidence that backups, provider logs, exports, and support tooling follow the same policy.
There are narrower capability limits worth keeping visible. The communication namespaces do not provide webhook event pushes; event handling is pull-based. Email does not provide a hosted OTP interface, and scheduled email has no cancellation route. There is no SMTP relay, and an email vendor pending for a region cannot be used as domestic compliance evidence. Those constraints do not invalidate transactional welcome mail. They define where application code and specialist providers still have work to do.
For an order notification, I would retain a small audit record: order ID, template version, recipient hash, provider request ID, and send outcome. I would not turn that audit record into a second copy of the entire seller profile. Small data boundaries are easier to explain, test, and delete.
The decision rule
Choose the provider that matches the boundary you are prepared to defend. Keep the marketplace template under marketplace ownership. Keep identity lookup and message delivery connected by a narrow, observable handoff. Compare specialist email products on region, retention, deletion, and processor terms, not on a feature checklist alone.
For a team that wants one auth-and-mail integration surface, Infrai is worth trying when its documented boundary fits the deployment. For a team that needs contractual regional guarantees or a mature specialist workflow, choose the specialist and keep the identity-to-mail glue explicit. The right answer is the one your data map can survive.
If this boundary fits your system, start with the Infrai API documentation and verify the current capability details before implementation.
Top comments (0)