Quickstart · Next.js

Send your first email from a Next.js 15 App Router app. Server action posts to Bird, webhook route receives the delivery event.

Prerequisites

  • Node 20 or later
  • pnpm 9 or later (npm, yarn, bun all work too)
  • A Bird test API key from the dashboard — it looks like bird_test_xxxxxxxx

Install the SDK

pnpm add @bird/sdk
# npm install @bird/sdk
# yarn add @bird/sdk
# bun add @bird/sdk

Set the env var

Add the key to .env.local at the project root:

BIRD_API_KEY=bird_test_xxxxxxxx

Send from a server action

Create app/actions/send-welcome.ts:

"use server";
import { BirdClient } from "@bird/sdk";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

export async function sendWelcome(to: string) {
  const { data, error } = await bird.email.send({
    from: "Bird <onboarding@bird.dev>",
    to: [to],
    subject: "Welcome",
    html: "<p>It works.</p>",
  });
  if (error) throw error;
  return data.id;
}

Call it from a client component or a route handler with to: 'delivered@bird.dev' — a sanctioned test recipient that always accepts and emits events without touching a real inbox.

Receive the delivery webhook

Create app/api/webhooks/bird/route.ts:

import { NextRequest, NextResponse } from "next/server";
import { BirdClient } from "@bird/sdk";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

export async function POST(req: NextRequest) {
  const raw = await req.text();
  const signature = req.headers.get("bird-signature") ?? "";

  try {
    const event = bird.webhooks.verify({
      body: raw,
      signature,
      secret: process.env.BIRD_WEBHOOK_SECRET!,
    });
    // event.type === 'email.delivered' | 'email.bounced' | ...
    return NextResponse.json({ received: true, id: event.data.id }, { status: 200 });
  } catch {
    return NextResponse.json({ error: "invalid_signature" }, { status: 401 });
  }
}

What just happened

The server action hit POST /v1/emails and Bird returned an email_* id. Within a second, the dashboard logs show the send, and Bird re-emits the delivery event to your webhook with an HMAC-SHA256 Bird-Signature header.

Next steps

Commencez avec un seul canal.
Ajoutez les autres quand vous êtes prêt.

Une clé API de test est disponible immédiatement. L'accès production se débloque dès que vous ajoutez un moyen de paiement et vérifiez un expéditeur.

CommencerLire la docou

Vous utilisez Claude Code, Cursor ou Codex ? Connectez-le à notre serveur MCP — 141 outils, un par endpoint API, avec des clés d'agent à portée limitée.