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

Цепочки, черновики и метки

Каждая команда пространств имён threads, drafts и labels и то, как они лежат под inbox, read, archive и другими почтовыми командами.

Обзор

Почтовые команды, такие как inbox, read, archive и label add, написаны для людей: они принимают сразу несколько идентификаторов цепочек, форматируют вывод и прячут идентификаторы меток. Каждая из них выполняет команды с этой страницы, то есть методы SDK для цепочек, черновиков и меток, по одной команде на метод, поэтому threads.listAttachments становится openemail threads list-attachments.

Пользуйтесь ими, когда нужно то, что почтовые команды опускают: цепочка ровно в том виде, в каком её возвращает API, файлы письма, черновики, а также создание, переименование, перекраска и удаление меток.

  • openemail thread и openemail draft работают так же, как имена во множественном числе. У openemail labels формы единственного числа нет: openemail label это почтовая команда, которая ставит метки на цепочки.
  • Глаголы принимают обычные псевдонимы: ls для list, show и view для get, new и add для create, edit для update, а также rm, del и remove для delete.
  • Все флаги есть в openemail <namespace> <verb> --help, например openemail threads list --help.

Цепочки

Разговоры в почтовом ящике. Идентификатор цепочки, например CAHk7pQ2x9LmZ4, берётся из threads list, openemail inbox или openemail search.

КомандаЧто делает
openemail threads listПоказать одну страницу цепочек в папке, новые сверху. Каждая строка это только идентификатор. --folder, --query, --label-ids, --sort, --date-from, --date-to и --from-contacts сужают и упорядочивают её
openemail threads get <id>Прочитать цепочку со всеми её письмами, старые сверху, с метками и признаком непрочитанности
openemail threads update <id>Отметить цепочку прочитанной через --read или непрочитанной через --no-read, а также ставить и снимать метки через --add-label-ids и --remove-label-ids, до 50 каждого вида
openemail threads trash <id>Переместить цепочку в корзину, за один шаг убрав её из входящих, спама, отложенных и архива. Просит подтверждения
openemail threads snooze <id> <wake-at>Скрыть цепочку до момента в будущем, например 2026-10-01T09:00:00Z. Повторное откладывание заменяет время возврата
openemail threads unsnooze <id>Вернуть отложенную цепочку во входящие сейчас и сбросить время возврата
openemail threads list-attachments <id> <message-id>Показать вложения одного письма, у каждого байты встроены в base64 в content
  • --folder по умолчанию равен inbox и сопоставляется как идентификатор метки, поэтому работают sent, archive, spam, trash, draft, snoozed, starred и unread, bin читается как trash, а также работает идентификатор пользовательской метки, например USER_RECEIPTS. Папка, которой ничего не соответствует, возвращает пустую страницу, а не ошибку.
  • --query принимает синтаксис поиска приложения, а in:anywhere ищет во всех папках. --label-ids сужает ещё сильнее, поскольку цепочка должна нести и папку, и каждый переданный идентификатор. --date-from и --date-to смотрят на самое новое письмо каждой цепочки, и обе границы включаются.
  • threads get включает в письма неотправленные черновики ответов с пометкой isDraft: true и открывает также идентификатор черновика.
  • threads update нужен --read, --no-read или метка, которую нужно поставить или снять. Снятие применяется до добавления. Идентификатор метки, которой нет, отклоняется с label_not_found, и в цепочке ничего не меняется, поэтому сначала создайте метку. TRASH, SNOOZED и DRAFT отклоняются с label_not_directly_settable: используйте threads trash и threads snooze.
  • threads trash ничего не удаляет, и цепочку по-прежнему можно прочитать через threads get, но ни одна команда не достаёт цепочку из корзины. Если отправить в корзину отложенную цепочку, её возврат тоже отменяется.
  • threads snooze отправляет <wake-at> как есть, поэтому передайте момент в будущем в ISO 8601 с Z или смещением: время без них читается в часовом поясе сервера. Задержка вроде 3h отклоняется как неверная. Задержку принимает openemail snooze --until 3h. Цепочки возвращаются при ежечасном обходе, с опозданием примерно до часа, и всегда во входящие.
  • threads list-attachments возвращает каждый файл целиком в одном ответе. Идентификатор письма берите из messages в выводе threads get. Если сохранённые байты не найдены, content это пустая строка, поэтому проверяйте длину перед декодированием.

Черновики

Неотправленные письма, сохранённые в ящике. Идентификатор черновика начинается с draft-.

КомандаЧто делает
openemail drafts listПоказать одну страницу черновиков, недавно сохранённые сверху. Каждая строка это только идентификатор, а --query ищет по ним
openemail drafts get <id>Прочитать получателей черновика, тему, тело, отправителя, цепочку, на которую он отвечает, и имена его вложений
openemail drafts createСохранить новый черновик из --to, --cc, --bcc, --subject, --html, --text, --from и --thread-id, все необязательны
openemail drafts update <id>Изменить поля сохранённого черновика. Поле, которое вы не указали, сохраняет своё значение
openemail drafts delete <id>Удалить черновик навсегда. В корзину он не попадает. Просит подтверждения
  • drafts list --query ищет по теме, отправителю и началу тела и никогда не выходит за пределы черновиков. older_than:30d и другие операторы даты смотрят на время последнего сохранения черновика, а to:, cc: и bcc: в черновике ничему не соответствуют.
  • Черновик хранится как цепочка с меткой DRAFT, поэтому threads get открывает его, а openemail inbox draft перечисляет черновики. drafts get, update и delete отклоняют идентификатор обычной цепочки с 404.
  • openemail drafts create без флагов сохраняет пустой черновик. Проверяются только длины: тема до 998 символов, а --html и --text до 1 000 000 каждый, причём если заданы оба, сохраняется --html. Флага для вложений нет.
  • drafts update заменяет каждое переданное поле. Список заменяет сохранённый целиком, поэтому --to с одним адресом убирает остальные, а обновление очищает список вложений черновика.
  • --thread-id записывает цепочку, на которую отвечает черновик, но сам черновик всё равно хранится как отдельная цепочка.
  • Повторный запуск drafts create сохраняет второй черновик, потому что команда не принимает ключ идемпотентности. Отображаемое имя с запятой распадается на двух испорченных получателей, поэтому не ставьте в нём запятую.
  • openemail send --draft <id> --to <address> отправляет черновик. Тело берётся из черновика, как и тема, если вы не передали --subject, а получатели те, кого вы указали. Её нельзя сочетать с телом, --template или --translate.

Метки

Метки, которые может нести цепочка. Идентификатор пользовательской метки это USER_ и имя, с которым она создана, в верхнем регистре, где каждая группа пробелов заменена на _, поэтому Big Clients становится USER_BIG_CLIENTS.

КомандаЧто делает
openemail labels listПоказать пользовательские метки рабочего пространства, по имени, каждую с цветом, threadCount, createdAt и updatedAt
openemail labels list-colorsПоказать палитру приложения: четырнадцать сплошных цветов и семь градиентов. Цветом передаётся value
openemail labels get <id>Прочитать одну пользовательскую метку, идентификатор сопоставляется с учётом регистра
openemail labels create --name <value>Создать пользовательскую метку. --color-background-color задаёт ей цвет
openemail labels update <id>Переименовать или перекрасить метку. Идентификатор остаётся прежним, как и цепочки, которые её несут
openemail labels delete <id>Удалить метку и снять её со всех цепочек, которые её несли. Просит подтверждения
  • Идентификатор никогда не меняется, даже после переименования, поэтому храните идентификаторы, а не имена.
  • Системные метки, такие как INBOX, STARRED и UNREAD, не перечисляются, их нельзя изменить или удалить, хотя threads update их принимает. labels get для такой метки возвращает 404.
  • В рабочем пространстве может быть до 50 пользовательских меток. Имя, которое уже есть у другой метки без учёта регистра, отклоняется с label_name_taken.
  • Цвет это шестнадцатеричное значение, например #3B82F6, или токен градиента, например gradient:sunset. --label-color принимает весь цвет в виде JSON, а --label-color null его сбрасывает.
  • Метка принадлежит рабочему пространству, поэтому переименование, перекраска или удаление меняет её для всех в нём.
  • У labels delete нет отмены. Если снова создать метку с тем же именем, получится тот же идентификатор, но цепочкам она не вернётся. threadCount в labels get говорит, сколько разговоров её лишится.

Как ими пользуются почтовые команды

Почтовая командаЧто она выполняет
inbox [folder]threads list для одной страницы, затем threads get для каждой цепочки, по шесть за раз
search <query...>threads list --query, затем threads get для каждой цепочки
read <thread-id>threads get, затем threads update --read, если вы не передали --no-mark-read
reply <thread-id>threads get для получателей, темы и адреса отправки, затем emails send в эту цепочку
archive <thread-id...>threads update --add-label-ids ARCHIVE --remove-label-ids INBOX
unarchive <thread-id...>threads update --add-label-ids INBOX --remove-label-ids ARCHIVE
star, unstar <thread-id...>threads update, который ставит или снимает STARRED
mark read, unread <thread-id...>threads update --read или --no-read
trash <thread-id...>threads trash
snooze <thread-id...> --until <when>threads snooze, причём задержка вроде 3h сначала превращается в момент времени
unsnooze <thread-id...>threads unsnooze
label add, remove <thread-id...>threads update --add-label-ids или --remove-label-ids
send --draft <id>emails send --draft-id
  • Почтовая команда принимает несколько идентификаторов цепочек и отчитывается по каждому, а с --json выводит { results, succeeded, failed }. Команда с этой страницы принимает один идентификатор и выводит то, что возвращает API.
  • openemail inbox читает каждую цепочку, которую перечисляет, чтобы показать, кто писал последним, и тему. threads list делает один запрос на страницу и выводит только идентификаторы, а конвейеру больше ничего и не нужно.
  • openemail read превращает HTML-письмо в текст и отмечает цепочку прочитанной. threads get выводит цепочку так, как её возвращает API, и ничего не меняет.

Примеры

Отметить цепочку прочитанной, отправить в архив и поставить метку одним запросом там, где mark read, archive и label add сделали бы три:

Одно обновление
openemail threads update CAHk7pQ2x9LmZ4 --read --add-label-ids ARCHIVE,USER_RECEIPTS --remove-label-ids INBOX --json

Создать метку и разложить под неё каждую подходящую цепочку. В конвейере --all выводит по одному JSON-объекту в строке:

Метка на результаты поиска
openemail labels create --name Receipts --color-background-color gradient:meadowopenemail threads list --query "in:anywhere subject:receipt newer_than:1y" --all | jq -r .id | xargs openemail label add --label USER_RECEIPTS

Сохранить один файл из письма. Идентификаторы писем есть в messages вывода threads get:

Сохранение вложения
openemail threads get CAHk7pQ2x9LmZ4 --json | jq -r ".messages[].id"openemail threads list-attachments CAHk7pQ2x9LmZ4 message_4c1b257a --json | jq -r '.[] | select(.filename == "invoice.pdf") | .content' | base64 --decode > invoice.pdf

Написать черновик, изменить его, прочитать обратно и отправить:

Черновик, затем отправка
DRAFT=$(openemail drafts create --to [email protected] --subject "Engine notes for Thursday" --html "<p>Agenda below.</p>" --json | jq -r .id)openemail drafts update "$DRAFT" --to [email protected],[email protected]openemail drafts get "$DRAFT"openemail send --draft "$DRAFT" --from [email protected] --to [email protected],[email protected]

Убрать черновики, которые никто не сохранял 30 дней. Пробный запуск выводит каждый DELETE, не отправляя его, а --yes отвечает на подтверждение:

Старые черновики
openemail drafts list --query older_than:30d --all | jq -r .id > stale.txtxargs -n 1 openemail drafts delete --dry-run < stale.txtxargs -n 1 openemail drafts delete --yes < stale.txt

Выбрать градиент из палитры, посмотреть изменение заранее, применить его, а позже снова снять цвет:

Перекраска метки
openemail labels list-colors --json | jq -r '.[] | select(.kind == "gradient") | .value'openemail labels update USER_RECEIPTS --name "Receipts 2026" --color-background-color gradient:aurora --dry-runopenemail labels update USER_RECEIPTS --name "Receipts 2026" --color-background-color gradient:auroraopenemail labels update USER_RECEIPTS --label-color null

Scope и коды подтверждения

ScopeКоманды
threads:readthreads list, get и list-attachments
threads:writethreads update, trash, snooze и unsnooze
drafts:readdrafts list и get
drafts:writedrafts create, update и delete
labels:readlabels list, list-colors и get
labels:writelabels create, update и delete

Без нужного scope команда останавливается с кодом выхода 4. Ни одна из этих команд не спрашивает код подтверждения, ни при входе через браузер, ни с API-ключом.

Вход или ключ, ограниченный некоторыми адресами, видит только цепочки, доставленные на них, а любая другая цепочка даёт 404, как будто её нет. Метки принадлежат рабочему пространству, поэтому он всё равно видит каждую метку, но threadCount считает только разговоры, которые ему видны.

Страницы, подтверждения и пробные запуски

  • threads list, drafts list и labels list читают одну страницу: 25 элементов, если --limit не говорит иначе, и до 100. --cursor продолжает с курсора, который вывела страница. Курсор цепочек сохраняет порядок, в котором он был выдан, поэтому передавайте с ним те же фильтры.
  • --all читает все страницы, а --max <n> останавливается после стольких элементов. В конвейере или с --ndjson выводится по одному JSON-объекту в строке, а с --json один документ { items, hasMore, nextCursor }.
  • hasMore может быть true на странице, которая оказывается последней, и тогда следующий вызов не возвращает элементов. Цепочка, получившая новую почту, пока вы листаете, уходит вперёд курсора и не возвращается следующими страницами, как и черновик, сохранённый, пока вы листаете.
  • threads trash, drafts delete и labels delete просят подтверждения. Без присмотра, с --json, --no-input или без терминала, они останавливаются с кодом выхода 2 и ничего не меняют, если вы не передадите --yes.
  • --dry-run выводит запрос, который отправила бы команда, со скрытыми учётными данными и завершается с кодом 0, не отправляя его и не прося подтверждения. С --json выводится { dryRun, request }.

Тела JSON и очистка поля

--data принимает всё тело в виде JSON: встроенно, из файла через @path или из stdin через -, а флаг, переданный вдобавок, переопределяет свой ключ.

Пустое значение флага это ошибка использования, поэтому поле, которое очищается пустым значением, передаётся через --data. --label-color null сбрасывает цвет метки.

Терминал
openemail drafts update draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8 --data '{"from":""}'openemail drafts update draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8 --data '{"threadId":""}'openemail drafts update draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8 --data '{"to":[]}'openemail drafts create --data @draft.json --subject "Overrides the file"

Первая сохраняет черновик без отправителя, вторая отвязывает его от цепочки, на которую он отвечал, а третья очищает его получателей.

Все флаги

Терминал
openemail threads --helpopenemail threads list --helpopenemail drafts create --help --json

openemail <namespace> <verb> --help показывает каждый аргумент и флаг с типом, scope, которые нужны вызову, его метод и путь, что он возвращает, и примечания из справочника API. Добавьте --json, чтобы получить ту же справку как данные.

Ваши входящие,
на ваших условиях.

Почтовая инфраструктура для бизнеса, ИИ, агентов и личной почты. Создана для масштаба, приватности и контроля. Всё, что должно было быть в почте с первого дня.

OpenEmail

Почтовая инфраструктура для бизнеса, ИИ, агентов и личной почты. Создана для масштаба, приватности и контроля. Всё, что должно было быть в почте с первого дня.

© 2026 OpenEmail. Все права защищены.