{
  "openapi": "3.1.0",
  "info": {
    "title": "TaxNotes.ca public API",
    "version": "1",
    "description": "Canadian tax figures (federal, provincial and territorial, from the CRA; Quebec from Revenu Québec), the same income tax calculator as the website, and plain-language guides. Read-only, JSON, no sign-in.\n\nFigures: money is in Canadian dollars; rates are decimals (0.145 = 14.5%). A figure not yet published by the CRA (or Revenu Québec) is {\"todo\": \"…\"} in section data and value null with formatted \"[TODO]\" in /figures; nothing is ever estimated or carried forward.\n\nCalculator scope: one individual, single, resident in one province or territory on December 31. Covers eligible and non-eligible (other than eligible) dividends from Canadian corporations. Not covered: AMT, OAS recovery tax, foreign tax credits, refundable benefits, spouse and dependant amounts, carry-forwards. When a calculation can’t be done (e.g. a figure isn’t published yet) `supported` is false and `issues` says why.\n\nRate limits: 60 requests per minute per client (POST /api/v1/calculate and the MCP calculate_income_tax tool); 300 requests per minute per client (every other /api/v1 request and every /mcp request). HTTP 429 with a Retry-After header (seconds).\n\nPrivacy: No sign-in, no API key and no cookies. Inputs (including incomes) are used only to answer the request: never logged, never stored.\n\nMCP: the same data is available to AI agents at https://taxnotes.ca/mcp (Streamable HTTP).\n\nLicense: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/): free to share and adapt, including commercially, with attribution: credit TaxNotes.ca and link to the page or data you used. Doesn't cover the TaxNotes.ca name or logo, or the site's code. Terms: https://taxnotes.ca/reproducing-our-content/\n\nGeneral information, not personal tax, legal or investment advice. Check with a qualified professional before acting.",
    "license": {
      "name": "CC BY 4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    }
  },
  "servers": [
    {
      "url": "https://taxnotes.ca/api/v1"
    }
  ],
  "externalDocs": {
    "description": "For AI agents and developers",
    "url": "https://taxnotes.ca/for-ai/"
  },
  "paths": {
    "/": {
      "get": {
        "operationId": "getIndex",
        "summary": "API index: endpoints, limits, data and MCP links",
        "responses": {
          "200": {
            "description": "The index.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached; wait for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "summary": "This document",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/figures": {
      "get": {
        "operationId": "getFigures",
        "summary": "Look up a tax figure, a section, or list the sections",
        "description": "With `path`: one figure (e.g. federal.basicPersonal.max, provinces.BC.brackets.0.rate, salesTax.provinces.ON.hst, corporate.provinces.ON.generalRate, quebec.basicPersonal, federal.indexation.rate, interest.quarters.0.overdue). With `section`: a whole section (e.g. federal, payroll, limits, salesTax, corporate, quebec, interest, provinces.ON). With neither: the list of sections and what they hold. Lists can be indexed by number or, where items carry a province code, by code.",
        "parameters": [
          {
            "name": "year",
            "in": "query",
            "required": false,
            "description": "Tax year: 2025, 2026. Default 2025.",
            "schema": {
              "type": "integer",
              "enum": [
                2025,
                2026
              ],
              "default": 2025
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "description": "Dot path to one figure.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "section",
            "in": "query",
            "required": false,
            "description": "A section key.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A figure (with `path`), a section (with `section`), or the section list.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/Figure"
                    },
                    {
                      "$ref": "#/components/schemas/Section"
                    },
                    {
                      "$ref": "#/components/schemas/SectionList"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid input; the message says what to change.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached; wait for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Estimate income tax and payroll contributions for one person",
        "description": "Same engine and same results as the income tax calculator at /calculators/income-tax/. Unknown fields are refused (400), so typos don’t go unnoticed.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CalculateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The result. Check `supported` and `issues`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalculateResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input; the message says what to change.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Body larger than 16 KB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Content-Type must be application/json.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached; wait for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/guides": {
      "get": {
        "operationId": "listGuides",
        "summary": "List guides",
        "parameters": [
          {
            "name": "audience",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "individuals",
                "self-employed",
                "corporations",
                "everyone"
              ]
            }
          },
          {
            "name": "topic",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "filing",
                "work",
                "students",
                "family",
                "home",
                "saving",
                "retiring",
                "disability",
                "self-employed",
                "corporations",
                "planning",
                "sales-tax",
                "about"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Guides in /guides/ order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GuideList"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input; the message says what to change.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached; wait for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/guides/{slug}": {
      "get": {
        "operationId": "getGuide",
        "summary": "One guide, with its full text as Markdown",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The guide.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Guide"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input; the message says what to change.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached; wait for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/changes": {
      "get": {
        "operationId": "listChanges",
        "summary": "Recent changes, newest first",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Changelog entries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangeList"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input; the message says what to change.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached; wait for Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CalculateInput": {
        "type": "object",
        "properties": {
          "year": {
            "default": 2025,
            "description": "Tax year. One of 2025, 2026; default 2025.",
            "type": "number",
            "enum": [
              2025,
              2026
            ]
          },
          "province": {
            "type": "string",
            "enum": [
              "AB",
              "BC",
              "MB",
              "NB",
              "NL",
              "NS",
              "NT",
              "NU",
              "ON",
              "PE",
              "QC",
              "SK",
              "YT"
            ],
            "description": "Province or territory of residence on December 31, as a two-letter code (e.g. \"ON\", \"QC\")."
          },
          "age": {
            "description": "Age at December 31 of the tax year. Leave out (or null) if unknown: age-based amounts are then skipped.",
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0,
                "maximum": 130
              },
              {
                "type": "null"
              }
            ]
          },
          "employment": {
            "default": 0,
            "description": "Employment income (T4 box 14). Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "selfEmployment": {
            "default": 0,
            "description": "Net self-employment income, after business expenses. Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "otherIncome": {
            "default": 0,
            "description": "Interest and other investment income (T5/T3), fully taxable. Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "eligibleDividends": {
            "default": 0,
            "description": "Eligible dividends, the actual amount received (the engine grosses them up). Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "nonEligibleDividends": {
            "default": 0,
            "description": "Dividends other than eligible dividends (non-eligible) from taxable Canadian corporations, the actual amount received (the engine grosses them up). Not foreign dividends: include those in otherIncome. Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "capitalGains": {
            "default": 0,
            "description": "The full capital gain (the engine applies the inclusion rate). Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "pension": {
            "default": 0,
            "description": "Pension and RRIF income (T4A/T4RIF); eligible pension income at 65+. Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "rrsp": {
            "default": 0,
            "description": "RRSP deduction claimed for the year. Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "fhsa": {
            "default": 0,
            "description": "FHSA deduction claimed for the year. Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "childCare": {
            "default": 0,
            "description": "Child care expenses. Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "unionDues": {
            "default": 0,
            "description": "Union and professional dues (T4 box 44). Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "tuition": {
            "default": 0,
            "description": "Current-year eligible tuition (T2202). Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "medical": {
            "default": 0,
            "description": "Medical expenses. Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "donations": {
            "default": 0,
            "description": "Charitable donations (official receipts). Dollars, 0 or more. Default 0.",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          },
          "livingAlone": {
            "description": "Quebec only: lives alone (amount for a person living alone). Ignored elsewhere.",
            "type": "boolean"
          },
          "rrspContribution": {
            "description": "Optional: an extra RRSP contribution to price. The response then includes rrspTaxSaved, the income tax it would save (same as the calculator’s “What would an RRSP contribution save?” box).",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000
          }
        },
        "required": [
          "province"
        ],
        "additionalProperties": false
      },
      "CalculateResult": {
        "type": "object",
        "properties": {
          "supported": {
            "type": "boolean",
            "description": "False when the data has figures not yet published that this calculation needs, or the input is out of scope. Amounts are then 0; see issues."
          },
          "issues": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Why the result is unsupported, and caveats or adjustments made to the input."
          },
          "income": {
            "type": "object",
            "properties": {
              "totalIncome": {
                "type": "number"
              },
              "netIncome": {
                "type": "number"
              },
              "taxableIncome": {
                "type": "number"
              },
              "grossedUpEligibleDividends": {
                "type": "number"
              },
              "grossedUpNonEligibleDividends": {
                "type": "number",
                "description": "Taxable (grossed-up) amount of dividends other than eligible dividends (T1 line 12010)."
              },
              "taxableCapitalGains": {
                "type": "number"
              },
              "eligiblePensionIncome": {
                "type": "number"
              },
              "childCareDeduction": {
                "type": "number"
              },
              "deductions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "label",
                    "amount"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "totalIncome",
              "netIncome",
              "taxableIncome",
              "grossedUpEligibleDividends",
              "grossedUpNonEligibleDividends",
              "taxableCapitalGains",
              "eligiblePensionIncome",
              "childCareDeduction",
              "deductions"
            ],
            "additionalProperties": false
          },
          "payroll": {
            "type": "object",
            "properties": {
              "plan": {
                "type": "string",
                "enum": [
                  "cpp",
                  "qpp"
                ]
              },
              "pensionBaseEmployee": {
                "type": "number"
              },
              "pensionEnhancedEmployee": {
                "type": "number"
              },
              "pensionSelfEmployedTotal": {
                "type": "number"
              },
              "pensionSelfEmployedCreditable": {
                "type": "number"
              },
              "pensionSelfEmployedDeductible": {
                "type": "number"
              },
              "ei": {
                "type": "number"
              },
              "qpip": {
                "type": "number"
              },
              "total": {
                "type": "number",
                "description": "All CPP/QPP contributions + EI + QPIP."
              },
              "lines": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "label",
                    "amount"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "plan",
              "pensionBaseEmployee",
              "pensionEnhancedEmployee",
              "pensionSelfEmployedTotal",
              "pensionSelfEmployedCreditable",
              "pensionSelfEmployedDeductible",
              "ei",
              "qpip",
              "total",
              "lines"
            ],
            "additionalProperties": false
          },
          "federal": {
            "type": "object",
            "properties": {
              "basicTax": {
                "type": "number",
                "description": "Tax on taxable income from the brackets, before credits."
              },
              "nonRefundableCredits": {
                "type": "number",
                "description": "Value of non-refundable credits (amounts × credit rates), excluding the dividend credit."
              },
              "dividendCredit": {
                "type": "number"
              },
              "adjustments": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "label",
                    "amount"
                  ],
                  "additionalProperties": false
                },
                "description": "Surtax, health premium, reductions, abatement, top-up credit, etc. (signed)."
              },
              "tax": {
                "type": "number",
                "description": "Final tax for this jurisdiction, never below 0."
              },
              "lines": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "label",
                    "amount"
                  ],
                  "additionalProperties": false
                },
                "description": "Printable breakdown, in return order."
              }
            },
            "required": [
              "basicTax",
              "nonRefundableCredits",
              "dividendCredit",
              "adjustments",
              "tax",
              "lines"
            ],
            "additionalProperties": false
          },
          "provincial": {
            "type": "object",
            "properties": {
              "basicTax": {
                "type": "number",
                "description": "Tax on taxable income from the brackets, before credits."
              },
              "nonRefundableCredits": {
                "type": "number",
                "description": "Value of non-refundable credits (amounts × credit rates), excluding the dividend credit."
              },
              "dividendCredit": {
                "type": "number"
              },
              "adjustments": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "label",
                    "amount"
                  ],
                  "additionalProperties": false
                },
                "description": "Surtax, health premium, reductions, abatement, top-up credit, etc. (signed)."
              },
              "tax": {
                "type": "number",
                "description": "Final tax for this jurisdiction, never below 0."
              },
              "lines": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "label",
                    "amount"
                  ],
                  "additionalProperties": false
                },
                "description": "Printable breakdown, in return order."
              }
            },
            "required": [
              "basicTax",
              "nonRefundableCredits",
              "dividendCredit",
              "adjustments",
              "tax",
              "lines"
            ],
            "additionalProperties": false,
            "description": "Provincial or territorial tax (Quebec’s TP-1 tax for Quebec residents)."
          },
          "incomeTax": {
            "type": "number",
            "description": "federal.tax + provincial.tax."
          },
          "total": {
            "type": "number",
            "description": "incomeTax + payroll.total."
          },
          "averageRate": {
            "type": "number",
            "description": "incomeTax ÷ totalIncome, as a decimal (0.2 = 20%)."
          },
          "marginalRate": {
            "type": "number",
            "description": "Combined federal + provincial rate on the next dollar of ordinary income, as a decimal."
          },
          "rrspContribution": {
            "description": "Echo of the extra RRSP contribution priced, when one was given.",
            "type": "number"
          },
          "rrspTaxSaved": {
            "description": "Income tax the extra RRSP contribution would save; null when the result is unsupported.",
            "type": [
              "number",
              "null"
            ]
          },
          "input": {
            "type": "object",
            "properties": {
              "year": {
                "type": "number"
              },
              "province": {
                "type": "string"
              },
              "age": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "employment": {
                "type": "number"
              },
              "selfEmployment": {
                "type": "number"
              },
              "otherIncome": {
                "type": "number"
              },
              "eligibleDividends": {
                "type": "number"
              },
              "nonEligibleDividends": {
                "type": "number"
              },
              "capitalGains": {
                "type": "number"
              },
              "pension": {
                "type": "number"
              },
              "rrsp": {
                "type": "number"
              },
              "fhsa": {
                "type": "number"
              },
              "childCare": {
                "type": "number"
              },
              "unionDues": {
                "type": "number"
              },
              "tuition": {
                "type": "number"
              },
              "medical": {
                "type": "number"
              },
              "donations": {
                "type": "number"
              },
              "livingAlone": {
                "type": "boolean"
              }
            },
            "required": [
              "year",
              "province",
              "age",
              "employment",
              "selfEmployment",
              "otherIncome",
              "eligibleDividends",
              "nonEligibleDividends",
              "capitalGains",
              "pension",
              "rrsp",
              "fhsa",
              "childCare",
              "unionDues",
              "tuition",
              "medical",
              "donations"
            ],
            "additionalProperties": false,
            "description": "The input as calculated, with defaults filled in."
          }
        },
        "required": [
          "supported",
          "issues",
          "income",
          "payroll",
          "federal",
          "provincial",
          "incomeTax",
          "total",
          "averageRate",
          "marginalRate",
          "input"
        ],
        "additionalProperties": false
      },
      "Figure": {
        "type": "object",
        "properties": {
          "year": {
            "type": "number"
          },
          "path": {
            "type": "string"
          },
          "section": {
            "type": "string",
            "description": "The section whose sources apply, e.g. \"federal\" or \"provinces.ON\"."
          },
          "value": {
            "description": "Dollars for money, a decimal for rates (0.145 = 14.5%); null when not yet published.",
            "type": [
              "number",
              "null"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "money",
              "rate",
              "number"
            ]
          },
          "formatted": {
            "type": "string",
            "description": "\"$16,129\", \"14.5%\", or \"[TODO]\" when not yet published."
          },
          "todo": {
            "description": "Why the figure isn’t available yet.",
            "type": "string"
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "checked": {
                  "type": "string",
                  "description": "YYYY-MM-DD"
                }
              },
              "required": [
                "title",
                "url",
                "checked"
              ],
              "additionalProperties": false
            }
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "year",
          "path",
          "section",
          "value",
          "kind",
          "formatted",
          "sources",
          "notes"
        ],
        "additionalProperties": false
      },
      "Section": {
        "type": "object",
        "properties": {
          "year": {
            "type": "number"
          },
          "section": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {},
            "description": "Money in dollars, rates as decimals; {\"todo\": \"…\"} marks a figure not yet published."
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "checked": {
                  "type": "string",
                  "description": "YYYY-MM-DD"
                }
              },
              "required": [
                "title",
                "url",
                "checked"
              ],
              "additionalProperties": false
            }
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "unsupported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "year",
          "section",
          "title",
          "data",
          "sources",
          "notes",
          "unsupported"
        ],
        "additionalProperties": false
      },
      "SectionList": {
        "type": "object",
        "properties": {
          "year": {
            "type": "number"
          },
          "years": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "sections": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "section": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "keys": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "sources": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "title": {
                        "type": "string"
                      },
                      "url": {
                        "type": "string"
                      },
                      "checked": {
                        "type": "string",
                        "description": "YYYY-MM-DD"
                      }
                    },
                    "required": [
                      "title",
                      "url",
                      "checked"
                    ],
                    "additionalProperties": false
                  }
                }
              },
              "required": [
                "section",
                "title",
                "keys",
                "sources"
              ],
              "additionalProperties": false
            }
          },
          "howTo": {
            "type": "string"
          }
        },
        "required": [
          "year",
          "years",
          "sections",
          "howTo"
        ],
        "additionalProperties": false
      },
      "GuideList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "number"
          },
          "guides": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "slug": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "audience": {
                  "type": "string",
                  "enum": [
                    "individuals",
                    "self-employed",
                    "corporations",
                    "everyone"
                  ]
                },
                "audienceLabel": {
                  "type": "string"
                },
                "topic": {
                  "type": "string",
                  "enum": [
                    "filing",
                    "work",
                    "students",
                    "family",
                    "home",
                    "saving",
                    "retiring",
                    "disability",
                    "self-employed",
                    "corporations",
                    "planning",
                    "sales-tax",
                    "about"
                  ]
                },
                "topicLabel": {
                  "type": "string"
                },
                "province": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "markdownUrl": {
                  "type": "string"
                },
                "lastReviewed": {
                  "type": "string",
                  "description": "YYYY-MM-DD"
                },
                "sources": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "title": {
                        "type": "string"
                      },
                      "url": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "title",
                      "url"
                    ],
                    "additionalProperties": false
                  }
                }
              },
              "required": [
                "slug",
                "title",
                "description",
                "audience",
                "audienceLabel",
                "topic",
                "topicLabel",
                "url",
                "markdownUrl",
                "lastReviewed",
                "sources"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "count",
          "guides"
        ],
        "additionalProperties": false
      },
      "Guide": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "audience": {
            "type": "string",
            "enum": [
              "individuals",
              "self-employed",
              "corporations",
              "everyone"
            ]
          },
          "audienceLabel": {
            "type": "string"
          },
          "topic": {
            "type": "string",
            "enum": [
              "filing",
              "work",
              "students",
              "family",
              "home",
              "saving",
              "retiring",
              "disability",
              "self-employed",
              "corporations",
              "planning",
              "sales-tax",
              "about"
            ]
          },
          "topicLabel": {
            "type": "string"
          },
          "province": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "markdownUrl": {
            "type": "string"
          },
          "lastReviewed": {
            "type": "string",
            "description": "YYYY-MM-DD"
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                }
              },
              "required": [
                "title",
                "url"
              ],
              "additionalProperties": false
            }
          },
          "related": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Related pages on the site (absolute URLs)."
          },
          "markdown": {
            "description": "The whole guide as Markdown, with tax figures filled in.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "slug",
          "title",
          "description",
          "audience",
          "audienceLabel",
          "topic",
          "topicLabel",
          "url",
          "markdownUrl",
          "lastReviewed",
          "sources",
          "related",
          "markdown"
        ],
        "additionalProperties": false
      },
      "ChangeList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "number"
          },
          "changes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "date": {
                  "type": "string",
                  "description": "YYYY-MM-DD"
                },
                "title": {
                  "type": "string"
                },
                "summary": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "notify": {
                  "type": "boolean",
                  "description": "Whether it was emailed to newsletter subscribers."
                },
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string"
                      },
                      "href": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "text"
                    ],
                    "additionalProperties": false
                  }
                },
                "body": {
                  "type": "string",
                  "description": "Markdown."
                }
              },
              "required": [
                "id",
                "date",
                "title",
                "summary",
                "url",
                "notify",
                "items",
                "body"
              ],
              "additionalProperties": false
            }
          },
          "page": {
            "type": "string"
          },
          "feeds": {
            "type": "object",
            "properties": {
              "atom": {
                "type": "string"
              },
              "json": {
                "type": "string"
              }
            },
            "required": [
              "atom",
              "json"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "count",
          "changes",
          "page",
          "feeds"
        ],
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "issues": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "path",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      }
    }
  }
}
