{
 "$schema": "https://json-schema.org/draft/2020-12/schema",
 "$id": "https://personalfinanceapps.guide/data/schema.json",
 "title": "Personal Finance Apps Guide dataset",
 "description": "One record per listing. Attribute states are a three-state enum; unknown is never flattened to no.",
 "type": "array",
 "items": {
  "type": "object",
  "additionalProperties": false,
  "properties": {
   "slug": {
    "type": "string",
    "pattern": "^[a-z0-9-]+$"
   },
   "name": {
    "type": "string"
   },
   "website": {
    "type": "string"
   },
   "description": {
    "type": "string",
    "maxLength": 160,
    "description": "One line, plain English, written through the site; empty when nobody has"
   },
   "notes": {
    "type": "string",
    "description": "Longer prose shown in the Notes card; empty when none"
   },
   "subreddit": {
    "type": "string",
    "description": "Subreddit name without r/, or empty"
   },
   "discord": {
    "type": "string",
    "description": "Discord invite link, or empty"
   },
   "status": {
    "enum": [
     "live",
     "discontinued",
     "unreachable"
    ]
   },
   "app_store_id": {
    "type": [
     "integer",
     "null"
    ],
    "description": "The App Store record a person matched"
   },
   "play_id": {
    "type": [
     "string",
     "null"
    ],
    "description": "The Google Play package a person matched"
   },
   "offer": {
    "type": [
     "object",
     "null"
    ],
    "additionalProperties": false,
    "properties": {
     "code": {
      "type": "string"
     },
     "terms": {
      "type": "string"
     },
     "expires": {
      "type": "string",
      "format": "date"
     },
     "posted": {
      "type": "string",
      "format": "date"
     }
    },
    "required": [
     "code",
     "terms",
     "expires",
     "posted"
    ],
    "description": "The verified owner's current offer; hidden on the page after it expires"
   },
   "roadmap": {
    "type": "array",
    "items": {
     "type": "object",
     "additionalProperties": false,
     "properties": {
      "title": {
       "type": "string"
      },
      "target": {
       "type": "string",
       "pattern": "^[0-9]{4}-Q[1-4]$"
      },
      "shipped": {
       "type": "string",
       "format": "date"
      }
     },
     "required": [
      "title",
      "target"
     ]
    },
    "description": "What the verified owner has published as planned, with targets"
   },
   "price_from_usd": {
    "type": [
     "number",
     "null"
    ],
    "description": "Cheapest recurring plan per year, USD. 0 means a genuinely free way in; null means not recorded."
   },
   "price_month_usd": {
    "type": [
     "number",
     "null"
    ],
    "description": "The monthly plan, USD per month; null when there is none or it is not recorded."
   },
   "price_year_usd": {
    "type": [
     "number",
     "null"
    ],
    "description": "The annual plan, USD per year; null when there is none or it is not recorded."
   },
   "price_note": {
    "type": "string"
   },
   "seeded": {
    "type": "string",
    "format": "date"
   },
   "verified": {
    "type": [
     "string",
     "null"
    ],
    "format": "date"
   },
   "recorded": {
    "type": "integer",
    "minimum": 0,
    "maximum": 60
   },
   "attributes_total": {
    "const": 60
   },
   "aggregators": {
    "type": "array",
    "items": {
     "enum": [
      "Plaid",
      "Yodlee",
      "MX",
      "Finicity",
      "Mastercard",
      "Intuit",
      "Akoya",
      "MoneyKit",
      "Teller",
      "SimpleFIN",
      "TrueLayer",
      "Salt Edge",
      "GoCardless",
      "Enable Banking",
      "Flinks",
      "Wealthica",
      "Vezgo",
      "eMoney",
      "Akahu",
      "Pluggy"
     ]
    }
   },
   "platforms": {
    "type": "array",
    "items": {
     "enum": [
      "Web",
      "iOS",
      "Android",
      "Desktop"
     ]
    }
   },
   "import_formats": {
    "type": "array",
    "items": {
     "enum": [
      "CSV",
      "Excel",
      "OFX",
      "QFX",
      "QIF",
      "PDF",
      "JSON",
      "Mint",
      "YNAB",
      "Quicken"
     ]
    }
   },
   "attributes": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
     "free_tier": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Free tier"
     },
     "price": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Price"
     },
     "lifetime": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Lifetime purchase"
     },
     "aggregation": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Account aggregation"
     },
     "connectors": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Connectors"
     },
     "refresh": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Refresh more than daily"
     },
     "manual_accounts": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Manual accounts"
     },
     "countries": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Countries"
     },
     "multi_currency": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Multi-currency"
     },
     "crypto": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Crypto and digital assets"
     },
     "edit": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Edit transactions"
     },
     "manual_txn": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Create manual transactions"
     },
     "rules": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Rules engine"
     },
     "mass_edit": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Mass edit"
     },
     "split": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Split transactions"
     },
     "history_import": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "History import"
     },
     "history_length": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "enum": [
         "",
         "Months",
         "Years",
         "Unlimited"
        ]
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Length of history"
     },
     "export": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Export"
     },
     "import_formats": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Import formats"
     },
     "category_depth": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Nested categories"
     },
     "tags": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Tags"
     },
     "attachments": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Receipt attachments"
     },
     "budgeting": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Budgeting"
     },
     "envelope": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Envelope budgeting"
     },
     "rollover": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Rollover budgeting"
     },
     "recurring": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Recurring transactions"
     },
     "bills": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Bills"
     },
     "goals": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Goal tracking"
     },
     "debt_payoff": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Debt payoff planning"
     },
     "forecast": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Cash-flow forecasting"
     },
     "subscriptions": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Cancel subscriptions"
     },
     "net_worth": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Net worth"
     },
     "balance_import": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Balance history import"
     },
     "investments": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Investment tracking"
     },
     "investment_txn": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Investment transactions"
     },
     "real_estate": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Real estate"
     },
     "reports": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Reports"
     },
     "trends": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Trends"
     },
     "credit_scores": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Credit scores"
     },
     "alerts": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Alerts"
     },
     "ai_chat": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "AI chat"
     },
     "ai_categorization": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "AI categorization"
     },
     "collaboration": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Partner or household"
     },
     "advisor": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Adviser access"
     },
     "business": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Business or rental separation"
     },
     "interfaces": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Interfaces"
     },
     "mobile_parity": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Full mobile app"
     },
     "widgets": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Home-screen widgets"
     },
     "offline": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Offline access"
     },
     "soc2": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "SOC 2"
     },
     "mfa": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "2FA / MFA"
     },
     "sells_data": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Sells or shares your data"
     },
     "read_only": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Read-only bank connections"
     },
     "data_held_by": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Data held by"
     },
     "self_host": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Self-hosting"
     },
     "open_source": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Open source"
     },
     "public_api": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Public API"
     },
     "spreadsheet": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Spreadsheet sync"
     },
     "webhooks": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Webhooks"
     },
     "tax_export": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "state": {
        "enum": [
         "yes",
         "no",
         "unknown"
        ]
       },
       "value": {
        "type": "string"
       }
      },
      "required": [
       "state",
       "value"
      ],
      "title": "Tax export"
     }
    },
    "required": [
     "free_tier",
     "price",
     "lifetime",
     "aggregation",
     "connectors",
     "refresh",
     "manual_accounts",
     "countries",
     "multi_currency",
     "crypto",
     "edit",
     "manual_txn",
     "rules",
     "mass_edit",
     "split",
     "history_import",
     "history_length",
     "export",
     "import_formats",
     "category_depth",
     "tags",
     "attachments",
     "budgeting",
     "envelope",
     "rollover",
     "recurring",
     "bills",
     "goals",
     "debt_payoff",
     "forecast",
     "subscriptions",
     "net_worth",
     "balance_import",
     "investments",
     "investment_txn",
     "real_estate",
     "reports",
     "trends",
     "credit_scores",
     "alerts",
     "ai_chat",
     "ai_categorization",
     "collaboration",
     "advisor",
     "business",
     "interfaces",
     "mobile_parity",
     "widgets",
     "offline",
     "soc2",
     "mfa",
     "sells_data",
     "read_only",
     "data_held_by",
     "self_host",
     "open_source",
     "public_api",
     "spreadsheet",
     "webhooks",
     "tax_export"
    ]
   }
  },
  "required": [
   "slug",
   "name",
   "website",
   "description",
   "notes",
   "status",
   "price_from_usd",
   "price_month_usd",
   "price_year_usd",
   "price_note",
   "app_store_id",
   "play_id",
   "offer",
   "roadmap",
   "seeded",
   "verified",
   "recorded",
   "attributes_total",
   "aggregators",
   "platforms",
   "import_formats",
   "attributes"
  ]
 }
}
