Email API for
Next.js.
Choose a Server Action for a trusted form or a route handler for an HTTP endpoint. Keep the Bird key in server environment variables; the browser calls your server, never Bird with that key.

To a traceable send.
See the first send.
npm install @messagebird/sdk@0.67.0Use in an existing App Router application"use server";
import { BirdClient } from "@messagebird/sdk";
const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });
export async function sendWelcome() {
const msg = await bird.email.send({
from: "onboarding@messagebird.dev",
to: ["delivered@messagebird.dev"],
subject: "Hello from Bird",
html: "<p>My first Bird email.</p>",
});
console.log(msg.id, msg.status); // "em_…", "accepted"
return { id: msg.id, status: msg.status };
}
Onboarding sender and sandbox recipient only. This page does not send an email or contain a key.
ZIP with the displayed request, setup notes and an empty key template. A sandbox code sample, not a complete application. SDK version in the sample: 0.67.0; review current maintained setup before adapting it.
Connect an App Router form
The bundle adds this wrapper for an existing App Router application. It awaits the action without returning its result to the form; the accepted ID/status stays in the server log. Authorize callers before exposing the action.
Existing TypeScript App Router applicationKeep local until caller authorization is implementedimport { sendWelcome } from "./actions/send-welcome";
export default function Home() {
async function submit(): Promise<void> {
"use server";
await sendWelcome();
}
return (
<form action={submit}>
<button type="submit">Send sandbox email</button>
</form>
);
}
em_01ky7ma8y2es1s2akzk53tmjn0 accepted
The returned ID lets you retrieve the message and follow recipient events. Acceptance does not prove delivery or inbox placement.
If your sender is not verified
A sender outside your verified domain or the onboarding domain is refused before sending. Correct the sender setup; a rejected request is not a delivery event.
Sending domains guideIf the response is missing
Keep the original operation unresolved and inspect its record before repeating it. The SDK reuses identity for retries within one call; a new invocation normally creates a new operation. Your application owns durable job identity and deliberate replay. Completed responses are retained for three hours; after expiry, the same key can start a new operation. Retention does not make side effects atomic. Follow the idempotency guide before replaying. This sample does not provide a retry queue.
Idempotency and recovery guide ↗SDK request and retry optionsRuntime and installation.
Bird’s Next.js quickstart uses an App Router Server Action with TypeScript and @messagebird/sdk. Use Node.js 20.9+ for the maintained Next.js quickstart; the SDK alone requires Node.js 20.3+.
Choose where to send.
Choose a Server Action when a form already belongs to the App Router. Choose a route handler when another client needs an HTTP endpoint; validate and authorize that request before sending.
Track delivery and retries.
Validate submitted form data and enforce who may trigger a send. A server directive protects the key, but does not authorize the caller. A transport error or “send failed” log can leave acceptance unknown; reconcile the original operation before retrying.
Prepare for
production sending.
Verify a production domain, keep your key on the server, and follow the recipient outcome separately from request acceptance.
For example, 10,000 signups with one welcome and one follow-up imply 20,000 planned sends before other traffic. Confirm actual processed units and peak daily volume, then compare included units, domain/webhook limits, overage and the send ceiling. Count dedicated IPs or other Email products separately where applicable. Sandbox testing is not an unlimited free-production offer.
Current Email plans and usage rates ↗ · Compare provider responsibilities and commercial units ↗