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

Создать правило

Условия с одной стороны, действия с другой. Включено, если вы не скажете иначе.

POSTapi.openemail.uk/rules

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

POST /rules

Условия с одной стороны, действия с другой. Включено, если вы не скажете иначе.

Пример

Требует rules:write. Возвращает 201. position не принимается. Новое правило дописывается в конец списка, а перемещает его POST /rules/reorder.

curl
curl -X POST "$OE/rules" -H "$AUTH" -H "Content-Type: application/json" \  -d '{    "name": "Receipts to their own label",    "match": "all",    "conditions": [      { "field": "from_domain", "op": "matches", "value": "*.stripe.com" },      { "field": "subject", "op": "contains", "value": "receipt" }    ],    "actions": [      { "type": "label", "value": "USER_RECEIPTS" },      { "type": "archive" }    ],    "stopProcessing": true  }'
Ответ
{  "object": "rule",  "id": "rul_7f3a1c94e05d3862c1f0a44b",  "name": "Receipts to their own label",  "description": null,  "enabled": true,  "position": 3,  "match": "all",  "conditions": [    { "field": "from_domain", "op": "matches", "value": "*.stripe.com", "negate": false },    { "field": "subject", "op": "contains", "value": "receipt", "negate": false }  ],  "actions": [    { "type": "label", "value": "USER_RECEIPTS" },    { "type": "archive" }  ],  "stopProcessing": true,  "lastMatchedAt": null,  "matchCount": 0,  "createdAt": "2026-08-30T10:41:02.000Z",  "updatedAt": "2026-08-30T10:41:02.000Z"}

Созданное здесь правило ВКЛЮЧЕНО и начинает действовать со следующего сообщения. Это правильное поведение по умолчанию для вызова, сделанного человеком осознанно, и оно противоположно инструменту MCP createRule, который пишет то же самое правило ОТКЛЮЧЁННЫМ, потому что модель, решившая архивировать почту, не должна архивировать её до того, как человек прочитает правило.

Дублирующееся name в том же подключении — это rule_name_taken, 409. По именам правило узнают в журнале запусков и на экране настроек, так что два правила с именем «Newsletters» — это отчёт, который никто не сможет прочитать.

101-е правило — это rule_limit_reached, 422. Потолок защищает от скрипта в цикле, а не является учётной границей, и он не блокируется. Два создания, идущие наперегонки при 99, могут оба пройти.

О чём может спросить условие

Условие — это { field, op, value }, с необязательным header, называющим, какой заголовок читать, и необязательным negate. value на проводе ВСЕГДА строка. Числовые поля сравниваются как числа после Number(value), а два булевых поля принимают буквальные строки "true" и "false", потому что одно поле с одним типом — это схема, которую генератор OpenAPI может описать, а объединение из трёх — нет.

ПолеЧто читаетОператоры
`from`Заголовок From:, нормализованный так же, как его нормализует чёрный список.текст
`from_domain`Домен из From: и его РОДИТЕЛЬСКИЕ домены, вплоть до двух меток: сообщение с mail.corp.example.com совпадёт и с corp.example.com, и с example.com, и не совпадёт ни с чем для com.текст
`envelope_from`SMTP-команда MAIL FROM. Отличается от from в любой рассылке и является единственной идентичностью, против которой можно написать reject.текст
`to`, `cc`, `bcc`Любой адрес в этом заголовке.текст
`recipient`Любой адрес в to, cc или bcc: сокращение сразу для всех трёх.текст
`reply_to`Заголовок Reply-To.текст
`delivered_to`Канонический адрес, на который была доставлена эта копия, с отброшенным плюс-тегом и приведённый к нижнему регистру, — именно так сопоставляется catch-all алиас.текст
`subject`Тема письма в том виде, в каком она пришла.текст
`body`Текстовая часть или HTML, сведённый к тексту. С ограничением, чтобы тело в 20 МБ не сканировалось целиком.текст
`header`Любой заголовок, названный в собственном поле header этого условия. Там оно обязательно и приводится к нижнему регистру перед сравнением.текст
`list_id`Заголовок List-Id: идентификатор, которым рассылка представляет себя.текст
`attachment_name`Имя файла любого вложения.текст
`attachment_type`MIME-тип любого вложения, например application/pdf.текст
`has_attachment`Есть ли вложение вообще.equals "true" / "false"
`spam`Вердикт о спаме, вынесенный на пути доставки, до запуска ваших правил.equals "true" / "false"
`attachment_size`Размер вложения в байтах. Сравнение срабатывает, когда ему удовлетворяет хотя бы одно вложение.gt, lt, equals
`message_size`Всё сообщение на проводе, в байтах.gt, lt, equals
`hour`Час получения, 0–23, UTC.gt, lt, equals
`weekday`День получения, 0–6, воскресенье — это 0, UTC.gt, lt, equals
ОператорЧто он делает
`matches`Глоб, и только глоб: * для любой последовательности символов, ? для одного. Никаких регулярных выражений. Шаблон от клиента API выполняется на пути доставки, а катастрофический бэктрекинг там — это почтовый ящик, который перестаёт принимать почту.
`contains`Подстрока, без учёта регистра.
`equals`Всё значение целиком, без учёта регистра. На числовом поле — числовое равенство.
`starts_with`Префикс, без учёта регистра.
`ends_with`Суффикс, без учёта регистра.
`gt`, `lt`Числовые, только на четырёх числовых полях. Текстовое поле с gt не совпадёт никогда.

Шаблон matches должен содержать не меньше двух собственных буквенно-цифровых символов — та же планка, что и у чёрного списка. Голая * отклоняется при записи, а не принимается, чтобы потом молча совпадать с каждым сообщением, которое когда-либо придёт: это авария, а не правило.

Условие, на которое движок не может ответить (неизвестное поле от более нового клиента, шаблон, который не компилируется, contains ""), трактуется как вопрос, который никогда не задавали, а не как «ложь», и negate его не переворачивает. Это различие несущее: отрицание сломанного условия, трактуемого как ложь, запускало бы своё правило на каждом сообщении в ящике. equals "" выполняется, потому что «тема письма пуста» — это настоящий вопрос.

Что может делать правило

Действие`value`Что происходит
`label`идентификатор меткиДобавляет метку. Идентификаторы USER_… берутся из GET /labels.
`remove_label`идентификатор меткиУдаляет её. Указание одной и той же метки в обоих действиях разрешается до того, как сообщение будет разложено, а не отдаётся на волю того, что выполнилось последним.
`archive`нетУбирает его из папки входящих.
`mark_read`нетСнимает UNREAD.
`star`нетДобавляет STARRED.
`spam`нетПомещает его в папку «Спам».
`trash`нетПомещает его в корзину, снимая метки, которые удалённое сообщение не сохраняет.
`forward`адресОтправляет копию дальше. Прежде чем пользоваться, прочитайте примечание ниже.
`reply`идентификатор или slug шаблонаАвтоматически отвечает опубликованным шаблоном, с учётом защиты от циклов ниже.
`block_sender`нетДобавляет отправителя в чёрный список, так что следующее сообщение отклоняется прямо на входе.
`reject`нетОтклоняет сообщение прямо на этапе SMTP с 550 5.7.1 Message refused by the recipient. Только по конверту. См. ниже.

reject отклоняется при записи, если в том же правиле нет хотя бы одного условия envelope_from: reject_needs_envelope, 422. Ответ 550 адресован тому, кто передал нам сообщение, а в случае рассылки это САМА РАССЫЛКА, которая прочитает отказ как отбивающегося подписчика и отпишет читателя от всего, тогда как он хотел лишь, чтобы перестал писать один человек. Даже при написанном условии совпадение, пришедшее только из заголовочных идентичностей, понижается до помещения в «Спам», потому что конверт — единственная идентичность, на которую отказ можно честно нацелить.

forward из правила уходит через путь отправки, который ПЕРЕСОБИРАЕТ сообщение: исходная подпись DKIM не сохраняется, как и экзотические части, необычные заголовки и всё, что выходит за исходящий потолок размера, который сообщение в 25 МБ с вложениями превысит. Это копия того, что пришло, а не само пришедшее сообщение. Адрес проверяется при записи правила, поэтому неподтверждённый адрес назначения — это 422 на вызове, а не правило, которое молча теряет каждое десятое сообщение.

reply не отвечает машине. Он подавляется, когда сообщение несёт Auto-Submitted (отличный от no), Precedence: bulk|list|junk, List-Id, List-Unsubscribe, X-Autoreply или X-Autorespond, когда отправитель в конверте пуст (форма, которую принимает любой отбой) и когда заголовки вообще не удалось прочитать. Сверх того, один отправитель получает не более одного автоответа в 24 часа от данного почтового ящика. Два ящика с правилами ответа и без защиты будут писать друг другу, пока кто-нибудь не заметит.