Перейти к документации
SDK

Конфигурация

Три способа построить клиент, все опции и то, что он отклоняет до отправки запроса.

Опции

openemail.ts
import OpenEmail, { createOpenEmail, init, openemail } from '@openemail/sdk' init({ apiKey: process.env.OPENEMAIL_API_KEY })await openemail.me.ping() export const billing = createOpenEmail({ apiKey: process.env.BILLING_API_KEY! }) const pinned = new OpenEmail({ apiKey: 'oe_live_…', baseUrl: 'https://api.openemail.uk' }) const quick = new OpenEmail('oe_live_…')
Точка входаЧто вы получаете
`init(options)`Настраивает общий клиент и возвращает его. С этого момента openemail — именно этот клиент, в любом модуле, а всё, что вы не указали, читается из окружения.
`openemail`Общий клиент. При использовании до init он строит себя из OPENEMAIL_API_KEY и OPENEMAIL_BASE_URL при первом вызове.
`createOpenEmail(options)`Отдельный клиент с тем же запасным чтением окружения — для второго ключа рядом с общим или чтобы построить экземпляр, который экспортирует ваш собственный модуль. createClient — та же функция под именем, которое использует envless SDK.
`new OpenEmail(options)` или `new OpenEmail(apiKey)`Отдельный клиент, построенный ровно из того, что вы передали. Он не читает окружение, так что apiKey обязателен. Он же экспорт по умолчанию.
options.ts
init({  apiKey: 'oe_live_…',  baseUrl: 'https://api.openemail.uk',  timeoutMs: 30_000,  maxRetries: 2,  fetch: myFetch,  headers: {},  userAgent: 'billing-service/1.4',  disableUpdateNotice: true,})
ОпцияПо умолчаниюПримечания
`apiKey`OPENEMAIL_API_KEYЧитается из окружения функциями init и createOpenEmail. Должен начинаться с oe_live_ или oe_test_.
`baseUrl`https://api.openemail.ukИли OPENEMAIL_BASE_URL. Завершающий слеш срезается, а init и createOpenEmail подставляют https:// перед голым хостом и http:// перед localhost.
`timeoutMs`30000На попытку, а не на вызов. Покрывает чтение тела, а не только заголовков. 0 отключает его.
`maxRetries`2Дополнительные попытки после первой, для вызовов, которые безопасно повторять. Задаётся на клиенте, а не на вызове.
`fetch`глобальныйПривязывается за вас. Передайте свой для прокси, привязки Worker или тестового двойника.
`headers`{}Отправляются с каждым запросом.
`userAgent`openemail-sdk/<version>Отправляется из любой среды, кроме браузера, который не разрешает его задавать.
`disableUpdateNotice`falseПропускает однократную за процесс проверку новой версии на npm. Проверка выполняется, только когда вывод идёт в терминал, и OPENEMAIL_DISABLE_UPDATE_NOTICE тоже её отключает.
`dangerouslyAllowBrowser`falseПозволяет клиенту стартовать там, где есть window и document. Предназначено для тестового стенда, который их определяет, а не для страницы.

Что он отклоняет до отправки

Они бросают обычный Error из той строки, где было неправильное значение, а не всплывают как непонятный сбой при вашей первой отправке. В сообщении сказано, что было не так и что передать вместо этого.

ОтклоненоПочему
Ключа нет вовсеНи apiKey, ни OPENEMAIL_API_KEY не заданы, так что аутентифицироваться нечем.
Сессионная кука или сессионный токенЗдесь аутентифицируют только oe_live_ и oe_test_, и API говорит то же самое. Проверка — это префикс и ничего больше, так что отозванный ключ всё равно упадёт на проводе.
`baseUrl`, не являющийся http- или https-адресомНичего другого получить нельзя, а непроверенный адрес упал бы позже сырым TypeError совсем из другого места.
БраузерКлюч смог бы прочитать любой, кто откроет devtools. См. раздел ниже.
Нигде нет `fetch`Передайте его как fetch или запускайтесь на Node 20+.
Пустой идентификатор или идентификатор из одних точек в любом методеБросается при вызове метода. Сегмент пути из точек удаляется любым парсером URL, так что запрос попал бы на другой эндпоинт.

Опции testMode нет и не будет. Схема ключа — часть учётных данных, а не подсказка, так что режим — свойство ключа. openemail.mode читает префикс и ничего не решает.

Один клиент, несколько ключей

Постройте клиент один раз и используйте его совместно. Новый экземпляр на каждый запрос без всякой пользы выбрасывает привязку fetch и конфигурацию, а никакое состояние в нём не привязано к вызывающей стороне.

Для случая, который иначе потребовал бы по экземпляру на ключ, — например, задания, отправляющего от имени нескольких рабочих пространств, — передайте apiKey в вызов. Он заменяет заголовок Authorization для этого запроса и ничего не оставляет на клиенте.

per-call-key.ts
await openemail.emails.send(message) await openemail.emails.send(message, { apiKey: workspace.apiKey }) await openemail.threads.list({ folder: 'inbox', apiKey: workspace.apiKey })await openemail.webhooks.list({ apiKey: workspace.apiKey })

Каждый метод вне tempMail принимает его в последнем аргументе, рядом с signal, а в списках — в том же объекте, что и фильтры. Он проверяется до отправки запроса, по тому же правилу, что и в конструкторе, так что опечатка бросит Error с упоминанием { apiKey } on this call, а не 401 про учётные данные, которые потом придётся искать. Повторённый вызов сохраняет выданный ему ключ.

signal — это AbortSignal. Его срабатывание останавливает запрос и любой повтор, ожидающий за ним.

openemail.mode описывает ключ, с которым клиент был СОЗДАН, и не следует за переопределением. Как только один клиент обслуживает несколько ключей, единого режима, о котором можно сообщить, не существует, так что читайте его по переданному ключу.

Из браузера

Клиент отказывается стартовать в браузере и бросает исключение до того, как уйдёт хоть один запрос. Ключ на странице — это опубликованный ключ: он может отправлять почту и читать почтовый ящик для любого, кто откроет devtools. Вызывайте его с сервера, из бессерверной функции или из скрипта.

Одноразовые ящики — исключение. createTempMail() строит клиент, который не несёт ключа API, поэтому он безопасен на странице. Он создаёт ящики анонимно, и каждое чтение отправляет токен, который вернул create, — либо для каждого вызова как inboxToken, либо один раз как createTempMail({ inboxToken }).

temp-mail.ts
import { createTempMail } from '@openemail/sdk' const tempMail = createTempMail() const inbox = await tempMail.create()const { items, expiresAt } = await tempMail.listMessages(inbox.id, { inboxToken: inbox.token })

Там, где вы всё же передадите dangerouslyAllowBrowser: true, API пропускает через свой CORS-предзапрос ровно Content-Type, Authorization и Idempotency-Key, так что лишний заголовок в headers провалит предзапрос, а не сам запрос, и то, что браузер об этом сообщит, не скажет ничего полезного.