# Create a rule

> **POST** `https://api.us.nylas.com/v3/rules`

Source: https://developer.nylas.com/docs/reference/api/rules/create-rule/

Creates a rule for your application. A rule defines a `trigger` (`inbound` or `outbound`), conditions against
sender or recipient fields, and actions to apply when the conditions match. Inbound rules run on incoming
messages; outbound rules run on sends before they're submitted to the email provider. Inbound and outbound
rules are isolated — inbound rules never run during sends, and outbound rules never run on message receipt.

Inbound rules can match `from.address`, `from.domain`, or `from.tld`. Outbound rules can match
`from.address`, `from.domain`, `from.tld`, `recipient.address`, `recipient.domain`, `recipient.tld`, or
`outbound.type` (`compose` or `reply`). Link inbound rules to a policy to apply them to specific Agent
Accounts. Outbound rules are currently evaluated from the sending application's enabled outbound rules.

The `application_id` and `organization_id` are derived from your API key and are read-only.

**Authentication:** NYLAS_API_KEY

## Request body

Content-Type: application/json

- `name` (string) **(required)** - A human-readable name for the rule.
- `description` (string)
- `priority` (integer)
- `enabled` (boolean)
- `trigger` (string) - When the rule is evaluated. `inbound` runs the rule on incoming messages; `outbound` runs the rule
on sends before they're submitted to the email provider. Inbound rules accept only `from.*`
conditions. Outbound rules accept `from.*`, `recipient.*`, and `outbound.type`.
- `match` (object) **(required)**
  - `operator` (string) - Optional. When omitted, the rule defaults to `all`.
  - `conditions` (array) **(required)**
    - `field` (string) **(required)** - The field to match against. `from.*` fields match the normalized sender address,
domain, or top-level domain. Inbound rules accept only `from.*`. Outbound rules also
accept `recipient.*` and `outbound.type`. For outbound rules, `recipient.*` matches
against any recipient — To, CC, BCC, and SMTP envelope recipients. `outbound.type`
classifies the send as `compose` (new message) or `reply` (replying to an existing
thread).
    - `operator` (string) **(required)** - How to compare the field value. `outbound.type` supports only `is` and `is_not`;
`contains` and `in_list` are rejected for that field.
    - `value` (any) **(required)** - The value to compare against. For `in_list`, pass an array of List IDs. For
`outbound.type`, pass `compose` or `reply` (case is normalized to lowercase).
      - **string**
      - **array**
- `actions` (array) **(required)**
  - `type` (string) **(required)**
  - `value` (string) - Required when `type` is `assign_to_folder`.

## Responses

### 201 - Created

- `request_id` (string) - ID of the request.
- `data` (object)
  - `id` (string) - Globally unique identifier for the rule (UUID).
  - `name` (string) - A human-readable name for the rule. Required on create.
  - `description` (string) - An optional description of what the rule does.
  - `priority` (integer) - Execution order for the rule. Lower numbers run first. Must be between `0` and `1000`. Defaults to `10`.
  - `enabled` (boolean) - Whether the rule is active. Defaults to `true`.
  - `trigger` (string) - When the rule is evaluated. `inbound` rules run on incoming messages. `outbound` rules run on sends
before the message is submitted to the email provider — an `outbound` rule with a `block` action
rejects the send with HTTP 403 and no message is delivered. Non-blocking actions (`mark_as_spam`,
`archive`, `mark_as_read`, `mark_as_starred`, `assign_to_folder`, `trash`) on outbound rules apply
to the stored sent copy. Inbound and outbound rules are isolated: inbound rules never run during sends, and
outbound rules never run on receipt.
  - `match` (object) - Defines the conditions that must be met for the rule to apply.
    - `operator` (string) - How conditions are combined. Use `any` to match when any condition is true (OR), or `all` to
require every condition to be true (AND). When omitted, the rule defaults to `all`.
    - `conditions` (array) - The list of conditions to evaluate. At least one condition is required.
      - `field` (string) - The field to match against. `from.*` fields match the normalized sender and are valid on
both triggers: `from.address` is the full sender email, `from.domain` is the domain
portion, and `from.tld` is the top-level domain. `recipient.*` fields are valid only on
`outbound` rules and match against **any** recipient — including To, CC, BCC, and SMTP
envelope recipients. For `is_not`, the condition is true only when **no** recipient
matches. `outbound.type` is valid only on `outbound` rules and classifies the send as
`compose` (a fresh message) or `reply` (a reply to an existing thread). The type is
derived as `reply` when the send includes `reply_to_message_id` or the raw MIME
contains `In-Reply-To` or `References` headers; otherwise it's `compose`.
      - `operator` (string) - How to compare the field value. Use `is` for an exact match, `is_not` for the inverse,
`contains` for substring matching, or `in_list` to check against one or more List
resources. String matching is case-insensitive. The `outbound.type` field accepts only
`is` and `is_not` — `contains` and `in_list` are rejected.
      - `value` (any) - The value to compare the field against. For `is`, `is_not`, and `contains`, this is a
string. For `in_list`, this is an array of List IDs. For `outbound.type`, this is
`compose` or `reply` — values are normalized to lowercase on write.
        - **string**
        - **array**
  - `actions` (array) - The actions to perform when the rule matches. At least one action is required. The `block` action cannot be
combined with other actions — it is terminal.
    - `type` (string) - The action to take on the matching message or send. `block` rejects inbound mail at the SMTP
level or rejects an outbound send before provider submission. `mark_as_spam` routes the
message or stored sent copy to the spam folder, `assign_to_folder` moves it to the folder
specified in `value`, and the remaining actions modify the message state.
    - `value` (string) - Required when `type` is `assign_to_folder` — the target folder ID. Optional for other action types.
  - `application_id` (string) - The ID of the application that owns the rule. Read-only; derived from the authenticated API key.
  - `organization_id` (string) - The ID of the Nylas organization that owns the rule. Read-only; derived from the authenticated API key.
  - `created_at` (integer) - When the rule was created, in seconds using the Unix timestamp format.
  - `updated_at` (integer) - When the rule was last updated, in seconds using the Unix timestamp format.

### 400 - Bad Request

- `request_id` (string) - The request ID.
- `error` (object) - The response error object.
  - `type` (string) - The error type.
  - `message` (string) - The error message.
  - `provider_error` (object) - The error from the provider.

### 401 - Unauthorized

- `request_id` (string) - The request ID.
- `error` (object) - The response error object.
  - `type` (string) - The error type.
  - `message` (string) - The error message.
  - `provider_error` (object) - The error from the provider.

### 429 - Rate Limit

- `request_id` (string) - The request ID.
- `error` (object) - The response error object.
  - `type` (string) - The error type.
  - `message` (string) - The error message.

## Code samples

### cURL

```bash
curl -X POST "https://api.us.nylas.com/v3/rules" \
  -H "Authorization: Bearer <NYLAS_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Block spam domains",
    "priority": 1,
    "trigger": "inbound",
    "match": {
      "operator": "any",
      "conditions": [
        {
          "field": "from.domain",
          "operator": "is",
          "value": "spam-domain.com"
        }
      ]
    },
    "actions": [
      { "type": "block" }
    ]
  }'

```

### Node.js SDK

```javascript
import Nylas from "nylas";

const nylas = new Nylas({
  apiKey: "<NYLAS_API_KEY>",
  apiUri: "<NYLAS_API_URI>",
});

async function createRule() {
  try {
    const rule = await nylas.rules.create({
      requestBody: {
        name: "Block spam domains",
        description: "Rejects messages from known spam domains.",
        priority: 1,
        trigger: "inbound",
        match: {
          operator: "any",
          conditions: [
            {
              field: "from.domain",
              operator: "is",
              value: "spam-domain.com",
            },
          ],
        },
        actions: [{ type: "block" }],
      },
    });

    console.log("Rule:", rule);
  } catch (error) {
    console.error("Error creating rule:", error);
  }
}

createRule();

```

### Python SDK

```python
from nylas import Client

nylas = Client(
    "<NYLAS_API_KEY>",
    "<NYLAS_API_URI>",
)

rule = nylas.rules.create(
    request_body={
        "name": "Block spam domains",
        "priority": 1,
        "trigger": "inbound",
        "match": {
            "operator": "any",
            "conditions": [
                {
                    "field": "from.domain",
                    "operator": "is",
                    "value": "spam-domain.com",
                },
            ],
        },
        "actions": [
            {"type": "block"},
        ],
    },
)

print(rule)

```
