{
 "openapi": "3.1.0",
 "info": {
  "title": "Deep Almanac: Australian term deposit rates",
  "version": "1.0.0",
  "summary": "Every Australian bank's term deposit rates, normalised from the public Consumer Data Right product feeds and refreshed daily.",
  "description": "Static JSON files regenerated once a day from every data holder's Consumer Data Right Product Reference Data API. Each record carries the bank's last-updated time and a link to a verbatim snapshot of the CDR response it was built from; the snapshot's snapshot_at says when that version was first fetched. Only index.json carries the generation and fetch times (generated_at, fetched_at, data_as_of): every other file changes only when the underlying data changes. Human-readable pages: https://deepalmanac.com/au/finance/term-deposits/ (every rate), https://deepalmanac.com/au/finance/term-deposits/best/ (best by term), https://deepalmanac.com/au/finance/term-deposits/banks/ (best at each bank) and one page per bank at https://deepalmanac.com/au/finance/banks/<brand_slug>/ (its term deposits under #term-deposits; the slugs are listed under brands_dir in index.json). No authentication, no rate limits beyond ordinary CDN behaviour; CORS is open. Rates change without notice; this is reference data, not financial advice.",
  "termsOfService": "https://deepalmanac.com/terms",
  "contact": {
   "name": "Deep Almanac",
   "url": "https://deepalmanac.com"
  },
  "license": {
   "name": "Reference data reproduced from CDR Product Reference Data; see licence_note in each file",
   "url": "https://deepalmanac.com/terms"
  }
 },
 "servers": [
  {
   "url": "https://deepalmanac.com"
  }
 ],
 "security": [],
 "tags": [
  {
   "name": "term-deposits",
   "description": "Australian term deposit rates (dataset au/finance/term-deposits)."
  }
 ],
 "paths": {
  "/au/finance/term-deposits/v1/index.json": {
   "get": {
    "tags": [
     "term-deposits"
    ],
    "operationId": "getTermDepositIndex",
    "summary": "Dataset index",
    "description": "Lists the dataset files, every per-bank file with its page URL, and how the CDR source snapshots are laid out.",
    "responses": {
     "200": {
      "description": "The dataset index.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DatasetIndex"
        }
       }
      }
     },
     "404": {
      "description": "The file has not been published yet or the path is wrong; static hosting returns the site's 404 page (HTML)."
     }
    }
   }
  },
  "/au/finance/term-deposits/v1/best.json": {
   "get": {
    "tags": [
     "term-deposits"
    ],
    "operationId": "getBestRates",
    "summary": "Every bank ranked per customer segment, reference deposit and term",
    "description": "rankings[segment][deposit][term] is an array of BestEntry ordered by rate (ties prefer interest paid at maturity), one entry per bank: the bank's highest fixed rate whose balance tier covers the reference deposit and whose term band includes the term. A product counts for every segment in its segments list. Keys are strings: deposit in AUD, term in months.",
    "responses": {
     "200": {
      "description": "Rankings for every segment, reference deposit and standard term.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/BestRates"
        }
       }
      }
     },
     "404": {
      "description": "The file has not been published yet or the path is wrong; static hosting returns the site's 404 page (HTML)."
     }
    }
   }
  },
  "/au/finance/term-deposits/v1/rates.json": {
   "get": {
    "tags": [
     "term-deposits"
    ],
    "operationId": "getAllRates",
    "summary": "Every normalised rate row",
    "description": "One row per product, term band, interest payment frequency and balance tier, across all banks. Several megabytes.",
    "responses": {
     "200": {
      "description": "All rate rows.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/RatesFile"
        }
       }
      }
     },
     "404": {
      "description": "The file has not been published yet or the path is wrong; static hosting returns the site's 404 page (HTML)."
     }
    }
   }
  },
  "/au/finance/term-deposits/v1/brands.json": {
   "get": {
    "tags": [
     "term-deposits"
    ],
    "operationId": "getBrandRegister",
    "summary": "CDR Register brands read for this dataset",
    "responses": {
     "200": {
      "description": "The banking data holder brands from the CDR Register.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/BrandRegister"
        }
       }
      }
     },
     "404": {
      "description": "The file has not been published yet or the path is wrong; static hosting returns the site's 404 page (HTML)."
     }
    }
   }
  },
  "/au/finance/term-deposits/v1/brands/{brand_slug}.json": {
   "get": {
    "tags": [
     "term-deposits"
    ],
    "operationId": "getBrand",
    "summary": "One bank: its term deposit products and every rate row",
    "parameters": [
     {
      "name": "brand_slug",
      "in": "path",
      "required": true,
      "description": "Brand slug as listed under brands_dir.brands[].brand_slug in index.json.",
      "schema": {
       "type": "string",
       "pattern": "^[a-z0-9-]+$",
       "enum": [
        "alex-bank",
        "amp-bank-go",
        "anz",
        "arab-bank-australia-limited",
        "australian-military-bank",
        "australian-mutual-bank-ltd",
        "auswide-bank-ltd",
        "bank-australia",
        "bank-first",
        "bank-of-china",
        "bank-of-melbourne",
        "bank-of-queensland-limited",
        "bank-of-sydney",
        "bank-of-us",
        "banksa",
        "bankvic",
        "bankwaw",
        "bankwest",
        "bcu-bank",
        "bendigo-bank",
        "beyond-bank-australia",
        "bnk-bank-goldfields-money-bchl",
        "boq-specialist",
        "border-bank",
        "broken-hill-bank",
        "cairns-bank",
        "central-murray-bank",
        "central-west-cul",
        "coastline-bank",
        "commbank",
        "commfcu",
        "credit-union-sa",
        "darling-downs-bank",
        "defence-bank",
        "dnister",
        "fire-service-credit-union",
        "firefighters-mutual-bank",
        "first-option-bank",
        "gateway-bank",
        "geelong-bank",
        "gmcu",
        "great-southern-bank",
        "greater-bank",
        "health-professionals-bank",
        "heartland",
        "horizon-bank",
        "hsbc-bank-australia-limited-wholesale-banking",
        "hume-bank",
        "imb-bank",
        "ing-bank-australia-ltd",
        "judo-bank",
        "laboratories-credit-union",
        "macquarie-bank-limited",
        "maitland-mutual-limited",
        "me-bank-me-go",
        "mystate-bank",
        "national-australia-bank",
        "newcastle-permanent",
        "northern-inland-credit-union-limited",
        "orange-credit-union-ltd",
        "p-n-bank",
        "people-first-and-heritage-bank",
        "police-bank",
        "police-credit-union-ltd",
        "qbank",
        "qudos-bank",
        "queensland-country-bank",
        "rabobank",
        "racq-bank",
        "regional-australia-bank",
        "rsl-money",
        "southern-cross-credit-union",
        "st-george-bank",
        "summerland-bank",
        "suncorp-bank",
        "swsbank",
        "teachers-mutual-bank",
        "the-capricornian",
        "the-mac",
        "tmcu",
        "traditional-credit-union",
        "tyro-payments",
        "unibank",
        "unity-bank",
        "westpac",
        "woolworths-team-bank"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The bank's products and rate rows.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/BrandFile"
        }
       }
      }
     },
     "404": {
      "description": "No such file. Static hosting returns the site's 404 page (HTML)."
     }
    }
   }
  },
  "/au/finance/term-deposits/v1/source/{brand_slug}/{safe_product_id}.json": {
   "get": {
    "tags": [
     "term-deposits"
    ],
    "operationId": "getSourceSnapshot",
    "summary": "Verbatim snapshot of a product's CDR detail response",
    "description": "The exact CDR product-detail payload the rows were built from, with the live endpoint and the x-v header it needs. Every row and product links to its snapshot as source_snapshot.",
    "parameters": [
     {
      "name": "brand_slug",
      "in": "path",
      "required": true,
      "description": "Brand slug as listed under brands_dir.brands[].brand_slug in index.json.",
      "schema": {
       "type": "string",
       "pattern": "^[a-z0-9-]+$",
       "enum": [
        "alex-bank",
        "amp-bank-go",
        "anz",
        "arab-bank-australia-limited",
        "australian-military-bank",
        "australian-mutual-bank-ltd",
        "auswide-bank-ltd",
        "bank-australia",
        "bank-first",
        "bank-of-china",
        "bank-of-melbourne",
        "bank-of-queensland-limited",
        "bank-of-sydney",
        "bank-of-us",
        "banksa",
        "bankvic",
        "bankwaw",
        "bankwest",
        "bcu-bank",
        "bendigo-bank",
        "beyond-bank-australia",
        "bnk-bank-goldfields-money-bchl",
        "boq-specialist",
        "border-bank",
        "broken-hill-bank",
        "cairns-bank",
        "central-murray-bank",
        "central-west-cul",
        "coastline-bank",
        "commbank",
        "commfcu",
        "credit-union-sa",
        "darling-downs-bank",
        "defence-bank",
        "dnister",
        "fire-service-credit-union",
        "firefighters-mutual-bank",
        "first-option-bank",
        "gateway-bank",
        "geelong-bank",
        "gmcu",
        "great-southern-bank",
        "greater-bank",
        "health-professionals-bank",
        "heartland",
        "horizon-bank",
        "hsbc-bank-australia-limited-wholesale-banking",
        "hume-bank",
        "imb-bank",
        "ing-bank-australia-ltd",
        "judo-bank",
        "laboratories-credit-union",
        "macquarie-bank-limited",
        "maitland-mutual-limited",
        "me-bank-me-go",
        "mystate-bank",
        "national-australia-bank",
        "newcastle-permanent",
        "northern-inland-credit-union-limited",
        "orange-credit-union-ltd",
        "p-n-bank",
        "people-first-and-heritage-bank",
        "police-bank",
        "police-credit-union-ltd",
        "qbank",
        "qudos-bank",
        "queensland-country-bank",
        "rabobank",
        "racq-bank",
        "regional-australia-bank",
        "rsl-money",
        "southern-cross-credit-union",
        "st-george-bank",
        "summerland-bank",
        "suncorp-bank",
        "swsbank",
        "teachers-mutual-bank",
        "the-capricornian",
        "the-mac",
        "tmcu",
        "traditional-credit-union",
        "tyro-payments",
        "unibank",
        "unity-bank",
        "westpac",
        "woolworths-team-bank"
       ]
      }
     },
     {
      "name": "safe_product_id",
      "in": "path",
      "required": true,
      "description": "The bank's productId with characters outside [A-Za-z0-9._-] replaced by _ (take it from a source_snapshot path).",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The snapshot.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SourceSnapshot"
        }
       }
      }
     },
     "404": {
      "description": "No such file. Static hosting returns the site's 404 page (HTML)."
     }
    }
   }
  }
 },
 "components": {
  "schemas": {
   "RateRow": {
    "type": "object",
    "description": "One normalised term deposit rate: one product, term band, interest payment frequency and balance tier.",
    "properties": {
     "brand": {
      "type": "string",
      "description": "Brand name exactly as in the CDR Register."
     },
     "brand_label": {
      "type": "string",
      "description": "Display name for the brand (register name tidied, e.g. 'CommFCU' -> 'Community First Bank')."
     },
     "brand_slug": {
      "type": "string",
      "description": "Stable URL slug for the brand; key for brands/{brand_slug}.json and the per-bank page."
     },
     "legal_entity_abn": {
      "type": [
       "string",
       "null"
      ],
      "description": "ABN of the data holder's legal entity."
     },
     "product_id": {
      "type": "string",
      "description": "The bank's CDR productId."
     },
     "product_name": {
      "type": "string",
      "description": "Product name exactly as published."
     },
     "product_label": {
      "type": "string",
      "description": "Harmonised display name (brand stripped, plurals and casing normalised)."
     },
     "product_url": {
      "type": [
       "string",
       "null"
      ],
      "description": "The bank's own page or application link for the product, when published.",
      "format": "uri"
     },
     "segment": {
      "type": "string",
      "description": "Primary customer segment (the one the product is named for, else the first of segments).",
      "enum": [
       "personal",
       "smsf",
       "business",
       "other"
      ]
     },
     "segments": {
      "type": "array",
      "description": "Every customer segment the product's own feed says it is open to, in the order personal, smsf, business, other.",
      "items": {
       "type": "string",
       "enum": [
        "personal",
        "smsf",
        "business",
        "other"
       ]
      }
     },
     "segments_inferred": {
      "type": "array",
      "description": "Segments that were inferred from sibling products of the same bank rather than stated on this product; empty when none.",
      "items": {
       "type": "string"
      }
     },
     "term_raw": {
      "type": [
       "string",
       "null"
      ],
      "description": "The term as the bank published it: usually an ISO-8601 duration (P12M, P90D), a range (P6M/P8M) or text."
     },
     "term_months": {
      "type": "integer",
      "description": "Shortest whole-month term the rate applies to (equals term_min_months; kept for compatibility).",
      "minimum": 1
     },
     "term_min_months": {
      "type": "integer",
      "description": "First whole-month term in the band the rate applies to.",
      "minimum": 1
     },
     "term_max_months": {
      "type": "integer",
      "description": "Last whole-month term in the band; equal to term_min_months for a single term.",
      "minimum": 1
     },
     "term_days": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Exact day count when the bank quotes a single term in days or weeks (P90D -> 90); null otherwise."
     },
     "term_days_min": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Start of a day-quoted term band (90 for 90-119 days); null when the term is quoted in months."
     },
     "term_days_max": {
      "type": [
       "integer",
       "null"
      ],
      "description": "End of a day-quoted term band; equals term_days_min for a single day term."
     },
     "rate": {
      "type": "number",
      "description": "Annual interest rate as a fraction (0.055 = 5.50% p.a.).",
      "minimum": 0
     },
     "rate_pct": {
      "type": "number",
      "description": "Annual interest rate as a percentage, rounded to two decimals."
     },
     "rate_type": {
      "type": [
       "string",
       "null"
      ],
      "description": "CDR depositRateType (FIXED, BONUS, INTRODUCTORY, VARIABLE, MARKET_LINKED) or FIXED+BONUS for a base rate with a stacked add-on."
     },
     "interest_paid": {
      "type": "string",
      "description": "How often interest is paid, derived from the bank's application frequency and text.",
      "enum": [
       "at_maturity",
       "annually",
       "half_yearly",
       "quarterly",
       "monthly",
       "unknown"
      ]
     },
     "min_balance": {
      "type": [
       "number",
       "null"
      ],
      "description": "Product-level minimum (opening) balance in AUD from the CDR constraints; null when not published."
     },
     "max_balance": {
      "type": [
       "number",
       "null"
      ],
      "description": "Product-level maximum balance in AUD; null when not published."
     },
     "tier_min": {
      "type": [
       "number",
       "null"
      ],
      "description": "Lower bound in AUD of the balance tier this rate applies to; null when the rate has no tier."
     },
     "tier_max": {
      "type": [
       "number",
       "null"
      ],
      "description": "Upper bound in AUD of the balance tier; null when open-ended."
     },
     "deposit_min": {
      "type": [
       "number",
       "null"
      ],
      "description": "Smallest deposit in AUD that earns this rate: the greater of min_balance and tier_min."
     },
     "deposit_max": {
      "type": [
       "number",
       "null"
      ],
      "description": "Largest deposit in AUD that earns this rate: the lesser of max_balance and tier_max; null when unbounded."
     },
     "is_special": {
      "type": "boolean",
      "description": "True for promotional, introductory or bonus rates (by rate type or the bank's wording)."
     },
     "conditional": {
      "type": "boolean",
      "description": "True when the rate carries any condition or is a special."
     },
     "conditions": {
      "type": "array",
      "description": "Conditions in the bank's own words plus short derived labels such as 'online only' or 'new customers only'.",
      "items": {
       "type": "string"
      }
     },
     "additional_info": {
      "type": [
       "string",
       "null"
      ],
      "description": "The rate's own additionalInfo text from the feed, truncated."
     },
     "stacked_bonus": {
      "type": [
       "number",
       "null"
      ],
      "description": "For rows with rate_type FIXED+BONUS: the add-on increment (as a fraction) that was stacked onto the base rate; null otherwise."
     },
     "source_url": {
      "type": [
       "string",
       "null"
      ],
      "description": "Live CDR product-detail endpoint for this product (needs an x-v header; not browsable).",
      "format": "uri"
     },
     "source_snapshot": {
      "type": [
       "string",
       "null"
      ],
      "description": "Site-relative path of our verbatim snapshot of the CDR detail response the row was built from."
     },
     "bank_last_updated": {
      "type": [
       "string",
       "null"
      ],
      "description": "The bank's lastUpdated timestamp for the product.",
      "format": "date-time"
     }
    },
    "required": [
     "brand",
     "brand_label",
     "brand_slug",
     "legal_entity_abn",
     "product_id",
     "product_name",
     "product_label",
     "product_url",
     "segment",
     "segments",
     "segments_inferred",
     "term_raw",
     "term_months",
     "term_min_months",
     "term_max_months",
     "term_days",
     "term_days_min",
     "term_days_max",
     "rate",
     "rate_pct",
     "rate_type",
     "interest_paid",
     "min_balance",
     "max_balance",
     "tier_min",
     "tier_max",
     "deposit_min",
     "deposit_max",
     "is_special",
     "conditional",
     "conditions",
     "additional_info",
     "stacked_bonus",
     "source_url",
     "source_snapshot",
     "bank_last_updated"
    ]
   },
   "BestEntry": {
    "type": "object",
    "description": "A bank's best eligible rate for one customer segment, reference deposit and standard term.",
    "properties": {
     "rank": {
      "type": "integer",
      "description": "Position in this segment / deposit / term ranking (1 = highest rate).",
      "minimum": 1
     },
     "brand": {
      "type": "string",
      "description": "Brand name exactly as in the CDR Register."
     },
     "brand_label": {
      "type": "string",
      "description": "Display name for the brand (register name tidied, e.g. 'CommFCU' -> 'Community First Bank')."
     },
     "brand_slug": {
      "type": "string",
      "description": "Stable URL slug for the brand; key for brands/{brand_slug}.json and the per-bank page."
     },
     "product_name": {
      "type": "string",
      "description": "Product name exactly as published."
     },
     "product_label": {
      "type": "string",
      "description": "Harmonised display name (brand stripped, plurals and casing normalised)."
     },
     "segment": {
      "type": "string",
      "description": "Primary customer segment (the one the product is named for, else the first of segments).",
      "enum": [
       "personal",
       "smsf",
       "business",
       "other"
      ]
     },
     "segments": {
      "type": "array",
      "description": "Every customer segment the product's own feed says it is open to, in the order personal, smsf, business, other.",
      "items": {
       "type": "string",
       "enum": [
        "personal",
        "smsf",
        "business",
        "other"
       ]
      }
     },
     "rate": {
      "type": "number",
      "description": "Annual interest rate as a fraction (0.055 = 5.50% p.a.).",
      "minimum": 0
     },
     "rate_pct": {
      "type": "number",
      "description": "Annual interest rate as a percentage, rounded to two decimals."
     },
     "interest_paid": {
      "type": "string",
      "description": "How often interest is paid, derived from the bank's application frequency and text.",
      "enum": [
       "at_maturity",
       "annually",
       "half_yearly",
       "quarterly",
       "monthly",
       "unknown"
      ]
     },
     "term_raw": {
      "type": [
       "string",
       "null"
      ],
      "description": "The term as the bank published it: usually an ISO-8601 duration (P12M, P90D), a range (P6M/P8M) or text."
     },
     "term_months": {
      "type": "integer",
      "description": "Shortest whole-month term the rate applies to (equals term_min_months; kept for compatibility).",
      "minimum": 1
     },
     "term_min_months": {
      "type": "integer",
      "description": "First whole-month term in the band the rate applies to.",
      "minimum": 1
     },
     "term_max_months": {
      "type": "integer",
      "description": "Last whole-month term in the band; equal to term_min_months for a single term.",
      "minimum": 1
     },
     "term_days": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Exact day count when the bank quotes a single term in days or weeks (P90D -> 90); null otherwise."
     },
     "term_days_min": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Start of a day-quoted term band (90 for 90-119 days); null when the term is quoted in months."
     },
     "term_days_max": {
      "type": [
       "integer",
       "null"
      ],
      "description": "End of a day-quoted term band; equals term_days_min for a single day term."
     },
     "min_balance": {
      "type": [
       "number",
       "null"
      ],
      "description": "Product-level minimum (opening) balance in AUD from the CDR constraints; null when not published."
     },
     "max_balance": {
      "type": [
       "number",
       "null"
      ],
      "description": "Product-level maximum balance in AUD; null when not published."
     },
     "tier_min": {
      "type": [
       "number",
       "null"
      ],
      "description": "Lower bound in AUD of the balance tier this rate applies to; null when the rate has no tier."
     },
     "tier_max": {
      "type": [
       "number",
       "null"
      ],
      "description": "Upper bound in AUD of the balance tier; null when open-ended."
     },
     "deposit_min": {
      "type": [
       "number",
       "null"
      ],
      "description": "Smallest deposit in AUD that earns this rate: the greater of min_balance and tier_min."
     },
     "deposit_max": {
      "type": [
       "number",
       "null"
      ],
      "description": "Largest deposit in AUD that earns this rate: the lesser of max_balance and tier_max; null when unbounded."
     },
     "is_special": {
      "type": "boolean",
      "description": "True for promotional, introductory or bonus rates (by rate type or the bank's wording)."
     },
     "conditional": {
      "type": "boolean",
      "description": "True when the rate carries any condition or is a special."
     },
     "conditions": {
      "type": "array",
      "description": "Conditions in the bank's own words plus short derived labels such as 'online only' or 'new customers only'.",
      "items": {
       "type": "string"
      }
     },
     "stacked_bonus": {
      "type": [
       "number",
       "null"
      ],
      "description": "For rows with rate_type FIXED+BONUS: the add-on increment (as a fraction) that was stacked onto the base rate; null otherwise."
     },
     "source_url": {
      "type": [
       "string",
       "null"
      ],
      "description": "Live CDR product-detail endpoint for this product (needs an x-v header; not browsable).",
      "format": "uri"
     },
     "source_snapshot": {
      "type": [
       "string",
       "null"
      ],
      "description": "Site-relative path of our verbatim snapshot of the CDR detail response the row was built from."
     },
     "product_url": {
      "type": [
       "string",
       "null"
      ],
      "description": "The bank's own page or application link for the product, when published.",
      "format": "uri"
     },
     "bank_last_updated": {
      "type": [
       "string",
       "null"
      ],
      "description": "The bank's lastUpdated timestamp for the product.",
      "format": "date-time"
     }
    },
    "required": [
     "rank",
     "brand",
     "brand_label",
     "brand_slug",
     "product_name",
     "product_label",
     "segment",
     "segments",
     "rate",
     "rate_pct",
     "interest_paid",
     "term_raw",
     "term_months",
     "term_min_months",
     "term_max_months",
     "term_days",
     "term_days_min",
     "term_days_max",
     "min_balance",
     "max_balance",
     "tier_min",
     "tier_max",
     "deposit_min",
     "deposit_max",
     "is_special",
     "conditional",
     "conditions",
     "stacked_bonus",
     "source_url",
     "source_snapshot",
     "product_url",
     "bank_last_updated"
    ]
   },
   "ProductSummary": {
    "type": "object",
    "description": "One term deposit product of a bank, with or without rate rows.",
    "properties": {
     "product_id": {
      "type": "string",
      "description": "The bank's CDR productId."
     },
     "product_name": {
      "type": "string",
      "description": "Product name exactly as published."
     },
     "product_label": {
      "type": "string",
      "description": "Harmonised display name (brand stripped, plurals and casing normalised)."
     },
     "segment": {
      "type": "string",
      "description": "Primary customer segment (the one the product is named for, else the first of segments).",
      "enum": [
       "personal",
       "smsf",
       "business",
       "other"
      ]
     },
     "segments": {
      "type": "array",
      "description": "Every customer segment the product's own feed says it is open to, in the order personal, smsf, business, other.",
      "items": {
       "type": "string",
       "enum": [
        "personal",
        "smsf",
        "business",
        "other"
       ]
      }
     },
     "segments_inferred": {
      "type": "array",
      "description": "Segments that were inferred from sibling products of the same bank rather than stated on this product; empty when none.",
      "items": {
       "type": "string"
      }
     },
     "product_url": {
      "type": [
       "string",
       "null"
      ],
      "description": "The bank's own page or application link for the product, when published.",
      "format": "uri"
     },
     "source_url": {
      "type": [
       "string",
       "null"
      ],
      "description": "Live CDR product-detail endpoint for this product (needs an x-v header; not browsable).",
      "format": "uri"
     },
     "source_snapshot": {
      "type": [
       "string",
       "null"
      ],
      "description": "Site-relative path of our verbatim snapshot of the CDR detail response the row was built from."
     },
     "snapshot_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "When the current version of the product's CDR record (its source_snapshot) was first fetched; changes only when the bank's data changes.",
      "format": "date-time"
     },
     "description": {
      "type": [
       "string",
       "null"
      ],
      "description": "The bank's product description, truncated."
     },
     "min_balance": {
      "type": [
       "number",
       "null"
      ],
      "description": "Product-level minimum (opening) balance in AUD from the CDR constraints; null when not published."
     },
     "max_balance": {
      "type": [
       "number",
       "null"
      ],
      "description": "Product-level maximum balance in AUD; null when not published."
     },
     "conditions": {
      "type": "array",
      "description": "Product-level conditions: OTHER constraints and non-universal eligibility, in the bank's words.",
      "items": {
       "type": "string"
      }
     },
     "bank_last_updated": {
      "type": [
       "string",
       "null"
      ],
      "description": "The bank's lastUpdated timestamp for the product.",
      "format": "date-time"
     },
     "rate_count": {
      "type": "integer",
      "description": "Number of rows in rates.json built from this product.",
      "minimum": 0
     },
     "addons": {
      "type": "array",
      "description": "Bonus add-ons the bank publishes as increments on top of base rates (stacked into FIXED+BONUS rows).",
      "items": {
       "type": "object",
       "properties": {
        "increment": {
         "type": "number",
         "description": "Add-on as a fraction (0.001 = 0.10% p.a.)."
        },
        "increment_pct": {
         "type": "number",
         "description": "Add-on as a percentage."
        },
        "applies_min_months": {
         "type": [
          "integer",
          "null"
         ],
         "description": "First term in months the add-on applies to; null for any term."
        },
        "applies_max_months": {
         "type": [
          "integer",
          "null"
         ],
         "description": "Last term in months the add-on applies to; null for any term."
        },
        "condition": {
         "type": "string",
         "description": "Short condition label, e.g. 'online bonus: open or renew online'."
        },
        "online": {
         "type": "boolean",
         "description": "True when the add-on requires opening or renewing online."
        },
        "rate_type": {
         "type": "string",
         "description": "CDR depositRateType of the add-on row (BONUS or INTRODUCTORY)."
        },
        "term_raw": {
         "type": [
          "string",
          "null"
         ],
         "description": "The add-on row's additionalValue as published."
        },
        "text": {
         "type": [
          "string",
          "null"
         ],
         "description": "The add-on row's additionalInfo as published."
        }
       }
      }
     },
     "no_rates_reason": {
      "type": [
       "string",
       "null"
      ],
      "description": "Why the product has no rows (detail not fetched, no deposit rates published), or null."
     }
    },
    "required": [
     "product_id",
     "product_name",
     "product_label",
     "segment",
     "segments",
     "segments_inferred",
     "product_url",
     "source_url",
     "source_snapshot",
     "snapshot_at",
     "description",
     "min_balance",
     "max_balance",
     "conditions",
     "bank_last_updated",
     "rate_count",
     "addons",
     "no_rates_reason"
    ]
   },
   "RatesFile": {
    "type": "object",
    "properties": {
     "source": {
      "type": "string",
      "description": "Data source statement."
     },
     "licence_note": {
      "type": "string",
      "description": "Terms of reuse and the not-advice note."
     },
     "row_count": {
      "type": "integer",
      "description": "Number of rows."
     },
     "rows": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/RateRow"
      }
     }
    },
    "required": [
     "row_count",
     "rows"
    ]
   },
   "BestRates": {
    "type": "object",
    "properties": {
     "source": {
      "type": "string",
      "description": "Data source statement."
     },
     "licence_note": {
      "type": "string",
      "description": "Terms of reuse and the not-advice note."
     },
     "reference_deposits": {
      "type": "array",
      "description": "Reference deposit sizes in AUD used as ranking keys.",
      "items": {
       "type": "integer"
      }
     },
     "segments": {
      "type": "array",
      "description": "Customer segments ranked.",
      "items": {
       "type": "string"
      }
     },
     "terms": {
      "type": "array",
      "description": "Standard terms in months ranked.",
      "items": {
       "type": "integer"
      }
     },
     "rankings": {
      "type": "object",
      "description": "segment -> deposit (string) -> term in months (string) -> ranked BestEntry array.",
      "additionalProperties": {
       "type": "object",
       "additionalProperties": {
        "type": "object",
        "additionalProperties": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/BestEntry"
         }
        }
       }
      }
     },
     "brand_count": {
      "type": "integer",
      "description": "Brands in the CDR Register we read."
     },
     "brands_with_rates": {
      "type": "array",
      "description": "brand_slug of every brand with at least one rate row.",
      "items": {
       "type": "string"
      }
     }
    },
    "required": [
     "reference_deposits",
     "segments",
     "terms",
     "rankings"
    ]
   },
   "BrandFile": {
    "type": "object",
    "properties": {
     "source": {
      "type": "string",
      "description": "Data source statement."
     },
     "licence_note": {
      "type": "string",
      "description": "Terms of reuse and the not-advice note."
     },
     "brand": {
      "type": "string",
      "description": "Brand name exactly as in the CDR Register."
     },
     "brand_label": {
      "type": "string",
      "description": "Display name for the brand (register name tidied, e.g. 'CommFCU' -> 'Community First Bank')."
     },
     "brand_slug": {
      "type": "string",
      "description": "Stable URL slug for the brand; key for brands/{brand_slug}.json and the per-bank page."
     },
     "legal_entity_abn": {
      "type": [
       "string",
       "null"
      ],
      "description": "ABN of the data holder's legal entity."
     },
     "logo_uri": {
      "type": [
       "string",
       "null"
      ],
      "description": "Brand logo from the CDR Register.",
      "format": "uri"
     },
     "public_base_uri": {
      "type": [
       "string",
       "null"
      ],
      "description": "The bank's CDR public base URI.",
      "format": "uri"
     },
     "bank_last_updated": {
      "type": [
       "string",
       "null"
      ],
      "description": "The bank's lastUpdated timestamp for the product.",
      "format": "date-time"
     },
     "status": {
      "type": [
       "string",
       "null"
      ],
      "description": "Fetch status for this brand (ok, no_products, error ...)."
     },
     "products": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ProductSummary"
      }
     },
     "rows": {
      "type": "array",
      "description": "This bank's rows from rates.json.",
      "items": {
       "$ref": "#/components/schemas/RateRow"
      }
     }
    },
    "required": [
     "brand",
     "brand_slug",
     "products",
     "rows"
    ]
   },
   "BrandRegister": {
    "type": "object",
    "properties": {
     "source": {
      "type": "string",
      "description": "Data source statement."
     },
     "brands": {
      "type": "array",
      "items": {
       "type": "object",
       "description": "A CDR Register data holder brand, as published.",
       "properties": {
        "dataHolderBrandId": {
         "type": "string"
        },
        "brandName": {
         "type": "string"
        },
        "industries": {
         "type": "array",
         "items": {
          "type": "string"
         }
        },
        "logoUri": {
         "type": [
          "string",
          "null"
         ]
        },
        "publicBaseUri": {
         "type": "string"
        },
        "abn": {
         "type": [
          "string",
          "null"
         ]
        },
        "acn": {
         "type": [
          "string",
          "null"
         ]
        },
        "lastUpdated": {
         "type": [
          "string",
          "null"
         ]
        }
       }
      }
     }
    },
    "required": [
     "brands"
    ]
   },
   "DatasetIndex": {
    "type": "object",
    "properties": {
     "generated_at": {
      "type": "string",
      "description": "When the dataset was generated (UTC). Only index.json carries this; the other files change only when the data does.",
      "format": "date-time"
     },
     "fetched_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "When the banks' feeds were fetched for this generation (UTC).",
      "format": "date-time"
     },
     "data_as_of": {
      "type": [
       "string",
       "null"
      ],
      "description": "The latest lastUpdated timestamp any bank gave for a term deposit product.",
      "format": "date-time"
     },
     "source": {
      "type": "string",
      "description": "Data source statement."
     },
     "licence_note": {
      "type": "string",
      "description": "Terms of reuse and the not-advice note."
     },
     "dataset": {
      "type": "string",
      "description": "Dataset name."
     },
     "page": {
      "type": "string",
      "description": "Human-readable page for the dataset.",
      "format": "uri"
     },
     "files": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "file": {
         "type": "string"
        },
        "url": {
         "type": "string",
         "format": "uri"
        },
        "description": {
         "type": "string"
        }
       }
      }
     },
     "brands_dir": {
      "type": "object",
      "properties": {
       "path": {
        "type": "string"
       },
       "url_template": {
        "type": "string"
       },
       "page_template": {
        "type": "string"
       },
       "description": {
        "type": "string"
       },
       "count": {
        "type": "integer"
       },
       "brands": {
        "type": "array",
        "items": {
         "type": "object",
         "properties": {
          "brand": {
           "type": "string",
           "description": "Brand name exactly as in the CDR Register."
          },
          "brand_label": {
           "type": "string",
           "description": "Display name for the brand (register name tidied, e.g. 'CommFCU' -> 'Community First Bank')."
          },
          "brand_slug": {
           "type": "string",
           "description": "Stable URL slug for the brand; key for brands/{brand_slug}.json and the per-bank page."
          },
          "url": {
           "type": "string",
           "format": "uri"
          },
          "page": {
           "type": "string",
           "description": "The bank's page, /au/finance/banks/<brand_slug>/; its term deposits are the #term-deposits section.",
           "format": "uri"
          },
          "product_count": {
           "type": "integer"
          },
          "row_count": {
           "type": "integer"
          }
         }
        }
       }
      }
     },
     "source_dir": {
      "type": "object",
      "properties": {
       "path": {
        "type": "string"
       },
       "url_template": {
        "type": "string"
       },
       "description": {
        "type": "string"
       },
       "count": {
        "type": "integer"
       },
       "brand_count": {
        "type": "integer"
       }
      }
     }
    },
    "required": [
     "generated_at",
     "files",
     "brands_dir"
    ]
   },
   "SourceSnapshot": {
    "type": "object",
    "properties": {
     "snapshot_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "When the current version of the product's CDR record (its source_snapshot) was first fetched; changes only when the bank's data changes.",
      "format": "date-time"
     },
     "brand": {
      "type": "string",
      "description": "Brand name exactly as in the CDR Register."
     },
     "brand_slug": {
      "type": "string",
      "description": "Stable URL slug for the brand; key for brands/{brand_slug}.json and the per-bank page."
     },
     "product_id": {
      "type": "string",
      "description": "The bank's CDR productId."
     },
     "cdr_url": {
      "type": [
       "string",
       "null"
      ],
      "description": "The live CDR product-detail endpoint.",
      "format": "uri"
     },
     "x_v": {
      "type": [
       "integer",
       "null"
      ],
      "description": "The x-v header value the endpoint required."
     },
     "how_to_fetch": {
      "type": "string",
      "description": "A curl command that reproduces the fetch."
     },
     "note": {
      "type": "string",
      "description": "What this file is and what snapshot_at means."
     },
     "data": {
      "type": "object",
      "description": "The bank's CDR product detail response, verbatim."
     }
    },
    "required": [
     "snapshot_at",
     "brand_slug",
     "product_id",
     "data"
    ]
   }
  }
 }
}
