Send your first email

Install an SDK or the CLI, verify a domain, and send a real email from your own address — then track its delivery and read the reply.

Send a real email from an address on your own domain, watch it deliver, and read the reply — using an SDK, the CLI, or plain curl. Once your domain is verified, the send itself takes about two minutes.

Before you start

You need:

  • A Dairo account and an API key.
  • A domain you control, so you can publish DNS records to verify it.

Every step also has a CLI tab, so you can complete the whole walkthrough from a terminal without writing code.

1. Install

npm install dairo

The SDKs page covers Ruby, PHP, Java, Rust, .NET, and Elixir, and the CLI page covers installing the CLI.

2. Set your API key

Store your key in an environment variable so it never lands in source control.

export DAIRO_API_KEY="dairo_live_..."

The Python SDK and the CLI read DAIRO_API_KEY from the environment on their own. The JavaScript SDK — and the other SDKs — take the key explicitly, so browser and edge runtimes stay predictable.

3. Verify a domain

Register your domain and Dairo returns the exact DNS records to publish. Once they resolve, your mail authenticates and lands in the inbox.

import { Dairo } from "dairo";

const dairo = new Dairo({ apiKey: process.env.DAIRO_API_KEY! });

const domain = await dairo.domains.create({ domain: "yourapp.com" });
for (const record of domain.records) {
  console.log(record.type, record.host, "→", record.value);
}

Publish the returned records at your DNS provider, then re-check until the domain's status is verified:

dairo domain recheck yourapp.com

DNS changes can take a few minutes to propagate; each re-check reads your records fresh. Add & verify a domain has the full reference, including what each record does.

4. Create an inbox

An inbox is the address you send from and receive replies to.

const inbox = await dairo.inboxes.create({
  username: "hello",
  domain: "yourapp.com",
});
console.log(inbox.id, inbox.address); // <id> hello@yourapp.com

Keep the returned inbox.id — every send names it.

5. Send an email

One call sends a real email. Pass an Idempotency-Key so a retried request never delivers twice — see Idempotency.

const result = await dairo.messages.send(
  {
    inboxId: inbox.id,
    to: "you@example.com",
    subject: "Hello from Dairo",
    text: "Dairo is sending real email now.",
  },
  { idempotencyKey: "quickstart-first-send" },
);

console.log(result.id, result.status, result.channel); // <id> sent email

An immediate send is performed while you wait: the response carries the message id, the channel it went out on (email), and a definitive status of sent — or a precise error if something knowable at submit time is wrong. Keep the id; it links this send to its delivery, bounce, and complaint events.

If a recipient previously reported your mail as spam, or their address hard-bounced, Dairo blocks the send with a 400 unless you pass ignoreComplaints: true — the response then carries a warnings entry for that recipient. See Land in the inbox before overriding.

To send later, add sendAt — an RFC 3339 timestamp with an explicit timezone offset, up to 30 days ahead (for example "2026-08-01T09:00:00Z"), or --send-at on the CLI. The response comes back scheduled, and you can cancel the send any time before it fires.

6. Track delivery

Delivery outcomes arrive as events on the message: Delivery when the recipient's provider accepts it, Bounce when it can't be delivered, Complaint when someone marks it as spam.

const { data: events } = await dairo.messages.listEvents(result.id);
for (const event of events) {
  console.log(event.type, event.recipient, event.occurredAt);
}

For real-time updates, register a webhook instead of polling — message.delivered, message.bounced, and message.complained fire as each outcome lands.

7. Read the reply

Reply to the email you sent, from your regular mail client. Incoming mail becomes a structured message in the inbox, grouped into a thread with the message it answers.

const page = await dairo.messages.list({ inboxId: inbox.id });
for (const m of page.data) {
  console.log(m.direction, m.from.address, m.subject);
}

Next steps

  • Send an email — HTML, React templates, attachments, CC/BCC, and scheduling.
  • Messages & threads — read incoming mail, walk threads, and reply.
  • Webhooks — react to events in real time and verify signatures.
  • For AI agents — the MCP server, the CLI, and patterns for reliable email agents.

On this page