---
title: "TypeScript email SDK"
description: "A dependency-free TypeScript client for the OpenEmail API: send mail, read threads and manage webhooks, with timeouts, retries and paging handled."
url: "https://openemail.uk/features/sdk"
---

[Agents, API & MCP](https://openemail.uk/features.md#agents)

# Typed SDKs The API, as typed methods.

@openemail/sdk is a dependency-free TypeScript client for the OpenEmail API, checked against its OpenAPI document on every build.

[Open mail](https://openemail.uk/mail/inbox) [Get Started](https://openemail.uk/signup.md)[All features](https://openemail.uk/features.md)

In short

## What is an SDK?

An SDK, or software development kit, wraps an HTTP API in the functions and types of one language. You call methods instead of building requests, and your editor checks the arguments before anything is sent.

0

Runtime dependencies

30 s

Timeout per attempt

2

Retries on repeatable calls

How it works

## Checked against the API on every build

A parity check reads the OpenAPI document and fails the build on drift: a missing method, a method with no operation, or a wrong scope.

## Paging without a cursor loop

iterate() follows the cursor and fetches each page only when your loop reaches it, so a break stops the requests.

## Retries that never send twice

Repeatable calls get up to two retries with backoff. A send reuses one idempotency key across them, so a retry returns the original message.

## Send your first email

Install it with bun add @openemail/sdk and set OPENEMAIL\_API\_KEY to a key from Settings, API keys.

send-email.ts

```
import { init, openemail } from '@openemail/sdk' init({ apiKey: process.env.OPENEMAIL_API_KEY }) const email = await openemail.emails.send({  from: 'Acme Billing <billing@acme.com>',  to: 'ada@example.com',  subject: 'Your September invoice',  html: '<p>Invoice attached.</p>',}) console.log(email.id, email.status)
```

What you get

## In the product today

Node, Bun and Deno

Node 20 or later, ESM or CommonJS, and it accepts your own fetch.

Keys checked early

A key with the wrong prefix throws at construction, not as a 401.

One client, many workspaces

Pass apiKey on a single call to act for another workspace.

Errors to branch on

OpenEmailApiError carries status, code and requestId, plus isRateLimited and isNotFound.

Good practice

## Getting the most out of it

1. 01
   
   Key in the environment
   
   Set OPENEMAIL\_API\_KEY and let the shared client read it, so no key sits in source.
2. 02
   
   Build one client
   
   Create the client once, in its own module, and import it elsewhere.
3. 03
   
   Read the status
   
   A resolved send can still be queued, scheduled or failed, so read status before treating it as delivered.

Where it stands

## Good to know

Questions

## Asked often

Keep going

## Works well with

REST API

A documented HTTP API with issuable, scopable, revocable keys.

Webhooks

Tell your endpoint when mail arrives, instead of making you poll.

MCP server

Point Claude, or any MCP client, at your mailbox.

Start

## Your domain, your mail.

Point a domain at OpenEmail and read it in a mailbox built around it. The free plan covers one domain.

[Open mail](https://openemail.uk/mail/inbox) [Get Started](https://openemail.uk/signup.md)[Read the reference](https://openemail.uk/docs/knowledge/agents/sdk.md)
