{
  "meta": {
    "name": "UK Pet Insurance: Cats and Dogs",
    "description": "Lifetime vet-fee cover for a single cat or dog, rated by species, breed, age, region, vet-fee limit and excess.",
    "summary": "Rates annual lifetime vet-fee cover for one cat or dog in the UK. Base rates by species and annual vet-fee limit are adjusted for age band, breed, region, voluntary excess and neutering, then 12% Insurance Premium Tax is added. Older pets and breed/species mismatches are declined; high-limit cover on high-risk breeds is referred."
  },
  "input": {
    "key": "input",
    "step": "input",
    "id": "input",
    "format": {
      "species": {
        "key": "species",
        "label": "Species",
        "sub_label": "Whether the pet being insured is a cat or a dog. Sets the base rate and age curve.",
        "exp": "{{species}}",
        "type": "string",
        "def": "cat",
        "items": [
          "cat",
          "dog"
        ]
      },
      "breed": {
        "key": "breed",
        "label": "Breed",
        "sub_label": "The pet's breed or breed group. Pedigree and brachycephalic breeds carry higher vet-fee risk.",
        "exp": "{{breed}}",
        "type": "string",
        "def": "moggie",
        "items": [
          "moggie",
          "persian",
          "bengal",
          "maine_coon",
          "mixed_dog",
          "labrador",
          "cockapoo",
          "german_shepherd",
          "french_bulldog"
        ]
      },
      "pet_age": {
        "key": "pet_age",
        "label": "Pet age (years)",
        "sub_label": "The pet's age in whole years at the start of cover. Use 0 for pets under one year old.",
        "exp": "{{pet_age}}",
        "type": "integer",
        "def": 3
      },
      "region": {
        "key": "region",
        "label": "Region",
        "sub_label": "Where the pet lives. Vet fees vary significantly by region, highest in Greater London.",
        "exp": "{{region}}",
        "type": "string",
        "def": "midlands",
        "items": [
          "greater_london",
          "south_east",
          "midlands",
          "north",
          "scotland",
          "wales",
          "northern_ireland"
        ]
      },
      "vet_fee_limit": {
        "key": "vet_fee_limit",
        "label": "Annual vet-fee limit (£)",
        "sub_label": "Maximum the policy pays for vet treatment each policy year. Resets on renewal.",
        "exp": "{{vet_fee_limit}}",
        "type": "integer",
        "def": 4000,
        "items": [
          1000,
          2000,
          4000,
          7000
        ]
      },
      "excess": {
        "key": "excess",
        "label": "Excess (£)",
        "sub_label": "Amount the policyholder pays towards each claim. A higher excess lowers the premium.",
        "exp": "{{excess}}",
        "type": "integer",
        "def": 100,
        "items": [
          50,
          100,
          250
        ]
      },
      "neutered": {
        "key": "neutered",
        "label": "Neutered",
        "sub_label": "Whether the pet has been spayed or neutered. Neutered pets receive a small discount.",
        "exp": "{{neutered}}",
        "type": "boolean",
        "def": true
      }
    }
  },
  "steps": [
    {
      "id": "base_rates",
      "key": "base_rates",
      "step": "collection",
      "name": "Base rate by species and limit",
      "retain": true,
      "description": "Annual base premium in GBP for each species and annual vet-fee limit.",
      "collection": [
        [
          "species",
          "limit",
          "base_annual"
        ],
        [
          "cat",
          1000,
          96
        ],
        [
          "cat",
          2000,
          118
        ],
        [
          "cat",
          4000,
          142
        ],
        [
          "cat",
          7000,
          171
        ],
        [
          "dog",
          1000,
          168
        ],
        [
          "dog",
          2000,
          205
        ],
        [
          "dog",
          4000,
          249
        ],
        [
          "dog",
          7000,
          298
        ]
      ],
      "format": {
        "base_premium": {
          "key": "base_premium",
          "label": "Base premium",
          "exp": "collection.filter(species=={{species}}).filter(limit=={{vet_fee_limit}}).map(base_annual).first()",
          "type": "decimal",
          "def": 0
        }
      }
    },
    {
      "id": "age_bands",
      "key": "age_bands",
      "step": "collection",
      "name": "Age factor",
      "retain": true,
      "description": "Age loading by species. Claims frequency rises sharply after age 7.",
      "collection": [
        [
          "species",
          "age_min",
          "age_max",
          "age_factor"
        ],
        [
          "cat",
          0,
          1,
          0.9
        ],
        [
          "cat",
          2,
          4,
          1
        ],
        [
          "cat",
          5,
          7,
          1.25
        ],
        [
          "cat",
          8,
          10,
          1.6
        ],
        [
          "cat",
          11,
          20,
          2.1
        ],
        [
          "dog",
          0,
          1,
          0.95
        ],
        [
          "dog",
          2,
          4,
          1
        ],
        [
          "dog",
          5,
          7,
          1.35
        ],
        [
          "dog",
          8,
          10,
          1.85
        ],
        [
          "dog",
          11,
          20,
          2.4
        ]
      ],
      "format": {
        "pet_age_factor": {
          "key": "pet_age_factor",
          "label": "Age factor",
          "exp": "collection.filter(species=={{species}}).filter(age_min<={{pet_age}}).filter(age_max>={{pet_age}}).map(age_factor).first()",
          "type": "decimal",
          "def": 1
        }
      }
    },
    {
      "id": "breed_factors",
      "key": "breed_factors",
      "step": "collection",
      "name": "Breed factor",
      "retain": true,
      "description": "Breed relativity keyed by species, so a breed that does not belong to the species finds no row.",
      "collection": [
        [
          "species",
          "breed",
          "breed_rel"
        ],
        [
          "cat",
          "moggie",
          0.9
        ],
        [
          "cat",
          "persian",
          1.3
        ],
        [
          "cat",
          "bengal",
          1.2
        ],
        [
          "cat",
          "maine_coon",
          1.15
        ],
        [
          "dog",
          "mixed_dog",
          0.95
        ],
        [
          "dog",
          "labrador",
          1.1
        ],
        [
          "dog",
          "cockapoo",
          1.05
        ],
        [
          "dog",
          "german_shepherd",
          1.4
        ],
        [
          "dog",
          "french_bulldog",
          1.75
        ]
      ],
      "format": {
        "breed_factor": {
          "key": "breed_factor",
          "label": "Breed factor",
          "exp": "collection.filter(species=={{species}}).filter(breed=={{breed}}).map(breed_rel).first()",
          "type": "decimal",
          "def": 1
        },
        "breed_matches": {
          "key": "breed_matches",
          "label": "Breed matches species",
          "exp": "collection.filter(species=={{species}}).filter(breed=={{breed}}).count()",
          "type": "integer",
          "def": 0
        }
      }
    },
    {
      "id": "region_factors",
      "key": "region_factors",
      "step": "collection",
      "name": "Region factor",
      "retain": true,
      "description": "Regional vet-fee relativity.",
      "collection": [
        [
          "region",
          "region_rel"
        ],
        [
          "greater_london",
          1.3
        ],
        [
          "south_east",
          1.12
        ],
        [
          "midlands",
          1
        ],
        [
          "north",
          0.92
        ],
        [
          "scotland",
          0.88
        ],
        [
          "wales",
          0.9
        ],
        [
          "northern_ireland",
          0.85
        ]
      ],
      "format": {
        "region_factor": {
          "key": "region_factor",
          "label": "Region factor",
          "exp": "collection.filter(region=={{region}}).map(region_rel).first()",
          "type": "decimal",
          "def": 1
        }
      }
    },
    {
      "id": "excess_factors",
      "key": "excess_factors",
      "step": "collection",
      "name": "Excess factor",
      "retain": true,
      "description": "Discount or load for the chosen voluntary excess.",
      "collection": [
        [
          "excess_amount",
          "excess_rel"
        ],
        [
          50,
          1.1
        ],
        [
          100,
          1
        ],
        [
          250,
          0.86
        ]
      ],
      "format": {
        "excess_factor": {
          "key": "excess_factor",
          "label": "Excess factor",
          "exp": "collection.filter(excess_amount=={{excess}}).map(excess_rel).first()",
          "type": "decimal",
          "def": 1
        }
      }
    },
    {
      "id": "neuter_factors",
      "key": "neuter_factors",
      "step": "collection",
      "name": "Neutered discount",
      "retain": true,
      "description": "5% discount for spayed or neutered pets.",
      "collection": [
        [
          "is_neutered",
          "neuter_rel"
        ],
        [
          true,
          0.95
        ],
        [
          false,
          1
        ]
      ],
      "format": {
        "neuter_factor": {
          "key": "neuter_factor",
          "label": "Neutered factor",
          "exp": "collection.filter(is_neutered=={{neutered}}).map(neuter_rel).first()",
          "type": "decimal",
          "def": 1
        }
      }
    },
    {
      "id": "risk_premium",
      "key": "risk_premium",
      "step": "calculation",
      "name": "Risk premium",
      "description": "Base premium multiplied by age, breed, region, excess and neutered factors, rounded to the penny.",
      "def": 0,
      "formula": "round({{base_premium}} * {{pet_age_factor}} * {{breed_factor}} * {{region_factor}} * {{excess_factor}} * {{neuter_factor}}, 2)"
    },
    {
      "id": "ipt",
      "key": "ipt",
      "step": "calculation",
      "name": "Insurance Premium Tax",
      "description": "UK Insurance Premium Tax at 12% of the risk premium.",
      "def": 0,
      "formula": "round({{risk_premium}} * 0.12, 2)"
    },
    {
      "id": "total_premium",
      "key": "total_premium",
      "step": "calculation",
      "name": "Annual premium",
      "description": "Risk premium plus IPT.",
      "def": 0,
      "formula": "round({{risk_premium}} + {{ipt}}, 2)"
    },
    {
      "id": "monthly_premium",
      "key": "monthly_premium",
      "step": "calculation",
      "name": "Monthly premium",
      "description": "Annual premium spread over 12 monthly instalments.",
      "def": 0,
      "formula": "round({{total_premium}} / 12, 2)"
    },
    {
      "id": "pet_exclusions",
      "key": "pet_exclusions",
      "step": "exclusion",
      "name": "Pet exclusions",
      "description": "Declines pets over 14 and breeds that do not belong to the chosen species.",
      "def": false,
      "items": [
        {
          "id": "too_old",
          "name": "Pet older than 14 at inception",
          "exp": "{{pet_age}} > 14",
          "def": false
        },
        {
          "id": "breed_mismatch",
          "name": "Breed does not match species",
          "exp": "{{breed_matches}} == 0",
          "def": false
        }
      ]
    },
    {
      "id": "pet_refers",
      "key": "pet_refers",
      "step": "refer",
      "name": "Pet refers",
      "description": "Refers £7,000 cover on high-risk breeds to an underwriter.",
      "def": false,
      "items": [
        {
          "id": "high_risk_high_limit",
          "name": "£7,000 limit on a high-risk breed",
          "exp": "{{vet_fee_limit}} == 7000 && ({{breed}} == 'french_bulldog' || {{breed}} == 'persian')",
          "def": false
        }
      ]
    }
  ],
  "output": {
    "key": "output",
    "step": "output",
    "id": "output",
    "result": {
      "key": "result",
      "formula": "round({{total_premium}}, 2)",
      "type": "decimal",
      "def": 0
    },
    "valid": {
      "key": "valid",
      "exp": "{{pet_exclusions}} == false",
      "type": "boolean",
      "def": false
    },
    "format": {
      "risk_premium": {
        "key": "risk_premium",
        "label": "Risk premium",
        "sub_label": "Premium before Insurance Premium Tax.",
        "exp": "{{risk_premium}}",
        "type": "decimal",
        "def": 0
      },
      "ipt": {
        "key": "ipt",
        "label": "IPT",
        "sub_label": "Insurance Premium Tax at 12 percent.",
        "exp": "{{ipt}}",
        "type": "decimal",
        "def": 0
      },
      "monthly_premium": {
        "key": "monthly_premium",
        "label": "Monthly premium",
        "sub_label": "Annual premium split into 12 instalments.",
        "exp": "{{monthly_premium}}",
        "type": "decimal",
        "def": 0
      },
      "base_premium": {
        "key": "base_premium",
        "label": "Base premium",
        "sub_label": "Base rate for species and vet-fee limit.",
        "exp": "{{base_premium}}",
        "type": "decimal",
        "def": 0
      },
      "refer": {
        "key": "refer",
        "label": "Refer to underwriter",
        "sub_label": "True when the quote needs underwriter review.",
        "exp": "{{pet_refers}}",
        "type": "boolean",
        "def": false
      }
    }
  },
  "tests": [
    {
      "id": "persian_london",
      "key": "persian_london",
      "name": "Persian cat, 3, Greater London, £4k limit, £100 excess, neutered",
      "input": {
        "species": "cat",
        "breed": "persian",
        "pet_age": 3,
        "region": "greater_london",
        "vet_fee_limit": 4000,
        "excess": 100,
        "neutered": true
      },
      "output": {
        "result": 255.34,
        "valid": true
      }
    },
    {
      "id": "labrador_north",
      "key": "labrador_north",
      "name": "Labrador, 6, North, £2k limit, £250 excess, entire",
      "input": {
        "species": "dog",
        "breed": "labrador",
        "pet_age": 6,
        "region": "north",
        "vet_fee_limit": 2000,
        "excess": 250,
        "neutered": false
      },
      "output": {
        "result": 269.76,
        "valid": true
      }
    },
    {
      "id": "senior_cat",
      "key": "senior_cat",
      "name": "Decline: cat aged 15",
      "input": {
        "species": "cat",
        "breed": "moggie",
        "pet_age": 15,
        "region": "wales",
        "vet_fee_limit": 2000,
        "excess": 100,
        "neutered": true
      },
      "output": {
        "valid": false
      }
    },
    {
      "id": "frenchie_refer",
      "key": "frenchie_refer",
      "name": "Refer: French Bulldog on £7k limit",
      "input": {
        "species": "dog",
        "breed": "french_bulldog",
        "pet_age": 2,
        "region": "south_east",
        "vet_fee_limit": 7000,
        "excess": 100,
        "neutered": true
      },
      "output": {
        "valid": true
      }
    },
    {
      "id": "mismatch",
      "key": "mismatch",
      "name": "Decline: cat with a dog breed",
      "input": {
        "species": "cat",
        "breed": "labrador",
        "pet_age": 4,
        "region": "midlands",
        "vet_fee_limit": 1000,
        "excess": 100,
        "neutered": true
      },
      "output": {
        "valid": false
      }
    }
  ]
}