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

# BosonMailClient

> Complete reference for the BosonMailClient class: import, constructor, readonly properties, methods, and exported TypeScript types.

`BosonMailClient` is the single entry point of the BosonMail SDK. It holds your API key and base URL, and exposes two methods: `sendEmail` and `getEmailStatus`. The client is lightweight, has zero runtime dependencies, and is safe to instantiate once and reuse across your application.

## Import

The package is ESM-only. Import the default export and any type you need.

```typescript lib/bosonmail.ts theme={null}
import BosonMailClient from "@bosonware-ent/bosonmail";
import type { Result, SendEmailBody, SendAttachment, EmailStatusResult, EmailStatusData, EmailSentStatus, BosonMailClientOptions } from "@bosonware-ent/bosonmail";
```

For CommonJS, use a dynamic import:

```javascript theme={null}
const { default: BosonMailClient } = await import("@bosonware-ent/bosonmail");
```

## Constructor

```typescript theme={null}
new BosonMailClient({ apiKey, baseUrl?, timeoutMs? }: BosonMailClientOptions)
```

The constructor validates its arguments immediately and throws if anything is invalid. All other errors in the SDK are returned as result objects, never thrown.

### Constructor behavior

* `apiKey` (required): trimmed and stored as `client.apiKey`.
* `baseUrl` (optional): defaults to `https://webmail.bosonware.com/api/v1`. Trimmed, trailing slashes stripped, and stored as `client.apiBaseUrl`.
* `timeoutMs` (optional): defaults to `30000`. Must be a finite number greater than `0`.

### Constructor errors (thrown)

| Condition | Thrown message |
| - | - |
| `apiKey` missing or empty after trim | `'apiKey' must be a non-empty string` |
| `timeoutMs` not a finite number > 0 | `'timeoutMs' must be a positive number` |
| `baseUrl` empty after trim | `'baseUrl' must be a non-empty URL` |
| `baseUrl` does not start with `http://` or `https://` | `'baseUrl' must be an absolute HTTP(S) URL` |

## Readonly properties

After construction, these properties are readable but not writable:

**apiKey** `string` *required*

The API key passed to the constructor. Do not log the client object: it contains this secret.

**apiBaseUrl** `string` *required*

The normalized base URL used for every request. Trailing slashes are removed.

**timeoutMs** `number` *required*

Per-request timeout in milliseconds. Implemented with `AbortController`.

## Methods

| Method | Signature | Purpose |
| - | - | - |
| `sendEmail` | `(to, subject, body) => Promise<Result>` | Submit an email for delivery |
| `getEmailStatus` | `(messageId) => Promise<EmailStatusResult>` | Look up the current status of a sent email |

Both methods always resolve, even on network failure, timeout, or API error. They never throw.

## Exported types

```typescript theme={null}
// From dist/index.d.ts
export type EmailSentStatus = "queued" | "sent" | "delivered" | "failed" | "bounced" | "rejected" | "deferred" | (string & {});

export interface Result {
  success: boolean;
  errorMessage?: string;
  statusCode?: number;
  id?: string;
  messageId?: string;
  status?: EmailSentStatus;
}

export interface SendAttachment {
  filename: string;
  content: Blob | Uint8Array | ArrayBuffer;
  contentType?: string;
}

export interface SendEmailBody {
  text?: string;
  html?: string;
  cc?: string | string[];
  bcc?: string | string[];
  attachments?: SendAttachment[];
}

export interface EmailStatusData {
  id: string | number;
  uuid: string;
  message_id: string;
  status: EmailSentStatus;
  delivery_status: EmailSentStatus;
  recipient: string | string[];
  subject: string;
  created_at: string;
}

export interface EmailStatusResult {
  success: boolean;
  data?: EmailStatusData;
  errorMessage?: string;
  errorCode?: string;
  statusCode?: number;
}

export interface BosonMailClientOptions {
  apiKey: string;
  baseUrl?: string;
  timeoutMs?: number;
}
```

## Recommended pattern: one shared instance

Create a single client in a module and import it wherever you need to send email or check status. This avoids repeating configuration and keeps the API key in one place.

```typescript lib/bosonmail.ts theme={null}
import BosonMailClient from "@bosonware-ent/bosonmail";

const apiKey = process.env.BOSONMAIL_API_KEY;
if (!apiKey) throw new Error("BOSONMAIL_API_KEY is not set");

export const bosonmail = new BosonMailClient({ apiKey });
```

> [!NOTE]
>
> The constructor is the only place the SDK throws. Methods return result objects so you can handle failures without `try/catch` around every call.

> [card] [Client configuration](https://docs.bosonware.com/sdk/client-configuration.md)
>
> All options, defaults, validation rules, and timeout behavior.

> [card] [Sending emails](https://docs.bosonware.com/sdk/sending-emails.md)
>
> Full reference for sendEmail, parameters, validation, and examples.

> [card] [Email status](https://docs.bosonware.com/sdk/email-status.md)
>
> How to check delivery status with getEmailStatus.

> [card] [Error handling](https://docs.bosonware.com/sdk/error-handling.md)
>
> How to read and act on every kind of SDK error.


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