> ## 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.

# Send your first email

> One call, and no domain to verify first. Every project can send from its own address on this platform from the day it signs up — the domain you own is an upgrade, not a prerequisite.

<Steps>
  <Step title="Send it">
    `email.send` takes one recipient and either a template with variables or an inline subject and body. Omit `from` and it uses the project's default sender.

    Give `text` as well as `html` when you write both; omit `text` and it is derived from the HTML. A message with neither is refused.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://platform.trylath.com/email/send \
        -H "Authorization: Bearer lath_live_..." \
        -H "Content-Type: application/json" \
        -d '{
          "to": "you@example.com",
          "subject": "First one",
          "text": "It sent."
        }'
      ```

      ```ts TypeScript theme={null}
      import { createLath } from "@trylath/sdk";

      const lath = createLath({ key: process.env.LATH_API_KEY });

      const { result } = await lath.email.send({
        to: "you@example.com",
        subject: "First one",
        text: "It sent.",
      });
      ```

      ```bash CLI theme={null}
      lath email send --to you@example.com --subject 'First one' --text 'It sent.'
      ```
    </CodeGroup>
  </Step>

  <Step title="Where it came from">
    The default sender is `no-reply@<your-project-slug>.via.trylath.com` — a subdomain of the sending parent, one per project, already authenticated. Nothing to configure and no DNS to wait on.

    It is allowed for transactional and auth mail and **not** for marketing. A broadcast needs a domain you own, because bulk mail from a shared parent is how a shared parent stops being deliverable for everybody on it.
  </Step>

  <Step title="Read the reply, not the HTTP status">
    The call returns the message id and a status. `queued` means it is on its way. A 200 with `suppressed` means the address is on your suppression list — it was stored and not sent, and `blocked` says which rule stopped it.

    This is the distinction most send APIs collapse. A suppressed send is not a failure and not a delivery, and treating the 200 as proof of either is how a bounce loop starts.
  </Step>

  <Step title="Then use your own domain">
    `email.domain.add` returns the domain's id and the DNS records to add; `email.domain.verify` takes that id and checks them. Once a domain is verified you can send from any address on it, and marketing sends become available.

    Delivery, bounce and complaint receipts land on the message either way, and a hard bounce or a complaint suppresses the address and fans out as an event.

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

    # once the records resolve, with the id the add call returned
    lath email domain verify --domainId <domainId>
    ```
  </Step>
</Steps>
