{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://mydatahub.emailmovers.com/schemas/audience/1.json",
  "type": "object",
  "properties": {
    "schema": {
      "type": "string",
      "const": "mydatahub.audience/1",
      "description": "The definition's namespace and version. Older versions are upgraded by a pure function."
    },
    "dataset": {
      "type": "string",
      "enum": [
        "uk_contacts",
        "ie_contacts",
        "global_contacts"
      ],
      "description": "The dataset an audience draws from. uk_contacts is live; ie_contacts and global_contacts are listed but not yet served."
    },
    "dataset_version": {
      "description": "The weekly build to count against, such as 2026-W39. Left out, the current version is filled in and returned.",
      "type": "string",
      "pattern": "^[0-9]{4}-W(0[1-9]|[1-4][0-9]|5[0-3])$",
      "examples": [
        "2026-W39"
      ]
    },
    "where": {
      "description": "The filters. Left out, the audience is the whole dataset after the defaults.",
      "$ref": "#/$defs/WhereNode"
    },
    "email_policy": {
      "$ref": "#/$defs/EmailPolicy"
    },
    "dedupe": {
      "type": "string",
      "enum": [
        "none",
        "one_per_company",
        "one_per_site"
      ],
      "description": "none keeps every matching contact, one_per_company keeps one contact per company, one_per_site keeps one per site. Default none."
    }
  },
  "required": [
    "schema"
  ],
  "additionalProperties": false,
  "title": "MyDataHub audience definition (mydatahub.audience/1)",
  "description": "Who you want, as filters grouped by entity (company., site., contact., email., phone., signal.). The server fills its defaults (active companies, named emails, corporate subscribers, the current dataset_version) and returns the effective definition with every count.",
  "examples": [
    {
      "schema": "mydatahub.audience/1",
      "dataset": "uk_contacts",
      "dataset_version": "2026-W39",
      "where": {
        "all": [
          {
            "field": "contact.title",
            "op": "matches",
            "terms": [
              "marketing manager"
            ],
            "mode": "contains",
            "expand": [
              "plural_singular",
              "department_synonyms",
              "ampersand_and",
              "abbreviations"
            ]
          },
          {
            "field": "contact.job_level_rank",
            "op": "in",
            "values": [
              1,
              2,
              3,
              4,
              5,
              6,
              8,
              9
            ]
          },
          {
            "field": "company.sic_2007",
            "op": "in",
            "values": [
              "C"
            ]
          },
          {
            "field": "company.employee_band",
            "op": "gte",
            "value": "50-99"
          },
          {
            "field": "site.location",
            "op": "within_radius",
            "centre": {
              "place": "Leeds"
            },
            "radius_miles": 20
          },
          {
            "not": {
              "field": "email.address_sha256",
              "op": "in_list",
              "list_id": "sup_01JB4H7Q2V7XN3M9R6T1Y5W8ZA"
            }
          }
        ]
      },
      "email_policy": {
        "min_deliverability_score": 70,
        "allow_catch_all": false
      },
      "dedupe": "none"
    }
  ],
  "$defs": {
    "WhereNode": {
      "anyOf": [
        {
          "$ref": "#/$defs/AllGroup"
        },
        {
          "$ref": "#/$defs/AnyGroup"
        },
        {
          "$ref": "#/$defs/NotGroup"
        },
        {
          "$ref": "#/$defs/BundleNode"
        },
        {
          "$ref": "#/$defs/Filter"
        }
      ],
      "description": "A group (all, any, not), a title bundle or a filter. Groups nest up to 32 deep, and a where tree holds up to 1,000 filters, groups and bundles."
    },
    "AllGroup": {
      "type": "object",
      "properties": {
        "all": {
          "minItems": 1,
          "type": "array",
          "items": {
            "$ref": "#/$defs/WhereNode"
          }
        }
      },
      "required": [
        "all"
      ],
      "additionalProperties": false,
      "description": "AND: every node inside must match."
    },
    "AnyGroup": {
      "type": "object",
      "properties": {
        "any": {
          "minItems": 1,
          "type": "array",
          "items": {
            "$ref": "#/$defs/WhereNode"
          }
        }
      },
      "required": [
        "any"
      ],
      "additionalProperties": false,
      "description": "OR: at least one node inside must match."
    },
    "NotGroup": {
      "type": "object",
      "properties": {
        "not": {
          "$ref": "#/$defs/WhereNode"
        }
      },
      "required": [
        "not"
      ],
      "additionalProperties": false,
      "description": "Negation: the single node inside must not match."
    },
    "BundleNode": {
      "type": "object",
      "properties": {
        "bundle": {
          "type": "string",
          "enum": [
            "sdm",
            "manager_and_above",
            "owner_managed"
          ]
        }
      },
      "required": [
        "bundle"
      ],
      "additionalProperties": false,
      "description": "A title bundle, resolved to its filters in the effective definition: sdm (senior decision makers), manager_and_above (managers and above), owner_managed (owner managed)."
    },
    "Filter": {
      "oneOf": [
        {
          "$ref": "#/$defs/InFilter"
        },
        {
          "$ref": "#/$defs/BetweenFilter"
        },
        {
          "$ref": "#/$defs/GteFilter"
        },
        {
          "$ref": "#/$defs/LteFilter"
        },
        {
          "$ref": "#/$defs/MatchesFilter"
        },
        {
          "$ref": "#/$defs/WithinRadiusFilter"
        },
        {
          "$ref": "#/$defs/InListFilter"
        },
        {
          "$ref": "#/$defs/SinceFilter"
        }
      ],
      "description": "One criterion: a field from GET /v1/catalogue/filters, an operator and its operands. Exclusions nest under not."
    },
    "InFilter": {
      "type": "object",
      "properties": {
        "field": {
          "type": "string",
          "enum": [
            "company.sic_2007",
            "company.business_class",
            "company.employee_band",
            "company.turnover_band",
            "company.fleet_band",
            "company.type",
            "company.status",
            "company.subscriber_class",
            "company.companies_house_number",
            "site.region",
            "site.county",
            "site.town",
            "site.postcode",
            "contact.title_family",
            "contact.job_function",
            "contact.job_level_rank",
            "contact.premium",
            "email.exists",
            "email.type",
            "phone.exists",
            "phone.tps_ctps_status"
          ]
        },
        "op": {
          "type": "string",
          "const": "in"
        },
        "values": {
          "minItems": 1,
          "maxItems": 10000,
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              }
            ],
            "description": "A code, a rank or a boolean, as the field's catalogue lists it."
          }
        }
      },
      "required": [
        "field",
        "op",
        "values"
      ],
      "additionalProperties": false,
      "description": "The field holds one of the listed codes.",
      "examples": [
        {
          "field": "company.sic_2007",
          "op": "in",
          "values": [
            "C"
          ]
        }
      ],
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.sic_2007"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^([A-U]|[0-9]{2,5})$"
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.business_class"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.employee_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "1-5",
                    "6-9",
                    "10-19",
                    "20-49",
                    "50-99",
                    "100-199",
                    "200-349",
                    "350-499",
                    "500-999",
                    "1000-1499",
                    "1500-4999",
                    "5000-9999",
                    "10000+",
                    "unclassified"
                  ]
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.turnover_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "1-100k",
                    "101k-200k",
                    "201k-500k",
                    "501k-750k",
                    "751k-1M",
                    "1.1M-2M",
                    "2.1M-5M",
                    "5.1M-7.5M",
                    "7.6M-10M",
                    "11M-20M",
                    "21M-50M",
                    "51M-75M",
                    "76M-100M",
                    "100M-250M",
                    "251M-500M",
                    "501M-1B",
                    "1B+",
                    "unclassified"
                  ]
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.fleet_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "1-2",
                    "3-5",
                    "6-9",
                    "10-19",
                    "20-49",
                    "50-99",
                    "100+",
                    "unclassified"
                  ]
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.type"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^[a-z0-9]+(_[a-z0-9]+)*$"
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.status"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^[a-z0-9]+(_[a-z0-9]+)*$"
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.subscriber_class"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "ltd",
                    "plc",
                    "llp",
                    "scottish_partnership",
                    "public_body",
                    "charity_incorporated",
                    "sole_trader",
                    "ordinary_partnership",
                    "unknown"
                  ]
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.companies_house_number"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^[A-Z0-9]{8}$"
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "site.region"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "north_east",
                    "north_west",
                    "yorkshire_and_the_humber",
                    "east_midlands",
                    "west_midlands",
                    "east_of_england",
                    "london",
                    "south_east",
                    "south_west",
                    "scotland",
                    "wales",
                    "northern_ireland",
                    "crown_dependencies"
                  ]
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "site.county"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "site.town"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "site.postcode"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^[A-Za-z]{1,2}([0-9][0-9A-Za-z]?( [0-9]([A-Za-z]{2})?| ?[0-9][A-Za-z]{2})?)?$"
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "contact.title_family"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "contact.job_function"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "contact.job_level_rank"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "enum": [
                    1,
                    2,
                    3,
                    4,
                    5,
                    6,
                    7,
                    8,
                    9,
                    10,
                    11,
                    12,
                    13,
                    0
                  ]
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "contact.premium"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "boolean"
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "email.exists"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "boolean"
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "email.type"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "named",
                    "generic_local_part",
                    "generic_domain"
                  ]
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "phone.exists"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "boolean"
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "phone.tps_ctps_status"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "clear",
                    "tps_registered",
                    "ctps_registered",
                    "tps_or_ctps_registered",
                    "not_screened"
                  ]
                }
              }
            }
          }
        }
      ]
    },
    "BetweenFilter": {
      "type": "object",
      "properties": {
        "field": {
          "type": "string",
          "enum": [
            "company.employee_band",
            "company.turnover_band",
            "company.fleet_band",
            "contact.job_level_rank",
            "email.deliverability_score"
          ]
        },
        "op": {
          "type": "string",
          "const": "between"
        },
        "from": {
          "anyOf": [
            {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            {
              "type": "number"
            }
          ],
          "description": "A band code or a number from the field's order."
        },
        "to": {
          "anyOf": [
            {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            {
              "type": "number"
            }
          ],
          "description": "A band code or a number from the field's order."
        }
      },
      "required": [
        "field",
        "op",
        "from",
        "to"
      ],
      "additionalProperties": false,
      "description": "The field lies from one value to another inclusive, over the field's order.",
      "examples": [
        {
          "field": "company.employee_band",
          "op": "between",
          "from": "10-19",
          "to": "200-349"
        }
      ],
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.employee_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "from": {
                "type": "string",
                "enum": [
                  "1-5",
                  "6-9",
                  "10-19",
                  "20-49",
                  "50-99",
                  "100-199",
                  "200-349",
                  "350-499",
                  "500-999",
                  "1000-1499",
                  "1500-4999",
                  "5000-9999",
                  "10000+"
                ]
              },
              "to": {
                "type": "string",
                "enum": [
                  "1-5",
                  "6-9",
                  "10-19",
                  "20-49",
                  "50-99",
                  "100-199",
                  "200-349",
                  "350-499",
                  "500-999",
                  "1000-1499",
                  "1500-4999",
                  "5000-9999",
                  "10000+"
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.turnover_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "from": {
                "type": "string",
                "enum": [
                  "1-100k",
                  "101k-200k",
                  "201k-500k",
                  "501k-750k",
                  "751k-1M",
                  "1.1M-2M",
                  "2.1M-5M",
                  "5.1M-7.5M",
                  "7.6M-10M",
                  "11M-20M",
                  "21M-50M",
                  "51M-75M",
                  "76M-100M",
                  "100M-250M",
                  "251M-500M",
                  "501M-1B",
                  "1B+"
                ]
              },
              "to": {
                "type": "string",
                "enum": [
                  "1-100k",
                  "101k-200k",
                  "201k-500k",
                  "501k-750k",
                  "751k-1M",
                  "1.1M-2M",
                  "2.1M-5M",
                  "5.1M-7.5M",
                  "7.6M-10M",
                  "11M-20M",
                  "21M-50M",
                  "51M-75M",
                  "76M-100M",
                  "100M-250M",
                  "251M-500M",
                  "501M-1B",
                  "1B+"
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.fleet_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "from": {
                "type": "string",
                "enum": [
                  "1-2",
                  "3-5",
                  "6-9",
                  "10-19",
                  "20-49",
                  "50-99",
                  "100+"
                ]
              },
              "to": {
                "type": "string",
                "enum": [
                  "1-2",
                  "3-5",
                  "6-9",
                  "10-19",
                  "20-49",
                  "50-99",
                  "100+"
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "contact.job_level_rank"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "from": {
                "type": "integer",
                "enum": [
                  1,
                  2,
                  3,
                  4,
                  5,
                  6,
                  7,
                  8,
                  9,
                  10,
                  11,
                  12,
                  13
                ]
              },
              "to": {
                "type": "integer",
                "enum": [
                  1,
                  2,
                  3,
                  4,
                  5,
                  6,
                  7,
                  8,
                  9,
                  10,
                  11,
                  12,
                  13
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "email.deliverability_score"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "from": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100
              },
              "to": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100
              }
            }
          }
        }
      ]
    },
    "GteFilter": {
      "type": "object",
      "properties": {
        "field": {
          "type": "string",
          "enum": [
            "company.employee_band",
            "company.turnover_band",
            "company.fleet_band",
            "contact.job_level_rank",
            "email.deliverability_score"
          ]
        },
        "op": {
          "type": "string",
          "const": "gte"
        },
        "value": {
          "anyOf": [
            {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            {
              "type": "number"
            }
          ],
          "description": "A band code or a number from the field's order."
        }
      },
      "required": [
        "field",
        "op",
        "value"
      ],
      "additionalProperties": false,
      "description": "The field is at or after the value in its order: for bands, the band and every larger one.",
      "examples": [
        {
          "field": "company.employee_band",
          "op": "gte",
          "value": "50-99"
        }
      ],
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.employee_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "string",
                "enum": [
                  "1-5",
                  "6-9",
                  "10-19",
                  "20-49",
                  "50-99",
                  "100-199",
                  "200-349",
                  "350-499",
                  "500-999",
                  "1000-1499",
                  "1500-4999",
                  "5000-9999",
                  "10000+"
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.turnover_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "string",
                "enum": [
                  "1-100k",
                  "101k-200k",
                  "201k-500k",
                  "501k-750k",
                  "751k-1M",
                  "1.1M-2M",
                  "2.1M-5M",
                  "5.1M-7.5M",
                  "7.6M-10M",
                  "11M-20M",
                  "21M-50M",
                  "51M-75M",
                  "76M-100M",
                  "100M-250M",
                  "251M-500M",
                  "501M-1B",
                  "1B+"
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.fleet_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "string",
                "enum": [
                  "1-2",
                  "3-5",
                  "6-9",
                  "10-19",
                  "20-49",
                  "50-99",
                  "100+"
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "contact.job_level_rank"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "integer",
                "enum": [
                  1,
                  2,
                  3,
                  4,
                  5,
                  6,
                  7,
                  8,
                  9,
                  10,
                  11,
                  12,
                  13
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "email.deliverability_score"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100
              }
            }
          }
        }
      ]
    },
    "LteFilter": {
      "type": "object",
      "properties": {
        "field": {
          "type": "string",
          "enum": [
            "company.employee_band",
            "company.turnover_band",
            "company.fleet_band",
            "contact.job_level_rank",
            "contact.company_contact_rank",
            "email.deliverability_score"
          ]
        },
        "op": {
          "type": "string",
          "const": "lte"
        },
        "value": {
          "anyOf": [
            {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            {
              "type": "number"
            }
          ],
          "description": "A band code or a number from the field's order."
        }
      },
      "required": [
        "field",
        "op",
        "value"
      ],
      "additionalProperties": false,
      "description": "The field is at or before the value in its order. Rank 1 is the most senior, so Director and above is contact.job_level_rank lte 6.",
      "examples": [
        {
          "field": "contact.job_level_rank",
          "op": "lte",
          "value": 6
        }
      ],
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.employee_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "string",
                "enum": [
                  "1-5",
                  "6-9",
                  "10-19",
                  "20-49",
                  "50-99",
                  "100-199",
                  "200-349",
                  "350-499",
                  "500-999",
                  "1000-1499",
                  "1500-4999",
                  "5000-9999",
                  "10000+"
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.turnover_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "string",
                "enum": [
                  "1-100k",
                  "101k-200k",
                  "201k-500k",
                  "501k-750k",
                  "751k-1M",
                  "1.1M-2M",
                  "2.1M-5M",
                  "5.1M-7.5M",
                  "7.6M-10M",
                  "11M-20M",
                  "21M-50M",
                  "51M-75M",
                  "76M-100M",
                  "100M-250M",
                  "251M-500M",
                  "501M-1B",
                  "1B+"
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "company.fleet_band"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "string",
                "enum": [
                  "1-2",
                  "3-5",
                  "6-9",
                  "10-19",
                  "20-49",
                  "50-99",
                  "100+"
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "contact.job_level_rank"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "integer",
                "enum": [
                  1,
                  2,
                  3,
                  4,
                  5,
                  6,
                  7,
                  8,
                  9,
                  10,
                  11,
                  12,
                  13
                ]
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "contact.company_contact_rank"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "integer",
                "minimum": 1,
                "maximum": 1000
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "email.deliverability_score"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "value": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100
              }
            }
          }
        }
      ]
    },
    "MatchesFilter": {
      "type": "object",
      "properties": {
        "field": {
          "type": "string",
          "enum": [
            "contact.title"
          ]
        },
        "op": {
          "type": "string",
          "const": "matches"
        },
        "terms": {
          "minItems": 1,
          "maxItems": 500,
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        },
        "mode": {
          "type": "string",
          "enum": [
            "contains",
            "starts_with",
            "exact"
          ],
          "description": "contains (the default) matches titles containing a term, starts_with matches titles beginning with it, exact takes verbatim titles with no expansion."
        },
        "expand": {
          "description": "Expansion sets to apply, each once: plural_singular, department_synonyms, ampersand_and, abbreviations, permutations. Left out, the first four apply; an empty list applies none. Not used with mode exact.",
          "uniqueItems": true,
          "maxItems": 5,
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "plural_singular",
              "department_synonyms",
              "ampersand_and",
              "abbreviations",
              "permutations"
            ]
          }
        },
        "exclude_terms": {
          "description": "Expanded terms removed by hand. Kept in the definition so the count stays reproducible when the title dictionary changes.",
          "maxItems": 500,
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        }
      },
      "required": [
        "field",
        "op",
        "terms"
      ],
      "additionalProperties": false,
      "description": "Job title keyword match. mode contains (the default) or starts_with expands each term with the expansion sets; mode exact matches verbatim titles. Every expanded term is returned with the count.",
      "examples": [
        {
          "field": "contact.title",
          "op": "matches",
          "terms": [
            "marketing manager"
          ],
          "mode": "contains",
          "expand": [
            "plural_singular",
            "department_synonyms",
            "ampersand_and",
            "abbreviations"
          ]
        }
      ],
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "mode": {
                "const": "exact"
              }
            },
            "required": [
              "mode"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "expand": {
                "type": "array",
                "maxItems": 0
              },
              "exclude_terms": {
                "type": "array",
                "maxItems": 0
              }
            }
          }
        }
      ]
    },
    "WithinRadiusFilter": {
      "type": "object",
      "properties": {
        "field": {
          "type": "string",
          "enum": [
            "site.location"
          ]
        },
        "op": {
          "type": "string",
          "const": "within_radius"
        },
        "centre": {
          "$ref": "#/$defs/RadiusCentre"
        },
        "radius_miles": {
          "type": "number",
          "minimum": 1,
          "maximum": 100,
          "description": "Radius in miles, 1 to 100. Under 5 miles needs an account."
        }
      },
      "required": [
        "field",
        "op",
        "centre",
        "radius_miles"
      ],
      "additionalProperties": false,
      "description": "Sites within radius_miles of the centre. The count reports the centroid used and the postcodes matched.",
      "examples": [
        {
          "field": "site.location",
          "op": "within_radius",
          "centre": {
            "place": "Leeds"
          },
          "radius_miles": 20
        }
      ]
    },
    "RadiusCentre": {
      "anyOf": [
        {
          "$ref": "#/$defs/PlaceCentre"
        },
        {
          "$ref": "#/$defs/PostcodeCentre"
        },
        {
          "$ref": "#/$defs/PointCentre"
        }
      ],
      "description": "The centre of a radius: a place, a postcode or a latitude and longitude."
    },
    "PlaceCentre": {
      "type": "object",
      "properties": {
        "place": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100,
          "description": "A place name, resolved with resolve_location, such as Leeds."
        },
        "code": {
          "description": "The ONS geography code of the chosen candidate when resolve_location found more than one, such as E08000035 for the Leeds district.",
          "type": "string",
          "minLength": 1,
          "maxLength": 20
        }
      },
      "required": [
        "place"
      ],
      "additionalProperties": false,
      "description": "A named place. Ambiguous names come back from resolve_location as candidates, never a silent choice."
    },
    "PostcodeCentre": {
      "type": "object",
      "properties": {
        "postcode": {
          "type": "string",
          "pattern": "^[A-Za-z]{1,2}([0-9][0-9A-Za-z]?( [0-9]([A-Za-z]{2})?| ?[0-9][A-Za-z]{2})?)?$",
          "description": "The centroid of a postcode unit, sector, district or area, such as LS1 4AP."
        }
      },
      "required": [
        "postcode"
      ],
      "additionalProperties": false,
      "description": "A postcode centroid from ONSPD."
    },
    "PointCentre": {
      "type": "object",
      "properties": {
        "lat": {
          "type": "number",
          "minimum": 49,
          "maximum": 61
        },
        "lon": {
          "type": "number",
          "minimum": -9,
          "maximum": 2
        }
      },
      "required": [
        "lat",
        "lon"
      ],
      "additionalProperties": false,
      "description": "A latitude and longitude in WGS84 degrees."
    },
    "InListFilter": {
      "type": "object",
      "properties": {
        "field": {
          "type": "string",
          "enum": [
            "company.companies_house_number",
            "contact.title",
            "email.address_sha256",
            "email.domain_sha256",
            "phone.e164_sha256"
          ]
        },
        "op": {
          "type": "string",
          "const": "in_list"
        },
        "list_id": {
          "type": "string",
          "pattern": "^sup_[0-7][0-9A-HJKMNP-TV-Z]{25}$",
          "description": "Format: a suppression list id: sup_ followed by a 26 character ULID in upper case Crockford base32, such as sup_01JB4H7Q2V7XN3M9R6T1Y5W8ZA.",
          "examples": [
            "sup_01JB4H7Q2V7XN3M9R6T1Y5W8ZA"
          ]
        }
      },
      "required": [
        "field",
        "op",
        "list_id"
      ],
      "additionalProperties": false,
      "description": "The record's hashed email, domain, phone, company number or title term is on a suppression list. Usually nested under not; each list reports the records it removed.",
      "examples": [
        {
          "field": "email.address_sha256",
          "op": "in_list",
          "list_id": "sup_01JB4H7Q2V7XN3M9R6T1Y5W8ZA"
        }
      ]
    },
    "SinceFilter": {
      "type": "object",
      "properties": {
        "field": {
          "type": "string",
          "enum": [
            "contact.last_validated_at",
            "email.last_verified_at",
            "signal.type",
            "signal.observed_at"
          ]
        },
        "op": {
          "type": "string",
          "const": "since"
        },
        "days": {
          "type": "integer",
          "minimum": 1,
          "maximum": 3650
        },
        "values": {
          "description": "For signal.type only: the signal types to look for, such as company.incorporated.",
          "minItems": 1,
          "maxItems": 10000,
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        }
      },
      "required": [
        "field",
        "op",
        "days"
      ],
      "additionalProperties": false,
      "description": "Within the last N days: a date field, or a Companies House signal of the listed types on signal.type.",
      "examples": [
        {
          "field": "signal.type",
          "op": "since",
          "values": [
            "company.incorporated"
          ],
          "days": 90
        }
      ],
      "allOf": [
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "contact.last_validated_at"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": false
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "email.last_verified_at"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": false
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "signal.type"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "required": [
              "values"
            ],
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "company.incorporated",
                    "company.name_changed",
                    "company.registered_office_moved",
                    "company.sic_changed",
                    "company.charge_created",
                    "company.accounts_overdue",
                    "company.confirmation_statement_overdue"
                  ]
                }
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "field": {
                "const": "signal.observed_at"
              }
            },
            "required": [
              "field"
            ]
          },
          "then": {
            "type": "object",
            "properties": {
              "values": false
            }
          }
        }
      ]
    },
    "EmailPolicy": {
      "type": "object",
      "properties": {
        "min_deliverability_score": {
          "description": "Lowest deliverability score counted, 0 to 100. Default 70.",
          "type": "integer",
          "minimum": 0,
          "maximum": 100
        },
        "allow_catch_all": {
          "description": "Whether catch-all addresses count. Default false.",
          "type": "boolean"
        }
      },
      "additionalProperties": false,
      "description": "Email quality floor. Defaults: min_deliverability_score 70, allow_catch_all false."
    }
  }
}
