{
  "openapi": "3.1.0",
  "info": {
    "title": "Texas Property Protest: Harris County property tax calculator",
    "version": "1.0.0",
    "description": "Estimate a yearly Harris County property tax bill from the appraised value on a notice, the taxing units on the home, a standard residence homestead yes or no and, if the person says so, an over-65 or disability answer. Ask the person. Never guess the answer. Tax ceilings are left out. Results are estimates. Each line names its tax year: 2026 where the unit's adopted rate is loaded, 2025 for the rest. The rates come from Harris Central Appraisal District public data, the Harris County Tax Office table and, for some units, the unit's own page. The bill itself comes from the county tax office. This API cannot say whether a home is over-appraised, whether a value or a bill will change, or whether a protest is worth doing, and it gives no tax or legal advice. Texas Property Protest is a service of The Ambrose Group. Ambrose Tax Consulting, Inc. (DBA The Ambrose Group) is licensed by TDLR to provide property tax consulting services. Daniel M. Ambrose is a licensed senior property tax consultant with TDLR, number 10992. Check it at www.tdlr.texas.gov/LicenseSearch."
  },
  "servers": [
    {
      "url": "https://texaspropertyprotest.com"
    }
  ],
  "security": [],
  "paths": {
    "/api/tax-estimate": {
      "post": {
        "operationId": "estimateHarrisPropertyTaxBillPost",
        "summary": "Estimate a Harris County property tax bill (JSON body)",
        "description": "Estimate a yearly Harris County property tax bill from the appraised value, the taxing units on the home and a standard residence homestead yes or no. Returns tax by unit and in total. Each line names its tax year. An estimate, not a bill. Inputs stay out of the web address.",
        "x-openai-isConsequential": false,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateRequest"
              },
              "example": {
                "appraised_value": 400000,
                "homestead": true,
                "units": [
                  "019"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The estimate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EstimateResult"
                }
              }
            }
          },
          "400": {
            "description": "The input was not usable. The body says what to send.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use the method this path lists. The Allow header names it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "The request body is larger than 16 KiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Send Content-Type: application/json.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "estimateHarrisPropertyTaxBill",
        "summary": "Estimate a Harris County property tax bill",
        "description": "Estimate a yearly Harris County property tax bill from the appraised value, the taxing units on the home and a standard residence homestead yes or no. Returns tax by unit and in total. Each line names its tax year. An estimate, not a bill. Inputs go in the web address. POST for age_or_disability.",
        "x-openai-isConsequential": false,
        "parameters": [
          {
            "name": "appraised_value",
            "in": "query",
            "required": true,
            "description": "The appraised value from the notice of appraised value, in dollars, for example 400000. Use the appraised value, not the market value.",
            "schema": {
              "type": "number",
              "minimum": 1000,
              "maximum": 100000000
            }
          },
          {
            "name": "homestead",
            "in": "query",
            "required": true,
            "description": "True if the home has a standard residence homestead exemption. False if it does not. Veteran and other exemptions are left out. Over-65 and disability count only if age_or_disability says so.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "units",
            "in": "query",
            "required": true,
            "description": "The taxing units on the home, as codes (for example 019) or exact unit names (for example Katy ISD), as listed by /api/tax-units (operationId listHarrisTaxingUnits). Exactly one must be a school district. Countywide units are added for you.",
            "schema": {
              "type": "array",
              "minItems": 1,
              "maxItems": 40,
              "items": {
                "type": "string",
                "maxLength": 100
              }
            },
            "style": "form",
            "explode": false
          },
          {
            "name": "county",
            "in": "query",
            "required": false,
            "description": "Optional. Only Harris County is available in this version.",
            "schema": {
              "type": "string",
              "maxLength": 40
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The estimate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EstimateResult"
                }
              }
            }
          },
          "400": {
            "description": "The input was not usable. The body says what to send.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use the method this path lists. The Allow header names it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/tax-units": {
      "get": {
        "operationId": "listHarrisTaxingUnits",
        "summary": "List Harris County taxing units",
        "description": "List Harris County taxing units with codes, types, rates per $100 (each names its tax year) and over-65 and disability amounts. Filter by place, type or a search word. Send the codes in an estimate.",
        "x-openai-isConsequential": false,
        "parameters": [
          {
            "name": "place",
            "in": "query",
            "required": false,
            "description": "A place such as katy, spring or la-porte. Lists the units on 100 or more homes there. A home may be in only some of them.",
            "schema": {
              "type": "string",
              "maxLength": 40
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Only units of this type.",
            "schema": {
              "type": "string",
              "enum": [
                "county",
                "school",
                "city",
                "college",
                "utility",
                "emergency",
                "other"
              ]
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Part of a unit name or a unit code.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Rows to return, 1 to 100. The default is 50.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Rows to skip, for the next page.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000
            }
          },
          {
            "name": "county",
            "in": "query",
            "required": false,
            "description": "Optional. Only Harris County is available in this version.",
            "schema": {
              "type": "string",
              "maxLength": 40
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The matching units.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnitsResult"
                }
              }
            }
          },
          "400": {
            "description": "The input was not usable. The body says what to send.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use the method this path lists. The Allow header names it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "EstimateRequest": {
        "type": "object",
        "properties": {
          "appraised_value": {
            "type": "number",
            "minimum": 1000,
            "maximum": 100000000,
            "description": "The appraised value from the notice of appraised value, in dollars, for example 400000. Use the appraised value, not the market value."
          },
          "homestead": {
            "type": "boolean",
            "description": "True if the home has a standard residence homestead exemption. False if it does not. Veteran and other exemptions are left out. Over-65 and disability count only if age_or_disability says so."
          },
          "age_or_disability": {
            "type": "string",
            "enum": [
              "none",
              "over_65",
              "disabled"
            ],
            "default": "none",
            "description": "Ask the person whether the home's record lists an over-65 or disability exemption. The notice of appraised value or the appraisal district's account page shows it. Do not decide from age or health. Never guess. none adds nothing. over_65 adds each unit's over-65 exemption. disabled adds each unit's disability exemption. A person who is both can get the over-65 exemption from one unit and the disability exemption from another (Texas Tax Code 11.13(h)). This tool uses one answer for every unit. It needs a homestead. Tax ceilings are left out."
          },
          "units": {
            "type": "array",
            "minItems": 1,
            "maxItems": 40,
            "items": {
              "type": "string",
              "maxLength": 100
            },
            "description": "The taxing units on the home, as codes (for example 019) or exact unit names (for example Katy ISD), as listed by /api/tax-units (operationId listHarrisTaxingUnits). Exactly one must be a school district. Countywide units are added for you."
          },
          "county": {
            "type": "string",
            "maxLength": 40,
            "description": "Optional. Only Harris County is available in this version."
          },
          "unit_codes": {
            "type": "array",
            "minItems": 1,
            "maxItems": 40,
            "items": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Another name for units. Send one of the two."
          }
        },
        "required": [
          "appraised_value",
          "homestead",
          "units"
        ]
      },
      "EstimateResult": {
        "type": "object",
        "properties": {
          "summary": {
            "type": "string",
            "description": "One sentence with the estimated total."
          },
          "estimate_notice": {
            "type": "string",
            "description": "Says this is an estimate and not a bill."
          },
          "county": {
            "type": "string",
            "description": "The county."
          },
          "appraised_value": {
            "type": "number",
            "description": "The appraised value used, in dollars."
          },
          "homestead": {
            "type": "boolean",
            "description": "Whether a homestead exemption was taken."
          },
          "age_or_disability": {
            "type": "string",
            "enum": [
              "none",
              "over_65",
              "disabled"
            ],
            "description": "The over-65 or disability answer that was used."
          },
          "rate_year_counts": {
            "type": "array",
            "description": "How many lines use each tax year's rate.",
            "items": {
              "type": "object",
              "required": [
                "rate_year",
                "units"
              ],
              "properties": {
                "rate_year": {
                  "type": "integer",
                  "description": "A tax year."
                },
                "units": {
                  "type": "integer",
                  "description": "Lines that use a rate of that year."
                }
              }
            }
          },
          "total_tax": {
            "type": "number",
            "description": "The estimated yearly tax in dollars: the sum of the lines."
          },
          "effective_rate_percent": {
            "type": "number",
            "description": "The total tax as a percent of the appraised value. It is not a comparison with other homes."
          },
          "tax_on_next_10000": {
            "type": "number",
            "description": "What $10,000 more of appraised value adds to the estimate at these rates, in dollars. It says nothing about a lower value, a lower bill or a protest result."
          },
          "next_10000_note": {
            "type": "string",
            "description": "Says what the figure is and that it predicts nothing."
          },
          "lines": {
            "type": "array",
            "description": "One line per taxing unit.",
            "items": {
              "type": "object",
              "required": [
                "code",
                "name",
                "hcad_name",
                "type",
                "rate_per_100",
                "rate_year",
                "rate_source",
                "rate_year_confirmed",
                "exemption",
                "homestead_exemption",
                "extra_exemption",
                "exemption_applied",
                "taxable_value",
                "tax"
              ],
              "properties": {
                "code": {
                  "type": "string",
                  "description": "The unit code."
                },
                "name": {
                  "type": "string",
                  "description": "The unit name."
                },
                "hcad_name": {
                  "type": "string",
                  "description": "The unit name as the district prints it. Match this to a name on a notice."
                },
                "type": {
                  "type": "string",
                  "description": "county, school, city, college, utility, emergency or other."
                },
                "rate_per_100": {
                  "type": "number",
                  "description": "Tax rate per $100 of taxable value."
                },
                "rate_year": {
                  "type": "integer",
                  "description": "The tax year of this line's rate."
                },
                "rate_source": {
                  "type": "string",
                  "description": "Where this rate was read: district file, county tax office table or unit page (an official page, the unit's own site or its county tax office). The result's rate_sources gives the address and date of the first two."
                },
                "rate_source_url": {
                  "type": "string",
                  "description": "Present only for a unit page: the address of the official page the rate was read from."
                },
                "rate_source_read_on": {
                  "type": "string",
                  "description": "Present only for a unit page: the date it was read, as YYYY-MM-DD."
                },
                "rate_source_adopted_on": {
                  "type": "string",
                  "description": "Present only for a unit page that prints the date the unit adopted the rate, as YYYY-MM-DD."
                },
                "rate_year_confirmed": {
                  "type": "boolean",
                  "description": "True if the rate is a tax year 2026 rate read from its source, or matches the county tax office's tax year 2025 rate. False if it could not be matched."
                },
                "rate_note": {
                  "type": "string",
                  "description": "Present only when rate_year_confirmed is false. Says why."
                },
                "rate_2026_note": {
                  "type": "string",
                  "description": "Present only when the unit keeps its tax year 2025 rate although a tax year 2026 figure was seen. Says why."
                },
                "exemption": {
                  "type": "number",
                  "description": "The total exemption this unit gives, in dollars: homestead_exemption plus extra_exemption. It can be more than the appraised value."
                },
                "homestead_exemption": {
                  "type": "number",
                  "description": "The homestead exemption this unit gives, in dollars."
                },
                "extra_exemption": {
                  "type": "number",
                  "description": "The over-65 or disability exemption this unit adds, in dollars. 0 when age_or_disability is none."
                },
                "exemption_applied": {
                  "type": "number",
                  "description": "The part of the exemption that comes off the appraised value: the lesser of exemption and the appraised value. The page shows this figure."
                },
                "taxable_value": {
                  "type": "number",
                  "description": "Appraised value minus exemption_applied, never below 0."
                },
                "tax": {
                  "type": "number",
                  "description": "Taxable value times the rate divided by 100, rounded to the cent."
                }
              }
            }
          },
          "rate_year_flag_note": {
            "type": "string",
            "description": "Present only when a unit in the estimate has a rate that could not be matched to the tax year. Names the units."
          },
          "added_countywide_units": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Codes of countywide units that were added because the call left them out."
          },
          "how_it_works": {
            "type": "string",
            "description": "How the estimate is worked out."
          },
          "ceiling_note": {
            "type": "string",
            "description": "Present only when age_or_disability is over_65 or disabled. Says in rule words that tax ceilings are left out."
          },
          "appraised_value_note": {
            "type": "string",
            "description": "Says to enter the appraised value, not the market value."
          },
          "homestead_note": {
            "type": "string",
            "description": "Says what the homestead input means."
          },
          "age_or_disability_note": {
            "type": "string",
            "description": "Says what the age_or_disability input means."
          },
          "service": {
            "type": "object",
            "description": "Who provides this calculator and the address of its page.",
            "required": [
              "provider",
              "url"
            ],
            "properties": {
              "provider": {
                "type": "string",
                "description": "Who provides the calculator."
              },
              "url": {
                "type": "string",
                "description": "The address of the calculator page."
              }
            }
          },
          "rate_years": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "The tax years of the rates used, the earlier year first. A unit shows its tax year 2026 rate where one is loaded and its tax year 2025 rate otherwise."
          },
          "rate_year_note": {
            "type": "string",
            "description": "Says which tax year each rate is and where the other years come from."
          },
          "rate_sources": {
            "type": "array",
            "description": "The district file and the county tax office table, with the address and the date each was read, for the kinds this result uses.",
            "items": {
              "type": "object",
              "required": [
                "kind",
                "url",
                "read_on"
              ],
              "properties": {
                "kind": {
                  "type": "string",
                  "description": "district file or county tax office table."
                },
                "url": {
                  "type": "string",
                  "description": "The address of the source."
                },
                "read_on": {
                  "type": "string",
                  "description": "The date it was read, as YYYY-MM-DD."
                }
              }
            }
          },
          "source": {
            "type": "string",
            "description": "Where the rates and exemption amounts come from."
          },
          "source_url": {
            "type": "string",
            "description": "The district's data page."
          },
          "file_date": {
            "type": "string",
            "description": "The date of the district files, as YYYY-MM-DD."
          },
          "bill_comes_from": {
            "type": "string",
            "description": "Says the actual bill comes from the county tax office."
          },
          "left_out": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "What this calculator leaves out."
          },
          "provided_by": {
            "type": "string",
            "description": "Who provides the service, with the license sentence."
          },
          "no_advice": {
            "type": "string",
            "description": "States that the calculator gives no tax or legal advice."
          }
        },
        "required": [
          "summary",
          "estimate_notice",
          "county",
          "appraised_value",
          "homestead",
          "age_or_disability",
          "rate_year_counts",
          "total_tax",
          "effective_rate_percent",
          "tax_on_next_10000",
          "next_10000_note",
          "lines",
          "added_countywide_units",
          "how_it_works",
          "appraised_value_note",
          "homestead_note",
          "age_or_disability_note",
          "service",
          "rate_years",
          "rate_year_note",
          "rate_sources",
          "source",
          "source_url",
          "file_date",
          "bill_comes_from",
          "left_out",
          "provided_by",
          "no_advice"
        ]
      },
      "UnitsResult": {
        "type": "object",
        "properties": {
          "summary": {
            "type": "string",
            "description": "One sentence with the number of matches."
          },
          "county": {
            "type": "string",
            "description": "The county."
          },
          "rate_unit": {
            "type": "string",
            "description": "What a rate is measured in."
          },
          "filters": {
            "type": "object",
            "description": "The filters that were applied."
          },
          "total_matches": {
            "type": "integer",
            "description": "Units that match the filters."
          },
          "returned": {
            "type": "integer",
            "description": "Units in this page."
          },
          "limit": {
            "type": "integer",
            "description": "The page size used."
          },
          "offset": {
            "type": "integer",
            "description": "The rows skipped."
          },
          "truncated": {
            "type": "boolean",
            "description": "True if more matches follow this page."
          },
          "units": {
            "type": "array",
            "description": "The matching units.",
            "items": {
              "type": "object",
              "required": [
                "code",
                "name",
                "hcad_name",
                "type",
                "rate_per_100",
                "rate_year",
                "rate_2025_per_100",
                "rate_source",
                "rate_year_confirmed",
                "countywide",
                "homestead_flat_amount",
                "homestead_percent",
                "homestead_percent_minimum",
                "over_65_flat_amount",
                "disability_flat_amount"
              ],
              "properties": {
                "code": {
                  "type": "string",
                  "description": "The unit code."
                },
                "name": {
                  "type": "string",
                  "description": "The unit name."
                },
                "hcad_name": {
                  "type": "string",
                  "description": "The unit name as the district prints it. Match this to a name on a notice."
                },
                "type": {
                  "type": "string",
                  "description": "county, school, city, college, utility, emergency or other."
                },
                "rate_per_100": {
                  "type": "number",
                  "description": "Tax rate per $100 of taxable value: the rate an estimate uses."
                },
                "rate_year": {
                  "type": "integer",
                  "description": "The tax year of that rate."
                },
                "rate_2025_per_100": {
                  "type": "number",
                  "description": "The unit's tax year 2025 rate from the district file."
                },
                "rate_2026_per_100": {
                  "type": "number",
                  "description": "Present only when the unit has an adopted tax year 2026 rate loaded. It is the rate an estimate uses."
                },
                "rate_source": {
                  "type": "string",
                  "description": "Where this rate was read: district file, county tax office table or unit page (an official page, the unit's own site or its county tax office). The result's rate_sources gives the address and date of the first two."
                },
                "rate_source_url": {
                  "type": "string",
                  "description": "Present only for a unit page: the address of the official page the rate was read from."
                },
                "rate_source_read_on": {
                  "type": "string",
                  "description": "Present only for a unit page: the date it was read, as YYYY-MM-DD."
                },
                "rate_source_adopted_on": {
                  "type": "string",
                  "description": "Present only for a unit page that prints the date the unit adopted the rate, as YYYY-MM-DD."
                },
                "rate_year_confirmed": {
                  "type": "boolean",
                  "description": "True if the rate is a tax year 2026 rate read from its source, or matches the county tax office's tax year 2025 rate. False if it could not be matched."
                },
                "rate_note": {
                  "type": "string",
                  "description": "Present only when rate_year_confirmed is false. Says why."
                },
                "rate_2026_note": {
                  "type": "string",
                  "description": "Present only when the unit keeps its tax year 2025 rate although a tax year 2026 figure was seen. Says why."
                },
                "countywide": {
                  "type": "boolean",
                  "description": "True if the unit covers the whole county, so every estimate includes it."
                },
                "homestead_flat_amount": {
                  "type": "number",
                  "description": "A flat homestead exemption in dollars."
                },
                "homestead_percent": {
                  "type": "number",
                  "description": "A percentage homestead exemption, as a percent of appraised value."
                },
                "homestead_percent_minimum": {
                  "type": "number",
                  "description": "The smallest dollar amount the percentage exemption gives."
                },
                "over_65_flat_amount": {
                  "type": "number",
                  "description": "The flat dollar amount this unit adds to the homestead exemption when age_or_disability is over_65."
                },
                "over_65_percent": {
                  "type": "number",
                  "description": "Present only when the unit's over-65 exemption has a percentage, as a percent of appraised value. None does today."
                },
                "disability_flat_amount": {
                  "type": "number",
                  "description": "The flat dollar amount this unit adds to the homestead exemption when age_or_disability is disabled."
                },
                "disability_percent": {
                  "type": "number",
                  "description": "Present only when the unit's disability exemption has a percentage, as a percent of appraised value. None does today."
                }
              }
            }
          },
          "places": {
            "type": "array",
            "description": "The places that can be used as a filter.",
            "items": {
              "type": "object",
              "properties": {
                "slug": {
                  "type": "string",
                  "description": "The place to send."
                },
                "label": {
                  "type": "string",
                  "description": "The place name."
                }
              }
            }
          },
          "countywide_note": {
            "type": "string",
            "description": "Says what countywide means."
          },
          "place_note": {
            "type": "string",
            "description": "Says what a place list means."
          },
          "rate_years": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "The tax years of the rates used, the earlier year first. A unit shows its tax year 2026 rate where one is loaded and its tax year 2025 rate otherwise."
          },
          "rate_year_note": {
            "type": "string",
            "description": "Says which tax year each rate is and where the other years come from."
          },
          "rate_sources": {
            "type": "array",
            "description": "The district file and the county tax office table, with the address and the date each was read, for the kinds this result uses.",
            "items": {
              "type": "object",
              "required": [
                "kind",
                "url",
                "read_on"
              ],
              "properties": {
                "kind": {
                  "type": "string",
                  "description": "district file or county tax office table."
                },
                "url": {
                  "type": "string",
                  "description": "The address of the source."
                },
                "read_on": {
                  "type": "string",
                  "description": "The date it was read, as YYYY-MM-DD."
                }
              }
            }
          },
          "source": {
            "type": "string",
            "description": "Where the rates and exemption amounts come from."
          },
          "source_url": {
            "type": "string",
            "description": "The district's data page."
          },
          "file_date": {
            "type": "string",
            "description": "The date of the district files, as YYYY-MM-DD."
          },
          "bill_comes_from": {
            "type": "string",
            "description": "Says the actual bill comes from the county tax office."
          },
          "left_out": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "What this calculator leaves out."
          },
          "provided_by": {
            "type": "string",
            "description": "Who provides the service, with the license sentence."
          },
          "no_advice": {
            "type": "string",
            "description": "States that the calculator gives no tax or legal advice."
          }
        },
        "required": [
          "summary",
          "county",
          "rate_unit",
          "filters",
          "total_matches",
          "returned",
          "limit",
          "offset",
          "truncated",
          "units",
          "places",
          "countywide_note",
          "rate_years",
          "rate_year_note",
          "rate_sources",
          "source",
          "source_url",
          "file_date",
          "bill_comes_from",
          "left_out",
          "provided_by",
          "no_advice"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "A short code for the problem."
              },
              "message": {
                "type": "string",
                "description": "What is wrong and how to fix it."
              },
              "details": {
                "type": "array",
                "description": "One entry per problem.",
                "items": {
                  "type": "object",
                  "properties": {
                    "field": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "usage": {
            "type": "string",
            "description": "What to send."
          }
        }
      }
    }
  }
}
