문서로 건너뛰기
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는 전송될 때 항상 string입니다. 숫자 필드는 Number(value) 후 숫자로 비교하고, 두 개의 boolean 필드는 리터럴 문자열 "true""false"를 받습니다. 하나의 타입을 가진 필드 하나는 OpenAPI 생성기가 기술할 수 있는 스키마이지만, 세 타입의 유니온은 그렇지 않기 때문입니다.

필드읽는 대상연산자
`from`From: 헤더. 차단 목록이 정규화하는 방식과 같게 정규화됩니다.텍스트
`from_domain`From:의 도메인과 그 상위 도메인들을 레이블 두 개까지. mail.corp.example.com에서 온 메시지는 corp.example.comexample.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 MB 본문을 전부 훑지는 않습니다.텍스트
`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 "")은 false가 아니라 애초에 묻지 않은 질문으로 취급되며, negate도 그것을 뒤집지 않습니다. 이 구분은 결정적입니다. 부정된 깨진 조건을 false로 취급하면 그 규칙이 메일함의 모든 메시지에 발동합니다. equals ""는 존중됩니다. "제목 줄이 비어 있다"는 실제 질문이기 때문입니다.

규칙이 할 수 있는 일

액션`value`일어나는 일
`label`레이블 id레이블을 추가합니다. USER_… id는 GET /labels에서 옵니다.
`remove_label`레이블 id레이블을 제거합니다. 같은 레이블을 양쪽에 지정하면 마지막에 실행된 쪽에 맡기지 않고 메시지를 분류하기 전에 해결합니다.
`archive`없음받은편지함에서 빼서 보관합니다.
`mark_read`없음UNREAD를 없앱니다.
`star`없음STARRED를 추가합니다.
`spam`없음스팸으로 분류합니다.
`trash`없음휴지통으로 분류하고, 휴지통에 있는 메시지가 유지하지 않는 레이블을 지웁니다.
`forward`주소사본을 전달합니다. 쓰기 전에 아래 메모를 읽으십시오.
`reply`템플릿 id 또는 슬러그게시된 템플릿으로 자동 회신합니다. 아래의 루프 방지 조건이 적용됩니다.
`block_sender`없음보낸 사람을 차단 목록에 추가해, 다음 메시지가 문 앞에서 거절되게 합니다.
`reject`없음SMTP 단계에서 550 5.7.1 Message refused by the recipient로 메시지를 거절합니다. 엔벌로프에만 적용됩니다. 아래를 보십시오.

reject는 같은 규칙에 envelope_from 조건이 최소 하나 없으면 쓰기 시점에 거부됩니다. reject_needs_envelope, 422입니다. 550은 메시지를 건넨 쪽에 답하는 것이고, 메일링 리스트에서 그것은 리스트입니다. 리스트는 그 거절을 반송되는 구독자로 읽고, 한 사람만 그만 올리길 바랐을 뿐인 독자를 구독 해지시킵니다. 조건을 적었더라도 헤더 신원만으로 일치한 경우에는 스팸으로 분류하는 것으로 낮춰집니다. 거절을 정직하게 겨눌 수 있는 유일한 신원은 엔벌로프이기 때문입니다.

규칙으로 동작하는 forward는 발송 경로를 거치며, 그 과정에서 메시지를 다시 만듭니다. 원래의 DKIM 서명은 살아남지 못하고, 특이한 파트, 흔치 않은 헤더, 발신 크기 상한을 넘는 것도 마찬가지입니다. 첨부가 달린 25 MB 메시지는 그 상한을 넘습니다. 도착한 메시지 자체가 아니라 그 사본입니다. 주소는 규칙을 쓸 때 확인하므로, 확인되지 않은 목적지는 열 번에 한 번씩 조용히 메시지를 버리는 규칙이 아니라 호출 시점의 422가 됩니다.

reply는 기계에 답하지 않습니다. 메시지가 Auto-Submitted(no가 아닌 값), Precedence: bulk|list|junk, List-Id, List-Unsubscribe, X-Autoreply, X-Autorespond를 담고 있을 때, 엔벌로프 발신자가 비어 있을 때(모든 반송이 갖는 형태입니다), 그리고 헤더를 전혀 읽을 수 없었을 때 억제됩니다. 그 위에, 한 발신자는 한 메일함으로부터 24시간에 최대 한 번만 자동 회신을 받습니다. 회신 규칙이 있고 방어 장치가 없는 두 메일함은 누군가 알아차릴 때까지 서로에게 메일을 보냅니다.