---
title: "Changelog"
description: "Every release of the package, newest first."
url: "https://openemail.uk/docs/sdk/changelog"
area: "SDK"
category: "Reference"
---

# Changelog

Every release of the package, newest first.

## 0.1.0

The second release. Contacts can be written and grouped into audiences, a domain can carry its own tracking and files names, and a key can rotate itself. One change breaks existing code, and it is listed under it.

- `openemail.audiences` is new: named lists of contacts, with `list`, `get`, `create`, `update`, `delete`, `listContacts`, `addContact` and `removeContact`. Every workspace has one default audience, the one whose `builtin` is `default`, which holds every contact and cannot be deleted.
- `openemail.contacts` can write. `create`, `update` and `delete` join `list` and `get`, and each one takes the email address as the id.
- `openemail.domains.update()` sets or clears a domain's own tracking name and files name, and `DomainResource.tracking` and `DomainResource.storage` report where each one stands.
- `openemail.me.rotate()` replaces the calling key's secret and resolves with the new key in full. There is no overlap window, so the old secret stops working the moment the call returns.
- `KeyResource.domainAllowlist` narrows a key to whole domains, beside the individual addresses in `addressAllowlist`. A domain covers every address on it, including ones created after the key was.
- Attachments can be sent by reference. `{ fileId }` stands beside the inline form, and `attachmentDelivery` picks between carrying files inside the message, replacing them with download links, or letting their size decide.
- Ten more webhook events, twenty in all: replies, deliveries, delays, suppressions, downloads, and the three domain events.
- `email.downloaded` fires when a person fetches a file that went out as a download link. One link serves everyone the message went to, so the event names no recipient.
- Four new scopes: `contacts:write`, `audiences:read`, `audiences:write` and `keys:write`.
- Nine fields that were loose strings now have named types, among them `RecipientKind`, `ContactSource`, `RuleMatchMode` and `WebhookDeliveryStatus`. They accept and return the same strings as before.

**audiences.ts**

```
const audience = await openemail.audiences.create({ name: 'Product updates' })

await openemail.contacts.create({ email: 'grace@example.com', name: 'Grace Hopper' })
await openemail.audiences.addContact(audience.id, { email: 'grace@example.com' })
```

## What breaks in 0.1.0

- `contacts.list` returns `Page<ContactResource>` instead of an array. Read the rows from `page.items` and follow `page.nextCursor` while `page.hasMore` is true. The address book is unbounded, and the old array stopped at 200 rows without saying so.
- `API_SCOPES`, `ERROR_TYPES`, `MESSAGE_ENCRYPTION_FORMATS`, `RULE_ACTIONS`, `RULE_FIELDS`, `RULE_OPERATORS` and `WEBHOOK_EVENTS` are keyed objects rather than arrays, so every member has a name to call it by. The values are unchanged.
- `contacts.list` sorts contacts that have never been mailed last rather than first, so a contact you just created no longer jumps to the top of the book.

**migrate.ts**

```
import { API_SCOPES, WEBHOOK_EVENTS } from '@openemail/sdk'

const scopes = Object.values(API_SCOPES)
const subscribable = new Set<string>(Object.values(WEBHOOK_EVENTS))

const page = await openemail.contacts.list()
for (const contact of page.items) send(contact.email)
```

> Code that only used the derived types keeps working untouched. `ApiScope`, `WebhookEvent` and the rest are the same types they were.

## 0.0.1

The first release: one typed method for every endpoint, and no runtime dependencies.

- Sending: one message, batches, scheduled sends, an undo window, and translation into the language the recipient reads.
- Templates: create, version, publish, preview and send.
- Tracking: opens, clicks, and a summary for each message.
- Mailbox: threads, drafts, labels, contacts and rules.
- Workspace: domains, addresses, members, roles and settings.
- Webhooks, with a signature verifier that runs anywhere WebCrypto does.
- Calendar events, including the ICS file.
- Disposable inboxes, the one part that also runs in a browser.
- Cursor paging on every list, through `listAll` and `iterate`.
- Two error classes, and retries that cannot duplicate a send.
- ESM and CommonJS, on Node 20+, Bun, Deno and Cloudflare Workers.
