YNAB File Format - popebp/neat-sheets GitHub Wiki
Jack Turnbull has done a bunch of RE work on the YNAB file format already, but I am not using it. The RE methodology used is very different from my own. The file formats are basically all JSON, but I want to be able to allow a user to point to their existing YNAB directory and import all of their content magically into Neat Sheets.
-
.ynabSettings.yroot
- // Probably defines base details for YNAB to understand where to find everything.
-
<BudgetName>~<??>.ynab4
- Budget Directory
-
Budget.ymeta
- JSON File
-
Backup_<Year>-<Month>-<Day>T<Hour>-<Min>-<Sec>_<DeviceShort>_<DeviceGUID>.y4backup
- Zip container that contains .ydiff and .ybsettings files. Additional details provided below. I'm guessing the time is in Zulu/GMT, otherwise it isn't the backup time.
-
data<Id>~<??>
- Directory containing Device GUID directories and a
device
metadata directory.
- Directory containing Device GUID directories and a
- Device GUID Directories
- Contains .ydiff, .ybsettings, and .yfull (optional)
-
device
directory- Contains .ydevice files
-
<shortDeviceId>.ydevice
- JSON file defining the device GUID, friendly name, short name, version details, etc.
-
Budget.yfull
- This is the complete budget database in JSON
-
<CSV>.ydiff
- Diff output of the JSON files. The name of the file describes what is included in the diff.
-
budgetSettings.ybsettings
- XML file that defines the settings for the UX.
- .yroot
- .ymeta
- .yfull
- .ydevice
-
TED
- Number
- Purpose Unknown
-
relativeDefaultBudgetsFolder
- String
- Name of directory containing Budgets
-
formatVersion
- String
- YRoot (??) file format version
-
relativeKnownBudgets
- Array of Strings
- Relative paths to Budget Directories (
.ynab4
folders)
-
formatVersion
- String
- YMeta (??) file format version
-
relativeDataFolderName
- String
- Active Data Folder
-
TED
- Number
- ??
-
masterCategories
- Array of Objects (referred to as
masterCategory
)-
entityType
- String [
masterCategory
] - Defines the type of entity
- String [
-
expanded
- Boolean
-
name
- String
- Category Name
-
type
- String
- Type of Category, Looks to be "OUTFLOW" for all of mine
-
deleteable
- Boolean
- Whether the category can be deleted or not (False means this is Required for the App to function)
-
subCategories
- Array of Objects (referred to as
category
)-
entityType
- String [
category
]
- String [
-
note
- String, Optional
-
name
- String
- When the Master Category is
__Hidden__
, the name has a special format.
-
cachedBalance
- Number
-
masterCategoryId
- String
-
isTombstone
- Boolean
- Deleted?
-
entityVersion
- String
-
isResolvedConflict
- Boolean
-
entityId
- String
-
sortableIndex
- Number
-
-
entityVersion
- String
-
entityId
- String
-
sortableIndex
- Number
- Array of Objects (referred to as
-
- Array of Objects (referred to as
-
payees
- Array of Objects (referred to as
payee
)
- Array of Objects (referred to as
-
monthlyBudgets
- Array of Objects (referred to as
monthlyBudget
)
- Array of Objects (referred to as
-
fileMetaData
- Object
-
entityType
- String [
fileMetaData
] - Defines the type of entity
- String [
-
budgetDataVersion
- String
- YFull (??) file format version number
-
currentKnowledge
- String
- CSV format defining the known data entries for each version.
-
- Object
-
transactions
- Array of Objects (referred to as
transaction
)
- Array of Objects (referred to as
-
scheduledTransactions
- Array of Objects (referred to as
scheduledTransaction
)
- Array of Objects (referred to as
-
accountMappings
- Array of Objects (referred to as
accountMapping
)-
entityType
- String [
accountMapping
]
- String [
-
skipImport
- Boolean
- ??
-
hash
- String
- Base64 encoded hash result (likely SHA256, given the decoded length is 256-bits)
-
fid
- String
- ??
-
dateSequence
- ?? (mine was
null
) - ??
- ?? (mine was
-
shortenedAccountId
- String
- ?? (other than what the name says, it's
-S90
in mine...)
-
shouldFlipPayeesMemos
- Boolean
- ??
-
salt
- String
- Looks like a 256-bit salt for the hash I suspect.
-
targetYNABAccountId
- String
- GUID for the account that it updates.
-
shouldImportMemos
- Boolean
- ??
-
entityVersion
- String
- [DEVICE]-[LASTENTRYID] format. I am guessing this might be the version state on the device when imported. I am going to guess this whole object is related to data import from CSV/QBF/etc for reconciling.
-
entityId
- String
- A GUID for referring to this entity
-
- Array of Objects (referred to as
-
budgetMetaData
- Object
-
entityType
- String [
budgetMetaData
]
- String [
-
strictBudget
- String
- Boolean value of whether this budget is strict or not.
-
currencyISOSymbol
- ?? (this is
null
in my file, but I am guessing it defines the Symbol for non-USD currencies)
- ?? (this is
-
entityVersion
- String
- [DEVICE]-[LASTENTRYID] format. Mine is just
A-0
, so I am not sure of the point of this.
-
currencyLocale
- String
- The locale for the currency (mine is
en_US
). Looks likeen_GB
for Pound Sterling.
-
budgetType
- String
- Setting between "Personal/Family" and "Small Business", which I suspect is
Personal
andBusiness
respectively.
-
dateLocale
- String
- Date format, mine is
en_US
, others areen_GB
-
entityId
- String
- All examples I have seen (a whole 2) this is just
A2
.
-
- Object
-
accounts
- Array of Objects
-
entityType
- String [
account
]
- String [
-
lastReconciledDate
- String
- Date of the last time the account was reconciled
-
lastEnteredCheckNumber
- Number
-
-1
for never entered, otherwise the number
-
lastReconciledBalance
- Number
- Balance when last reconciled. This makes it a source of truth (instead of needing to calculate backwards)
-
accountType
- String
- "Cash", "Savings", "Checking", etc Defines the account type. I suspect special sauce is added depending on the type. Will need to enumerate the options.
-
hidden
- Boolean
- Whether or not the account is hidden in the UI
-
sortableIndex
- Number
- ??, maybe a UX thing
-
onBudget
- Boolean
- Whether or not this account affects the budget and requires Category when transactions are placed against it.
-
accountName
- String
- Displayed name for the account
-
entityVersion
- String
- [DEVICE]-[LASTENTRYID] format. Looks like it might be the update state.
-
entityId
- String
- Unique GUID for representing the entity.
-
- Array of Objects
-
deviceGUID
- String
- Unique Identifier representing the Device
-
YNABVersion
- String
- Version string of the YNAB client
-
shortDeviceId
- String
- Character representation of the device (seems to be A, B, C, etc.)
-
formatVersion
- String
- YDevice (??) file format version
-
deviceType
- String
- Complex String providing details about the device (e.g. iPhone, Desktop, Android). Some more detailed than others
-
highestDataVersionImported
- String
- ??
-
friendlyName
- String
- Hostname of the device
-
knowledgeInFullBudgetFile
- String
- CSV string of data versions for each device in the format of (DEVICE)-(LASTENTRYID)[,(DEVICE)-(LASTENTRYID)]. This is
null
whenhasFullKnowledge
isfalse
.
-
hasFullKnowledge
- Boolean
- Seems to represent if the device is capable of full knowledge. Desktops are, mobile devices seem to not have full knowledge. This might be a feature thing where if you were to pay for the mobile app maybe you got full features in the app?
-
lastDataVersionFullyKnown
- String
- ?? (I'm beginning to suspect this might be the Version of the YFull file format, I guess I will learn more when I get to understanding more of the YFull format).
-
knowledge
- String
- Same format as
knowledgeInFullBudgetFile
, but seems to exist regardless ofhasFullKnowledge
.