Breww recipe files allow you to share recipes between Breww accounts or edit recipe definitions outside of Breww using any text editor. The files use the YAML format (.breww-recipe.yaml) and contain a complete description of a recipe's stages, actions, input variables, and calculated variables.
This is particularly useful for:
- Sharing recipes between different Breww accounts (e.g. between brewery locations or with contract brewing partners)
- Backing up recipes in a human-readable format
- Editing recipes in bulk using a text editor before importing them
- Creating recipes programmatically from external tools or spreadsheets
Renamed: What used to be called reporting tags are now input variables, and calculated fields are now calculated variables. The Breww recipe file format has been updated to use the new key names (input_variables, calculated_variables, input_variable_name, calculated_variable_name). The old key names (reporting_tags, calculated_fields, reporting_tag_name, calculated_field_name) are still accepted on import for backwards compatibility, so existing recipe files will continue to work — but they're deprecated and exports now always use the new names. We recommend updating any recipe files you maintain to use the new names.
Exporting a recipe
You can export any recipe as a Breww recipe file from its detail page.
- Navigate to the recipe you want to export (via
Production->View->Recipes, then select the recipe) - Click the Actions & tools button in the page header
- Select Export as Breww recipe file
This will download a .breww-recipe.yaml file containing the recipe's current version. The file is named using the pattern Recipe Name - v1.breww-recipe.yaml.
You can also export a specific version of a recipe by navigating to that version's detail page (via Actions & tools -> View version history on the recipe, then selecting the version) and using the same Export as Breww recipe file option.
The exported file will contain:
- Recipe details (name, beer name, batch size, brewhouse efficiency, expected wastage)
- All stages with their type, category, duration, and settings
- All actions within each stage (ingredients, readings, temperature changes, checks, etc.), including any targets and threshold bands defined on reading or calculation actions
- Any input variables referenced by actions in the recipe
- Any calculated variables referenced by actions in the recipe (including their measurement type)
Importing a recipe
To import a Breww recipe file, head to Production -> View -> Recipes and click either:
- New recipe -> Import from Breww recipe file, or
- The Import Breww recipe file button on the new recipe page
The import process uses a multi-step wizard to guide you through the process.
Step 1: Upload file
Select the .breww-recipe.yaml file you wish to import. Breww will validate the file structure and report any errors found in the file.
Note: Breww recipe files can be opened and edited with any text editor. For a better experience, we recommend Visual Studio Code (free, Windows/Mac/Linux) which provides syntax highlighting and formatting for YAML files.
Step 2: Recipe details
Confirm or adjust the basic recipe details parsed from the file:
- Recipe name - Pre-filled from the file. Must be unique within your account.
- Beer - If the file contains a
beer_nameand a beer with a matching name exists in your account, it will be pre-selected. You can change this or leave it blank (you can link the recipe to a beer later). - Batch size - Pre-filled from the file, converted to your account's production volume unit.
- Brewhouse efficiency - Pre-filled from the file if specified.
- Expected wastage - Pre-filled from the file if specified.
Step 3: Stock item mapping
For each ingredient referenced in the recipe file, you need to map it to a stock item in your Breww account. Breww will automatically attempt to match ingredients by name:
- Exact match found (green badge) - The ingredient name in the file exactly matches a stock item name in your account.
- Similar match found (amber badge) - A stock item with a very similar name was found. Check that this is the correct item.
- No match found (red badge) - No matching stock item could be found. You will need to manually select the correct stock item from the dropdown.
Breww will also validate that the unit type of the selected stock item is compatible with the unit used in the recipe file (e.g. you cannot map a recipe ingredient specified in kilograms to a stock item tracked in litres).
If the recipe does not contain any ingredient additions, this step will be skipped.
Step 4: Stage type mapping
For each stage type used in the recipe, you need to map it to a stage type in your Breww account. Breww will automatically match stage types by name within the same category (e.g. Brewing, Fermenting).
- Exact match found (green badge) - A stage type with the same name and category already exists in your account.
- New stage type will be created (blue badge) - No matching stage type was found. If you leave the field blank, a new stage type will be created automatically with the name and category from the file.
You can also select a different existing stage type from the dropdown if you prefer.
Step 5: Input variables and calculated variables
This step only appears if the recipe file includes input variables or calculated variables.
For each input variable and calculated variable defined in the file:
- If a matching variable already exists in your account, it will show as Use existing and no action is needed.
- If no match exists, you can choose to Create it in your account or Ignore from recipe (which will skip any actions that reference it).
Step 6: Review
The final step shows a summary of the import, including:
- Recipe name, beer, and batch size
- Total number of stages and actions
- Stock item mappings
- Stage type mappings
- Input variable and calculated variable actions
Review the summary and click Import recipe to create the recipe. The imported recipe will be created as a draft version, ready for you to review and tweak.
Breww recipe file format reference
A Breww recipe file is a YAML document with four top-level sections: recipe, stages, input_variables, and calculated_variables. Only recipe and stages are required.
Here is a minimal example:
recipe:
name: Simple Pale Ale
batch_size: 1000 l
stages:
- name: Mash
type:
name: Single Infusion Mash
category: brewing
actions:
- type: add_ingredient
trigger:
type: start_of_stage
stock_item_name: Pale Malt
quantity: 200 kg
The recipe section
The recipe section defines the top-level recipe details.
| Field | Required | Description |
|---|---|---|
name |
Yes | The recipe name. |
beer_name |
No | The name of the beer this recipe is for. Used to auto-match to a beer in your account during import. |
batch_size |
Yes | The batch size as a quantity with a unit (e.g. 1000 l, 30 bbl, 10 hl). See the units section for supported units. |
brewhouse_efficiency |
No | Brewhouse efficiency as a percentage value (e.g. 75 for 75%). |
expected_wastage |
No | Expected wastage as a quantity with a unit (e.g. 5 l, 0.5 bbl). |
The stages section
The stages section is a list of recipe stages in order. Each stage represents a phase of the brewing process (e.g. Mash, Boil, Fermentation).
| Field | Required | Default | Description |
|---|---|---|---|
name |
Yes | The display name for this stage. | |
type |
Yes | An object containing name (stage type name) and category (see below). |
|
duration |
No | The duration of this stage (e.g. 1 hour, 7 days, 1 hour 30 minutes). See durations. |
|
repeated_per_turn |
No | false |
Whether this stage is repeated for each turn in a multi-turn batch. |
auto_allocate_stock |
No | true |
Whether to auto-allocate stock for ingredient additions in this stage. |
include_in_pre_allocate_stock |
No | true |
Whether to include this stage's ingredients in pre-allocation when starting a batch. |
actions |
No | [] |
A list of actions to perform during this stage. |
Stage type categories
Each stage type must belong to one of these categories:
| Category value | Description |
|---|---|
preparation |
Preparation stages (e.g. water treatment, starter preparation). |
brewing |
Brewing stages (e.g. mash, boil, whirlpool). |
fermenting |
Fermentation stages (e.g. primary fermentation, secondary fermentation). |
post_fermentation |
Post-fermentation stages (e.g. conditioning, dry hopping). |
Actions
Each stage can contain a list of actions. Every action must have a type field and a trigger field. The type determines what kind of action it is, and the trigger determines when it should happen.
All action types support an optional notes field for additional free-text notes.
Action type: add_ingredient
Adds a stock item (ingredient) to the brew.
| Field | Required | Description |
|---|---|---|
stock_item_name |
Yes | The name of the ingredient (mapped to a stock item during import). |
quantity |
Yes | The quantity to add, with a unit (e.g. 200 kg, 500 g, 2 units). |
ingredient_attributes |
No | A dictionary of attribute names and their decimal values (e.g. {alpha_acid: 5.5}). |
adjust_quantity_by_attribute |
No | The name of an attribute to use for automatic quantity adjustment (e.g. alpha_acid for hop additions). |
notes |
No | Additional notes for this action. |
Action type: add_water
Adds water to the brew.
| Field | Required | Description |
|---|---|---|
quantity |
Yes | The volume of water to add, with a unit (e.g. 100 l, 750 ml). |
notes |
No | Additional notes for this action. |
Action type: reading
Records a reading (e.g. gravity, temperature, pH).
| Field | Required | Description |
|---|---|---|
reading_type |
Yes | The type of reading. Must be one of: temperature, ph, gravity, time, weight, volume, custom. |
reading_unit |
No | The unit for the reading (e.g. SG, plato, brix, c, f, ph, l, kg). Only needed when target and thresholds values do not include a unit suffix. See specifying units on reading values below. |
target |
No | The target value for this reading (e.g. "1.050 SG", "65 °C", "5.4 pH"). When set, brewers see the target on the brew sheet, and any deviation can produce a warning or alert via the optional thresholds block. For time readings, the target is an HH:MM:SS string (e.g. "01:30:00"). |
expected_value |
No | Legacy alias for target — accepted on import for backwards compatibility with older recipe files. Exports always use target. We recommend updating any maintained recipe files to use target. |
thresholds |
No | An optional threshold block defining acceptable and/or warning ranges for the reading. Values outside acceptable show a warning, and values outside warning show an alert on the brew sheet. |
copy_to_batch_readings |
No | Set to true to copy this reading to the batch's analysis tab. Defaults to false. |
input_variable_name |
No | The variable name of an input variable to associate with this reading. Must be defined in the input_variables section or already exist on your account. The legacy alias reporting_tag_name is also accepted for backwards compatibility. |
custom_reading_name |
No | A custom name for this reading (only used when reading_type is custom). |
notes |
No | Additional notes for this action. |
Tip: For full background on what targets and threshold bands mean in Breww — including the difference between warnings and alerts, brewery-level defaults, and how thresholds are evaluated — see Deviation thresholds and targets.
Specifying units on reading values
For reading types that use units (temperature, gravity, ph, volume, weight), the unit must be provided. There are two ways to do this:
Approach 1: Include the unit in the value string (recommended)
The simplest approach is to include the unit directly in the value, e.g. "1.050 SG", "65 °C", "5.2 pH", "2350 l", "50 kg". This is the recommended approach because the unit is clear and self-contained.
# Target only:
- type: reading
trigger:
type: start_of_stage
reading_type: gravity
target: "1.050 SG"
# Target with an acceptable threshold range:
- type: reading
trigger:
type: start_of_stage
reading_type: gravity
target: "1.050 SG"
thresholds:
acceptable:
min: "1.045 SG"
max: "1.055 SG"
Approach 2: Use the reading_unit field
Alternatively, you can specify the unit separately using the reading_unit field and provide plain numeric values. This works for target and any thresholds ranges:
- type: reading
trigger:
type: start_of_stage
reading_type: ph
reading_unit: ph
target: "5.3"
thresholds:
acceptable:
min: "5.2"
max: "5.4"
Note: If you include units in the value strings and specify
reading_unit, the two must agree. For example, usingreading_unit: Platowithtarget: "1.050 SG"will produce an error.
When all values include a unit suffix, reading_unit is not needed. When values are plain numbers, reading_unit is required for reading types that use units.
All values within a single reading action — target and every thresholds.{band}.min / thresholds.{band}.max — must use the same unit. For example, you cannot mix "1.045 SG" and "10.5 Plato" in the same action.
Supported reading units
The following units are supported in reading values and the reading_unit field:
Temperature:
| Unit | Aliases |
|---|---|
°C |
C, celsius |
°F |
F, fahrenheit |
Gravity:
| Unit | Aliases |
|---|---|
SG |
sg |
Plato |
plato |
Brix |
brix |
pH:
| Unit | Aliases |
|---|---|
pH |
ph |
Volume:
| Unit | Aliases |
|---|---|
l |
litre, litres, liter, liters |
gal |
gallon, gallons |
bbl |
barrel, barrels |
imp_gal |
Weight:
| Unit | Aliases |
|---|---|
kg |
kilogram, kilograms |
lb |
lbs, pound, pounds |
time and custom reading types do not require a unit. time reading targets are written as HH:MM:SS strings (e.g. "01:30:00"), and their threshold ranges use signed offsets with a time unit — see Threshold blocks below.
Action type: change_temperature
Sets a target temperature.
| Field | Required | Description |
|---|---|---|
target |
Yes | The target temperature (e.g. 65 °C, 149 °F). The ° symbol is optional. |
notes |
No | Additional notes for this action. |
Action type: check
Adds a check (a yes/no verification step) to the brew sheet.
| Field | Required | Description |
|---|---|---|
check_to_make |
Yes | The description of what should be checked. |
input_variable_name |
No | The variable name of an input variable to associate with this check. The legacy alias reporting_tag_name is also accepted. |
notes |
No | Additional notes for this action. |
Action type: custom_instructions
Adds custom free-text instructions to the brew sheet.
| Field | Required | Description |
|---|---|---|
instructions |
Yes | The instruction text. |
notes |
No | Additional notes for this action. |
Action type: take_notes
Adds a note-taking prompt to the brew sheet.
| Field | Required | Description |
|---|---|---|
note_title |
Yes | The title/prompt for the notes. |
notes |
No | Additional notes for this action. |
Action type: calculation
Adds a calculated variable result to the brew sheet.
| Field | Required | Description |
|---|---|---|
calculated_variable_name |
Yes | The variable name of the calculated variable. Must be defined in the calculated_variables section or already exist on your account. The legacy alias calculated_field_name is also accepted. |
target |
No | The target value for the calculation result, as a plain number (e.g. "75"). Calculation targets and thresholds are always unit-less — never include a unit suffix. When set, a deviation from the target on the brew sheet can produce a warning or alert via the optional thresholds block. |
thresholds |
No | An optional threshold block defining acceptable and/or warning ranges. All min/max values must be plain numbers (no unit suffix). |
notes |
No | Additional notes for this action. |
Threshold blocks
Reading and calculation actions can include a thresholds block that defines the bands within which a measurement is considered acceptable or only mildly off-target. When a brewer enters a value on the brew sheet that falls outside these bands, Breww will display a warning or an alert.
For the full feature overview — including the difference between warnings and alerts, brewery-level defaults, and how thresholds are evaluated against readings — see Deviation thresholds and targets.
Structure
A thresholds block has up to two bands — acceptable and warning — and at least one must be defined. Each band has a min and a max:
thresholds:
acceptable:
min: "<lower bound>"
max: "<upper bound>"
warning:
min: "<lower bound>"
max: "<upper bound>"
- A reading inside the
acceptableband is fine. - A reading outside
acceptablebut insidewarningshows a warning on the brew sheet. - A reading outside
warningshows an alert on the brew sheet.
You can define just acceptable, just warning, or both. If only acceptable is given, anything outside it shows an alert. If only warning is given, anything outside it shows an alert and there's no warning band in between.
[Screenshot needed: brew sheet showing a reading with an acceptable band, a warning band, and an alert state]
Units on threshold values (non-time reading actions)
For non-time reading types (temperature, gravity, ph, volume, weight), each min and max is written as an absolute value with a unit suffix — exactly the same way target is written. All values within the action — target and every thresholds.{band}.min / thresholds.{band}.max — must use the same unit. Mixing units within a single action (for example a target in SG and a threshold in Plato) will produce an import error.
Example — gravity reading with both an acceptable and a warning band:
- type: reading
trigger:
type: start_of_stage
reading_type: gravity
target: "1.050 SG"
thresholds:
acceptable:
min: "1.045 SG"
max: "1.055 SG"
warning:
min: "1.040 SG"
max: "1.060 SG"
Example — temperature reading using °C:
- type: reading
trigger:
type: start_of_stage
reading_type: temperature
target: "19 °C"
thresholds:
acceptable:
min: "18.5 °C"
max: "19.5 °C"
warning:
min: "18 °C"
max: "20 °C"
Units on threshold values (time reading actions)
time readings work slightly differently because the target is an HH:MM:SS string rather than a value+unit. Threshold min and max values for time readings are written as signed offsets with a time unit (second, minute, hour, or day):
- type: reading
trigger:
type: start_of_stage
reading_type: time
target: "01:30:00"
thresholds:
acceptable:
min: "-5 minutes"
max: "10 minutes"
In this example, the reading is acceptable from 5 minutes before the target up to 10 minutes after.
Calculation thresholds (unit-less)
Calculation actions are always unit-less. The target, and every min / max in the thresholds block, must be a plain number with no unit suffix:
- type: calculation
trigger:
type: start_of_stage
calculated_variable_name: apparent_attenuation
target: "75"
thresholds:
acceptable:
min: "70"
max: "80"
Including a unit suffix on a calculation target or thresholds value (e.g. "75 percent") will produce an import error.
[Screenshot needed: editing a reading or calculation action's target and thresholds in the recipe editor]
Triggers
Every action requires a trigger that determines when the action should occur during the stage. The trigger is an object with a type field and, for some types, additional fields.
Trigger type: start_of_stage
The action occurs at the start of the stage. No additional fields required.
trigger:
type: start_of_stage
Trigger type: immediately_after_previous_action
The action occurs immediately after the previous action in the stage completes. No additional fields required.
trigger:
type: immediately_after_previous_action
Trigger type: time_after_previous_action
The action occurs a specified time after the previous action completes.
| Field | Required | Description |
|---|---|---|
duration |
Yes | The delay after the previous action (e.g. 30 minutes, 1 hour). |
trigger:
type: time_after_previous_action
duration: 30 minutes
Trigger type: time_before_end_of_stage
The action occurs a specified time before the end of the stage.
| Field | Required | Description |
|---|---|---|
duration |
Yes | The time before the end of stage (e.g. 15 minutes, 1 hour). |
trigger:
type: time_before_end_of_stage
duration: 15 minutes
Trigger type: time_after_start_of_stage
The action occurs a specified time after the stage starts.
| Field | Required | Description |
|---|---|---|
duration |
Yes | The time after the start of the stage (e.g. 2 hours, 30 minutes). |
trigger:
type: time_after_start_of_stage
duration: 2 hours
Trigger type: on_fermentation_gravity_reading
The action is triggered when a gravity reading falls below a specified value.
| Field | Required | Description |
|---|---|---|
gravity_below |
Yes | The gravity threshold value (e.g. 1.010). |
gravity_unit |
Yes | The gravity unit (e.g. SG, plato, brix). |
trigger:
type: on_fermentation_gravity_reading
gravity_below: 1.010
gravity_unit: SG
Trigger type: end_of_stage
The action occurs at the end of the stage. No additional fields required.
trigger:
type: end_of_stage
Units on quantities
Quantity fields (such as batch_size, quantity on ingredients, and expected_wastage) must include a numeric value followed by a unit, separated by a space.
The following units are supported:
Mass units:
| Unit | Aliases |
|---|---|
kg |
kilogram, kilograms |
g |
gram, grams |
lb |
lbs, pound, pounds |
oz |
ounce, ounces |
Volume units:
| Unit | Aliases |
|---|---|
l |
litre, litres, liter, liters |
hl |
hectolitre, hectolitres, hectoliter, hectoliters |
ml |
millilitre, millilitres |
gal |
gallon, gallons |
bbl |
barrel, barrels |
fl oz |
floz |
Dimensionless units:
| Unit | Aliases |
|---|---|
unit |
units |
Examples: 200 kg, 500 g, 30 bbl, 1000 l, 2 units, 3.5 lb
When exporting, Breww uses the display unit configured for each stock item (for ingredients) or your account's production volume unit (for batch size and water additions).
Durations
Duration fields (such as stage duration and trigger duration) use natural language time expressions. Supported tokens are:
days/dayhours/hour/hrs/hrminutes/minute/mins/minseconds/second/secs/sec
Tokens can be combined: 1 hour 30 minutes, 2 days 4 hours.
Examples: 1 hour, 7 days, 30 minutes, 1 hour 30 minutes, 2 days 12 hours
Temperatures
Temperature values (in change_temperature target and reading target/threshold values for temperature readings) use the format:
<number> °C
<number> °F
The ° symbol is optional, and full words (celsius, fahrenheit) are also accepted. Examples: 65 °C, 149 °F, 65 C, 65 celsius.
The input_variables section
The input_variables section is an optional list of input variable definitions used by actions in the recipe. Each input variable is referenced by its variable_name from reading or check actions.
The legacy section name reporting_tags is still accepted on import for backwards compatibility, but exports always use input_variables. We recommend updating any existing recipe files you maintain to use input_variables.
| Field | Required | Description |
|---|---|---|
name |
Yes | The display name of the input variable. |
variable_name |
Yes | The unique variable name used to reference this input variable in actions and formulas. |
action_type |
Yes | The type of action this input variable applies to. Must be reading or check. |
reading_type |
No | Required when action_type is reading. Must be one of: temperature, ph, gravity, time, weight, volume, custom. |
Example:
input_variables:
- name: Original Gravity
variable_name: og_reading
action_type: reading
reading_type: gravity
- name: Clarity Check
variable_name: clarity_check
action_type: check
The calculated_variables section
The calculated_variables section is an optional list of calculated variable definitions. These are formulas that compute values from input variables (and other calculated variables) and are displayed on the brew sheet.
The legacy section name calculated_fields is still accepted on import for backwards compatibility, but exports always use calculated_variables. We recommend updating any existing recipe files you maintain to use calculated_variables.
| Field | Required | Description |
|---|---|---|
name |
Yes | The display name of the calculated variable. |
variable_name |
Yes | The unique variable name for this calculated variable (can be referenced in other formulas). |
formula |
Yes | The calculation formula, using input variable and calculated variable names. |
measurement_type |
No | The kind of value this calculation produces. One of temperature, gravity, ph, weight, volume, time, or unitless. Defaults to unitless when omitted. The measurement type controls how the calculated value is formatted on the brew sheet, and which unit is used when displaying any thresholds applied to the calculated variable. |
Example:
calculated_variables:
- name: Total Extract
variable_name: total_extract
formula: og_reading * batch_volume
measurement_type: unitless
- name: ABV Estimate
variable_name: abv_estimate
formula: (og_reading - fg_reading) * 131.25
measurement_type: unitless
- name: Mash Out Temperature
variable_name: mash_out_temp
formula: mash_temp + 10
measurement_type: temperature
Complete example
Here is a complete example showing all sections, action types, and trigger types:
recipe:
name: Full Test Recipe
beer_name: My Test Beer
batch_size: 500 l
brewhouse_efficiency: 75
expected_wastage: 5 l
stages:
- name: Preparation Stage
type:
name: Starter Prep
category: preparation
duration: 1 hour
repeated_per_turn: false
auto_allocate_stock: true
include_in_pre_allocate_stock: true
actions:
- type: add_ingredient
trigger:
type: start_of_stage
stock_item_name: Water Treatment
quantity: 10 g
ingredient_attributes:
alpha_acid: 5.5
adjust_quantity_by_attribute: alpha_acid
notes: Add carefully
- type: add_water
trigger:
type: immediately_after_previous_action
quantity: 100 l
- type: reading
trigger:
type: time_after_previous_action
duration: 30 minutes
reading_type: gravity
target: "1.050 SG"
thresholds:
acceptable:
min: "1.045 SG"
max: "1.055 SG"
warning:
min: "1.040 SG"
max: "1.060 SG"
copy_to_batch_readings: true
input_variable_name: og_reading
custom_reading_name: Original Gravity
- type: change_temperature
trigger:
type: time_before_end_of_stage
duration: 15 minutes
target: 65 °C
- type: check
trigger:
type: time_after_start_of_stage
duration: 45 minutes
check_to_make: Verify clarity
input_variable_name: clarity_check
- type: custom_instructions
trigger:
type: end_of_stage
instructions: Clean all equipment thoroughly
- type: take_notes
trigger:
type: time_after_start_of_stage
duration: 2 hours
note_title: Batch observations
- type: calculation
trigger:
type: start_of_stage
calculated_variable_name: total_extract
target: "1500"
thresholds:
acceptable:
min: "1450"
max: "1550"
- name: Fermentation
type:
name: Primary Fermentation
category: fermenting
duration: 7 days
repeated_per_turn: true
auto_allocate_stock: false
include_in_pre_allocate_stock: false
actions:
- type: reading
trigger:
type: start_of_stage
reading_type: temperature
input_variables:
- name: Original Gravity
variable_name: og_reading
action_type: reading
reading_type: gravity
- name: Clarity Check
variable_name: clarity_check
action_type: check
calculated_variables:
- name: Total Extract
variable_name: total_extract
formula: og_reading * batch_volume
measurement_type: unitless