Ir a la documentación
API

Crear una regla

Condiciones de un lado, acciones del otro. Activada salvo que indiques lo contrario.

POSTapi.openemail.uk/rules

Ejecuta la llamada real contra tu espacio de trabajo, con tu propia clave.

POST /rules

Condiciones de un lado, acciones del otro. Activada salvo que indiques lo contrario.

Ejemplo

Requiere rules:write. Devuelve 201. No se acepta position. Una regla nueva se agrega al final de la lista, y para moverla se usa 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  }'
Respuesta
{  "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"}

Una regla creada aquí queda ACTIVADA y empieza a actuar sobre el siguiente mensaje. Ese es el valor predeterminado correcto para una llamada que alguien hizo deliberadamente, y es lo contrario de la herramienta MCP createRule, que escribe la misma regla DESACTIVADA porque un modelo que decide archivar correo no debería ponerse a archivar antes de que una persona haya leído la regla.

Un name duplicado en la misma conexión es rule_name_taken, un 409. Los nombres son la forma de reconocer una regla en un registro de ejecuciones y en la pantalla de ajustes, así que dos reglas llamadas «Newsletters» son un informe que nadie puede leer.

La regla número 101 es rule_limit_reached, un 422. El tope es una protección contra un script en bucle, no un límite contable, y no está bloqueado. Dos creaciones simultáneas en 99 pueden tener éxito ambas.

Qué puede preguntar una condición

Una condición es { field, op, value }, con un header opcional que indica qué cabecera leer y un negate opcional. value es SIEMPRE un string en la transmisión. Los campos numéricos se comparan como números tras Number(value), y los dos campos booleanos aceptan los strings literales "true" y "false", porque un campo con un tipo es un esquema que un generador de OpenAPI puede describir y una unión de tres no lo es.

CampoLeeOperadores
`from`La cabecera From:, normalizada igual que la normaliza la lista de bloqueo.texto
`from_domain`El dominio de From: y sus dominios PADRE, hasta dos etiquetas: un mensaje de mail.corp.example.com coincide también con corp.example.com y example.com, y no coincide con nada para com.texto
`envelope_from`El MAIL FROM de SMTP. Distinto de from en todas las listas de correo, y la única identidad contra la que se puede escribir un reject.texto
`to`, `cc`, `bcc`Cualquier dirección de esa cabecera.texto
`recipient`Cualquier dirección en to, cc o bcc: la forma abreviada de los tres.texto
`reply_to`La cabecera Reply-To.texto
`delivered_to`La dirección canónica a la que se entregó esta copia, sin la etiqueta con + y en minúsculas, que es como se hace coincidir un alias catch-all.texto
`subject`La línea de asunto tal como llegó.texto
`body`La parte de texto, o el HTML reducido a texto. Está limitado, así que un cuerpo de 20 MB no se analiza entero.texto
`header`Cualquier cabecera, indicada en el propio campo header de la condición. Allí es obligatorio y se pasa a minúsculas antes de comparar.texto
`list_id`La cabecera List-Id: el identificador con el que una lista de correo se presenta.texto
`attachment_name`El nombre de archivo de cualquier adjunto.texto
`attachment_type`El tipo MIME de cualquier adjunto, por ejemplo application/pdf.texto
`has_attachment`Si hay alguno o no.equals "true" / "false"
`spam`El veredicto de spam al que llegó la ruta de entrega, antes de que se ejecutaran tus reglas.equals "true" / "false"
`attachment_size`El tamaño de un adjunto en bytes. Una comparación coincide cuando cualquiera de los adjuntos la cumple.gt, lt, equals
`message_size`El mensaje completo tal como viaja, en bytes.gt, lt, equals
`hour`Hora de llegada, 0–23, UTC.gt, lt, equals
`weekday`Día de llegada, 0–6, el domingo es 0, UTC.gt, lt, equals
OperadorQué hace
`matches`Un glob, y solo un glob: * para cualquier secuencia de caracteres, ? para uno. Nada de expresiones regulares. Un patrón enviado por un cliente de la API se ejecuta en la ruta de entrega, y uno con retroceso catastrófico ahí es un buzón que deja de recibir.
`contains`Subcadena, sin distinguir mayúsculas y minúsculas.
`equals`El valor completo, sin distinguir mayúsculas y minúsculas. En un campo numérico, igualdad numérica.
`starts_with`Prefijo, sin distinguir mayúsculas y minúsculas.
`ends_with`Sufijo, sin distinguir mayúsculas y minúsculas.
`gt`, `lt`Numérico, solo en los cuatro campos numéricos. Un campo de texto con gt nunca coincide.

Un patrón matches tiene que llevar al menos dos caracteres alfanuméricos propios, el mismo listón que aplica la lista de bloqueo. Un * a secas se rechaza en el momento de la escritura, en lugar de aceptarse y luego coincidir en silencio con todos los mensajes que lleguen jamás, lo que es una caída del servicio y no una regla.

Una condición que el motor no puede responder (un campo desconocido de un cliente más nuevo, un patrón que no compila, contains "") se trata como una pregunta que nunca se hizo y no como falsa, y negate no la invierte. Esa distinción es clave: una condición rota y negada, tratada como falsa, dispararía su regla en todos los mensajes del buzón. equals "" sí se respeta, porque «la línea de asunto está vacía» es una pregunta real.

Qué puede hacer una regla

Acción`value`Qué ocurre
`label`un id de etiquetaAñade la etiqueta. Los ids USER_… vienen de GET /labels.
`remove_label`un id de etiquetaLa quita. Nombrar la misma etiqueta en ambas acciones se resuelve antes de archivar el mensaje, en lugar de dejarlo a la que se ejecutara en último lugar.
`archive`ningunoLo archiva fuera de la bandeja de entrada.
`mark_read`ningunoQuita UNREAD.
`star`ningunoAñade STARRED.
`spam`ningunoLo archiva en Spam.
`trash`ningunoLo archiva en la Papelera y borra las etiquetas que un mensaje en la papelera no conserva.
`forward`una direcciónReenvía una copia. Lee la nota de abajo antes de usarlo.
`reply`un id o slug de plantillaResponde automáticamente con una plantilla publicada, sujeto a la protección contra bucles descrita abajo.
`block_sender`ningunoAñade al remitente a la lista de bloqueo, de modo que el siguiente mensaje se rechaza en la puerta.
`reject`ningunoRechaza el mensaje en el momento de SMTP con 550 5.7.1 Message refused by the recipient. Solo sobre el sobre. Ver más abajo.

reject se rechaza en el momento de la escritura salvo que la misma regla lleve al menos una condición envelope_from: reject_needs_envelope, un 422. Un 550 responde a quien nos entregó el mensaje, y en una lista de correo eso es la LISTA, que interpreta el rechazo como un suscriptor que rebota y da de baja al lector de algo de lo que solo quería que dejara de publicar una persona. Incluso con la condición escrita, una coincidencia que provino únicamente de las identidades de las cabeceras se degrada a archivar en Spam, porque el sobre es la única identidad a la que un rechazo puede apuntar honestamente.

Un forward disparado por una regla sale por la ruta de envío, que RECONSTRUYE el mensaje: la firma DKIM original no sobrevive, y tampoco las partes exóticas, las cabeceras poco habituales ni nada que supere el tope de tamaño de salida, que un mensaje de 25 MB con adjuntos superará. Es una copia de lo que llegó, no el mensaje que llegó. La dirección se comprueba cuando se escribe la regla, así que un destino no verificado es un 422 en la llamada y no una regla que descarta en silencio uno de cada diez mensajes.

reply no responde a una máquina. Se suprime cuando el mensaje lleva Auto-Submitted (con un valor distinto de no), Precedence: bulk|list|junk, List-Id, List-Unsubscribe, X-Autoreply o X-Autorespond, cuando el remitente del sobre está vacío (la forma que adopta todo rebote) y cuando no se pudieron leer las cabeceras. Además, un remitente recibe como mucho una respuesta automática cada 24 horas desde un buzón dado. Dos buzones con reglas de respuesta y sin protección se escriben mutuamente hasta que alguien se da cuenta.