HD Grain Database Format
Grain Bill Estimator JSON Format
This page documents the JSON format used by the HD Grain Bill Estimator ingredient database.
The JSON database defines fermentables, grains, extracts, sugars, syrups, enzymes, and process aids used by the calculator. Each entry describes not only display information, but also how the ingredient behaves in calculations such as:
- gravity contribution
- mash efficiency handling
- conversion warnings
- maltster substitution
- ingredient grouping
- notes and guidance display
Overview
The grain bill estimator loads ingredient data from a wiki page containing raw JSON. The JSON must be an array of objects.
Each object represents one ingredient.
Example top-level structure:
[
{
"key": "corn_cracked",
"label": "Corn, Cracked",
"maltster": "Generic",
"ppg": 37,
"ppg_low": 35,
"ppg_high": 39,
"category": "Adjunct Grain",
"base_fermentable": "corn",
"fermentable_source_type": "grain",
"efficiency_class": "mash",
"requires_conversion": true,
"provides_diastatic_power": false,
"notes": "Common cracked corn used in bourbon-style mash bills.",
"guidance": "Requires cooking/gelatinization and a source of enzymatic conversion."
}
]Required Structure
Each ingredient entry should follow this structure:
{
"key": "unique_machine_key",
"label": "Human Readable Label",
"maltster": "Generic",
"ppg": 37,
"ppg_low": 35,
"ppg_high": 39,
"category": "Adjunct Grain",
"base_fermentable": "corn",
"fermentable_source_type": "grain",
"efficiency_class": "mash",
"requires_conversion": true,
"provides_diastatic_power": false,
"notes": "Short ingredient notes.",
"guidance": "Practical usage guidance."
}Field Reference
key
Machine-readable unique identifier.
- Must be unique across the entire database.
- Used internally by the estimator, examples, saved preferences, and maltster substitution logic.
- Should be lowercase with underscores.
- Should remain stable once published.
Examples:
"key": "corn_cracked"
"key": "barley_2row_malted"
"key": "molasses_blackstrap"
"key": "rahr_pale_ale_malt"Recommended style:
- lowercase only
- words separated by underscores
- no spaces
- no punctuation other than underscores
label
Human-readable ingredient name shown in the UI.
This is what users see in the ingredient dropdown.
Examples:
"label": "Corn, Cracked"
"label": "Barley, 2-Row Malted"
"label": "Molasses (Blackstrap)"
"label": "Rahr Pale Ale Malt"Recommended style:
- clear and readable
- include form/type if relevant
- include maltster branding when appropriate
maltster
Defines the maltster or ingredient source grouping.
Used for:
- maltster filtering
- ingredient substitution when a user chooses a maltster
- sorting/grouping behavior in the ingredient selector
Typical values:
"maltster": "Generic"
"maltster": "Briess"
"maltster": "Weyermann"
"maltster": "Simpsons"
"maltster": "Crisp"
"maltster": "Rahr"Guidelines:
- Use `"Generic"` for non-brand-specific ingredients and baseline entries.
- Use a specific maltster name only when the entry represents a real branded product.
- Generic ingredients remain important even when maltster-specific versions exist.
ppg
Primary points-per-pound-per-gallon value used by the estimator.
This is the nominal gravity potential used in calculations.
Examples:
"ppg": 37
"ppg": 44
"ppg": 0Interpretation:
- grains and mashables typically use values in the low-to-high 30s
- extracts and sugars typically use higher direct values
- enzymes and non-fermentable process aids should use `0`
ppg_low
ppg_high
Optional low and high gravity-potential range values.
Used to estimate:
- gravity range
- OG range
- ABV range
Examples:
"ppg_low": 35,
"ppg_high": 39Rules:
- If omitted, the estimator will fall back to `ppg`.
- If present, they should represent a realistic practical range for that ingredient.
- `ppg_low` should be less than or equal to `ppg`.
- `ppg_high` should be greater than or equal to `ppg`.
Recommended usage:
- Use ranges where the real-world extract potential varies meaningfully.
- For enzymes and process aids, use `0` / `0`.
category
Category controls ingredient grouping in the dropdown UI and helps with replacement logic.
Common categories currently used:
"category": "Base Malt"
"category": "Specialty Malt"
"category": "Roasted Malt"
"category": "Adjunct Grain"
"category": "Sugar / Syrup"
"category": "Extract"
"category": "Processing Aid"
"category": "Other"Guidelines:
- Keep category names consistent.
- Avoid inventing near-duplicates unless the calculator logic is updated to support them.
- Categories affect sorting and substitution heuristics.
base_fermentable
Normalized underlying fermentable family.
This field is extremely important for:
- maltster substitution
- finding “best replacement” ingredients
- preserving conceptual equivalence when switching maltsters
Examples:
"base_fermentable": "barley"
"base_fermentable": "corn"
"base_fermentable": "rye"
"base_fermentable": "wheat"
"base_fermentable": "oats"
"base_fermentable": "rice"
"base_fermentable": "sugarcane"
"base_fermentable": "sorghum"
"base_fermentable": "enzyme"
"base_fermentable": "process_liquid"Guidelines:
- Use broad, normalized ingredient families.
- Keep values stable and consistent.
- Do not use labels or product names here.
This field is one of the main signals used to answer questions like:
- “If the user switches to Briess, what is the closest equivalent of this rye malt?”
- “If the ingredient is generic corn, should it remain generic?”
fermentable_source_type
Defines the overall source/behavior type of the ingredient.
Common values:
"fermentable_source_type": "grain"
"fermentable_source_type": "extract"
"fermentable_source_type": "processing_aid"Meaning:
- `grain`
- mashable or grain-based material
- may require conversion
- may or may not provide diastatic power
- `extract`
- direct fermentables such as sugar, syrup, molasses, DME, LME
- contributes gravity directly
- does not use mash efficiency in the same way as mash grains
- `processing_aid`
- enzymes, rice hulls, dunder/backset, and similar materials
- may affect process or notes
- should not directly contribute fermentable gravity unless intentionally modeled otherwise
This field strongly affects calculator behavior.
efficiency_class
Defines how the ingredient should be treated in gravity calculations.
Common values:
"efficiency_class": "mash"
"efficiency_class": "direct"Meaning:
- `mash`
- ingredient is subject to mash efficiency
- typical for grains and mash-converted ingredients
- `direct`
- ingredient contributes directly without mash efficiency reduction
- typical for sugars, syrups, extracts, and process aids that are not gravity-bearing grains
Examples:
"efficiency_class": "mash"
"efficiency_class": "direct"Typical usage:
- malted grain → `mash`
- flaked adjuncts → usually `mash`
- sugar → `direct`
- DME/LME → `direct`
- molasses → `direct`
- enzymes → `direct`
requires_conversion
Boolean field indicating whether the ingredient requires enzymatic conversion.
Examples:
"requires_conversion": true
"requires_conversion": falseUse `true` for ingredients that contain starch and require enzymatic conversion, such as:
- unmalted grains
- flaked grains
- many cereal adjuncts
- crush-and-cook grains without self-conversion
Use `false` for:
- sugars
- extracts
- syrups
- already-converted materials
- process aids
This field contributes to conversion-warning logic.
provides_diastatic_power
Boolean field indicating whether the ingredient can provide enzymatic conversion power.
Examples:
"provides_diastatic_power": true
"provides_diastatic_power": falseUse `true` for:
- most malted base malts
- high-diastatic malts
- distillers malts that are intended to provide conversion
Use `false` for:
- unmalted grains
- sugars
- extracts
- syrups
- roasted grains without meaningful DP
- process aids unless the calculator logic is intentionally modeling them differently
This field is used by the estimator’s warning logic to flag bills that may not self-convert.
notes
Short descriptive notes about the ingredient.
These are shown to the user in the ingredient notes section.
Examples:
"notes": "Medium molasses with moderate sugar content and richer flavor."
"notes": "Raw sorghum grain requiring cooking/conversion support for starch extraction."Recommended usage:
- 1 short sentence
- factual description
- avoid duplicating guidance
guidance
Practical user guidance for the ingredient.
Examples:
"guidance": "Commonly used in rum and other molasses-based fermentations."
"guidance": "Use with an enzyme source or highly diastatic malt."Recommended usage:
- brief practical advice
- usage caveats
- process implications
- recipe-role hints
This field is especially valuable for:
- unusual ingredients
- process aids
- grains requiring conversion
- flavor-heavy syrups and sugars
Common Ingredient Types
Mash grains
Typical profile:
{
"fermentable_source_type": "grain",
"efficiency_class": "mash",
"requires_conversion": true,
"provides_diastatic_power": true
}Used for:
- base malts
- malted grains
- mash-converted ingredients
Adjunct grains requiring help
Typical profile:
{
"fermentable_source_type": "grain",
"efficiency_class": "mash",
"requires_conversion": true,
"provides_diastatic_power": false
}Used for:
- raw grains
- flaked grains
- cereal adjuncts
- grains that need enzymes or malt support
Sugars, syrups, extracts
Typical profile:
{
"fermentable_source_type": "extract",
"efficiency_class": "direct",
"requires_conversion": false,
"provides_diastatic_power": false
}Used for:
- white sugar
- brown sugar
- molasses
- honey
- DME
- LME
- syrup ingredients
Enzymes and process aids
Typical profile:
{
"fermentable_source_type": "processing_aid",
"efficiency_class": "direct",
"requires_conversion": false,
"provides_diastatic_power": false,
"ppg": 0,
"ppg_low": 0,
"ppg_high": 0
}Used for:
- alpha amylase
- glucoamylase
- beta amylase
- high-temp alpha amylase
- dunder/backset
- rice hulls
Example Entries
Base malt example
{
"key": "barley_2row_malted",
"label": "Barley, 2-Row Malted",
"maltster": "Generic",
"ppg": 37,
"ppg_low": 36,
"ppg_high": 38,
"category": "Base Malt",
"base_fermentable": "barley",
"fermentable_source_type": "grain",
"efficiency_class": "mash",
"requires_conversion": true,
"provides_diastatic_power": true,
"notes": "General-purpose 2-row malted barley.",
"guidance": "Use as a versatile base malt in mash bills."
}Sugar example
{
"key": "sugar_white",
"label": "Sugar, White",
"maltster": "Generic",
"ppg": 46,
"ppg_low": 46,
"ppg_high": 46,
"category": "Sugar / Syrup",
"base_fermentable": "sugarcane",
"fermentable_source_type": "extract",
"efficiency_class": "direct",
"requires_conversion": false,
"provides_diastatic_power": false,
"notes": "Refined white sugar.",
"guidance": "Direct fermentable; commonly used in sugarheads and wash adjustment."
}Molasses example
{
"key": "molasses_blackstrap",
"label": "Molasses (Blackstrap)",
"maltster": "Generic",
"ppg": 28,
"ppg_low": 26,
"ppg_high": 30,
"category": "Sugar / Syrup",
"base_fermentable": "sugarcane",
"fermentable_source_type": "extract",
"efficiency_class": "direct",
"requires_conversion": false,
"provides_diastatic_power": false,
"notes": "Blackstrap molasses with lower sugar content and high mineral content.",
"guidance": "Use for strong flavor contribution; often blended with sugar or lighter molasses."
}Process aid example
{
"key": "alpha_amylase_enzyme",
"label": "Alpha Amylase (Enzyme)",
"maltster": "Generic",
"ppg": 0,
"ppg_low": 0,
"ppg_high": 0,
"category": "Processing Aid",
"base_fermentable": "enzyme",
"fermentable_source_type": "processing_aid",
"efficiency_class": "direct",
"requires_conversion": false,
"provides_diastatic_power": false,
"notes": "Enzyme process aid used during conversion.",
"guidance": "Does not directly contribute fermentable gravity."
}Maltster-Specific Entries
Maltster-specific entries should be represented as separate ingredient objects, not as aliases.
Example:
{
"key": "rahr_2row_malt",
"label": "Rahr 2-Row Malt",
"maltster": "Rahr",
"ppg": 37,
"ppg_low": 36,
"ppg_high": 38,
"category": "Base Malt",
"base_fermentable": "barley",
"fermentable_source_type": "grain",
"efficiency_class": "mash",
"requires_conversion": true,
"provides_diastatic_power": true,
"notes": "North American 2-row base malt with clean, neutral profile.",
"guidance": "Use as a general-purpose base malt."
}Best practice:
- Keep a Generic version when appropriate.
- Add branded/maltster entries only when the product is meaningfully distinct or useful to users.
- Use consistent `base_fermentable`, `category`, and `fermentable_source_type` values so substitution logic works properly.
Examples and Key Stability
The calculator’s example recipes depend on ingredient keys.
This means:
- Example definitions reference ingredient entries by `key`
- Renaming a key can break examples
- Removing a key can cause fallback behavior or undesirable substitutions
Therefore:
- Do not rename existing keys casually.
- If a label needs improving, prefer changing `label` rather than `key`.
- If replacing an ingredient, update example recipes accordingly.
Substitution Logic Considerations
The estimator uses ingredient metadata to make “best replacement” decisions when a user selects a maltster.
Fields especially important for substitution quality:
- `maltster`
- `base_fermentable`
- `category`
- `fermentable_source_type`
To improve replacement accuracy:
- keep generic adjuncts/sugars available
- keep base fermentable naming normalized
- avoid overloading categories with inconsistent labels
- keep branded base malts mapped to the same normalized fermentable family as their Generic equivalents
Validation / Best Practices
Before saving new JSON entries, verify:
- `key` is unique
- `label` is clear
- `ppg` is numeric
- `ppg_low` and `ppg_high` are numeric if used
- `ppg_low <= ppg <= ppg_high`
- booleans are proper JSON booleans (`true` / `false`)
- commas and quotes are valid JSON
- category names match existing categories
- `base_fermentable` is normalized and consistent
- `efficiency_class` is correct for the ingredient type
- `requires_conversion` and `provides_diastatic_power` reflect real behavior
Common Mistakes
Using the wrong key in example recipes
Bad:
{ "key": "molasses" }If no such key exists, the estimator may fall back to an unrelated ingredient.
Correct approach:
{ "key": "molasses_medium" }Treating sugars like mash grains
Sugars and syrups should generally use:
"efficiency_class": "direct"not:
"efficiency_class": "mash"Giving enzymes gravity points
Enzymes and process aids should generally use:
"ppg": 0unless the estimator is intentionally modeling them as gravity-bearing materials.
Inconsistent fermentable family naming
Bad:
"base_fermentable": "2-row barley"
"base_fermentable": "barley 2 row"
"base_fermentable": "barley"Better:
"base_fermentable": "barley"Recommended Naming Conventions
Generic ingredients
Use labels like:
- `Corn, Cracked`
- `Barley, 2-Row Malted`
- `Rye, Unmalted`
- `Molasses (Medium)`
Maltster-specific ingredients
Use labels like:
- `Briess Rye Malt`
- `Weyermann Pilsner Malt`
- `Crisp Best Ale Malt`
- `Rahr Pale Ale Malt`
Processing aids
Use labels like:
- `Alpha Amylase (Enzyme)`
- `High Temp Alpha Amylase (Enzyme)`
- `Dunder / Backset (Non-fermentable contribution)`
Change Management
When adding new ingredients:
- Add the new JSON entry
- Confirm it parses
- Verify it appears in the ingredient selector
- Verify category grouping is correct
- Verify notes/guidance render properly
- Verify examples still behave correctly
- Verify maltster switching still works sensibly
When adding a maltster-specific entry:
- Confirm the product is real and distinct
- Use a stable unique key
- Normalize `base_fermentable`
- Keep category consistent with its Generic equivalent
- Verify substitution behavior with example recipes