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

> ## Agent Instructions
> Every Lath operation is POST https://platform.trylath.com/<operation name with dots replaced by slashes>, with a JSON body and `Authorization: Bearer <key>`. `email.send` is POST /email/send.
> Branch on `error.code`, never on `error.message`. Every refusal also carries `error.fix`, which names the next step.
> Send an `Idempotency-Key` header on any operation that is not retry-safe, so a retry cannot run it twice.
> A `lath_test_` key emails only the account's own members and sends no SMS; a `lath_live_` key reaches real recipients and is billed.
> The OpenAPI document, generated from the same registry as the routes, is at https://platform.trylath.com/openapi.json.

# Domains and deliverability

> Five DNS records — three required, two strongly recommended — and what each one is actually for. Then the small number of things that genuinely decide whether mail arrives.

## Add the domain

`email.domain.add` generates a DKIM key for you and returns the domain's id and every record to create. Nothing is shared with another customer: the selector and the key are yours.

You do not have to wait for it. Lath re-checks pending domains on its own and emits `email.domain.verified` when they resolve, so you can add the records and get on with something else.

```bash theme={null}
lath email domain add --domain mail.example.com
```

## The three required records

**DKIM** — a `TXT` at `<selector>._domainkey.your-domain`. It signs every message as yours. Your DNS host may split the long value into 255-character strings; that is normal and does not break it.

**Return-path MX** — an `MX` at `lath.your-domain`, priority 10, pointing at Amazon SES's feedback address. Bounces come back here. It is on a subdomain of yours rather than a shared one so that alignment passes.

**Return-path SPF** — a `TXT` at the same `lath.your-domain`, `v=spf1 include:amazonses.com -all`, authorising that subdomain to send.

All three must resolve before the domain verifies. `email.domain.verify` looks them up live and names exactly which one is missing rather than saying the domain failed.

```bash theme={null}
lath email domain verify --domainId <domainId>
```

## The two recommended ones

**SPF on the domain itself** — `v=spf1 include:amazonses.com ~all`. If the domain already has an SPF record, **add the include to the existing one**. A second SPF record is not additive: a domain with two is treated as having a permanent error, and that is worse than having none.

**DMARC** — `v=DMARC1; p=none;` at `_dmarc.your-domain`, if no DMARC record exists yet. Start at `p=none`, which asks for reports and quarantines nothing, and tighten only once the reports look clean. Publishing `p=reject` on day one is how people discover their own newsletters were failing alignment.

## Before you verify anything

You can send immediately from `no-reply@<project-slug>.via.trylath.com` — already authenticated, no DNS. It is allowed for transactional and auth mail and not for marketing.

That split is not arbitrary. Bulk mail from a shared parent domain is how a shared parent stops being deliverable for everybody on it, so marketing needs a domain you own and whose reputation is yours.

## What actually decides whether mail arrives

Authentication is the entry fee, not the prize. SPF, DKIM and DMARC stop you being rejected outright; none of them earns a place in the inbox.

**Send to people who asked.** Complaint rate is the strongest signal a mailbox provider has, and it is the fastest thing to ruin. Lath records a complaint as an event, suppresses the address, and will not send to it again.

**Let bounces suppress.** A hard bounce means the address does not exist. Sending to it again is the clearest possible signal that you are not maintaining a list — the suppression list exists so you do not have to remember, and `audience.suppression.lift` is there for the rare genuine mistake.

**Warm up gradually.** A domain with no history that sends fifty thousand messages on its first day looks exactly like a compromised one. Start small and increase over days.

**Keep transactional and marketing apart.** Different subdomains, so a campaign that draws complaints cannot take your password resets down with it.

## When it does not verify

`email.domain.get` carries a `blocker` saying what is outstanding; before the first check it says so rather than implying a failure.

DNS is cached, so a record you just created may not be visible yet — the TTL of whatever was there before has to expire first. If `email.domain.verify` answers `dns_unavailable` with a 503, the resolver failed rather than your records: try again in a minute.

The most common real cause is a host that appends the domain to a name that already ends in it, producing `lath.example.com.example.com`. Check the record's fully-qualified name at your host before assuming the value is wrong.

## Receiving mail

`email.domain.receiving.set` with `enabled: true` adds one more record: an `MX` on the domain itself. Understand what that does before you enable it — **every message anybody sends to any address at that domain arrives at Lath**, is stored, and reaches your webhooks as `email.inbound.received`. It replaces wherever that domain's mail goes today.

Turning it off stops Lath accepting mail; delete the MX record afterwards.
