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

Домены и адреса

Добавляйте и подтверждайте домены, читайте нужные им DNS-записи, управляйте адресами на них и проверяйте, от имени каких адресов можно отправлять.

Обзор

Домены охватывают два пространства имён. openemail domains управляет доменами, подключёнными к рабочему пространству: их добавлением и удалением, DNS-записями, нужными каждому, тем, может ли он принимать и отправлять, его catch-all, доменами отслеживания и файлов и адресами на нём. openemail addresses отвечает на более узкий вопрос: от имени каких адресов может отправлять ключ или вход, которым вы пользуетесь.

  • Команда домена принимает идентификатор домена, UUID из domains list или domains create. Имя хоста вместо него не принимается, поэтому openemail domains get acme.com даёт 404 и завершается с кодом 5.
  • Команда адреса принимает идентификатор домена, а затем идентификатор адреса, UUID из domains list-addresses или domains create-address.
  • domain и address тоже работают как имена пространств имён. Глаголы доменов откликаются на обычные псевдонимы, такие как ls, show, new, edit и rm, как и addresses list. У пяти глаголов для адресов на домене, таких как create-address, псевдонимов нет.
  • openemail <command> --help перечисляет каждый аргумент и флаг с типом, scope, который нужен вызову, методом и путём и тем, что возвращается. Добавьте --json, чтобы получить ту же страницу как данные.

Все команды

КомандаЧто делает
openemail domains listПоказать домены рабочего пространства по алфавиту с состоянием приёма, отправки, отслеживания и файлов
openemail domains get <id>Прочитать один домен с его адресами, каждой DNS-записью, которую он использует, и тем, найдена ли она, а также с прочтением DMARC
openemail domains create --domain <value>Добавить домен. Ответ содержит каждую DNS-запись для публикации, уже один раз проверенную
openemail domains verify <id>Сразу проверить DNS домена и вернуть домен в том виде, в каком его оставила проверка
openemail domains update <id>Включить или выключить catch-all и задать или убрать домен отслеживания и домен файлов
openemail domains delete <id>Удалить домен и каждый адрес на нём. Просит подтверждения
openemail domains list-addresses <id>Показать адреса на домене с идентификаторами, подписями, состоянием включения и временем, когда каждый последний раз получал почту
openemail domains create-address <id> --local-part <value>Создать на домене включённый адрес с необязательным --label
openemail domains get-address <id> <address-id>Прочитать один адрес на домене
openemail domains update-address <id> <address-id>Переименовать адрес через --label или выключить и включить его через --no-enabled и --enabled
openemail domains delete-address <id> <address-id>Удалить адрес с его домена. Просит подтверждения
openemail addresses listПоказать адреса, от имени которых можно отправлять с этим ключом или входом, и состояние приёма и отправки каждого домена

Все флаги есть в справке своей команды, например openemail domains update --help или openemail domains create-address --help.

Приём и отправка

Домен сообщает о двух независимых фактах. receiving.verified становится true, когда публичный DNS отвечает его MX-записями и TXT-записью _openemail-challenge, и с этого момента он принимает почту. sending.status это состояние подписи, каким его увидела последняя проверка: verified, pending, failed, no_identity или unknown. sending.canSend говорит, была бы отправка с домена принята прямо сейчас, а отрицательный вердикт старше суток считается неизвестным, поэтому скрипту стоит ветвиться по canSend, а не по status. Пока он false, отправка с домена отклоняется с 409 domain_not_sendable.

  • domains create выполняет первую проверку DNS во время вызова, поэтому у каждой записи в records уже есть status: found, missing или null, если её ещё не проверяли. Публикуйте каждую запись ровно в том виде, в каком она дана, поскольку значения свои у каждого домена.
  • domains verify проверяет сразу. В течение 10 секунд после последней проверки она ничего нового не проверяет и возвращает домен как есть. На подтверждённом домене она снова проверяет записи подписи, поэтому sending свежий.
  • domains get на неподтверждённом домене проверяет снова, если последней проверке больше 20 секунд, поэтому опрос get тоже работает, и ему нужен только domains:read, тогда как verify нужен domains:write.
  • Запись, опубликованная только что, может появиться в публичном DNS через несколько минут.

В терминале get, create и verify выводят по одному полю в строке, а вложенные блоки, такие как receiving, sending и records, в виде компактного JSON. Добавьте --json и читайте их инструментом вроде jq, как в примерах ниже.

Catch-all, домены отслеживания и файлов

domains update меняет три настройки, которые не зависят друг от друга. Флаг, который вы не указали, остаётся нетронутым, а без флагов домен возвращается без изменений.

ФлагЧто меняет
--catch-all, --no-catch-allВключённый принимает почту на любой адрес на домене, который никто не создавал, и адрес появляется в list-addresses с первого письма. Выключенный отклоняет почту на каждый адрес, созданный не вручную, включая те, что catch-all подхватил раньше. Новый домен начинает с включённым
--tracking-host <value>Поддомен, например links.acme.com, для отслеживаемых ссылок и пикселя открытия. null убирает его
--storage-host <value>Поддомен, например files.acme.com, для ссылок на скачивание файлов, отправленных с домена. null убирает его
  • Новый хост сохраняется и проверяется в том же вызове. Опубликуйте CNAME-запись с именем record.name и значением record.value из блока tracking или storage ответа, с выключенным проксированием. Повторная настройка хоста может дать ему другое значение, поэтому публикуйте то, о котором сообщает последний ответ.
  • Пока проверка не пройдена, хост в состоянии pending, и новая почта продолжает использовать хост OpenEmail по умолчанию. Когда проверка проходит, он становится active. OpenEmail продолжает проверять сам, и активный хост, который трижды подряд не прошёл проверку или последняя успешная проверка которого была 2 часа назад, становится failed, а новая почта возвращается на хост по умолчанию.
  • Убирайте хост через null, как в --tracking-host null. Пустое значение, например --tracking-host=, в CLI считается ошибкой использования и завершается с кодом 2.
  • Новому хосту нужен подтверждённый домен или хотя бы опубликованная TXT-запись _openemail-challenge. Иначе вызов отклоняется с 409 domain_not_verified.
  • Флаги применяются по порядку: catch-all, затем домен отслеживания, затем домен файлов. Если более поздний флаг отклонён, более раннее изменение может остаться сохранённым, поэтому отправляйте их отдельными вызовами, когда каждое должно действовать само по себе.

Адреса на домене

Домен содержит адреса, созданные вручную или через API, и те, что его catch-all подхватил, когда на них впервые пришла почта. list-addresses показывает оба вида, включая выключенные. Сам catch-all строкой не является: это receiving.catchAll домена.

  • create-address принимает --local-part, часть перед @, и необязательный --label. Домен не обязан быть уже подтверждён, но адрес ничего не получает, пока он не подтверждён. Одиночная * отклоняется, потому что так записывается catch-all.
  • Создание адреса, который уже существует или был удалён, не ошибка. Он возвращается включённым, с переданной подписью или без неё, и сохраняет свой идентификатор. Адрес, подхваченный catch-all, становится созданным вручную, поэтому продолжает принимать почту после выключения catch-all.
  • При включённом catch-all новый адрес начинает с настроек catch-all для отдельного адреса, таких как подпись и отслеживание, кроме настроек конфиденциальности. Они копируются один раз и не синхронизируются.
  • update-address --no-enabled прекращает приём почты на адрес, так что отправители получают отказ, и с него ничего нельзя отправить. Он сохраняет свою почту, настройки и людей, у которых есть к нему доступ, а --enabled продолжает с того же места. --label переименовывает его, а --label null убирает имя.
  • delete-address идёт дальше. Почта на адрес отклоняется даже при включённом catch-all, его пересылка прекращается, его настройки удаляются, люди, которым дали к нему доступ, этот доступ теряют, а вход по паролю отзывается. Уже полученная почта остаётся в ящике. Повторное создание возвращает тот же идентификатор, но без старых настроек и доступа.

От имени каких адресов можно отправлять

openemail addresses list отвечает на вопрос, стоящий за 403 from_address_forbidden: какие адреса ключ или вход, которым вы вызываете, может ставить в From. Ей нужен emails:send, а не scope чтения, потому что она описывает, что приняла бы отправка.

  • В терминале она выводит две таблицы: адреса, с тем, включён ли каждый и можно ли с него отправлять, а затем домены, с тем, подтверждён ли каждый для приёма и для отправки, и с его catch-all.
  • unrestricted равен true, когда учётные данные ничем не сужены. Тогда отправлять можно с любой локальной части на доменах рабочего пространства, включая те, что никто не создавал. Иначе canSend равен true только для включённого адреса, который покрывают учётные данные, через выданный им целый домен или собственный список адресов.
  • canSend равен false для выключенного адреса, для адреса, который учётные данные не покрывают, и для адреса, домен которого ещё не может подписывать.
  • Перечисляются только созданные адреса. Учётные данные, которым выдан целый домен, всё равно могут отправлять с любой локальной части на нём, а с адреса из их списка, за которым нет ящика, можно отправлять, хотя здесь он не появится.
  • С --json она выводит { unrestricted, addresses, domains, hasMore, nextCursor } для одной страницы и { unrestricted, addresses, domains } с --all вместо документа { items, hasMore, nextCursor }, который выводят другие списки. С --all в конвейере или с --ndjson она выводит по одному адресу в строке.

status, open и DNS-провайдеры

openemail status одновременно читает ваш вход, addresses list и domains list и выводит их вместе. Её таблица Sender addresses показывает каждый адрес с тем, может ли он отправлять и включён ли он. Её таблица Domains показывает каждый домен как verified или not verified для приёма, его статус отправки и его catch-all. Она показывает первые 100 записей каждого вида и называет команду с --all для остальных.

  • Часть, которую ваши учётные данные не могут прочитать, например домены без domains:read или адреса без emails:send, пишет Not available с причиной, а остальное всё равно выводится.
  • Если адресов ещё нет, она предлагает openemail domains create --domain example.com.
  • openemail status --json выводит один объект с account, addresses, domains и unavailable, где unavailable даёт причину для каждой части, которую не удалось прочитать.

Подключение DNS-провайдера, чтобы записи нового домена писались за вас, в 0.0.2 выполняется только в веб-приложении. openemail open providers или open dns открывает эту страницу. open domains открывает домены и их DNS-записи, а open addresses адреса. Пересылка тоже в веб-приложении, и open forwarding <address> открывает её для одного адреса. --print выводит ссылку вместо того, чтобы открывать браузер.

Там, где OpenEmail сама записала DNS домена, domains delete забирает эти записи обратно и перечисляет в leftBehind те, которые не смогла, чтобы вы удалили их у своего DNS-провайдера. Записи, которые вы опубликовали сами, никогда не трогаются, поэтому удалите и их, когда домена не станет.

Примеры

Добавить домен и опубликовать его записи
openemail domains create --domain acme.com --json > acme.jsonjq -r '.records[] | [.type, .name, .value, (.priority // "")] | @tsv' acme.jsonopenemail domains verify "$(jq -r .id acme.json)"
Дождаться приёма, затем проверить отправку
id=b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6funtil openemail domains get "$id" --json | jq -e .receiving.verified > /dev/null; do  sleep 30doneopenemail domains get "$id" --json | jq '.sending | {status, canSend, error}'
Выключить catch-all, оставив один адрес
openemail domains list-addresses "$id" --allopenemail domains create-address "$id" --local-part invoices --label Invoicesopenemail domains update "$id" --no-catch-all --dry-runopenemail domains update "$id" --no-catch-all

Созданный вручную invoices продолжает принимать почту после выключения catch-all, а почта на каждый другой адрес, подхваченный catch-all, отклоняется. Пробный запуск выводит PATCH и его тело, не отправляя его.

Задать домен отслеживания, затем убрать его
openemail domains update "$id" --tracking-host links.acme.com --json | jq '.tracking | {status, record, error}'openemail domains update "$id" --tracking-host null
Вывести адрес из употребления
address_id=$(openemail domains list-addresses "$id" --all | jq -r 'select(.address == "[email protected]") | .id')openemail domains update-address "$id" "$address_id" --no-enabledopenemail domains delete-address "$id" "$address_id" --yes

Выключение адреса сначала можно отменить через --enabled. Удаление отменить нельзя, и в скрипте ему нужен --yes. При входе через браузер оно ещё и спрашивает код подтверждения, который --yes никогда не пропускает.

Аудит из скрипта
openemail domains list --all | jq -r 'select(.sending.canSend | not) | [.domain, .sending.status] | @tsv'openemail addresses list --all --json | jq -r '.addresses[] | select(.canSend) | .address'

Scope, подтверждения и ошибки

ScopeКоманды
domains:readdomains list, get, list-addresses, get-address
domains:writedomains create, verify, update, delete, create-address, update-address, delete-address
emails:sendaddresses list
  • Вход или ключ без нужного scope останавливается с кодом выхода 4, называет недостающий scope и объясняет, как его получить.
  • domains delete и domains delete-address просят подтверждения. Ответ «нет» завершает их с кодом 10 и ничего не меняет. Без присмотра и без --yes они останавливаются с кодом выхода 2 до любой отправки.
  • При входе через браузер эти два удаления ещё и спрашивают код подтверждения, как веб-приложение. Без присмотра ввести его некому, поэтому команда останавливается с кодом выхода 4. Сначала запустите openemail verify, и следующие 60 минут код не понадобится. У API-ключа код не спрашивают никогда.
  • --dry-run выводит запрос, который отправило бы изменение, с его телом и завершается с кодом 0, не отправляя его и не прося подтверждения.
  • Список читает одну страницу: --limit принимает от 1 до 100, а если его не указать, сервер отдаёт 25, и --cursor принимает nextCursor предыдущей страницы. --all читает все страницы, --max <n> останавливается после стольких элементов, а --ndjson или --all в конвейере выводит по одному JSON-объекту в строке. С --json domains list и list-addresses выводят один документ { items, hasMore, nextCursor }.
  • Ключ или вход, ограниченный определёнными доменами или адресами, всё равно видит каждый домен и адрес. Добавить домен он не может, а для любого другого изменения нужно, чтобы весь домен был среди выданных ему доменов, иначе вызов отклоняется с 422 capability_unsupported.
  • Отказ завершается кодом своего статуса: 4 для 403, например domain_allowance_reached, когда тариф больше не разрешает доменов, 5 для 404, 6 для 409, например domain_already_added или domain_claimed, и 7 для 422, например invalid_tracking_host или workspace_limit_reached.
  • Последний домен рабочего пространства нельзя удалить из CLI. Это 409 last_domain, потому что его удаление стирает весь почтовый ящик, а веб-приложение сначала просит это подтвердить. Домен с зарезервированными адресами аккаунта даёт 409 domain_holds_reserved_addresses.
  • domains create и два удаления никогда не повторяются после сбоя сети. 409 domain_already_added или 404 при вашей собственной второй попытке после потерянного ответа означает, что первая сработала. verify, update, create-address и update-address повторяются сами, поскольку двойная отправка даёт тот же результат.

Куда дальше

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

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

OpenEmail

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

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