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

Список и получение

`emails.list`, `emails.listAll`, `emails.iterate`, `emails.get` и `emails.listEvents`.

emails.list

list-emails.ts
const first = await openemail.emails.list({  status: ['queued', 'scheduled'],  from: '[email protected]',  limit: 50,}) const second = first.nextCursor  ? await openemail.emails.list({ status: ['queued', 'scheduled'], limit: 50, cursor: first.nextCursor })  : null

Страница — это { items, hasMore, nextCursor }. Передайте nextCursor обратно как cursor, с теми же фильтрами, чтобы получить следующую страницу.

emails.iterate и emails.listAll

iterate-emails.ts
for await (const email of openemail.emails.iterate({ status: 'failed' })) {  console.error(email.id, email.lastError)} const failures = await openemail.emails.listAll({ status: 'failed', from: '[email protected]' })

Оба следуют за nextCursor за вас. iterate запрашивает страницу только когда цикл до неё доходит, так что выход из цикла прекращает запросы, а listAll обходит все страницы, прежде чем разрешиться одним массивом, — так что дайте ему фильтр, который когда-нибудь закончится. В обоих случаях постраничность keyset, так что сообщение, пришедшее посреди обхода, не заставит пропустить строку, как это было бы со смещением.

emails.get и emails.listEvents

get-email.ts
const email = await openemail.emails.get('msg_…')console.log(email.status, email.recipients) const events = await openemail.emails.listEvents('msg_…')for (const event of events) console.log(event.type, event.createdAt)

get — единственный вызов, возвращающий recipients, по строке на адрес. Список из пятидесяти сообщений, каждое со своими получателями, — это страница отчёта, о которой никто не просил.

Параметры

statusEmailStatus | EmailStatus[]
Один статус или несколько (`queued`, `scheduled`, `sending`, `sent`, `partial`, `cancelled`, `failed`), совпадение по любому из перечисленных. SDK отправляет массив одним значением через запятую, потому что сервер разбивает по запятым; значение вне этого набора — 422 с указанием неизвестного.
fromstring
Точное совпадение по адресу отправки в том виде, в каком он записан, то есть голый `addr@host` в нижнем регистре. Строка пишется с отброшенным отображаемым именем, так что угловая форма вроде `Acme <[email protected]>` не совпадёт ни с чем. Ваше значение приводится к нижнему регистру перед сравнением, и это именно равенство, а не совпадение по префиксу или домену.
limitnumber
Строк на странице, от 1 до 100, по умолчанию 25. Значение вне диапазона отклоняется как 422, а не обрезается до границы.
cursorstring
Идентификатор сообщения (`msg_…`), от которого листать. Keyset, а не смещение: строки приходят строго старше, чем `createdAt` того сообщения, так что отправки, случившиеся посреди страницы, не протолкнут строку мимо вас. Идентификатор, не называющий сообщения в этом рабочем пространстве, — это 400.

Ответ: Page<EmailResource>

itemsEmailResource[]
Одна страница сообщений, новые сверху по `createdAt`, извлечённая из конверта `data` у API. Строки списка никогда не несут разбивки `recipients` по адресам. Она есть в `get`.
hasMoreboolean
Есть ли за этой страницей ещё строки, подходящие под фильтр. Отвечается выборкой на одну строку больше, чем `limit`, а не вторым запросом с подсчётом.
nextCursorstring | null
Идентификатор, который надо передать обратно как `cursor`, и null на последней странице. `iterate` и `listAll` останавливаются, когда он null или `hasMore` равно false, поскольку страница, заявляющая о продолжении, но не называющая курсора, зациклилась бы навсегда.
items[].object'email'
Всегда `'email'` в строке этого списка.
items[].idstring
Собственный идентификатор этого API, `msg_…`. Именно его принимает любой другой эндпоинт emails и именно его называет курсор.
items[].statusEmailStatus
Где сообщение находится в своей жизни. `partial` — самостоятельное состояние, а не разновидность failed: у части получателей оно уже есть и его нельзя «разотправить», так что повтор будет ошибкой.
items[].modeApiKeyMode
`live` или `test`, берётся из ключа, которым отправлено. Тестовая отправка записывается здесь и никогда не передаётся.
items[].fromstring
Адрес, под которым была авторизована отправка, хранимый голым и в нижнем регистре, так что отображаемое имя, переданное в `from`, всё равно уходит на провод, но здесь не сохраняется. Обычная строка, а не объект, потому что это авторизованная идентичность: адрес вне области отправки ключа, не принадлежащий ни одному его домену и не названный в нём, отклоняется с 403, а не подменяется тихо тем, который принадлежит.
items[].subjectstring | null
Тема как сохранена. Null у сообщения, записанного без неё.
items[].messageIdstring | null
Message-ID по RFC 5322, а не наш идентификатор. Null, пока не существует MIME, и переписывается сервисом отправки на выходе, так что позднейший отбой или DSN несёт другой идентификатор и соотносится по `items[].id`.
items[].threadIdstring | null
Цепочка, которой принадлежит сообщение, если она была задана или назначена. Иначе null.
items[].transportEmailTransport | (string & {}) | null
Как ушли байты. Null до отправки, и тип открытый, чтобы транспорт, которого этот SDK ещё не называет, не был ломающим изменением: сохранённые записи могут называть и те, что уже не используются.
items[].attemptsnumber
Сколько попыток отправки было у сообщения, 0 до первой.
items[].lastErrorstring | null
Самая свежая ошибка отправки, написанная для человека. Null, пока ничего не падало.
items[].scheduledAtstring | null
Когда сообщение должно уйти, как момент ISO-8601. Null только у немедленной отправки без окна отмены: окно — это всего лишь короткая задержка, так что `cancellableForSeconds` тоже заполняет это поле, у строки, чей `status` равен `queued`, а не `scheduled`.
items[].cancellableUntilstring | null
Момент, когда сообщение должно уйти, несущий то же значение, что и `scheduledAt`, у любой отложенной отправки и null у неотложенной. Это отметка времени для показа, а не проверка, которую делает сервер: `cancel` ветвится по `status` и останавливает сообщение, только пока оно `queued` или `scheduled`.
items[].sentAtstring | null
Когда оно ушло. Null, пока отправка не завершена, — поэтому ветвиться нужно по `status`, а не по этому полю.
items[].tagsRecord<string, string>
Метки, переданные при отправке, возвращаемые как есть и никогда не интерпретируемые. Всегда объект (`{}`, когда ничего не задано, никогда не null), и именно возвращаемые: этот эндпоинт фильтрует по `status` и `from`, так что метка — это то, что читают у сообщения, а не способ его найти.
items[].sourceEmailSource
Какая поверхность запросила отправку: `composer`, `api`, `mcp`, `ai` или `queue`. `api` — это данный клиент.
items[].createdAtstring
Когда была записана запись об отправке, то есть до самой отправки. Именно по этому полю упорядочен список и именно с ним сравнивается курсор.
items[].trackingEmailTrackingSummary
Сводка по вовлечённости, присутствует только в строке, чьё сообщение отслеживалось, и отсутствует в остальных. Именно отсутствие отвечает на вопрос «отслеживалось ли это», тогда как `openCount: 0` читался бы как «никто не открыл».
items[].tracking.opensboolean
Ушло ли это сообщение с пикселем. Это то, что было применено к данному сообщению, а не то, что говорит настройка аккаунта сейчас.
items[].tracking.clicksboolean
Были ли переписаны ссылки этого сообщения. False, когда в теле не было ссылок для переписывания, поскольку тогда ничего не менялось.
items[].tracking.openedboolean
Было ли зафиксировано хоть одно засчитанное открытие, выводится из `openCount > 0`.
items[].tracking.clickedboolean
Был ли зафиксирован хоть один засчитанный клик, выводится из `clickCount > 0`.
items[].tracking.openCountnumber
Открытия, которые считаются вызванными человеком, просуммированные по всем копиям сообщения. Сканеры и прокси приватности фиксируются, но исключаются, а повторные загрузки в течение тридцати секунд схлопываются в одну.
items[].tracking.clickCountnumber
Засчитанные клики, просуммированные по копиям. Дедуплицируются по ссылке, а не по сообщению, потому что переход по двум ссылкам с разницей в секунды — это два действия, а не повтор.
items[].tracking.firstOpenAtstring | null
Самое раннее засчитанное открытие среди копий, и null, пока его нет. Машинные обращения его не сдвигают.
items[].translationEmailTranslationResource
Никогда не присутствует в строке списка: запись о переводе живёт в сохранённом запросе, который список намеренно не подтягивает. Её отсутствие здесь ничего не говорит о том, переводилось ли сообщение. Спросите `get`.