# Quickstart: send and receive email from code

> Send your first email, give an agent its own mailbox and read the replies. Every snippet runs as pasted.

This page gets a script or an AI agent from nothing to sending and receiving real email on your own domain. Every command runs as pasted once two values are set.

## What you need first

1. **A Faivelo account with a verified domain.** A person sets this up once: sign up at [faivelo.com](https://faivelo.com/register), add a domain, and Faivelo writes the DNS records for most hosts (or run `npx faivelo init yourdomain.com` from a terminal). See [Set up from the terminal](/cli).
2. **An API key.** A person on the account creates it in [Settings → Developers](https://faivelo.com/settings/developers). Pick the **agent** kind for anything autonomous. Give it the scopes `mail:send`, `mail:read`, `mailboxes:read` and `mailboxes:write`. The key starts with `fvl_live_` and is shown once.

The API is included on every paid plan and during the free trial.

Set both values in your shell:

```bash
export FAIVELO_API_KEY="fvl_live_..."    # the key from Settings → Developers
export DOMAIN="yourdomain.com"           # a verified domain on the account
```

Check the key works:

```bash
curl https://faivelo.com/api/v1/mailboxes \
  -H "Authorization: Bearer $FAIVELO_API_KEY"
```

A `200` with `{"success":true,"data":[...]}` means you are ready. Anything else returns an error with a `code` and a `fix`; see [Errors](/developers/errors).

## Send an email

`POST /api/v1/emails` sends from any address on a verified domain. No mailbox has to exist for the sender.

```bash
curl https://faivelo.com/api/v1/emails \
  -H "Authorization: Bearer $FAIVELO_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"from\": \"hello@$DOMAIN\",
    \"to\": \"you@example.com\",
    \"subject\": \"It works\",
    \"text\": \"Sent with the Faivelo API.\"
  }"
```

The response holds an `id`. `GET /api/v1/emails/{id}` returns its delivery status (`sent`, `delivered`, `bounced`, `complained` or `failed`).

To retry safely after a network error, add an `Idempotency-Key` header. Two requests with the same key send at most one email. See [Sending via the API](/transactional/send-api).

## The same in Node.js

```bash
npm install faivelo
```

```ts
import { Faivelo } from 'faivelo'

const faivelo = new Faivelo(process.env.FAIVELO_API_KEY!)

const email = await faivelo.emails.send({
  from: `hello@${process.env.DOMAIN}`,
  to: 'you@example.com',
  subject: 'It works',
  text: 'Sent with the Faivelo SDK.'
})

console.log(email.id)
```

A failed call throws `FaiveloError` with the HTTP `statusCode` and the API's message.

## Give an agent its own mailbox

An agent that signs up for services or talks to people needs an address that can receive mail too. Create one:

```bash
curl https://faivelo.com/api/v1/mailboxes \
  -H "Authorization: Bearer $FAIVELO_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"domain\": \"$DOMAIN\", \"localPart\": \"agent\"}"
```

`agent@yourdomain.com` now exists. An agent key can only see mailboxes it created or was granted, so it can never read the rest of the account. A key may create 10 mailboxes per 24 hours.

Send as that mailbox (the message lands in its Sent folder, and replies come back to it):

```bash
curl "https://faivelo.com/api/v1/mailboxes/agent@$DOMAIN/send" \
  -H "Authorization: Bearer $FAIVELO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to": "you@example.com", "subject": "Hello from an agent", "text": "Reply to this and I will read it."}'
```

## Read the replies

List the newest messages in the inbox:

```bash
curl "https://faivelo.com/api/v1/mailboxes/agent@$DOMAIN/messages?folder=INBOX&limit=10" \
  -H "Authorization: Bearer $FAIVELO_API_KEY"
```

Each message has a `uid`. Read one in full, body included:

```bash
curl "https://faivelo.com/api/v1/mailboxes/agent@$DOMAIN/messages/<uid>" \
  -H "Authorization: Bearer $FAIVELO_API_KEY"
```

Polling works for a script that waits for one verification code. For anything long-running, use a webhook instead.

## Get replies pushed as webhooks

Add an endpoint in [Settings → Developers → Webhooks](https://faivelo.com/settings/developers/webhooks) and subscribe to `message.received` (Pro and Business). Faivelo sends a signed `POST` to your URL the moment mail arrives:

```json
{
  "id": "evt_01J8ZK3V5QXR7",
  "type": "message.received",
  "created_at": "2026-09-20T14:02:11Z",
  "data": {
    "mailbox": "agent@yourdomain.com",
    "message_id": "eaaaaab",
    "thread_id": "b",
    "folder": "INBOX",
    "from": { "name": "Dana Whitfield", "address": "dana@northwind.io" },
    "subject": "Re: Hello from an agent",
    "snippet": "Thanks, here is the code you asked for..."
  }
}
```

Check the signature before trusting the body. Pass the raw body, not parsed JSON:

```ts
import { Faivelo } from 'faivelo'

const event = await Faivelo.webhooks.verify(
  rawBody,
  request.headers['x-faivelo-signature'],
  process.env.FAIVELO_WEBHOOK_SECRET!
)

if (event.type === 'message.received') {
  // event.data.message_id works anywhere the API takes a message uid
}
```

Every event, the payloads and the retry rules are in [Webhooks](/developers/webhooks).

## Use it from an AI agent over MCP

The hosted MCP server exposes the same actions as tools (`send_message`, `list_messages`, `read_message`, `create_mailbox` and more) at `https://faivelo.com/api/mcp`, over Streamable HTTP. It is included from the Growth plan.

Claude Code, with an API key:

```bash
claude mcp add --transport http faivelo https://faivelo.com/api/mcp \
  --header "Authorization: Bearer $FAIVELO_API_KEY"
```

Any MCP client that reads JSON config:

```json
{
  "mcpServers": {
    "faivelo": {
      "type": "http",
      "url": "https://faivelo.com/api/mcp",
      "headers": { "Authorization": "Bearer fvl_live_..." }
    }
  }
}
```

Without a key, `claude mcp add --transport http faivelo https://faivelo.com/api/mcp` signs in through the browser instead, and the person picks which mailboxes the agent may use. See [Connect Claude](/developers/connect-claude) and [AI agents & API keys](/developers/ai-agents).

## For agents reading this page

- Every docs page is available as markdown: add `.md` to its URL, for example `https://faivelo.com/docs/developers/quickstart.md`.
- The index of all pages is at [https://faivelo.com/docs/llms.txt](https://faivelo.com/docs/llms.txt), and all of them in one file at [https://faivelo.com/llms-full.txt](https://faivelo.com/llms-full.txt).
- The OpenAPI 3.1 spec is at [https://faivelo.com/api/v1/openapi.json](https://faivelo.com/api/v1/openapi.json).
- Errors carry a stable `code`, a `fix` and a `docs` link. Branch on `code`. See [Errors](/developers/errors).
- Creating an account, verifying a domain and creating a key need a person today.
