> ## Documentation Index
> Fetch the complete documentation index at: https://developers.everflow.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Rulesets

> How to configure offer targeting rules (geo, device, connection, day parting, IP) in the Everflow API.

Rulesets define targeting restrictions for offers. They control which traffic is accepted based on geography, device characteristics, connection type, scheduling, and IP addresses.

## Rule categories

**Geotargeting:** `countries`, `regions`, `cities`, `dmas`, `postal_codes`, `mobile_carriers`

**Device:** `browsers`, `device_types`, `brands`, `os_versions`, `platforms`

**Connection:** `isps`, `connection_types`

**Other:** `ips`, `languages`, `is_block_proxy`, day parting settings

## Common fields

Every rule entry includes:

| Field            | Values                                 | Description                                 |
| ---------------- | -------------------------------------- | ------------------------------------------- |
| `targeting_type` | `include`, `exclude`                   | Whether to allow or block matching traffic. |
| `match_type`     | `exact`, `minimum`, `maximum`, `range` | How the value is compared.                  |

### Match type support

| Match type | Supported by                                                                                                       |
| ---------- | ------------------------------------------------------------------------------------------------------------------ |
| `exact`    | countries, regions, cities, dmas, postal\_codes, mobile\_carriers, browsers, device\_types, brands, platforms, ips |
| `minimum`  | os\_versions                                                                                                       |
| `maximum`  | os\_versions                                                                                                       |
| `range`    | ips                                                                                                                |

## Geotargeting precedence

When combining geotargeting rules, more specific rules override less specific ones:

**City > DMA > ZIP/Postal Code > Region > Country**

For example, if you exclude the US but include New York City, traffic from New York City is still accepted.

## Examples

<AccordionGroup>
  <Accordion title="Empty ruleset (all traffic allowed)">
    ```json theme={null}
    { "ruleset": {} }
    ```
  </Accordion>

  <Accordion title="Single country targeting">
    ```json theme={null}
    {
      "ruleset": {
        "countries": [
          { "country_id": 227, "match_type": "exact", "targeting_type": "include" }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="OS version range (iOS 12.0+)">
    ```json theme={null}
    {
      "ruleset": {
        "os_versions": [
          {
            "os_version_id": 34,
            "match_type": "minimum",
            "targeting_type": "include",
            "platform_id": 2
          }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="IP exclusion range">
    The following ruleset excludes all IPs in the `10.11.12.13`–`10.11.12.100` range as well as the single address `1.2.3.4`:

    ```json theme={null}
    {
      "ruleset": {
        "ips": [
          {
            "match_type": "range",
            "targeting_type": "exclude",
            "ip_from": "10.11.12.13",
            "ip_to": "10.11.12.100"
          },
          {
            "match_type": "exact",
            "targeting_type": "exclude",
            "ip_from": "1.2.3.4",
            "ip_to": "1.2.3.4"
          }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="OS version ceiling (exclude Android 7.0 and below)">
    Pair `match_type: "maximum"` with `targeting_type: "exclude"` to block everything up to and including a given version:

    ```json theme={null}
    {
      "ruleset": {
        "os_versions": [
          {
            "os_version_id": 7,
            "match_type": "maximum",
            "targeting_type": "exclude",
            "platform_id": 1
          }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="Combining multiple rules">
    Rules of different types can be combined — the resulting ruleset accepts traffic only when **every** rule matches. The following ruleset accepts:

    * Devices running iOS between version 9.0 and 11.4
    * Traffic from New York City
    * Mobile connection (not Wi-Fi)
    * Not from a known proxy

    ```json theme={null}
    {
      "ruleset": {
        "os_versions": [
          { "os_version_id": 16, "match_type": "minimum", "targeting_type": "include", "platform_id": 2 },
          { "os_version_id": 33, "match_type": "maximum", "targeting_type": "include", "platform_id": 2 }
        ],
        "cities": [
          { "city_id": 479, "match_type": "exact", "targeting_type": "include" }
        ],
        "connection_types": [
          { "connection_type_id": 2, "match_type": "exact", "targeting_type": "include" }
        ],
        "is_block_proxy": true
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Day parting

Control when an offer accepts traffic by time of day and day of week.

| Field                     | Type    | Description                                   |
| ------------------------- | ------- | --------------------------------------------- |
| `is_use_day_parting`      | boolean | Enable day parting.                           |
| `day_parting_apply_to`    | string  | `user_timezone` or `selected_timezone`.       |
| `day_parting_timezone_id` | integer | Timezone ID (when using `selected_timezone`). |
| `days_parting`            | array   | Time windows per day.                         |

Each entry in `days_parting`:

| Field          | Type    | Description                                |
| -------------- | ------- | ------------------------------------------ |
| `day_of_week`  | integer | 0 = Sunday, 1 = Monday, ..., 6 = Saturday. |
| `start_hour`   | integer | Start hour (0–23).                         |
| `start_minute` | integer | Start minute (0–59).                       |
| `end_hour`     | integer | End hour (0–23).                           |
| `end_minute`   | integer | End minute (0–59).                         |

### Day parting examples

<AccordionGroup>
  <Accordion title="Mon–Thu, 9AM–6PM user timezone">
    ```json theme={null}
    {
      "ruleset": {
        "is_use_day_parting": true,
        "day_parting_apply_to": "user_timezone",
        "days_parting": [
          { "day_of_week": 1, "start_hour": 9, "end_hour": 18 },
          { "day_of_week": 2, "start_hour": 9, "end_hour": 18 },
          { "day_of_week": 3, "start_hour": 9, "end_hour": 18 },
          { "day_of_week": 4, "start_hour": 9, "end_hour": 18 }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="Saturday noon–2PM UTC (fixed timezone)">
    Use `day_parting_apply_to: "selected_timezone"` with `day_parting_timezone_id` to schedule based on a fixed timezone regardless of the device user's local time:

    ```json theme={null}
    {
      "ruleset": {
        "is_use_day_parting": true,
        "day_parting_apply_to": "selected_timezone",
        "day_parting_timezone_id": 67,
        "days_parting": [
          { "day_of_week": 6, "start_hour": 12, "end_hour": 14 }
        ]
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Complete ruleset reference

<Accordion title="Full schema — every rule type populated">
  The following example exercises every rule type available. It's unlikely you'd combine all of these in production, but it's a useful reference for the full schema shape:

  ```json theme={null}
  {
    "ruleset": {
      "platforms": [
        { "platform_id": 1, "match_type": "exact", "targeting_type": "include" }
      ],
      "device_types": [
        { "device_type_id": 3, "match_type": "exact", "targeting_type": "include" }
      ],
      "os_versions": [
        { "os_version_id": 32, "match_type": "minimum", "targeting_type": "include", "platform_id": 1 },
        { "os_version_id": 45, "match_type": "maximum", "targeting_type": "include", "platform_id": 1 }
      ],
      "browsers": [
        { "browser_id": 2, "match_type": "exact", "targeting_type": "include" }
      ],
      "brands": [
        { "brand_id": 23, "match_type": "exact", "targeting_type": "include" }
      ],
      "postal_codes": [
        { "postal_code": "90210", "match_type": "exact", "targeting_type": "include" },
        { "postal_code": "90211", "match_type": "exact", "targeting_type": "include" }
      ],
      "languages": [
        { "browser_language_id": 10, "match_type": "exact", "targeting_type": "include" }
      ],
      "countries": [
        { "country_id": 227, "match_type": "exact", "targeting_type": "include" }
      ],
      "regions": [
        { "region_id": 1140, "match_type": "exact", "targeting_type": "include" }
      ],
      "cities": [
        { "city_id": 555, "match_type": "exact", "targeting_type": "include" }
      ],
      "dmas": [
        { "dma_code": 807, "match_type": "exact", "targeting_type": "include" }
      ],
      "isps": [
        { "isp_id": 3827, "match_type": "exact", "targeting_type": "include" }
      ],
      "mobile_carriers": [
        { "mobile_carrier_id": 32, "match_type": "exact", "targeting_type": "include" }
      ],
      "connection_types": [
        { "connection_type_id": 2, "match_type": "exact", "targeting_type": "include" }
      ],
      "ips": [
        {
          "match_type": "range",
          "targeting_type": "exclude",
          "ip_from": "100.100.100.100",
          "ip_to": "100.100.100.255"
        }
      ],
      "is_use_day_parting": true,
      "is_block_proxy": true,
      "day_parting_apply_to": "selected_timezone",
      "day_parting_timezone_id": 90,
      "days_parting": [
        { "day_of_week": 1, "start_hour": 8, "end_hour": 17 },
        { "day_of_week": 2, "start_hour": 8, "end_hour": 17 }
      ]
    }
  }
  ```
</Accordion>
