> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dairo.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Land in the inbox

> Get your mail into the inbox, not the spam folder — and keep it there.

Two things decide whether your mail reaches the inbox: authentication, which
lets a receiver prove the message is really from you, and reputation, the trust
receivers build in your domain over time. Dairo handles authentication when you
verify a domain, and guards you against the signal that damages reputation
fastest. Building the rest of that trust is up to you.

## Authentication is handled for you

When you [verify a domain](/domains/domains), Dairo generates the full
authentication record set and hands it to you to publish. Once the records
resolve, every message you send is cryptographically signed and aligned with
your domain, so receivers can confirm it wasn't forged or altered in transit.

| Standard | Records you publish    | What receivers check                                                                      |
| -------- | ---------------------- | ----------------------------------------------------------------------------------------- |
| DKIM     | Three `CNAME` records  | A cryptographic signature on each message, verified against a public key in your DNS.     |
| SPF      | `MX` + `TXT` on `mail` | That the envelope sender aligns with your domain and Dairo is authorized to send for you. |
| DMARC    | `TXT` on `_dmarc`      | Your policy for mail that fails DKIM or SPF alignment, and where to send reports.         |

### Tighten DMARC over time

The DMARC record Dairo returns starts in monitor-only mode:
`v=DMARC1; p=none; rua=mailto:postmaster@yourapp.com`. Publish it as is, collect
reports, and tighten the policy once they show clean authentication.

| Policy         | Effect                             | When to use it                           |
| -------------- | ---------------------------------- | ---------------------------------------- |
| `p=none`       | Monitor only; collect reports.     | Start here.                              |
| `p=quarantine` | Failing mail goes to spam.         | After reports show clean authentication. |
| `p=reject`     | Failing mail is rejected outright. | Once you're confident.                   |

## Bounces and complaints

Two delivery events move reputation the wrong way:

* **Bounce** (`message.bounced`) — delivery failed. A `Permanent` bounce means
  the address is undeliverable: stop sending to it. A `Transient` bounce (full
  mailbox, temporary server issue) may succeed on a later attempt.
* **Complaint** (`message.complained`) — the recipient marked your message as
  spam. This is the single most damaging signal there is.

Read the delivery events for one message with
`GET /v1/messages/{messageId}/events` (scope `messages:read`):

```bash theme={null}
curl "https://api.dairo.app/v1/messages/msg_3fa85f64/events" \
  -H "Authorization: Bearer $DAIRO_API_KEY"
```

```json theme={null}
{
  "events": [
    {
      "eventId": "evt_5f3c9a2e",
      "type": "Bounce",
      "recipient": "old@example.com",
      "bounceType": "Permanent",
      "occurredAt": "2026-07-14T18:22:05Z"
    },
    {
      "eventId": "evt_7b1d4c88",
      "type": "Complaint",
      "recipient": "casey@example.com",
      "occurredAt": "2026-07-14T20:03:41Z"
    }
  ]
}
```

[Track delivery](/sending/outbound-tracking) documents the full event surface —
lifecycle statuses, every event field, and bounce classifications. To react the
moment a bounce or complaint happens, push events to your app with
[webhooks](/webhooks/webhooks).

## Complaints become suppressions

When a recipient complains, Dairo records a suppression for that address on your
account. From then on, any email you send to that address — API, SDK, CLI, or
MCP — is refused with a `400`, so one bad signal can't snowball into a
blocklisted domain:

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_request",
    "message": "Could not send email: recipient complained (casey@example.com). Recipient complained — do not contact again. To override deliberately, set ignoreComplaints=true in the API/MCP request or pass --ignore-complaints in the CLI."
  }
}
```

Scheduled sends are re-validated when they fire, so a complaint recorded after
you schedule still blocks the send.

### Override a suppression deliberately

If a human decides the recipient should be contacted anyway, set
`ignoreComplaints: true` on the send (or `--ignore-complaints` in the CLI). The
send proceeds, and the response carries a `warnings` array naming each
suppressed recipient:

<CodeGroup>
  ```bash title="cURL" theme={null}
  curl -X POST https://api.dairo.app/v1/messages \
    -H "Authorization: Bearer $DAIRO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "inboxId": "inbox_7c9e6679",
      "to": "casey@example.com",
      "subject": "Following up",
      "text": "Checking in one last time.",
      "ignoreComplaints": true
    }'
  ```

  ```ts title="TypeScript" theme={null}
  const result = await dairo.messages.send({
    inboxId: "inbox_7c9e6679",
    to: "casey@example.com",
    subject: "Following up",
    text: "Checking in one last time.",
    ignoreComplaints: true,
  });
  for (const w of result.warnings ?? []) {
    console.warn(w.recipient, w.message);
  }
  ```

  ```bash title="CLI" theme={null}
  dairo send \
    --inbox-id inbox_7c9e6679 \
    --to casey@example.com \
    --subject "Following up" \
    --text "Checking in one last time." \
    --ignore-complaints
  ```
</CodeGroup>

```json theme={null}
{
  "id": "msg_3fa85f64",
  "channel": "email",
  "status": "sent",
  "warnings": [
    {
      "recipient": "casey@example.com",
      "reason": "complaint",
      "message": "Recipient previously complained; do not contact again unless you are sure.",
      "lastEventAt": "2026-06-30T09:14:03Z"
    }
  ]
}
```

<Warning>
  Overriding a suppression is a deliberate, human decision — never a default in
  automation. Emailing people who marked your mail as spam will get your domain
  blocklisted regardless of intent.
</Warning>

Bounces don't create suppressions. Prune addresses that bounce `Permanent`
yourself — repeatedly sending to dead addresses erodes reputation too.

## Reputation is built by you

Authentication is necessary but not sufficient. A brand-new domain has no
history, so even perfectly authenticated mail can land in spam at first.

* **Warm up gradually.** Ramp volume over days and weeks so mailbox providers
  learn your domain sends wanted mail. Your mail rides Dairo's shared, actively
  monitored [sending IPs](/platform/dedicated-ips), so there is no IP warmup to
  manage — only your domain's reputation to build.
* **Send to people who want it.** Opens, replies, and "not spam" actions are the
  strongest positive signals. Prune recipients who never engage.
* **Keep the bad signals low.** High complaint or hard-bounce rates erase
  reputation fast. Honor suppressions and drop addresses that bounce `Permanent`.
* **Mind your content.** Spammy phrasing, link-heavy bodies, and misleading
  subjects trip content filters. Plain, relevant content lands better on a cold
  domain.

<Note>
  For an AI agent that sends on its own, see
  [Send limits & reputation](/agents/reputation) to gate its sends on recent
  bounce and complaint signals.
</Note>

## Next steps

* [Send an email](/sending/sending-email) — start sending from your verified domain.
* [API reference](/api-reference) — full schemas for messages, events, and domains.
