`npm i lumail@2.1.0`. Base URL `https://lumail.io/api`. Bearer `lum_` token. Methods return `{ data, error }` — no `try/catch` for ordinary API errors. Missing API key still throws at construction.

```typescript
import { Lumail } from "lumail";

const lumail = new Lumail({ apiKey: process.env.LUMAIL_API_KEY! });

const { data, error } = await lumail.emails.send(
  {
    from: "hello@yourdomain.com",
    to: "user@example.com",
    subject: "Welcome",
    html: "<p>Hello</p>",
  },
  { idempotencyKey: "welcome-1" },
);
```

Network, timeout, and abort errors use `error.name` of `network_error`, `timeout`, or `aborted` and do not invent an HTTP `statusCode`.

Optional `baseUrl` for self-hosted or beta.

## Resources

- [`lumail.emails`](/docs/sdk/v2/emails)
- [`lumail.subscribers`](/docs/sdk/v2/subscribers)
- [`lumail.domains`](/docs/sdk/v2/domains)
- [`lumail.campaigns`](/docs/sdk/v2/campaigns)
- [`lumail.tags`](/docs/sdk/v2/tags)
- [`lumail.events`](/docs/sdk/v2/events)
- [`lumail.tokens`](/docs/sdk/v2/tokens)
- [`lumail.tools`](/docs/sdk/v2/tools)

v1 HTTP stays frozen. New code uses v2. Rewrite guide: [Migration to V2](/docs/api-reference/v2/migration). v2 send accepts `html`, `tiptap`, or `markdown`.
