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

# Typescript

# TypeScript / Node.js SDK

The official Mailofly library for Node.js and TypeScript. Type-safe, fast, and ships with zero unnecessary baggage.

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

***

## Install it

```bash theme={null}
npm install @mailofly/node
```

***

## Set it up

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

const client = new Mailofly({
  apiKey: process.env.MAILOFLY_API_KEY!, // Don't hardcode this!
});
```

You'll need an [API key](/docs/getting-started/api-keys.md) first. Create one in the dashboard.

***

## Send an email

```ts theme={null}
try {
  const { id } = await client.emails.send({
    from: "Your App <hello@yourdomain.com>",
    to: ["friend@example.com"],
    subject: "Hey there!",
    html: "<p>This just sent from Mailofly. Pretty cool, right? 🚀</p>",
  });
  console.log("Sent! Email ID:", id);
} catch (e) {
  if (e instanceof MailoflyError) {
    console.error("Something broke:", e.status, e.error, e.detailMessage);
  }
  throw e;
}
```

### Using a saved template

If you've built a template in the dashboard, reference it by ID:

```ts theme={null}
await client.emails.send({
  from: "Your App <hello@yourdomain.com>",
  to: ["friend@example.com"],
  template: {
    id: "your-template-uuid",
    variables: { first_name: "Alex", promo_code: "WELCOME20" },
  },
});
```

### With attachments, tags, and custom headers

```ts theme={null}
await client.emails.send({
  from: "Your App <hello@yourdomain.com>",
  to: ["friend@example.com"],
  subject: "Your invoice is ready",
  html: "<p>See the attached PDF!</p>",
  tags: [{ name: "type", value: "invoice" }],
  headers: { "X-Custom-Ref": "inv_1234" },
  attachments: [{ filename: "invoice.pdf", content: "<base64-string>" }],
});
```

### Batch send (up to 100 at once)

```ts theme={null}
const { data } = await client.batch.send([
  {
    from: "Your App <hello@yourdomain.com>",
    to: ["alice@example.com"],
    subject: "Hi Alice!",
    html: "<p>Your personalized message here.</p>",
  },
  {
    from: "Your App <hello@yourdomain.com>",
    to: ["bob@example.com"],
    subject: "Hi Bob!",
    html: "<p>Bob's personalized message here.</p>",
  },
]);

console.log("All sent:", data.map(row => row.id));
```

***

## Other things you can do

| What you're doing | How |
| :- | :- |
| List your sending identities | `client.identities.list()` |
| Add a contact | `client.contacts.create({ email, first_name, ... })` |
| Send a campaign right now | `client.campaigns.send("campaign-id", { send_now: true })` |
| Check failed email logs | `client.mailLogs.list({ status: "failed", page: 1 })` |
| Get a specific email | `client.emails.get("msg_id")` |
| Cancel a scheduled email | `client.emails.cancel("msg_id")` |

***

## Handling errors

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

try {
  await client.identities.list();
} catch (e) {
  if (e instanceof MailoflyError) {
    // e.status — the HTTP status code (400, 401, 429, etc.)
    // e.error — a short error code string
    // e.detailMessage — a readable explanation of what went wrong
    console.error(e.status, e.error, e.detailMessage);
  }
}
```

***

## Related

* [Node.js quickstart](/docs/getting-started/nodejs.md)
* [All SDKs](/docs/sdks.md)
* [API Reference: Emails](/docs/api/emails.md)
* [API Keys](/docs/getting-started/api-keys.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.