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

# Typescript

# TypeScript SDK

Official **Node.js / TypeScript** client for the Mailofly REST API.

**Package:** [`mailofly`](https://www.npmjs.com/package/mailofly) · **Requires:** Node.js 18+ · **Quickstart:** [Node.js](../getting-started/nodejs.md)

***

## Install

```bash theme={null}
npm install mailofly
```

***

## Initialize

```ts theme={null}
import { Mailofly, MailoflyError } from "mailofly";

const client = new Mailofly({
  apiKey: process.env.MAILOFLY_API_KEY!,
});
```

Create an [API key](../getting-started/api-keys.md) first.

***

## Send email

Resend-compatible `client.emails.send()`:

```ts theme={null}
try {
  const { id } = await client.emails.send({
    from: "Acme <onboarding@example.com>",
    to: ["alex@example.com"],
    subject: "Hello",
    html: "<p>Thanks for signing up.</p>",
    account_key: "acc_…",
  });
  console.log("Sent:", id);
} catch (e) {
  if (e instanceof MailoflyError) {
    console.error(e.status, e.error, e.detailMessage);
  }
  throw e;
}
```

### With a saved template

```ts theme={null}
await client.emails.send({
  from: "Acme <onboarding@example.com>",
  to: ["alex@example.com"],
  template: {
    id: "uuid-of-template",
    variables: { first_name: "Alex", promo_code: "SAVE20" },
  },
});
```

### With attachments, tags, and headers

```ts theme={null}
await client.emails.send({
  from: "Acme <onboarding@example.com>",
  to: ["alex@example.com"],
  subject: "Your invoice",
  html: "<p>See attached.</p>",
  tags: [{ name: "category", value: "billing" }],
  headers: { "X-Entity-Ref-ID": "123" },
  attachments: [{ filename: "invoice.pdf", content: "<base64>" }],
});
```

### Retrieve & list

```ts theme={null}
const { data, has_more } = await client.emails.list({ limit: 20 });
const email = await client.emails.get("4ef9a417-02e9-4d39-ad75-9611e0fcc33c");
```

`last_event` is mapped from mail log status (`sent` → `delivered`). `cc`, `bcc`, and `reply_to` are not stored and return `null` / `[]`. Use [`GET /v1/mail-logs`](https://docs.mailofly.com/api/mail-logs) for campaign context and page-based filters.

`client.compose.send` is deprecated and forwards to `/v1/emails`.

### Batch send (up to 100 emails)

```ts theme={null}
const { data } = await client.batch.send([
  {
    from: "Acme <onboarding@example.com>",
    to: ["foo@example.com"],
    subject: "hello world",
    html: "<h1>it works!</h1>",
  },
  {
    from: "Acme <onboarding@example.com>",
    to: ["bar@example.com"],
    subject: "world hello",
    html: "<p>it works!</p>",
  },
]);
console.log(data.map((row) => row.id));
```

***

## Resources

| Namespace          | Methods                                                                 |
| ------------------ | ----------------------------------------------------------------------- |
| `client.accounts`  | `list`, `create`, `get`, `update`, `delete`                             |
| `client.contacts`  | `list`, `create`, `get`, `update`, `delete`                             |
| `client.templates` | `list`, `create`, `get`, `update`, `delete`                             |
| `client.segments`  | `list`, `create`, `get`, `update`, `delete`, `contacts.list/add/remove` |
| `client.campaigns` | `list`, `create`, `get`, `update`, `delete`, `runs`, `send`             |
| `client.emails`    | `list`, `get`, `send`                                                   |
| `client.batch`     | `send`                                                                  |
| `client.compose`   | `send` (deprecated — use `emails`)                                      |
| `client.mailLogs`  | `list`                                                                  |

### Examples

```ts theme={null}
// List sending accounts
const { data: accounts } = await client.accounts.list();

// Create a contact
await client.contacts.create({
  email: "alex@example.com",
  first_name: "Alex",
  custom_fields: { plan: "pro" },
});

// Send a campaign now
await client.campaigns.send("campaign-uuid", { send_now: true });

// Query failed mail logs
const logs = await client.mailLogs.list({
  status: "failed",
  page: 1,
  page_size: 50,
});
```

***

## Discovery (no API key)

```ts theme={null}
const meta = await Mailofly.discovery();
console.log(meta.resources);
```

***

## Error handling

```ts theme={null}
import { Mailofly, MailoflyError } from "mailofly";

try {
  await client.accounts.list();
} catch (e) {
  if (e instanceof MailoflyError) {
    // e.status — HTTP status
    // e.error — error code string
    // e.detailMessage — human-readable message
  }
}
```

***

## Related

* [Node.js quickstart](../getting-started/nodejs.md)
* [SDK overview](README.md)
* [API: Emails](https://docs.mailofly.com/api/emails)
* [API keys](../getting-started/api-keys.md)


## Related topics

- [SDKs](/sdks/index.md)
- [Nodejs](/getting-started/nodejs.md)
- [Introduction](/sending/introduction.md)
- [Examples](/examples/index.md)
- [Dart](/getting-started/dart.md)
