@roastbook/open-coffee-schema 0.0.0-stage → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +65 -2
- package/brew-methods/latest.json +312 -0
- package/brew-methods/v0.1.0.json +265 -0
- package/brew-methods/v0.2.0.json +265 -0
- package/brew-methods/v0.3.0.json +272 -0
- package/brew-methods/v0.4.0.json +312 -0
- package/coffee-places/context.latest.json +246 -0
- package/coffee-places/context.v0.1.0.json +241 -0
- package/coffee-places/context.v0.3.0.json +246 -0
- package/coffee-places/context.v0.4.0.json +246 -0
- package/coffee-places/latest.json +577 -0
- package/coffee-places/v0.1.0.json +518 -0
- package/coffee-places/v0.2.0.json +518 -0
- package/coffee-places/v0.3.0.json +577 -0
- package/coffee-places/v0.4.0.json +577 -0
- package/common/latest.json +197 -0
- package/common/v0.1.0.json +192 -0
- package/common/v0.2.0.json +197 -0
- package/common/v0.3.0.json +197 -0
- package/common/v0.4.0.json +197 -0
- package/equipment/latest.json +895 -0
- package/equipment/v0.1.0.json +1122 -0
- package/equipment/v0.2.0.json +1122 -0
- package/equipment/v0.3.0.json +895 -0
- package/equipment/v0.4.0.json +895 -0
- package/index.d.ts +1114 -0
- package/index.js +94 -0
- package/package.json +67 -4
- package/schemas.d.ts +5 -0
- package/schemas.js +3 -0
package/schemas.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Generated by scripts/build-package.ts. Every schema version, keyed by $id. Do not edit.
|
|
2
|
+
export const schemas = {"https://schema.roastbook.coffee/brew-methods/brew-methods.schema.v0.1.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/brew-methods/brew-methods.schema.v0.1.0.json","title":"Open Coffee brew methods","description":"Ways of brewing coffee (espresso, pour-over, V60, AeroPress, cold brew…), their typical parameters and what a coffee journal should record for each. Methods form a tree: a device-specific method such as v60 has the general method pour-over as parent. Part of Roastbook Open Coffee.","type":"object","required":["$schema","meta","brew_methods"],"additionalProperties":false,"properties":{"$schema":{"type":"string","pattern":"^https://schema\\.roastbook\\.coffee/brew-methods/brew-methods\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$","description":"Canonical URL of the schema version this file follows."},"meta":{"type":"object","$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/dataset_meta","unevaluatedProperties":false},"brew_methods":{"type":"array","items":{"$ref":"#/$defs/brew_method"}}},"$defs":{"range":{"title":"Range","type":"object","additionalProperties":false,"minProperties":1,"properties":{"min":{"type":"number","minimum":0,"description":"Lowest common value, in the unit named by the parameter (for example grams for dose_g, degrees Celsius for water_temperature_celsius)."},"max":{"type":"number","minimum":0,"description":"Highest common value, in the unit named by the parameter."},"typical":{"type":"number","minimum":0,"description":"A good starting value, in the unit named by the parameter."}}},"parameter":{"title":"Brew parameter","enum":["dose_g","brew_water_g","yield_g","ratio","grind_setting","brew_time_seconds","target_time_seconds","water_temperature_celsius","bloom_time_seconds","bloom_water_g","preinfusion_time_seconds","preinfusion_pressure_bar","brew_pressure_bar","flow_rate_ml_per_second","tamp_force_kg","paper_filter_position","distribution_method","pour_count","steep_time_seconds"],"description":"Parameter keys shared with coffee journals such as Roastbook. ratio is brew water to coffee (16 means 1:16); for espresso it is yield to dose (2 means 1:2)."},"grind_size":{"title":"Grind size","enum":["extra_fine","fine","medium_fine","medium","medium_coarse","coarse","extra_coarse"],"description":"Descriptive grind size; extra_fine is Turkish, fine espresso, medium filter, coarse French press and cold brew."},"brew_method":{"title":"Brew method","type":"object","additionalProperties":false,"required":["id","name","category","extraction","description","checked_at"],"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/id","description":"Stable readable slug, e.g. v60, french-press. Never reused.","examples":["v60"]},"name":{"type":"string","minLength":1,"description":"Common English name of the method, for example Pour-over or French press."},"aliases":{"type":"array","uniqueItems":true,"items":{"type":"string","minLength":1},"description":"Other names in any language, e.g. Filterkaffee, drip."},"parent":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/id","description":"The more general method, e.g. pour-over for v60."},"category":{"enum":["espresso","filter","immersion","pressure","vacuum","boiling","cold"],"description":"Family used for grouping: espresso (9-bar style pressure), filter (percolation through a filter), immersion (steep, then separate), pressure (non-espresso pressure such as AeroPress or moka pot), vacuum (siphon), boiling (cezve/ibrik), cold (cold water over hours)."},"extraction":{"enum":["percolation","immersion","hybrid"],"description":"Physical principle; matches equipment brewer.mechanism."},"description":{"type":"string","minLength":20,"maxLength":600,"description":"Short neutral explanation in our own words."},"introduced_year":{"type":"integer","minimum":1000,"maximum":2100,"description":"Year the method or device was invented or first sold."},"origin_country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/country_code"},"equipment_types":{"type":"array","uniqueItems":true,"description":"Equipment types needed, from the equipment schema's type list.","items":{"$ref":"https://schema.roastbook.coffee/equipment/equipment.schema.v0.1.0.json#/$defs/type"}},"typical_parameters":{"title":"Typical parameters","type":"object","additionalProperties":false,"description":"Common starting ranges, not rules.","properties":{"dose_g":{"$ref":"#/$defs/range"},"ratio":{"$ref":"#/$defs/range"},"water_temperature_celsius":{"$ref":"#/$defs/range"},"brew_time_seconds":{"$ref":"#/$defs/range"},"brew_pressure_bar":{"$ref":"#/$defs/range"},"grind_size":{"type":"array","uniqueItems":true,"minItems":1,"items":{"$ref":"#/$defs/grind_size"}},"grind_d50_microns":{"$ref":"#/$defs/range","description":"Median particle size in micrometres, comparable across grinders."}}},"recorded_parameters":{"type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/parameter"},"description":"Parameters a coffee journal should offer when logging a brew with this method."},"typical_drinks":{"type":"array","uniqueItems":true,"items":{"type":"string","minLength":1},"description":"Drinks usually made with this method, in plain lowercase English, for example espresso, cappuccino or flat white."},"xref":{"type":"object","additionalProperties":false,"properties":{"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the method, for example Q180289 for espresso."},"beanconqueror":{"type":"string","pattern":"^[A-Z0-9_]+$","description":"Beanconqueror PREPARATION_TYPES key, for app imports."}},"description":"Identifiers of the method in other datasets and apps."},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/image"},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/datetime"},"filter_types":{"type":"array","uniqueItems":true,"items":{"enum":["paper","metal","cloth","none"]},"description":"Filters the method can use. paper: paper filters; metal: metal mesh or perforated metal; cloth: cloth filters; none: no filter (for example cezve or cold brew in a jar)."}}}}},"https://schema.roastbook.coffee/brew-methods/brew-methods.schema.v0.2.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/brew-methods/brew-methods.schema.v0.2.0.json","title":"Open Coffee brew methods","description":"Ways of brewing coffee (espresso, pour-over, V60, AeroPress, cold brew…), their typical parameters and what a coffee journal should record for each. Methods form a tree: a device-specific method such as v60 has the general method pour-over as parent. Part of Roastbook Open Coffee.","type":"object","required":["$schema","meta","brew_methods"],"additionalProperties":false,"properties":{"$schema":{"type":"string","pattern":"^https://schema\\.roastbook\\.coffee/brew-methods/brew-methods\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$","description":"Canonical URL of the schema version this file follows."},"meta":{"type":"object","$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/dataset_meta","unevaluatedProperties":false},"brew_methods":{"type":"array","items":{"$ref":"#/$defs/brew_method"}}},"$defs":{"range":{"title":"Range","type":"object","additionalProperties":false,"minProperties":1,"properties":{"min":{"type":"number","minimum":0,"description":"Lowest common value, in the unit named by the parameter (for example grams for dose_g, degrees Celsius for water_temperature_celsius)."},"max":{"type":"number","minimum":0,"description":"Highest common value, in the unit named by the parameter."},"typical":{"type":"number","minimum":0,"description":"A good starting value, in the unit named by the parameter."}}},"parameter":{"title":"Brew parameter","enum":["dose_g","brew_water_g","yield_g","ratio","grind_setting","brew_time_seconds","target_time_seconds","water_temperature_celsius","bloom_time_seconds","bloom_water_g","preinfusion_time_seconds","preinfusion_pressure_bar","brew_pressure_bar","flow_rate_ml_per_second","tamp_force_kg","paper_filter_position","distribution_method","pour_count","steep_time_seconds"],"description":"Parameter keys shared with coffee journals such as Roastbook. ratio is brew water to coffee (16 means 1:16); for espresso it is yield to dose (2 means 1:2)."},"grind_size":{"title":"Grind size","enum":["extra_fine","fine","medium_fine","medium","medium_coarse","coarse","extra_coarse"],"description":"Descriptive grind size; extra_fine is Turkish, fine espresso, medium filter, coarse French press and cold brew."},"brew_method":{"title":"Brew method","type":"object","additionalProperties":false,"required":["id","name","category","extraction","description","checked_at"],"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/id","description":"Stable readable slug, e.g. v60, french-press. Never reused.","examples":["v60"]},"name":{"type":"string","minLength":1,"description":"Common English name of the method, for example Pour-over or French press."},"aliases":{"type":"array","uniqueItems":true,"items":{"type":"string","minLength":1},"description":"Other names in any language, e.g. Filterkaffee, drip."},"parent":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/id","description":"The more general method, e.g. pour-over for v60."},"category":{"enum":["espresso","filter","immersion","pressure","vacuum","boiling","cold"],"description":"Family used for grouping: espresso (9-bar style pressure), filter (percolation through a filter), immersion (steep, then separate), pressure (non-espresso pressure such as AeroPress or moka pot), vacuum (siphon), boiling (cezve/ibrik), cold (cold water over hours)."},"extraction":{"enum":["percolation","immersion","hybrid"],"description":"Physical principle; matches equipment brewer.mechanism."},"description":{"type":"string","minLength":20,"maxLength":600,"description":"Short neutral explanation in our own words."},"introduced_year":{"type":"integer","minimum":1000,"maximum":2100,"description":"Year the method or device was invented or first sold."},"origin_country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/country_code"},"equipment_types":{"type":"array","uniqueItems":true,"description":"Equipment types needed, from the equipment schema's type list.","items":{"$ref":"https://schema.roastbook.coffee/equipment/equipment.schema.v0.2.0.json#/$defs/type"}},"typical_parameters":{"title":"Typical parameters","type":"object","additionalProperties":false,"description":"Common starting ranges, not rules.","properties":{"dose_g":{"$ref":"#/$defs/range"},"ratio":{"$ref":"#/$defs/range"},"water_temperature_celsius":{"$ref":"#/$defs/range"},"brew_time_seconds":{"$ref":"#/$defs/range"},"brew_pressure_bar":{"$ref":"#/$defs/range"},"grind_size":{"type":"array","uniqueItems":true,"minItems":1,"items":{"$ref":"#/$defs/grind_size"}},"grind_d50_microns":{"$ref":"#/$defs/range","description":"Median particle size in micrometres, comparable across grinders."}}},"recorded_parameters":{"type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/parameter"},"description":"Parameters a coffee journal should offer when logging a brew with this method."},"typical_drinks":{"type":"array","uniqueItems":true,"items":{"type":"string","minLength":1},"description":"Drinks usually made with this method, in plain lowercase English, for example espresso, cappuccino or flat white."},"xref":{"type":"object","additionalProperties":false,"properties":{"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the method, for example Q180289 for espresso."},"beanconqueror":{"type":"string","pattern":"^[A-Z0-9_]+$","description":"Beanconqueror PREPARATION_TYPES key, for app imports."}},"description":"Identifiers of the method in other datasets and apps."},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/image"},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/datetime"},"filter_types":{"type":"array","uniqueItems":true,"items":{"enum":["paper","metal","cloth","none"]},"description":"Filters the method can use. paper: paper filters; metal: metal mesh or perforated metal; cloth: cloth filters; none: no filter (for example cezve or cold brew in a jar)."}}}}},"https://schema.roastbook.coffee/brew-methods/brew-methods.schema.v0.3.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/brew-methods/brew-methods.schema.v0.3.0.json","title":"Open Coffee brew methods","description":"Ways of brewing coffee (espresso, pour-over, V60, AeroPress, cold brew…), their typical parameters and what a coffee journal should record for each. Methods form a tree: a device-specific method such as v60 has the general method pour-over as parent. Part of Roastbook Open Coffee.","type":"object","required":["$schema","meta","brew_methods"],"additionalProperties":false,"properties":{"$schema":{"type":"string","pattern":"^https://schema\\.roastbook\\.coffee/brew-methods/brew-methods\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$","description":"Canonical URL of the schema version this file follows."},"meta":{"type":"object","$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/dataset_meta","unevaluatedProperties":false},"brew_methods":{"type":"array","items":{"$ref":"#/$defs/brew_method"}}},"$defs":{"range":{"title":"Range","type":"object","additionalProperties":false,"minProperties":1,"properties":{"min":{"type":"number","minimum":0,"description":"Lowest common value, in the unit named by the parameter (for example grams for dose_g, degrees Celsius for water_temperature_celsius)."},"max":{"type":"number","minimum":0,"description":"Highest common value, in the unit named by the parameter."},"typical":{"type":"number","minimum":0,"description":"A good starting value, in the unit named by the parameter."}},"description":"A starting range. When several values are given they must be ordered: min ≤ typical ≤ max. JSON Schema cannot compare two values, so this repository checks it in its examples and data repositories check it in their data."},"parameter":{"title":"Brew parameter","enum":["dose_g","brew_water_g","yield_g","brew_ratio","yield_ratio","grind_setting","brew_time_seconds","target_time_seconds","water_temperature_celsius","bloom_time_seconds","bloom_water_g","preinfusion_time_seconds","preinfusion_pressure_bar","brew_pressure_bar","flow_rate_ml_per_second","tamp_force_kg","paper_filter_position","distribution_method","pour_count","steep_time_seconds"],"description":"Parameter keys shared with coffee journals such as Roastbook. brew_ratio is grams of brew water per gram of coffee (16 means 1:16); yield_ratio is grams of drink in the cup per gram of coffee (2 means a 1:2 espresso)."},"grind_size":{"title":"Grind size","enum":["extra_fine","fine","medium_fine","medium","medium_coarse","coarse","extra_coarse"],"description":"Descriptive grind size; extra_fine is Turkish, fine espresso, medium filter, coarse French press and cold brew."},"brew_method":{"title":"Brew method","type":"object","additionalProperties":false,"required":["id","name","category","extraction","description","checked_at"],"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/id","description":"Stable readable slug, e.g. v60, french-press. Never reused.","examples":["v60"]},"name":{"type":"string","minLength":1,"description":"Common English name of the method, for example Pour-over or French press."},"aliases":{"type":"array","uniqueItems":true,"items":{"type":"string","minLength":1},"description":"Other names in any language, e.g. Filterkaffee, drip."},"parent":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/id","description":"The more general method, e.g. pour-over for v60."},"category":{"enum":["espresso","filter","immersion","pressure","vacuum","boiling","cold"],"description":"Family used for grouping: espresso (9-bar style pressure), filter (percolation through a filter), immersion (steep, then separate), pressure (non-espresso pressure such as AeroPress or moka pot), vacuum (siphon), boiling (cezve/ibrik), cold (cold water over hours)."},"extraction":{"enum":["percolation","immersion","hybrid"],"description":"Physical principle; matches equipment brewer.mechanism."},"description":{"type":"string","minLength":20,"maxLength":600,"description":"Short neutral explanation in our own words."},"introduced_year":{"type":"integer","minimum":1000,"maximum":2100,"description":"Year the method or device was invented or first sold."},"origin_country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/country_code"},"equipment_types":{"type":"array","uniqueItems":true,"description":"Equipment types needed, from the equipment schema's type list.","items":{"$ref":"https://schema.roastbook.coffee/equipment/equipment.schema.v0.3.0.json#/$defs/type"}},"typical_parameters":{"title":"Typical parameters","type":"object","additionalProperties":false,"description":"Common starting ranges, not rules.","properties":{"dose_g":{"$ref":"#/$defs/range"},"brew_ratio":{"$ref":"#/$defs/range","description":"Grams of brew water per gram of coffee, for example 16 for 1:16. Used for filter, immersion and cold brew."},"yield_ratio":{"$ref":"#/$defs/range","description":"Grams of drink in the cup per gram of coffee, for example 2 for a 1:2 espresso. Used where the drink is weighed, mainly espresso."},"water_temperature_celsius":{"$ref":"#/$defs/range"},"brew_time_seconds":{"$ref":"#/$defs/range"},"brew_pressure_bar":{"$ref":"#/$defs/range"},"grind_size":{"type":"array","uniqueItems":true,"minItems":1,"items":{"$ref":"#/$defs/grind_size"}},"grind_d50_microns":{"$ref":"#/$defs/range","description":"Median particle size in micrometres, comparable across grinders."}}},"recorded_parameters":{"type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/parameter"},"description":"Parameters a coffee journal should offer when logging a brew with this method."},"typical_drinks":{"type":"array","uniqueItems":true,"items":{"type":"string","minLength":1},"description":"Drinks usually made with this method, in plain lowercase English, for example espresso, cappuccino or flat white."},"xref":{"type":"object","additionalProperties":false,"properties":{"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the method, for example Q180289 for espresso."},"beanconqueror":{"type":"string","pattern":"^[A-Z0-9_]+$","description":"Beanconqueror PREPARATION_TYPES key, for app imports."}},"description":"Identifiers of the method in other datasets and apps."},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/image"},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/datetime"},"filter_types":{"type":"array","uniqueItems":true,"items":{"enum":["paper","metal","cloth","none"]},"description":"Filters the method can use. paper: paper filters; metal: metal mesh or perforated metal; cloth: cloth filters; none: no filter (for example cezve or cold brew in a jar)."}}}}},"https://schema.roastbook.coffee/brew-methods/brew-methods.schema.v0.4.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/brew-methods/brew-methods.schema.v0.4.0.json","title":"Open Coffee brew methods","description":"Ways of brewing coffee (espresso, pour-over, V60, AeroPress, cold brew…), their typical parameters and what a coffee journal should record for each. Methods form a tree: a device-specific method such as v60 has the general method pour-over as parent. Part of Roastbook Open Coffee.","type":"object","required":["$schema","meta","brew_methods"],"additionalProperties":false,"properties":{"$schema":{"type":"string","pattern":"^https://schema\\.roastbook\\.coffee/brew-methods/brew-methods\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$","description":"Canonical URL of the schema version this file follows."},"meta":{"type":"object","$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/dataset_meta","unevaluatedProperties":false},"brew_methods":{"type":"array","items":{"$ref":"#/$defs/brew_method"}}},"$defs":{"range":{"title":"Range","type":"object","additionalProperties":false,"minProperties":1,"properties":{"min":{"type":"number","minimum":0,"description":"Lowest common value, in the unit named by the parameter (for example grams for dose_g, degrees Celsius for brew_temperature_celsius)."},"max":{"type":"number","minimum":0,"description":"Highest common value, in the unit named by the parameter."},"typical":{"type":"number","minimum":0,"description":"A good starting value, in the unit named by the parameter."}},"description":"A starting range. When several values are given they must be ordered: min ≤ typical ≤ max. JSON Schema cannot compare two values, so this repository checks it in its examples and data repositories check it in their data."},"parameter":{"title":"Brew parameter","enum":["dose_g","brew_water_g","yield_g","brew_ratio","yield_ratio","grind_setting","brew_time_seconds","target_time_seconds","brew_temperature_celsius","bloom_time_seconds","bloom_water_g","preinfusion_time_seconds","preinfusion_pressure_bar","brew_pressure_bar","flow_rate_ml_per_second","tamp_force_kg","uses_puck_screen","paper_filter_position","distribution_method","pour_count","steep_time_seconds"],"description":"Parameter keys shared with coffee journals such as Roastbook. brew_ratio is grams of brew water per gram of coffee (16 means 1:16); yield_ratio is grams of drink in the cup per gram of coffee (2 means a 1:2 espresso). brew_temperature_celsius is the temperature of the brew water. uses_puck_screen records whether a puck screen sat on top of the espresso puck (true or false). paper_filter_position takes a paper_filter_position value and distribution_method a distribution_method value."},"grind_size":{"title":"Grind size","enum":["extra_fine","fine","medium_fine","medium","medium_coarse","coarse","extra_coarse"],"description":"Descriptive grind size; extra_fine is Turkish, fine espresso, medium filter, coarse French press and cold brew."},"paper_filter_position":{"title":"Paper filter position","enum":["none","top","bottom","both"],"description":"Where paper filter discs sit in an espresso basket. none: no paper filter; top: on top of the coffee, under the shower screen; bottom: under the coffee, at the basket floor; both: one disc on top and one at the bottom."},"distribution_method":{"title":"Distribution method","enum":["wdt","blind_shaker","distribution_tool","stockfleth_move"],"description":"How ground coffee is spread evenly in the basket before tamping. wdt: stirring with fine needles (Weiss Distribution Technique); blind_shaker: grinding into a closed cup, shaking it and tipping the coffee into the basket; distribution_tool: a spinning leveller set on the basket; stockfleth_move: sweeping the coffee level with a finger while turning the portafilter."},"brew_method":{"title":"Brew method","type":"object","additionalProperties":false,"required":["id","name","category","extraction","description","checked_at"],"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/id","description":"Stable readable slug, e.g. v60, french-press. Never reused.","examples":["v60"]},"name":{"type":"string","minLength":1,"description":"Common English name of the method, for example Pour-over or French press."},"aliases":{"type":"array","uniqueItems":true,"items":{"type":"string","minLength":1},"description":"Other names in any language, e.g. Filterkaffee, drip."},"parent":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/id","description":"The more general method, e.g. pour-over for v60."},"category":{"enum":["espresso","filter","immersion","pressure","vacuum","boiling","cold"],"description":"Family used for grouping: espresso (9-bar style pressure), filter (percolation through a filter), immersion (steep, then separate), pressure (non-espresso pressure such as AeroPress or moka pot), vacuum (siphon), boiling (cezve/ibrik), cold (cold water over hours)."},"extraction":{"enum":["percolation","immersion","hybrid"],"description":"Physical principle; matches equipment brewer.mechanism."},"description":{"type":"string","minLength":20,"maxLength":600,"description":"Short neutral explanation in our own words."},"introduced_year":{"type":"integer","minimum":1000,"maximum":2100,"description":"Year the method or device was invented or first sold."},"origin_country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/country_code"},"equipment_types":{"type":"array","uniqueItems":true,"description":"Equipment types needed, from the equipment schema's type list.","items":{"$ref":"https://schema.roastbook.coffee/equipment/equipment.schema.v0.4.0.json#/$defs/type"}},"typical_parameters":{"title":"Typical parameters","type":"object","additionalProperties":false,"description":"Common starting ranges, not rules.","properties":{"dose_g":{"$ref":"#/$defs/range"},"brew_ratio":{"$ref":"#/$defs/range","description":"Grams of brew water per gram of coffee, for example 16 for 1:16. Used for filter, immersion and cold brew. A journal that keeps one ratio and a basis puts the ratio here when the basis is brew water (Roastbook: ratioBasis brew_water)."},"yield_ratio":{"$ref":"#/$defs/range","description":"Grams of drink in the cup per gram of coffee, for example 2 for a 1:2 espresso. Used where the drink is weighed, mainly espresso. A journal that keeps one ratio and a basis puts the ratio here when the basis is the yield (Roastbook: ratioBasis target_yield)."},"brew_temperature_celsius":{"$ref":"#/$defs/range","description":"Temperature of the brew water, in degrees Celsius."},"brew_time_seconds":{"$ref":"#/$defs/range"},"brew_pressure_bar":{"$ref":"#/$defs/range"},"grind_size":{"type":"array","uniqueItems":true,"minItems":1,"items":{"$ref":"#/$defs/grind_size"}},"grind_d50_microns":{"$ref":"#/$defs/range","description":"Median particle size in micrometres, comparable across grinders."},"paper_filter_position":{"type":"array","uniqueItems":true,"minItems":1,"items":{"$ref":"#/$defs/paper_filter_position"},"description":"Paper filter positions commonly used with this method."},"distribution_method":{"type":"array","uniqueItems":true,"minItems":1,"items":{"$ref":"#/$defs/distribution_method"},"description":"Distribution methods commonly used with this method."}}},"recorded_parameters":{"type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/parameter"},"description":"Parameters a coffee journal should offer when logging a brew with this method."},"typical_drinks":{"type":"array","uniqueItems":true,"items":{"type":"string","minLength":1},"description":"Drinks usually made with this method, in plain lowercase English, for example espresso, cappuccino or flat white."},"xref":{"type":"object","additionalProperties":false,"properties":{"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the method, for example Q180289 for espresso."},"beanconqueror":{"type":"string","pattern":"^[A-Z0-9_]+$","description":"Beanconqueror PREPARATION_TYPES key, for app imports."}},"description":"Identifiers of the method in other datasets and apps."},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/image"},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/datetime"},"filter_types":{"type":"array","uniqueItems":true,"items":{"enum":["paper","metal","cloth","none"]},"description":"Filters the method can use. paper: paper filters; metal: metal mesh or perforated metal; cloth: cloth filters; none: no filter (for example cezve or cold brew in a jar)."}}}}},"https://schema.roastbook.coffee/coffee-places/coffee-places.schema.v0.1.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/coffee-places/coffee-places.schema.v0.1.0.json","title":"Open Coffee places dataset","description":"One file per city listing cafés, coffee bars and other places that serve coffee. Part of Roastbook Open Coffee.","type":"object","required":["$schema","meta","places"],"additionalProperties":false,"properties":{"$schema":{"description":"Canonical URL of the schema version this file follows.","type":"string","pattern":"^https://schema\\.roastbook\\.coffee/coffee-places/coffee-places\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$"},"meta":{"$ref":"#/$defs/meta"},"places":{"type":"array","items":{"$ref":"#/$defs/place"}}},"$defs":{"meta":{"title":"File metadata","type":"object","allOf":[{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/dataset_meta"}],"required":["country_code","city"],"properties":{"country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/country_code"},"city":{"description":"City slug, matching the file name.","type":"string","pattern":"^[a-z0-9-]+$"},"city_name":{"type":"string","description":"City name in the local language."},"licence":true},"unevaluatedProperties":false},"tier":{"title":"Specialty tier","description":"A: coffee is the core product; the place roasts its own beans or serves named specialty roasters and usually offers filter coffee. B: food or something else leads, but the place serves a specialty roaster. none: not a specialty place (kept in the dataset). unknown: not yet assessed.","enum":["A","B","none","unknown"]},"serving":{"title":"Serving","description":"Coffee preparation offered. true: offered; false: confirmed not offered; absent: unknown.","type":"object","additionalProperties":false,"properties":{"espresso":{"type":"boolean","description":"Espresso and espresso-based drinks."},"filter":{"type":"boolean","description":"Any filter coffee."},"pour_over":{"type":"boolean","description":"Hand-brewed filter (V60, Kalita, Chemex and similar)."},"batch_brew":{"type":"boolean","description":"Filter coffee from a batch brewer."},"cold_brew":{"type":"boolean","description":"Coffee brewed with cold water over many hours. true: offered; false: confirmed not offered; absent: unknown."},"decaf":{"type":"boolean","description":"Decaffeinated coffee. true: offered; false: confirmed not offered; absent: unknown."},"plant_milk":{"type":"boolean","description":"At least one plant-based milk."}}},"amenities":{"title":"Amenities","description":"true: available; false: confirmed not available; absent: unknown.","type":"object","additionalProperties":false,"properties":{"wifi":{"type":"boolean","description":"Wi-Fi for guests. true: available; false: confirmed not available; absent: unknown."},"laptop_friendly":{"type":"boolean","description":"Laptops are welcome (no laptop ban, seats with sockets or tables)."},"kids_friendly":{"type":"boolean","description":"Suitable for children, for example with high chairs, space for prams or a kids' menu. true: yes; false: confirmed not suitable; absent: unknown."},"vegan_options":{"type":"boolean","description":"Vegan food beyond plant milk."},"dogs_allowed":{"type":"boolean","description":"Dogs may come inside. true: allowed; false: confirmed not allowed; absent: unknown."},"outdoor_seating":{"type":"boolean","description":"Seats outside, such as a terrace or tables on the pavement. true: available; false: confirmed none; absent: unknown."},"card_payment":{"type":"boolean","description":"Payment by debit or credit card. true: accepted; false: confirmed not accepted; absent: unknown."},"cash_only":{"type":"boolean","description":"Only cash is accepted. true: cash only; false: other payment methods are accepted; absent: unknown."},"wheelchair_accessible":{"type":"boolean","description":"Step-free entrance."}}},"food":{"title":"Food","type":"object","additionalProperties":false,"properties":{"focus":{"description":"coffee_led: coffee is the main product; food_led: food or a restaurant concept leads; balanced: both matter equally.","enum":["coffee_led","food_led","balanced"]},"breakfast":{"type":"boolean","description":"Breakfast is served. true: served; false: confirmed not served; absent: unknown."},"lunch":{"type":"boolean","description":"Lunch dishes are served. true: served; false: confirmed not served; absent: unknown."},"cakes_baked_in_house":{"type":"boolean","description":"Cakes or pastries are baked by the place itself. true: baked in house; false: confirmed bought in; absent: unknown."}}},"links":{"title":"Links","type":"object","additionalProperties":false,"properties":{"website":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/url"},"instagram":{"type":"string","pattern":"^https://(www\\.)?instagram\\.com/[A-Za-z0-9_.]+/?$","description":"Address of the place's own Instagram profile, for example https://www.instagram.com/example.coffee/."},"facebook":{"type":"string","pattern":"^https://(www\\.|m\\.)?facebook\\.com/.+","description":"Address of the place's own Facebook page."}}},"xref":{"title":"Identifiers in other datasets","description":"Crosswalk to other datasets. google_place_id is the only Google data we may store.","type":"object","additionalProperties":false,"properties":{"overture":{"type":"string","minLength":1,"description":"Overture Maps place GERS id."},"foursquare":{"type":"string","minLength":1,"description":"Foursquare Open Source Places fsq_place_id."},"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the place, for example Q42."},"google_place_id":{"type":"string","minLength":1,"description":"Google Maps place id, stored only so a known place can be matched. No other Google data is stored."}}},"roaster_ref":{"title":"Roaster served","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Name of the roastery whose coffee is served."},"roaster_id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/id","description":"Reserved for the future Open Coffee roasters dataset."},"url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/url"},"own":{"type":"boolean","description":"The place roasts this coffee itself."}}},"award":{"title":"Award","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Name of the award or ranking, for example a national barista championship or a city guide's list."},"year":{"type":"integer","minimum":1900,"maximum":2100,"description":"Year the award was given, for example 2025."},"url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/url"}}},"price":{"title":"Observed price","type":"object","required":["amount","currency","observed_on"],"additionalProperties":false,"properties":{"amount":{"type":"number","exclusiveMinimum":0,"description":"Price paid for one standard drink, in the currency given by currency, for example 3.9."},"currency":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/currency"},"observed_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/date"},"source_url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/url"}}},"operator":{"title":"Operator","description":"The legal entity running the place, taken from its Impressum or legal notice. Only companies and other legal entities; never the name of a natural person (sole traders are omitted).","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Registered name of the company that runs the place, as written in its legal notice."},"legal_form":{"type":"string","description":"For example GmbH, UG (haftungsbeschränkt), KG, e.K."},"register_id":{"type":"string","description":"Commercial register number, for example HRB 123456 (Amtsgericht München)."}}},"good_for":{"title":"Good for","enum":["working","meetings","quick_espresso","takeaway","brunch","groups","reading","date","coffee_nerds","families"]},"place":{"title":"Coffee place","type":"object","required":["id","name","status","location","address","specialty_tier","checked_at"],"additionalProperties":false,"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/id"},"name":{"type":"string","minLength":1,"maxLength":200,"description":"The name the place uses on its sign or website."},"status":{"description":"open; temporarily_closed (renovation, holiday longer than a month); closed (permanently); unverified (found but not yet confirmed to exist).","enum":["open","temporarily_closed","closed","unverified"]},"merged_into":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/id","description":"Set when this record turned out to be a duplicate. The record stays as a tombstone so its id is never reused or lost."},"opened_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/date"},"closed_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/date"},"last_verified_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/datetime","description":"When a primary source last confirmed that the place exists with this status."},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/datetime","description":"When the record as a whole was last reviewed or enriched."},"address":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/address"},"location":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/location"},"opening_hours":{"description":"Opening hours in OpenStreetMap opening_hours syntax (used as a format only; no OSM data), for example \"Mo-Fr 08:00-18:00; Sa,Su 09:00-17:00\".","type":"string","minLength":2,"maxLength":255},"open_sunday":{"type":"boolean","description":"Regularly open on Sundays."},"description":{"description":"Short English description written only from the facts stored in this record. Never copied from the place's own texts.","type":"string","minLength":20,"maxLength":600},"specialty_tier":{"$ref":"#/$defs/tier"},"roasts_own_beans":{"type":"boolean","description":"Whether the place roasts coffee itself. true: roasts its own beans; false: confirmed not roasting; absent: unknown."},"roasters_served":{"type":"array","items":{"$ref":"#/$defs/roaster_ref"}},"serving":{"$ref":"#/$defs/serving"},"amenities":{"$ref":"#/$defs/amenities"},"food":{"$ref":"#/$defs/food"},"sells_beans":{"type":"boolean","description":"Whether whole beans or ground coffee are sold to take home. true: sold; false: confirmed not sold; absent: unknown."},"sells_equipment":{"type":"boolean","description":"Whether brewing equipment such as grinders, drippers or kettles is sold. true: sold; false: confirmed not sold; absent: unknown."},"offers_courses":{"type":"boolean","description":"Barista courses, brewing classes or public cuppings."},"reusable_cup_systems":{"description":"Deposit or reusable cup schemes accepted, for example recup, vytal, own_cup.","type":"array","uniqueItems":true,"items":{"type":"string","pattern":"^[a-z0-9_-]+$"}},"good_for":{"type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/good_for"}},"awards":{"type":"array","items":{"$ref":"#/$defs/award"}},"prices":{"type":"object","additionalProperties":false,"properties":{"cappuccino":{"$ref":"#/$defs/price"}},"description":"Prices we observed, each with the date and page where we saw it. Currently only the cappuccino price, as a comparable reference."},"operator":{"$ref":"#/$defs/operator"},"links":{"$ref":"#/$defs/links"},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/image"},"xref":{"$ref":"#/$defs/xref"},"external_ratings":{"description":"References to rating pages elsewhere. Rating values are never stored.","type":"array","items":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/external_ref"}}},"allOf":[{"if":{"properties":{"status":{"const":"closed"}},"required":["status"]},"else":{"properties":{"closed_on":false}}}]}}},"https://schema.roastbook.coffee/coffee-places/coffee-places.schema.v0.2.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/coffee-places/coffee-places.schema.v0.2.0.json","title":"Open Coffee places dataset","description":"One file per city listing cafés, coffee bars and other places that serve coffee. Part of Roastbook Open Coffee.","type":"object","required":["$schema","meta","places"],"additionalProperties":false,"properties":{"$schema":{"description":"Canonical URL of the schema version this file follows.","type":"string","pattern":"^https://schema\\.roastbook\\.coffee/coffee-places/coffee-places\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$"},"meta":{"$ref":"#/$defs/meta"},"places":{"type":"array","items":{"$ref":"#/$defs/place"}}},"$defs":{"meta":{"title":"File metadata","type":"object","allOf":[{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/dataset_meta"}],"required":["country_code","city"],"properties":{"country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/country_code"},"city":{"description":"City slug, matching the file name.","type":"string","pattern":"^[a-z0-9-]+$"},"city_name":{"type":"string","description":"City name in the local language."},"licence":true},"unevaluatedProperties":false},"tier":{"title":"Specialty tier","description":"A: coffee is the core product; the place roasts its own beans or serves named specialty roasters and usually offers filter coffee. B: food or something else leads, but the place serves a specialty roaster. none: not a specialty place (kept in the dataset). unknown: not yet assessed.","enum":["A","B","none","unknown"]},"serving":{"title":"Serving","description":"Coffee preparation offered. true: offered; false: confirmed not offered; absent: unknown.","type":"object","additionalProperties":false,"properties":{"espresso":{"type":"boolean","description":"Espresso and espresso-based drinks."},"filter":{"type":"boolean","description":"Any filter coffee."},"pour_over":{"type":"boolean","description":"Hand-brewed filter (V60, Kalita, Chemex and similar)."},"batch_brew":{"type":"boolean","description":"Filter coffee from a batch brewer."},"cold_brew":{"type":"boolean","description":"Coffee brewed with cold water over many hours. true: offered; false: confirmed not offered; absent: unknown."},"decaf":{"type":"boolean","description":"Decaffeinated coffee. true: offered; false: confirmed not offered; absent: unknown."},"plant_milk":{"type":"boolean","description":"At least one plant-based milk."}}},"amenities":{"title":"Amenities","description":"true: available; false: confirmed not available; absent: unknown.","type":"object","additionalProperties":false,"properties":{"wifi":{"type":"boolean","description":"Wi-Fi for guests. true: available; false: confirmed not available; absent: unknown."},"laptop_friendly":{"type":"boolean","description":"Laptops are welcome (no laptop ban, seats with sockets or tables)."},"kids_friendly":{"type":"boolean","description":"Suitable for children, for example with high chairs, space for prams or a kids' menu. true: yes; false: confirmed not suitable; absent: unknown."},"vegan_options":{"type":"boolean","description":"Vegan food beyond plant milk."},"dogs_allowed":{"type":"boolean","description":"Dogs may come inside. true: allowed; false: confirmed not allowed; absent: unknown."},"outdoor_seating":{"type":"boolean","description":"Seats outside, such as a terrace or tables on the pavement. true: available; false: confirmed none; absent: unknown."},"card_payment":{"type":"boolean","description":"Payment by debit or credit card. true: accepted; false: confirmed not accepted; absent: unknown."},"cash_only":{"type":"boolean","description":"Only cash is accepted. true: cash only; false: other payment methods are accepted; absent: unknown."},"wheelchair_accessible":{"type":"boolean","description":"Step-free entrance."}}},"food":{"title":"Food","type":"object","additionalProperties":false,"properties":{"focus":{"description":"coffee_led: coffee is the main product; food_led: food or a restaurant concept leads; balanced: both matter equally.","enum":["coffee_led","food_led","balanced"]},"breakfast":{"type":"boolean","description":"Breakfast is served. true: served; false: confirmed not served; absent: unknown."},"lunch":{"type":"boolean","description":"Lunch dishes are served. true: served; false: confirmed not served; absent: unknown."},"cakes_baked_in_house":{"type":"boolean","description":"Cakes or pastries are baked by the place itself. true: baked in house; false: confirmed bought in; absent: unknown."}}},"links":{"title":"Links","type":"object","additionalProperties":false,"properties":{"website":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/url"},"instagram":{"type":"string","pattern":"^https://(www\\.)?instagram\\.com/[A-Za-z0-9_.]+/?$","description":"Address of the place's own Instagram profile, for example https://www.instagram.com/example.coffee/."},"facebook":{"type":"string","pattern":"^https://(www\\.|m\\.)?facebook\\.com/.+","description":"Address of the place's own Facebook page."}}},"xref":{"title":"Identifiers in other datasets","description":"Crosswalk to other datasets. google_place_id is the only Google data we may store.","type":"object","additionalProperties":false,"properties":{"overture":{"type":"string","minLength":1,"description":"Overture Maps place GERS id."},"foursquare":{"type":"string","minLength":1,"description":"Foursquare Open Source Places fsq_place_id."},"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the place, for example Q42."},"google_place_id":{"type":"string","minLength":1,"description":"Google Maps place id, stored only so a known place can be matched. No other Google data is stored."}}},"roaster_ref":{"title":"Roaster served","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Name of the roastery whose coffee is served."},"roaster_id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/id","description":"Reserved for the future Open Coffee roasters dataset."},"url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/url"},"own":{"type":"boolean","description":"The place roasts this coffee itself."}}},"award":{"title":"Award","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Name of the award or ranking, for example a national barista championship or a city guide's list."},"year":{"type":"integer","minimum":1900,"maximum":2100,"description":"Year the award was given, for example 2025."},"url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/url"}}},"price":{"title":"Observed price","type":"object","required":["amount","currency","observed_on"],"additionalProperties":false,"properties":{"amount":{"type":"number","exclusiveMinimum":0,"description":"Price paid for one standard drink, in the currency given by currency, for example 3.9."},"currency":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/currency"},"observed_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/date"},"source_url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/url"}}},"operator":{"title":"Operator","description":"The legal entity running the place, taken from its Impressum or legal notice. Only companies and other legal entities; never the name of a natural person (sole traders are omitted).","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Registered name of the company that runs the place, as written in its legal notice."},"legal_form":{"type":"string","description":"For example GmbH, UG (haftungsbeschränkt), KG, e.K."},"register_id":{"type":"string","description":"Commercial register number, for example HRB 123456 (Amtsgericht München)."}}},"good_for":{"title":"Good for","enum":["working","meetings","quick_espresso","takeaway","brunch","groups","reading","date","coffee_nerds","families"]},"place":{"title":"Coffee place","type":"object","required":["id","name","status","location","address","specialty_tier","checked_at"],"additionalProperties":false,"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/id"},"name":{"type":"string","minLength":1,"maxLength":200,"description":"The name the place uses on its sign or website."},"status":{"description":"open; temporarily_closed (renovation, holiday longer than a month); closed (permanently); unverified (found but not yet confirmed to exist).","enum":["open","temporarily_closed","closed","unverified"]},"merged_into":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/id","description":"Set when this record turned out to be a duplicate. The record stays as a tombstone so its id is never reused or lost."},"opened_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/date"},"closed_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/date"},"last_verified_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/datetime","description":"When a primary source last confirmed that the place exists with this status."},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/datetime","description":"When the record as a whole was last reviewed or enriched."},"address":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/address"},"location":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/location"},"opening_hours":{"description":"Opening hours in OpenStreetMap opening_hours syntax (used as a format only; no OSM data), for example \"Mo-Fr 08:00-18:00; Sa,Su 09:00-17:00\".","type":"string","minLength":2,"maxLength":255},"open_sunday":{"type":"boolean","description":"Regularly open on Sundays."},"description":{"description":"Short English description written only from the facts stored in this record. Never copied from the place's own texts.","type":"string","minLength":20,"maxLength":600},"specialty_tier":{"$ref":"#/$defs/tier"},"roasts_own_beans":{"type":"boolean","description":"Whether the place roasts coffee itself. true: roasts its own beans; false: confirmed not roasting; absent: unknown."},"roasters_served":{"type":"array","items":{"$ref":"#/$defs/roaster_ref"}},"serving":{"$ref":"#/$defs/serving"},"amenities":{"$ref":"#/$defs/amenities"},"food":{"$ref":"#/$defs/food"},"sells_beans":{"type":"boolean","description":"Whether whole beans or ground coffee are sold to take home. true: sold; false: confirmed not sold; absent: unknown."},"sells_equipment":{"type":"boolean","description":"Whether brewing equipment such as grinders, drippers or kettles is sold. true: sold; false: confirmed not sold; absent: unknown."},"offers_courses":{"type":"boolean","description":"Barista courses, brewing classes or public cuppings."},"reusable_cup_systems":{"description":"Deposit or reusable cup schemes accepted, for example recup, vytal, own_cup.","type":"array","uniqueItems":true,"items":{"type":"string","pattern":"^[a-z0-9_-]+$"}},"good_for":{"type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/good_for"}},"awards":{"type":"array","items":{"$ref":"#/$defs/award"}},"prices":{"type":"object","additionalProperties":false,"properties":{"cappuccino":{"$ref":"#/$defs/price"}},"description":"Prices we observed, each with the date and page where we saw it. Currently only the cappuccino price, as a comparable reference."},"operator":{"$ref":"#/$defs/operator"},"links":{"$ref":"#/$defs/links"},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/image"},"xref":{"$ref":"#/$defs/xref"},"external_ratings":{"description":"References to rating pages elsewhere. Rating values are never stored.","type":"array","items":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/external_ref"}}},"allOf":[{"if":{"properties":{"status":{"const":"closed"}},"required":["status"]},"else":{"properties":{"closed_on":false}}}]}}},"https://schema.roastbook.coffee/coffee-places/coffee-places.schema.v0.3.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/coffee-places/coffee-places.schema.v0.3.0.json","title":"Open Coffee places dataset","description":"One file per city listing cafés, coffee bars and other places that serve coffee. Part of Roastbook Open Coffee.","type":"object","required":["$schema","meta","places"],"additionalProperties":false,"properties":{"$schema":{"description":"Canonical URL of the schema version this file follows.","type":"string","pattern":"^https://schema\\.roastbook\\.coffee/coffee-places/coffee-places\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$"},"meta":{"$ref":"#/$defs/meta"},"places":{"type":"array","items":{"$ref":"#/$defs/place"}}},"$defs":{"meta":{"title":"File metadata","type":"object","allOf":[{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/dataset_meta"}],"required":["country_code","city"],"properties":{"country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/country_code"},"city":{"description":"City slug, matching the file name.","type":"string","pattern":"^[a-z0-9-]+$"},"city_name":{"type":"string","description":"City name in the local language."},"licence":true},"unevaluatedProperties":false},"tier":{"title":"Specialty tier","description":"A: coffee is the core product; the place roasts its own beans or serves named specialty roasters and usually offers filter coffee. B: food or something else leads, but the place serves a specialty roaster. none: not a specialty place (kept in the dataset). unknown: not yet assessed.","enum":["A","B","none","unknown"]},"serving":{"title":"Serving","description":"Coffee preparation offered. true: offered; false: confirmed not offered; absent: unknown.","type":"object","additionalProperties":false,"properties":{"espresso":{"type":"boolean","description":"Espresso and espresso-based drinks."},"filter":{"type":"boolean","description":"Any filter coffee."},"pour_over":{"type":"boolean","description":"Hand-brewed filter (V60, Kalita, Chemex and similar)."},"batch_brew":{"type":"boolean","description":"Filter coffee from a batch brewer."},"cold_brew":{"type":"boolean","description":"Coffee brewed with cold water over many hours. true: offered; false: confirmed not offered; absent: unknown."},"decaf":{"type":"boolean","description":"Decaffeinated coffee. true: offered; false: confirmed not offered; absent: unknown."},"plant_milk":{"type":"boolean","description":"At least one plant-based milk."}},"allOf":[{"if":{"properties":{"pour_over":{"const":true}},"required":["pour_over"]},"then":{"properties":{"filter":{"const":true}}}}]},"amenities":{"title":"Amenities","description":"true: available; false: confirmed not available; absent: unknown.","type":"object","additionalProperties":false,"properties":{"wifi":{"type":"boolean","description":"Wi-Fi for guests. true: available; false: confirmed not available; absent: unknown."},"laptop_friendly":{"type":"boolean","description":"Laptops are welcome (no laptop ban, seats with sockets or tables)."},"kids_friendly":{"type":"boolean","description":"Suitable for children, for example with high chairs, space for prams or a kids' menu. true: yes; false: confirmed not suitable; absent: unknown."},"vegan_options":{"type":"boolean","description":"Vegan food beyond plant milk."},"dogs_allowed":{"type":"boolean","description":"Dogs may come inside. true: allowed; false: confirmed not allowed; absent: unknown."},"outdoor_seating":{"type":"boolean","description":"Seats outside, such as a terrace or tables on the pavement. true: available; false: confirmed none; absent: unknown."},"card_payment":{"type":"boolean","description":"Payment by debit or credit card. true: accepted; false: confirmed not accepted; absent: unknown."},"cash_only":{"type":"boolean","description":"Only cash is accepted. true: cash only; false: other payment methods are accepted; absent: unknown."},"wheelchair_accessible":{"type":"boolean","description":"Step-free entrance."}},"allOf":[{"if":{"properties":{"cash_only":{"const":true}},"required":["cash_only"]},"then":{"properties":{"card_payment":{"const":false}}}}]},"food":{"title":"Food","type":"object","additionalProperties":false,"properties":{"focus":{"description":"coffee_led: coffee is the main product; food_led: food or a restaurant concept leads; balanced: both matter equally.","enum":["coffee_led","food_led","balanced"]},"breakfast":{"type":"boolean","description":"Breakfast is served. true: served; false: confirmed not served; absent: unknown."},"lunch":{"type":"boolean","description":"Lunch dishes are served. true: served; false: confirmed not served; absent: unknown."},"cakes_baked_in_house":{"type":"boolean","description":"Cakes or pastries are baked by the place itself. true: baked in house; false: confirmed bought in; absent: unknown."}}},"links":{"title":"Links","type":"object","additionalProperties":false,"properties":{"website":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/url"},"instagram":{"type":"string","pattern":"^https://(www\\.)?instagram\\.com/(?!(?:p|reel|reels|explore|stories|tv|accounts)(?:[/?]|$))[A-Za-z0-9_.]+/?(\\?[^#\\s]*)?$","description":"Address of the place's own Instagram profile. Write it as https://www.instagram.com/<handle>/ with the handle in lower case and no query string, for example https://www.instagram.com/example.coffee/. Posts, reels, stories and other non-profile pages are rejected."},"facebook":{"type":"string","pattern":"^https://(www\\.|m\\.)?facebook\\.com/.+","description":"Address of the place's own Facebook page."}}},"xref":{"title":"Identifiers in other datasets","description":"Crosswalk to other datasets. google_place_id is the only Google data we may store.","type":"object","additionalProperties":false,"properties":{"overture":{"type":"string","minLength":1,"description":"Overture Maps place GERS id."},"foursquare":{"type":"string","minLength":1,"description":"Foursquare Open Source Places fsq_place_id."},"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the place, for example Q42."},"google_place_id":{"type":"string","minLength":1,"description":"Google Maps place id, stored only so a known place can be matched. No other Google data is stored."}}},"roaster_ref":{"title":"Roaster served","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Name of the roastery whose coffee is served."},"roaster_id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/id","description":"Reserved for the future Open Coffee roasters dataset."},"url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/url"},"own":{"type":"boolean","description":"The place roasts this coffee itself."}}},"award":{"title":"Award","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Name of the award or ranking, for example a national barista championship or a city guide's list."},"year":{"type":"integer","minimum":1900,"maximum":2100,"description":"Year the award was given, for example 2025."},"url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/url"}}},"price":{"title":"Observed price","type":"object","required":["amount","currency","observed_on"],"additionalProperties":false,"properties":{"amount":{"type":"number","exclusiveMinimum":0,"description":"Price paid for one standard drink, in the currency given by currency, for example 3.9."},"currency":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/currency"},"observed_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/date"},"source_url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/url"}}},"operator":{"title":"Operator","description":"The legal entity running the place, taken from its Impressum or legal notice. Only companies and other legal entities; never the name of a natural person (sole traders are omitted).","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Registered name of the company that runs the place, as written in its legal notice."},"legal_form":{"type":"string","description":"For example GmbH, UG (haftungsbeschränkt), KG, e.K."},"register_id":{"type":"string","description":"Commercial register number, for example HRB 123456 (Amtsgericht München)."}}},"good_for":{"title":"Good for","enum":["working","meetings","quick_espresso","takeaway","brunch","groups","reading","date","coffee_nerds","families"]},"place":{"title":"Coffee place","type":"object","required":["id","type","name","status","location","address","specialty_tier","checked_at"],"additionalProperties":false,"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/id"},"type":{"description":"Kind of place, as a schema.org type. Every place is a CafeOrCoffeeShop for now; JSON-LD processors read it as the record's @type.","enum":["CafeOrCoffeeShop"]},"name":{"type":"string","minLength":1,"maxLength":200,"description":"The name the place uses on its sign or website."},"status":{"description":"open; temporarily_closed (renovation, holiday longer than a month); closed (permanently); unverified (found but not yet confirmed to exist).","enum":["open","temporarily_closed","closed","unverified"]},"merged_into":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/id","description":"Set when this record turned out to be a duplicate: the id of the record that is kept. The record stays as a tombstone so its id is never reused or lost; its status must not be open."},"opened_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/date"},"closed_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/date"},"last_verified_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/datetime","description":"When a primary source last confirmed that the place exists with this status."},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/datetime","description":"When the record as a whole was last reviewed or enriched."},"address":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/address"},"location":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/location"},"opening_hours":{"description":"Opening hours in OpenStreetMap opening_hours syntax (used as a format only; no OSM data), for example \"Mo-Fr 08:00-18:00; Sa,Su 09:00-17:00\".","type":"string","minLength":2,"maxLength":255},"description":{"description":"Short English description written only from the facts stored in this record. Never copied from the place's own texts.","type":"string","minLength":20,"maxLength":600},"specialty_tier":{"$ref":"#/$defs/tier"},"roasts_own_beans":{"type":"boolean","description":"Whether the place roasts coffee itself. true: roasts its own beans; false: confirmed not roasting; absent: unknown."},"roasters_served":{"type":"array","items":{"$ref":"#/$defs/roaster_ref"}},"serving":{"$ref":"#/$defs/serving"},"amenities":{"$ref":"#/$defs/amenities"},"food":{"$ref":"#/$defs/food"},"sells_beans":{"type":"boolean","description":"Whether whole beans or ground coffee are sold to take home. true: sold; false: confirmed not sold; absent: unknown."},"sells_equipment":{"type":"boolean","description":"Whether brewing equipment such as grinders, drippers or kettles is sold. true: sold; false: confirmed not sold; absent: unknown."},"offers_courses":{"type":"boolean","description":"Barista courses, brewing classes or public cuppings."},"reusable_cup_systems":{"description":"Deposit or reusable cup schemes accepted, for example recup, vytal, own_cup.","type":"array","uniqueItems":true,"items":{"type":"string","pattern":"^[a-z0-9_-]+$"}},"good_for":{"type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/good_for"}},"awards":{"type":"array","items":{"$ref":"#/$defs/award"}},"prices":{"type":"object","additionalProperties":false,"properties":{"cappuccino":{"$ref":"#/$defs/price"}},"description":"Prices we observed, each with the date and page where we saw it. Currently only the cappuccino price, as a comparable reference."},"operator":{"$ref":"#/$defs/operator"},"links":{"$ref":"#/$defs/links"},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/image"},"xref":{"$ref":"#/$defs/xref"},"external_ratings":{"description":"References to rating pages elsewhere. Rating values are never stored.","type":"array","items":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/external_ref"}}},"allOf":[{"if":{"properties":{"status":{"const":"closed"}},"required":["status"]},"else":{"properties":{"closed_on":false}}}],"dependentSchemas":{"merged_into":{"properties":{"status":{"enum":["temporarily_closed","closed","unverified"]}}}},"description":"One place that serves coffee. In JSON-LD it is a schema.org CafeOrCoffeeShop whose IRI is https://data.roastbook.coffee/places/<id>."}}},"https://schema.roastbook.coffee/coffee-places/coffee-places.schema.v0.4.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/coffee-places/coffee-places.schema.v0.4.0.json","title":"Open Coffee places dataset","description":"One file per city listing cafés, coffee bars and other places that serve coffee. Part of Roastbook Open Coffee.","type":"object","required":["$schema","meta","places"],"additionalProperties":false,"properties":{"$schema":{"description":"Canonical URL of the schema version this file follows.","type":"string","pattern":"^https://schema\\.roastbook\\.coffee/coffee-places/coffee-places\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$"},"meta":{"$ref":"#/$defs/meta"},"places":{"type":"array","items":{"$ref":"#/$defs/place"}}},"$defs":{"meta":{"title":"File metadata","type":"object","allOf":[{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/dataset_meta"}],"required":["country_code","city"],"properties":{"country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/country_code"},"city":{"description":"City slug, matching the file name.","type":"string","pattern":"^[a-z0-9-]+$"},"city_name":{"type":"string","description":"City name in the local language."},"licence":true},"unevaluatedProperties":false},"tier":{"title":"Specialty tier","description":"A: coffee is the core product; the place roasts its own beans or serves named specialty roasters and usually offers filter coffee. B: food or something else leads, but the place serves a specialty roaster. none: not a specialty place (kept in the dataset). unknown: not yet assessed.","enum":["A","B","none","unknown"]},"serving":{"title":"Serving","description":"Coffee preparation offered. true: offered; false: confirmed not offered; absent: unknown.","type":"object","additionalProperties":false,"properties":{"espresso":{"type":"boolean","description":"Espresso and espresso-based drinks."},"filter":{"type":"boolean","description":"Any filter coffee."},"pour_over":{"type":"boolean","description":"Hand-brewed filter (V60, Kalita, Chemex and similar)."},"batch_brew":{"type":"boolean","description":"Filter coffee from a batch brewer."},"cold_brew":{"type":"boolean","description":"Coffee brewed with cold water over many hours. true: offered; false: confirmed not offered; absent: unknown."},"decaf":{"type":"boolean","description":"Decaffeinated coffee. true: offered; false: confirmed not offered; absent: unknown."},"plant_milk":{"type":"boolean","description":"At least one plant-based milk."}},"allOf":[{"if":{"properties":{"pour_over":{"const":true}},"required":["pour_over"]},"then":{"properties":{"filter":{"const":true}}}}]},"amenities":{"title":"Amenities","description":"true: available; false: confirmed not available; absent: unknown.","type":"object","additionalProperties":false,"properties":{"wifi":{"type":"boolean","description":"Wi-Fi for guests. true: available; false: confirmed not available; absent: unknown."},"laptop_friendly":{"type":"boolean","description":"Laptops are welcome (no laptop ban, seats with sockets or tables)."},"kids_friendly":{"type":"boolean","description":"Suitable for children, for example with high chairs, space for prams or a kids' menu. true: yes; false: confirmed not suitable; absent: unknown."},"vegan_options":{"type":"boolean","description":"Vegan food beyond plant milk."},"dogs_allowed":{"type":"boolean","description":"Dogs may come inside. true: allowed; false: confirmed not allowed; absent: unknown."},"outdoor_seating":{"type":"boolean","description":"Seats outside, such as a terrace or tables on the pavement. true: available; false: confirmed none; absent: unknown."},"card_payment":{"type":"boolean","description":"Payment by debit or credit card. true: accepted; false: confirmed not accepted; absent: unknown."},"cash_only":{"type":"boolean","description":"Only cash is accepted. true: cash only; false: other payment methods are accepted; absent: unknown."},"wheelchair_accessible":{"type":"boolean","description":"Step-free entrance."}},"allOf":[{"if":{"properties":{"cash_only":{"const":true}},"required":["cash_only"]},"then":{"properties":{"card_payment":{"const":false}}}}]},"food":{"title":"Food","type":"object","additionalProperties":false,"properties":{"focus":{"description":"coffee_led: coffee is the main product; food_led: food or a restaurant concept leads; balanced: both matter equally.","enum":["coffee_led","food_led","balanced"]},"breakfast":{"type":"boolean","description":"Breakfast is served. true: served; false: confirmed not served; absent: unknown."},"lunch":{"type":"boolean","description":"Lunch dishes are served. true: served; false: confirmed not served; absent: unknown."},"cakes_baked_in_house":{"type":"boolean","description":"Cakes or pastries are baked by the place itself. true: baked in house; false: confirmed bought in; absent: unknown."}}},"links":{"title":"Links","type":"object","additionalProperties":false,"properties":{"website":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/url"},"instagram":{"type":"string","pattern":"^https://(www\\.)?instagram\\.com/(?!(?:p|reel|reels|explore|stories|tv|accounts)(?:[/?]|$))[A-Za-z0-9_.]+/?(\\?[^#\\s]*)?$","description":"Address of the place's own Instagram profile. Write it as https://www.instagram.com/<handle>/ with the handle in lower case and no query string, for example https://www.instagram.com/example.coffee/. Posts, reels, stories and other non-profile pages are rejected."},"facebook":{"type":"string","pattern":"^https://(www\\.|m\\.)?facebook\\.com/.+","description":"Address of the place's own Facebook page."}}},"xref":{"title":"Identifiers in other datasets","description":"Crosswalk to other datasets. google_place_id is the only Google data we may store.","type":"object","additionalProperties":false,"properties":{"overture":{"type":"string","minLength":1,"description":"Overture Maps place GERS id."},"foursquare":{"type":"string","minLength":1,"description":"Foursquare Open Source Places fsq_place_id."},"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the place, for example Q42."},"google_place_id":{"type":"string","minLength":1,"description":"Google Maps place id, stored only so a known place can be matched. No other Google data is stored."}}},"roaster_ref":{"title":"Roaster served","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Name of the roastery whose coffee is served."},"roaster_id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/id","description":"Reserved for the future Open Coffee roasters dataset."},"url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/url"},"own":{"type":"boolean","description":"The place roasts this coffee itself."}}},"award":{"title":"Award","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Name of the award or ranking, for example a national barista championship or a city guide's list."},"year":{"type":"integer","minimum":1900,"maximum":2100,"description":"Year the award was given, for example 2025."},"url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/url"}}},"price":{"title":"Observed price","type":"object","required":["amount","currency","observed_on"],"additionalProperties":false,"properties":{"amount":{"type":"number","exclusiveMinimum":0,"description":"Price paid for one standard drink, in the currency given by currency, for example 3.9."},"currency":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/currency"},"observed_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/date"},"source_url":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/url"}}},"operator":{"title":"Operator","description":"The legal entity running the place, taken from its Impressum or legal notice. Only companies and other legal entities; never the name of a natural person (sole traders are omitted).","type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Registered name of the company that runs the place, as written in its legal notice."},"legal_form":{"type":"string","description":"For example GmbH, UG (haftungsbeschränkt), KG, e.K."},"register_id":{"type":"string","description":"Commercial register number, for example HRB 123456 (Amtsgericht München)."}}},"good_for":{"title":"Good for","enum":["working","meetings","quick_espresso","takeaway","brunch","groups","reading","date","coffee_nerds","families"]},"place":{"title":"Coffee place","type":"object","required":["id","type","name","status","location","address","specialty_tier","checked_at"],"additionalProperties":false,"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/id"},"type":{"description":"Kind of place, as a schema.org type. Every place is a CafeOrCoffeeShop for now; JSON-LD processors read it as the record's @type.","enum":["CafeOrCoffeeShop"]},"name":{"type":"string","minLength":1,"maxLength":200,"description":"The name the place uses on its sign or website."},"status":{"description":"open; temporarily_closed (renovation, holiday longer than a month); closed (permanently); unverified (found but not yet confirmed to exist).","enum":["open","temporarily_closed","closed","unverified"]},"merged_into":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/id","description":"Set when this record turned out to be a duplicate: the id of the record that is kept. The record stays as a tombstone so its id is never reused or lost; its status must not be open."},"opened_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/date"},"closed_on":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/date"},"last_verified_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/datetime","description":"When a primary source last confirmed that the place exists with this status."},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/datetime","description":"When the record as a whole was last reviewed or enriched."},"address":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/address"},"location":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/location"},"opening_hours":{"description":"Opening hours in OpenStreetMap opening_hours syntax (used as a format only; no OSM data), for example \"Mo-Fr 08:00-18:00; Sa,Su 09:00-17:00\".","type":"string","minLength":2,"maxLength":255},"description":{"description":"Short English description written only from the facts stored in this record. Never copied from the place's own texts.","type":"string","minLength":20,"maxLength":600},"specialty_tier":{"$ref":"#/$defs/tier"},"roasts_own_beans":{"type":"boolean","description":"Whether the place roasts coffee itself. true: roasts its own beans; false: confirmed not roasting; absent: unknown."},"roasters_served":{"type":"array","items":{"$ref":"#/$defs/roaster_ref"}},"serving":{"$ref":"#/$defs/serving"},"amenities":{"$ref":"#/$defs/amenities"},"food":{"$ref":"#/$defs/food"},"sells_beans":{"type":"boolean","description":"Whether whole beans or ground coffee are sold to take home. true: sold; false: confirmed not sold; absent: unknown."},"sells_equipment":{"type":"boolean","description":"Whether brewing equipment such as grinders, drippers or kettles is sold. true: sold; false: confirmed not sold; absent: unknown."},"offers_courses":{"type":"boolean","description":"Barista courses, brewing classes or public cuppings."},"reusable_cup_systems":{"description":"Deposit or reusable cup schemes accepted, for example recup, vytal, own_cup.","type":"array","uniqueItems":true,"items":{"type":"string","pattern":"^[a-z0-9_-]+$"}},"good_for":{"type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/good_for"}},"awards":{"type":"array","items":{"$ref":"#/$defs/award"}},"prices":{"type":"object","additionalProperties":false,"properties":{"cappuccino":{"$ref":"#/$defs/price"}},"description":"Prices we observed, each with the date and page where we saw it. Currently only the cappuccino price, as a comparable reference."},"operator":{"$ref":"#/$defs/operator"},"links":{"$ref":"#/$defs/links"},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/image"},"xref":{"$ref":"#/$defs/xref"},"external_ratings":{"description":"References to rating pages elsewhere. Rating values are never stored.","type":"array","items":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/external_ref"}}},"allOf":[{"if":{"properties":{"status":{"const":"closed"}},"required":["status"]},"else":{"properties":{"closed_on":false}}}],"dependentSchemas":{"merged_into":{"properties":{"status":{"enum":["temporarily_closed","closed","unverified"]}}}},"description":"One place that serves coffee. In JSON-LD it is a schema.org CafeOrCoffeeShop whose IRI is https://data.roastbook.coffee/places/<id>."}}},"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json","title":"Open Coffee common definitions","description":"Building blocks shared by every Open Coffee dataset (coffee places now; roasters, beans and gear later). Reference them by absolute $id plus a JSON pointer.","$defs":{"id":{"title":"Identifier","description":"Permanent, opaque identifier. Never reused, never derived from a name, never deleted.","type":"string","pattern":"^[a-z0-9_.-]+$","minLength":3,"maxLength":64,"examples":["cp-7k2m9x4qvd"]},"date":{"title":"Date","description":"Calendar date, YYYY-MM-DD.","type":"string","format":"date"},"datetime":{"title":"Timestamp","description":"RFC 3339 timestamp with time zone, for example 2026-11-05T14:00:00Z.","type":"string","format":"date-time"},"url":{"title":"URL","description":"Absolute http or https URL.","type":"string","format":"uri","pattern":"^https?://"},"country_code":{"title":"Country code","description":"ISO 3166-1 alpha-2 code in upper case.","type":"string","pattern":"^[A-Z]{2}$"},"currency":{"title":"Currency","description":"ISO 4217 currency code.","type":"string","pattern":"^[A-Z]{3}$"},"address":{"title":"Postal address","type":"object","required":["country_code"],"additionalProperties":false,"properties":{"street_address":{"type":"string","minLength":1,"description":"Street and house number."},"postal_code":{"type":"string","minLength":1,"description":"Postal code as used locally, for example 80331."},"locality":{"type":"string","minLength":1,"description":"City or town."},"region":{"type":"string","minLength":1,"description":"State or region."},"country_code":{"$ref":"#/$defs/country_code"}}},"location":{"title":"Coordinates","description":"WGS 84 coordinates of the entrance or building.","type":"object","required":["lat","lon"],"additionalProperties":false,"properties":{"lat":{"type":"number","minimum":-90,"maximum":90,"description":"Latitude in decimal degrees (WGS 84); positive is north of the equator, for example 48.1371."},"lon":{"type":"number","minimum":-180,"maximum":180,"description":"Longitude in decimal degrees (WGS 84); positive is east of Greenwich, for example 11.5754."}}},"image":{"title":"Image","description":"An openly licensed image. Each image carries its own licence, author and source.","type":"object","required":["url","licence","author","source_url"],"additionalProperties":false,"properties":{"url":{"$ref":"#/$defs/url","description":"Where the file is served from (our assets folder or the original host)."},"licence":{"type":"string","minLength":2,"description":"SPDX identifier, for example CC-BY-4.0, CC-BY-SA-4.0 or CC0-1.0."},"author":{"type":"string","minLength":1,"description":"Name of the photographer or creator, as the licence requires it to be credited."},"source_url":{"$ref":"#/$defs/url","description":"Page describing the original file and its licence."},"title":{"type":"string","description":"Short caption describing what the image shows."},"width":{"type":"integer","minimum":1,"description":"Width of the image file in pixels."},"height":{"type":"integer","minimum":1,"description":"Height of the image file in pixels."}}},"external_ref":{"title":"External reference","description":"A pointer to a record in another service. Never stores the other service's values.","type":"object","required":["source","id"],"additionalProperties":false,"properties":{"source":{"type":"string","pattern":"^[a-z0-9_.-]+$","description":"Short name of the other service, for example tripadvisor or untappd. Lowercase letters, digits, dots, dashes and underscores."},"id":{"type":"string","minLength":1,"description":"The record's identifier in the other service."},"url":{"$ref":"#/$defs/url"}}},"dataset_meta":{"title":"Dataset metadata","type":"object","required":["licence"],"properties":{"licence":{"const":"MIT","description":"Licence of the file: MIT, with the copyright notice “Roastbook Open Coffee contributors”."}},"description":"File-level facts that are not records. The schema version is the $schema URL; the data version is the release tag."}}},"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json","title":"Open Coffee common definitions","description":"Building blocks shared by every Open Coffee dataset (coffee places now; roasters, beans and gear later). Reference them by absolute $id plus a JSON pointer.","$defs":{"id":{"title":"Identifier","description":"Permanent, opaque identifier. Never reused, never derived from a name, never deleted.","type":"string","pattern":"^[a-z0-9_.-]+$","minLength":3,"maxLength":64,"examples":["cp-7k2m9x4qvd"]},"date":{"title":"Date","description":"Calendar date, YYYY-MM-DD.","type":"string","format":"date"},"datetime":{"title":"Timestamp","description":"RFC 3339 timestamp with time zone, for example 2026-11-05T14:00:00Z.","type":"string","format":"date-time"},"url":{"title":"URL","description":"Absolute http or https URL.","type":"string","format":"uri","pattern":"^https?://"},"country_code":{"title":"Country code","description":"ISO 3166-1 alpha-2 code in upper case.","type":"string","pattern":"^[A-Z]{2}$"},"currency":{"title":"Currency","description":"ISO 4217 currency code.","type":"string","pattern":"^[A-Z]{3}$"},"address":{"title":"Postal address","type":"object","required":["country_code"],"additionalProperties":false,"properties":{"street_address":{"type":"string","minLength":1,"description":"Street and house number."},"postal_code":{"type":"string","minLength":1,"description":"Postal code as used locally, for example 80331."},"locality":{"type":"string","minLength":1,"description":"City or town."},"region":{"type":"string","minLength":1,"description":"State or region."},"country_code":{"$ref":"#/$defs/country_code"}}},"location":{"title":"Coordinates","description":"WGS 84 coordinates of the entrance or building.","type":"object","required":["lat","lon"],"additionalProperties":false,"properties":{"lat":{"type":"number","minimum":-90,"maximum":90,"description":"Latitude in decimal degrees (WGS 84); positive is north of the equator, for example 48.1371."},"lon":{"type":"number","minimum":-180,"maximum":180,"description":"Longitude in decimal degrees (WGS 84); positive is east of Greenwich, for example 11.5754."}}},"image":{"title":"Image","description":"An openly licensed image. Each image carries its own licence, author and source.","type":"object","required":["url","licence","author","source_url"],"additionalProperties":false,"properties":{"url":{"$ref":"#/$defs/url","description":"Where the file is served from (our assets folder or the original host)."},"licence":{"type":"string","minLength":2,"description":"SPDX identifier, for example CC-BY-4.0, CC-BY-SA-4.0 or CC0-1.0."},"author":{"type":"string","minLength":1,"description":"Name of the photographer or creator, as the licence requires it to be credited."},"source_url":{"$ref":"#/$defs/url","description":"Page describing the original file and its licence."},"title":{"type":"string","description":"Short caption describing what the image shows."},"width":{"type":"integer","minimum":1,"description":"Width of the image file in pixels."},"height":{"type":"integer","minimum":1,"description":"Height of the image file in pixels."}}},"external_ref":{"title":"External reference","description":"A pointer to a record in another service. Never stores the other service's values.","type":"object","required":["source","id"],"additionalProperties":false,"properties":{"source":{"type":"string","pattern":"^[a-z0-9_.-]+$","description":"Short name of the other service, for example tripadvisor or untappd. Lowercase letters, digits, dots, dashes and underscores."},"id":{"type":"string","minLength":1,"description":"The record's identifier in the other service."},"url":{"$ref":"#/$defs/url"}}},"dataset_meta":{"title":"Dataset metadata","type":"object","required":["licence"],"properties":{"licence":{"type":"string","pattern":"^\\(*[A-Za-z0-9][A-Za-z0-9.-]*\\+?(?: WITH [A-Za-z0-9][A-Za-z0-9.-]*\\+?)?\\)*(?: (?:AND|OR) \\(*[A-Za-z0-9][A-Za-z0-9.-]*\\+?(?: WITH [A-Za-z0-9][A-Za-z0-9.-]*\\+?)?\\)*)*$","description":"Licence of the file as an SPDX licence expression, for example MIT, CC0-1.0, CC-BY-4.0, ODbL-1.0 or \"MIT OR Apache-2.0\". Use identifiers from the SPDX licence list (https://spdx.org/licenses/) or LicenseRef-<name> for others.","examples":["MIT","CC-BY-4.0"]}},"description":"File-level facts that are not records. The schema version is the $schema URL; the data version is the release tag."}}},"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json","title":"Open Coffee common definitions","description":"Building blocks shared by every Open Coffee dataset (coffee places, brew methods and equipment; roasters and beans later). Reference them by absolute $id plus a JSON pointer.","$defs":{"id":{"title":"Identifier","description":"Permanent, opaque identifier. Never reused, never derived from a name, never deleted. Lowercase letters, digits, dots, dashes and underscores; starts and ends with a letter or digit.","type":"string","pattern":"^[a-z0-9][a-z0-9_.-]*[a-z0-9]$","minLength":3,"maxLength":64,"examples":["cp-7k2m9x4qvd"]},"date":{"title":"Date","description":"Calendar date, YYYY-MM-DD.","type":"string","format":"date"},"datetime":{"title":"Timestamp","description":"RFC 3339 timestamp with time zone, for example 2026-11-05T14:00:00Z.","type":"string","format":"date-time"},"url":{"title":"URL","description":"Absolute http or https address. Letters outside ASCII, such as umlauts in the host or path, may be written as they are (an IRI, for example https://kaffee-münchen.de/über-uns). The scheme is not case-sensitive.","type":"string","format":"iri","pattern":"^[Hh][Tt][Tt][Pp][Ss]?://"},"country_code":{"title":"Country code","description":"ISO 3166-1 alpha-2 code in upper case.","type":"string","pattern":"^[A-Z]{2}$"},"currency":{"title":"Currency","description":"ISO 4217 currency code.","type":"string","pattern":"^[A-Z]{3}$"},"address":{"title":"Postal address","type":"object","required":["country_code"],"additionalProperties":false,"properties":{"street_address":{"type":"string","minLength":1,"description":"Street and house number."},"postal_code":{"type":"string","minLength":1,"description":"Postal code as used locally, for example 80331."},"locality":{"type":"string","minLength":1,"description":"City or town."},"region":{"type":"string","minLength":1,"description":"State or region."},"country_code":{"$ref":"#/$defs/country_code"}}},"location":{"title":"Coordinates","description":"WGS 84 coordinates of the entrance or building.","type":"object","required":["lat","lon"],"additionalProperties":false,"properties":{"lat":{"type":"number","minimum":-90,"maximum":90,"description":"Latitude in decimal degrees (WGS 84); positive is north of the equator, for example 48.1371."},"lon":{"type":"number","minimum":-180,"maximum":180,"description":"Longitude in decimal degrees (WGS 84); positive is east of Greenwich, for example 11.5754."}}},"image":{"title":"Image","description":"An openly licensed image. Each image carries its own licence, author and source.","type":"object","required":["url","licence","author","source_url"],"additionalProperties":false,"properties":{"url":{"$ref":"#/$defs/url","description":"Where the file is served from (our assets folder or the original host)."},"licence":{"type":"string","minLength":2,"description":"SPDX identifier, for example CC-BY-4.0, CC-BY-SA-4.0 or CC0-1.0."},"author":{"type":"string","minLength":1,"description":"Name of the photographer or creator, as the licence requires it to be credited."},"source_url":{"$ref":"#/$defs/url","description":"Page describing the original file and its licence."},"title":{"type":"string","description":"Short caption describing what the image shows."},"width":{"type":"integer","minimum":1,"description":"Width of the image file in pixels."},"height":{"type":"integer","minimum":1,"description":"Height of the image file in pixels."}}},"external_ref":{"title":"External reference","description":"A pointer to a record in another service. Never stores the other service's values.","type":"object","required":["source","id"],"additionalProperties":false,"properties":{"source":{"type":"string","pattern":"^[a-z0-9_.-]+$","description":"Short name of the other service, for example tripadvisor or untappd. Lowercase letters, digits, dots, dashes and underscores."},"id":{"type":"string","minLength":1,"description":"The record's identifier in the other service."},"url":{"$ref":"#/$defs/url"}}},"dataset_meta":{"title":"Dataset metadata","type":"object","required":["licence"],"properties":{"licence":{"type":"string","pattern":"^\\(*[A-Za-z0-9][A-Za-z0-9.-]*\\+?(?: WITH [A-Za-z0-9][A-Za-z0-9.-]*\\+?)?\\)*(?: (?:AND|OR) \\(*[A-Za-z0-9][A-Za-z0-9.-]*\\+?(?: WITH [A-Za-z0-9][A-Za-z0-9.-]*\\+?)?\\)*)*$","description":"Licence of the file as an SPDX licence expression, for example MIT, CC0-1.0, CC-BY-4.0, ODbL-1.0 or \"MIT OR Apache-2.0\". Use identifiers from the SPDX licence list (https://spdx.org/licenses/) or LicenseRef-<name> for others.","examples":["MIT","CC-BY-4.0"]}},"description":"File-level facts that are not records. The schema version is the $schema URL; the data version is the release tag."}}},"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json","title":"Open Coffee common definitions","description":"Building blocks shared by every Open Coffee dataset (coffee places, brew methods and equipment; roasters and beans later). Reference them by absolute $id plus a JSON pointer.","$defs":{"id":{"title":"Identifier","description":"Permanent, opaque identifier. Never reused, never derived from a name, never deleted. Lowercase letters, digits, dots, dashes and underscores; starts and ends with a letter or digit.","type":"string","pattern":"^[a-z0-9][a-z0-9_.-]*[a-z0-9]$","minLength":3,"maxLength":64,"examples":["cp-7k2m9x4qvd"]},"date":{"title":"Date","description":"Calendar date, YYYY-MM-DD.","type":"string","format":"date"},"datetime":{"title":"Timestamp","description":"RFC 3339 timestamp with time zone, for example 2026-11-05T14:00:00Z.","type":"string","format":"date-time"},"url":{"title":"URL","description":"Absolute http or https address. Letters outside ASCII, such as umlauts in the host or path, may be written as they are (an IRI, for example https://kaffee-münchen.de/über-uns). The scheme is not case-sensitive.","type":"string","format":"iri","pattern":"^[Hh][Tt][Tt][Pp][Ss]?://"},"country_code":{"title":"Country code","description":"ISO 3166-1 alpha-2 code in upper case.","type":"string","pattern":"^[A-Z]{2}$"},"currency":{"title":"Currency","description":"ISO 4217 currency code.","type":"string","pattern":"^[A-Z]{3}$"},"address":{"title":"Postal address","type":"object","required":["country_code"],"additionalProperties":false,"properties":{"street_address":{"type":"string","minLength":1,"description":"Street and house number."},"postal_code":{"type":"string","minLength":1,"description":"Postal code as used locally, for example 80331."},"locality":{"type":"string","minLength":1,"description":"City or town."},"region":{"type":"string","minLength":1,"description":"State or region."},"country_code":{"$ref":"#/$defs/country_code"}}},"location":{"title":"Coordinates","description":"WGS 84 coordinates of the entrance or building.","type":"object","required":["lat","lon"],"additionalProperties":false,"properties":{"lat":{"type":"number","minimum":-90,"maximum":90,"description":"Latitude in decimal degrees (WGS 84); positive is north of the equator, for example 48.1371."},"lon":{"type":"number","minimum":-180,"maximum":180,"description":"Longitude in decimal degrees (WGS 84); positive is east of Greenwich, for example 11.5754."}}},"image":{"title":"Image","description":"An openly licensed image. Each image carries its own licence, author and source.","type":"object","required":["url","licence","author","source_url"],"additionalProperties":false,"properties":{"url":{"$ref":"#/$defs/url","description":"Where the file is served from (our assets folder or the original host)."},"licence":{"type":"string","minLength":2,"description":"SPDX identifier, for example CC-BY-4.0, CC-BY-SA-4.0 or CC0-1.0."},"author":{"type":"string","minLength":1,"description":"Name of the photographer or creator, as the licence requires it to be credited."},"source_url":{"$ref":"#/$defs/url","description":"Page describing the original file and its licence."},"title":{"type":"string","description":"Short caption describing what the image shows."},"width":{"type":"integer","minimum":1,"description":"Width of the image file in pixels."},"height":{"type":"integer","minimum":1,"description":"Height of the image file in pixels."}}},"external_ref":{"title":"External reference","description":"A pointer to a record in another service. Never stores the other service's values.","type":"object","required":["source","id"],"additionalProperties":false,"properties":{"source":{"type":"string","pattern":"^[a-z0-9_.-]+$","description":"Short name of the other service, for example tripadvisor or untappd. Lowercase letters, digits, dots, dashes and underscores."},"id":{"type":"string","minLength":1,"description":"The record's identifier in the other service."},"url":{"$ref":"#/$defs/url"}}},"dataset_meta":{"title":"Dataset metadata","type":"object","required":["licence"],"properties":{"licence":{"type":"string","pattern":"^\\(*[A-Za-z0-9][A-Za-z0-9.-]*\\+?(?: WITH [A-Za-z0-9][A-Za-z0-9.-]*\\+?)?\\)*(?: (?:AND|OR) \\(*[A-Za-z0-9][A-Za-z0-9.-]*\\+?(?: WITH [A-Za-z0-9][A-Za-z0-9.-]*\\+?)?\\)*)*$","description":"Licence of the file as an SPDX licence expression, for example MIT, CC0-1.0, CC-BY-4.0, ODbL-1.0 or \"MIT OR Apache-2.0\". Use identifiers from the SPDX licence list (https://spdx.org/licenses/) or LicenseRef-<name> for others.","examples":["MIT","CC-BY-4.0"]}},"description":"File-level facts that are not records. The schema version is the $schema URL; the data version is the release tag."}}},"https://schema.roastbook.coffee/equipment/equipment.schema.v0.1.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/equipment/equipment.schema.v0.1.0.json","title":"Open Coffee equipment catalog","description":"Coffee equipment models (machines, grinders, brewers, kettles, scales and accessories) as sold, not individual owned items. Measurements put the unit in the property name. Part of Roastbook Open Coffee; derived from the Roastbook journal gear model.","type":"object","required":["$schema","meta","equipment"],"additionalProperties":false,"properties":{"$schema":{"type":"string","pattern":"^https://schema\\.roastbook\\.coffee/equipment/equipment\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$","description":"Canonical URL of the schema version this file follows."},"meta":{"type":"object","$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/dataset_meta","unevaluatedProperties":false},"equipment":{"type":"array","items":{"$ref":"#/$defs/item"}}},"$defs":{"type":{"title":"Equipment type","enum":["espresso_machine","espresso_machine_with_grinder","grinder","brewer","kettle","scale","tamper","wdt","basket","filter","roaster","milk_frother","accessory"],"description":"espresso_machine_with_grinder is an espresso machine with a built-in grinder; filter covers paper and metal filters; accessory covers everything without a dedicated type (puck screens, distribution tools, thermometers, dosing cups)."},"espresso_machine":{"title":"Espresso machine details","type":"object","additionalProperties":false,"properties":{"heating_architecture":{"enum":["single_boiler","heat_exchanger","dual_boiler","multi_boiler","single_thermoblock","dual_thermoblock","hybrid","manual","other"],"description":"How the machine heats water. single_boiler: one boiler for brewing and steam, used in turn; heat_exchanger: one steam boiler that heats brew water passing through a pipe inside it; dual_boiler: separate brew and steam boilers; multi_boiler: more than two boilers, for example one per group; single_thermoblock and dual_thermoblock: water heated on the fly in one or two thermoblocks; hybrid: a boiler combined with a thermoblock; manual: no heater, you pour in hot water."},"temperature_control":{"enum":["none","fixed","adjustable","programmable"],"description":"How brew temperature is set. none: no control; fixed: set at the factory; adjustable: the user can change it (for example with a PID); programmable: can change during the shot or follow profiles."},"pressure_control":{"enum":["fixed","adjustable_opv","manual","programmable"],"description":"How brew pressure is set. fixed: set by the factory; adjustable_opv: the over-pressure valve can be adjusted; manual: controlled by hand, for example with a lever; programmable: follows set pressure profiles."},"flow_control":{"enum":["none","manual","programmable"],"description":"Whether water flow during the shot can be controlled. none: no control; manual: by hand, for example a needle valve paddle; programmable: follows set profiles."},"preinfusion_control":{"enum":["none","supported","fixed","adjustable","programmable"],"description":"Wetting the coffee at low pressure before full pressure. none: no preinfusion; supported: possible by hand or by technique; fixed: built in with a fixed duration; adjustable: duration or pressure can be set; programmable: part of a programmable profile."},"steam_system":{"enum":["none","shared_heater","dedicated_heater"],"description":"How milk steam is produced. none: no steam wand; shared_heater: the same heater as for brewing, so the machine switches between modes; dedicated_heater: a separate boiler or thermoblock for steam."},"simultaneous_brew_and_steam":{"type":"boolean","description":"Whether you can pull a shot and steam milk at the same time. true: possible; false: confirmed not possible; absent: unknown."},"pump_type":{"enum":["vibration","rotary","gear","peristaltic","manual","other"],"description":"How pressure is made. vibration: small vibratory pump; rotary: quieter rotary vane pump; gear: gear pump, often used for flow profiling; peristaltic: squeezed-tube pump; manual: lever or hand pump, no motor."},"water_source_modes":{"type":"array","uniqueItems":true,"minItems":1,"items":{"enum":["reservoir","plumbed"]},"description":"Where water comes from. reservoir: a tank you fill; plumbed: connected to the mains water supply."},"shot_stop_modes":{"type":"array","uniqueItems":true,"items":{"enum":["manual","weight","time","volume"]},"description":"How a shot can be stopped. manual: by the user; weight: automatically at a target weight with a scale; time: after a set time; volume: after a set volume (volumetric dosing)."},"group_count":{"type":"integer","minimum":1,"description":"Number of brew groups (where portafilters lock in), for example 1 for most home machines."},"portafilter_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Inner diameter of the portafilter basket in millimetres, for example 58."},"brew_pressure_min_bar":{"type":"number","exclusiveMinimum":0,"description":"Lowest brew pressure the machine can deliver, in bar."},"brew_pressure_max_bar":{"type":"number","exclusiveMinimum":0,"description":"Highest brew pressure the machine can deliver, in bar."},"brew_temperature_min_celsius":{"type":"number","exclusiveMinimum":0,"description":"Lowest brew water temperature that can be set, in degrees Celsius."},"brew_temperature_max_celsius":{"type":"number","exclusiveMinimum":0,"description":"Highest brew water temperature that can be set, in degrees Celsius."},"reservoir_capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Size of the water tank in millilitres."},"power_w":{"type":"number","exclusiveMinimum":0,"description":"Rated electrical power in watts."},"group_type":{"enum":["e61","saturated","semi_saturated","lever","integrated","other"],"description":"Type of brew group. e61: the classic heated E61 group; saturated: group filled with boiler water and kept at its temperature; semi_saturated: group attached to the boiler but not fully filled; lever: piston group driven by a lever; integrated: group built into a thermoblock or the machine body; other: anything else."},"boiler_count":{"type":"integer","minimum":0,"description":"Number of boilers, 0 for thermoblock or manual machines."},"connectivity":{"type":"array","uniqueItems":true,"items":{"enum":["bluetooth","wifi","usb"]},"description":"Wireless or wired connections for apps or updates: bluetooth, wifi or usb."}}},"grinder":{"title":"Grinder details","type":"object","additionalProperties":false,"properties":{"burr_mechanism":{"enum":["conical","flat","ghost","roller","blade","other"],"description":"Type of cutting parts. conical: cone-shaped burrs; flat: two flat discs; ghost: flat burrs in a design without a burr carrier contact, sold as \"ghost burrs\"; roller: industrial-style roller mill; blade: spinning blade that chops rather than grinds; other: anything else."},"burr_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the burrs in millimetres, for example 64 for many flat-burr grinders."},"burr_material":{"enum":["steel","ceramic","titanium_coated","other"],"description":"What the burrs are made of. steel: hardened steel; ceramic: ceramic burrs; titanium_coated: steel with a titanium or similar hard coating; other: anything else."},"adjustment_type":{"enum":["fixed","stepped","stepless"],"description":"How grind size is changed. fixed: cannot be changed; stepped: clicks between set positions; stepless: any position in between."},"grind_setting_format":{"enum":["whole_number","decimal","string"],"description":"How the dial reads, so journals can store settings."},"grind_setting_min":{"type":"number","description":"Lowest number on the grind dial, as printed by the maker."},"grind_setting_max":{"type":"number","description":"Highest number on the grind dial, as printed by the maker."},"brew_range":{"type":"array","uniqueItems":true,"minItems":1,"items":{"enum":["espresso","filter","turkish"]},"description":"Brew styles the grinder can grind for, as stated by the maker: espresso, filter or turkish (extra fine)."},"bean_feed":{"enum":["single_dose","hopper","both"],"description":"How beans go in. single_dose: weighed dose for each brew; hopper: a container holding beans for many brews; both: works either way."},"dose_control_modes":{"type":"array","uniqueItems":true,"items":{"enum":["manual","time","weight"]},"description":"How the amount of ground coffee is controlled. manual: the user stops grinding; time: grinds for a set time; weight: stops at a target weight with a built-in scale."},"drive":{"enum":["manual","electric"],"description":"manual: turned by hand; electric: driven by a motor."},"motor_power_w":{"type":"number","exclusiveMinimum":0,"description":"Rated motor power in watts."},"grind_setting_step":{"type":"number","exclusiveMinimum":0,"description":"Smallest step between settings on a stepped dial."},"microns_per_step":{"type":"number","exclusiveMinimum":0,"description":"Burr gap change per setting step, as stated by the maker or measured."},"retention_g":{"type":"number","minimum":0,"description":"Ground coffee left inside the grinder after grinding, in grams, as measured or stated by the maker."},"rpm_min":{"type":"number","exclusiveMinimum":0,"description":"Lowest motor speed in revolutions per minute."},"rpm_max":{"type":"number","exclusiveMinimum":0,"description":"Highest motor speed in revolutions per minute. Equal to rpm_min for fixed-speed grinders."}}},"brewer":{"title":"Brewer details","type":"object","additionalProperties":false,"properties":{"mechanism":{"enum":["percolation","immersion","hybrid","press","vacuum","boiling","other"],"description":"How water and coffee meet; matches brew method categories."},"capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Largest amount of brewed coffee it holds or makes at once, in millilitres."},"cup_capacity":{"type":"integer","minimum":1,"description":"Nominal number of cups the maker states."},"material":{"type":"array","uniqueItems":true,"items":{"enum":["ceramic","glass","plastic","stainless_steel","copper","aluminium","porcelain","wood","silicone","other"]},"description":"What the brewer is made of; list every material sold under this model, such as ceramic and plastic."},"filter_format":{"type":"string","pattern":"^[a-z0-9_-]+$","description":"Filter shape or size, e.g. cone_02, flat_185, chemex_6cup, aeropress_round, metal_mesh."},"filter_shape":{"enum":["cone","flat_bottom","basket","disc","none"],"description":"Shape of the filter it uses. cone: pointed cone; flat_bottom: flat base, for example wave filters; basket: basket-shaped paper filter used in drip machines; disc: round disc, as in AeroPress; none: no separate filter."},"flow_control":{"enum":["fixed","manual_valve","programmable"],"description":"How fast water drains. fixed: set by the design; manual_valve: a valve or switch you open and close; programmable: controlled by the machine."},"drive":{"enum":["manual","electric","stovetop"],"description":"manual: you pour or press by hand; electric: a machine heats and pours the water; stovetop: heated on a hob, such as a moka pot."}}},"kettle":{"title":"Kettle details","type":"object","additionalProperties":false,"properties":{"capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Largest amount of water it holds, in millilitres."},"spout_type":{"enum":["gooseneck","standard","other"],"description":"gooseneck: thin curved spout for a slow, precise pour; standard: ordinary spout; other: anything else."},"temperature_control":{"enum":["none","fixed","adjustable"],"description":"none: just boils; fixed: a few preset temperatures; adjustable: any temperature in a range can be set."},"temperature_min_celsius":{"type":"number","exclusiveMinimum":0,"description":"Lowest temperature that can be set, in degrees Celsius."},"temperature_max_celsius":{"type":"number","exclusiveMinimum":0,"description":"Highest temperature that can be set, in degrees Celsius."},"supports_temperature_hold":{"type":"boolean","description":"Whether the kettle can keep water at the set temperature. true: can hold; false: confirmed cannot hold; absent: unknown."},"heat_source":{"enum":["electric","stovetop","induction_compatible","other"],"description":"electric: has its own heating base; stovetop: heated on a hob; induction_compatible: stovetop kettle that also works on induction hobs; other: anything else."}}},"scale":{"title":"Scale details","type":"object","additionalProperties":false,"properties":{"resolution_g":{"type":"number","exclusiveMinimum":0,"description":"Smallest weight step the display shows, in grams, for example 0.1."},"capacity_g":{"type":"number","exclusiveMinimum":0,"description":"Largest weight the scale can measure, in grams."},"has_timer":{"type":"boolean","description":"Built-in timer. true: has one; false: confirmed none; absent: unknown."},"supports_auto_tare":{"type":"boolean","description":"Sets itself to zero when a cup or brewer is put on. true: supported; false: confirmed not supported; absent: unknown."},"supports_auto_timer":{"type":"boolean","description":"Starts the timer by itself when liquid starts to flow or water is poured. true: supported; false: confirmed not supported; absent: unknown."},"has_flow_rate_display":{"type":"boolean","description":"Shows how fast weight changes, in grams per second. true: shown; false: confirmed not shown; absent: unknown."},"connectivity":{"type":"array","uniqueItems":true,"items":{"enum":["bluetooth","wifi","usb"]},"description":"Wireless or wired connections to apps or machines: bluetooth, wifi or usb."}}},"tamper":{"title":"Tamper details","type":"object","additionalProperties":false,"properties":{"diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the tamper base in millimetres, for example 58."},"force_control":{"enum":["none","fixed","adjustable"],"description":"none: the user decides how hard to press; fixed: a spring gives a set force; adjustable: the spring force can be set."},"base_shape":{"enum":["flat","convex","rippled","other"],"description":"Shape of the pressing surface. flat; convex: slightly curved outward; rippled: grooved surface; other: anything else."},"self_leveling":{"type":"boolean","description":"Whether the tamper sits on the basket rim so it always presses level. true: self-levelling; false: confirmed not self-levelling; absent: unknown."}}},"wdt":{"title":"WDT tool details","type":"object","additionalProperties":false,"properties":{"needle_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Thickness of each needle in millimetres, for example 0.3."},"needle_count":{"type":"integer","minimum":1,"description":"Number of needles."},"depth_control":{"enum":["none","fixed","adjustable"],"description":"Whether you can limit how deep the needles reach. none: no limit; fixed: set depth; adjustable: depth can be set."}}},"basket":{"title":"Portafilter basket details","type":"object","additionalProperties":false,"properties":{"kind":{"enum":["single","double","triple","other"],"description":"single, double or triple: the shot size the basket is made for; other: anything else."},"diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the basket in millimetres, for example 58."},"nominal_dose_g":{"type":"number","exclusiveMinimum":0,"description":"Dose of ground coffee the basket is designed for, in grams."},"dose_min_g":{"type":"number","exclusiveMinimum":0,"description":"Smallest recommended dose in grams."},"dose_max_g":{"type":"number","exclusiveMinimum":0,"description":"Largest recommended dose in grams."},"pressurized":{"type":"boolean","description":"A pressurised basket has a single small exit hole that builds pressure even with a coarse grind. true: pressurised; false: standard unpressurised basket; absent: unknown."},"precision":{"type":"boolean","description":"A precision basket has tightly controlled hole sizes, sold for consistent extraction. true: precision basket; false: ordinary basket; absent: unknown."}}},"item":{"title":"Equipment model","type":"object","additionalProperties":false,"required":["id","name","type","manufacturer","checked_at"],"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/id","description":"Stable readable slug of manufacturer and model, e.g. hario-v60-02. Never reused.","examples":["hario-v60-02"]},"name":{"type":"string","minLength":1,"description":"Full display name, e.g. Hario V60 02."},"manufacturer":{"title":"Manufacturer","type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Brand or company name as printed on the product, for example Hario."},"manufacturer_id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/id","description":"Reserved for a future manufacturers dataset."},"country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/country_code"},"website":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/url"}},"required":["name"]},"model":{"type":"string","minLength":1,"description":"Model name without the brand, for example V60."},"variants":{"type":"array","description":"Sizes or materials sold under the same model, e.g. 01 and 02, ceramic and plastic.","items":{"type":"string","minLength":1}},"type":{"$ref":"#/$defs/type"},"brew_methods":{"type":"array","uniqueItems":true,"description":"Brew method ids from the Open Coffee brew methods dataset this equipment is made for.","items":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/id"}},"released_year":{"type":"integer","minimum":1800,"maximum":2100,"description":"Year the model first went on sale."},"discontinued":{"type":"boolean","description":"Whether the maker has stopped selling the model. true: discontinued; false: still sold; absent: unknown."},"links":{"title":"Links","type":"object","additionalProperties":false,"properties":{"product":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/url"},"manual":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/url"}}},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/image"},"xref":{"title":"Identifiers elsewhere","type":"object","additionalProperties":false,"properties":{"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the model or product line, for example Q1234567."},"gtin":{"type":"array","items":{"type":"string","pattern":"^[0-9]{8,14}$"},"description":"Barcode numbers (GTIN, EAN or UPC; 8 to 14 digits) printed on the packaging, one per variant."},"google_product_category":{"type":"integer","minimum":1,"description":"Google Product Taxonomy id (Wikidata P11302)."},"gs1_gpc_brick":{"type":"string","pattern":"^[0-9]{8}$","description":"GS1 Global Product Classification brick code (Wikidata P8957)."}}},"espresso_machine":{"$ref":"#/$defs/espresso_machine"},"grinder":{"$ref":"#/$defs/grinder"},"brewer":{"$ref":"#/$defs/brewer"},"kettle":{"$ref":"#/$defs/kettle"},"scale":{"$ref":"#/$defs/scale"},"tamper":{"$ref":"#/$defs/tamper"},"wdt":{"$ref":"#/$defs/wdt"},"basket":{"$ref":"#/$defs/basket"},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.1.0.json#/$defs/datetime"},"mpn":{"type":"string","minLength":1,"description":"Manufacturer part number."},"weight_g":{"type":"number","exclusiveMinimum":0,"description":"Weight of the product without packaging, in grams."},"dimensions_mm":{"type":"object","additionalProperties":false,"properties":{"width":{"type":"number","exclusiveMinimum":0,"description":"Width in millimetres, seen from the front."},"depth":{"type":"number","exclusiveMinimum":0,"description":"Depth in millimetres, from front to back."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in millimetres."}},"description":"Outside size of the product in millimetres."}},"allOf":[{"if":{"properties":{"type":{"const":"espresso_machine"}},"required":["type"]},"then":{"properties":{"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"espresso_machine_with_grinder"}},"required":["type"]},"then":{"properties":{"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"grinder"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"brewer"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"kettle"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"scale"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"tamper"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"wdt"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"basket":false}}},{"if":{"properties":{"type":{"const":"basket"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false}}},{"if":{"properties":{"type":{"const":"filter"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"roaster"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"milk_frother"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"accessory"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}}]}}},"https://schema.roastbook.coffee/equipment/equipment.schema.v0.2.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/equipment/equipment.schema.v0.2.0.json","title":"Open Coffee equipment catalog","description":"Coffee equipment models (machines, grinders, brewers, kettles, scales and accessories) as sold, not individual owned items. Measurements put the unit in the property name. Part of Roastbook Open Coffee; derived from the Roastbook journal gear model.","type":"object","required":["$schema","meta","equipment"],"additionalProperties":false,"properties":{"$schema":{"type":"string","pattern":"^https://schema\\.roastbook\\.coffee/equipment/equipment\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$","description":"Canonical URL of the schema version this file follows."},"meta":{"type":"object","$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/dataset_meta","unevaluatedProperties":false},"equipment":{"type":"array","items":{"$ref":"#/$defs/item"}}},"$defs":{"type":{"title":"Equipment type","enum":["espresso_machine","espresso_machine_with_grinder","grinder","brewer","kettle","scale","tamper","wdt","basket","filter","roaster","milk_frother","accessory"],"description":"espresso_machine_with_grinder is an espresso machine with a built-in grinder; filter covers paper and metal filters; accessory covers everything without a dedicated type (puck screens, distribution tools, thermometers, dosing cups)."},"espresso_machine":{"title":"Espresso machine details","type":"object","additionalProperties":false,"properties":{"heating_architecture":{"enum":["single_boiler","heat_exchanger","dual_boiler","multi_boiler","single_thermoblock","dual_thermoblock","hybrid","manual","other"],"description":"How the machine heats water. single_boiler: one boiler for brewing and steam, used in turn; heat_exchanger: one steam boiler that heats brew water passing through a pipe inside it; dual_boiler: separate brew and steam boilers; multi_boiler: more than two boilers, for example one per group; single_thermoblock and dual_thermoblock: water heated on the fly in one or two thermoblocks; hybrid: a boiler combined with a thermoblock; manual: no heater, you pour in hot water."},"temperature_control":{"enum":["none","fixed","adjustable","programmable"],"description":"How brew temperature is set. none: no control; fixed: set at the factory; adjustable: the user can change it (for example with a PID); programmable: can change during the shot or follow profiles."},"pressure_control":{"enum":["fixed","adjustable_opv","manual","programmable"],"description":"How brew pressure is set. fixed: set by the factory; adjustable_opv: the over-pressure valve can be adjusted; manual: controlled by hand, for example with a lever; programmable: follows set pressure profiles."},"flow_control":{"enum":["none","manual","programmable"],"description":"Whether water flow during the shot can be controlled. none: no control; manual: by hand, for example a needle valve paddle; programmable: follows set profiles."},"preinfusion_control":{"enum":["none","supported","fixed","adjustable","programmable"],"description":"Wetting the coffee at low pressure before full pressure. none: no preinfusion; supported: possible by hand or by technique; fixed: built in with a fixed duration; adjustable: duration or pressure can be set; programmable: part of a programmable profile."},"steam_system":{"enum":["none","shared_heater","dedicated_heater"],"description":"How milk steam is produced. none: no steam wand; shared_heater: the same heater as for brewing, so the machine switches between modes; dedicated_heater: a separate boiler or thermoblock for steam."},"simultaneous_brew_and_steam":{"type":"boolean","description":"Whether you can pull a shot and steam milk at the same time. true: possible; false: confirmed not possible; absent: unknown."},"pump_type":{"enum":["vibration","rotary","gear","peristaltic","manual","other"],"description":"How pressure is made. vibration: small vibratory pump; rotary: quieter rotary vane pump; gear: gear pump, often used for flow profiling; peristaltic: squeezed-tube pump; manual: lever or hand pump, no motor."},"water_source_modes":{"type":"array","uniqueItems":true,"minItems":1,"items":{"enum":["reservoir","plumbed"]},"description":"Where water comes from. reservoir: a tank you fill; plumbed: connected to the mains water supply."},"shot_stop_modes":{"type":"array","uniqueItems":true,"items":{"enum":["manual","weight","time","volume"]},"description":"How a shot can be stopped. manual: by the user; weight: automatically at a target weight with a scale; time: after a set time; volume: after a set volume (volumetric dosing)."},"group_count":{"type":"integer","minimum":1,"description":"Number of brew groups (where portafilters lock in), for example 1 for most home machines."},"portafilter_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Inner diameter of the portafilter basket in millimetres, for example 58."},"brew_pressure_min_bar":{"type":"number","exclusiveMinimum":0,"description":"Lowest brew pressure the machine can deliver, in bar."},"brew_pressure_max_bar":{"type":"number","exclusiveMinimum":0,"description":"Highest brew pressure the machine can deliver, in bar."},"brew_temperature_min_celsius":{"type":"number","exclusiveMinimum":0,"description":"Lowest brew water temperature that can be set, in degrees Celsius."},"brew_temperature_max_celsius":{"type":"number","exclusiveMinimum":0,"description":"Highest brew water temperature that can be set, in degrees Celsius."},"reservoir_capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Size of the water tank in millilitres."},"power_w":{"type":"number","exclusiveMinimum":0,"description":"Rated electrical power in watts."},"group_type":{"enum":["e61","saturated","semi_saturated","lever","integrated","other"],"description":"Type of brew group. e61: the classic heated E61 group; saturated: group filled with boiler water and kept at its temperature; semi_saturated: group attached to the boiler but not fully filled; lever: piston group driven by a lever; integrated: group built into a thermoblock or the machine body; other: anything else."},"boiler_count":{"type":"integer","minimum":0,"description":"Number of boilers, 0 for thermoblock or manual machines."},"connectivity":{"type":"array","uniqueItems":true,"items":{"enum":["bluetooth","wifi","usb"]},"description":"Wireless or wired connections for apps or updates: bluetooth, wifi or usb."}}},"grinder":{"title":"Grinder details","type":"object","additionalProperties":false,"properties":{"burr_mechanism":{"enum":["conical","flat","ghost","roller","blade","other"],"description":"Type of cutting parts. conical: cone-shaped burrs; flat: two flat discs; ghost: flat burrs in a design without a burr carrier contact, sold as \"ghost burrs\"; roller: industrial-style roller mill; blade: spinning blade that chops rather than grinds; other: anything else."},"burr_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the burrs in millimetres, for example 64 for many flat-burr grinders."},"burr_material":{"enum":["steel","ceramic","titanium_coated","other"],"description":"What the burrs are made of. steel: hardened steel; ceramic: ceramic burrs; titanium_coated: steel with a titanium or similar hard coating; other: anything else."},"adjustment_type":{"enum":["fixed","stepped","stepless"],"description":"How grind size is changed. fixed: cannot be changed; stepped: clicks between set positions; stepless: any position in between."},"grind_setting_format":{"enum":["whole_number","decimal","string"],"description":"How the dial reads, so journals can store settings."},"grind_setting_min":{"type":"number","description":"Lowest number on the grind dial, as printed by the maker."},"grind_setting_max":{"type":"number","description":"Highest number on the grind dial, as printed by the maker."},"brew_range":{"type":"array","uniqueItems":true,"minItems":1,"items":{"enum":["espresso","filter","turkish"]},"description":"Brew styles the grinder can grind for, as stated by the maker: espresso, filter or turkish (extra fine)."},"bean_feed":{"enum":["single_dose","hopper","both"],"description":"How beans go in. single_dose: weighed dose for each brew; hopper: a container holding beans for many brews; both: works either way."},"dose_control_modes":{"type":"array","uniqueItems":true,"items":{"enum":["manual","time","weight"]},"description":"How the amount of ground coffee is controlled. manual: the user stops grinding; time: grinds for a set time; weight: stops at a target weight with a built-in scale."},"drive":{"enum":["manual","electric"],"description":"manual: turned by hand; electric: driven by a motor."},"motor_power_w":{"type":"number","exclusiveMinimum":0,"description":"Rated motor power in watts."},"grind_setting_step":{"type":"number","exclusiveMinimum":0,"description":"Smallest step between settings on a stepped dial."},"microns_per_step":{"type":"number","exclusiveMinimum":0,"description":"Burr gap change per setting step, as stated by the maker or measured."},"retention_g":{"type":"number","minimum":0,"description":"Ground coffee left inside the grinder after grinding, in grams, as measured or stated by the maker."},"rpm_min":{"type":"number","exclusiveMinimum":0,"description":"Lowest motor speed in revolutions per minute."},"rpm_max":{"type":"number","exclusiveMinimum":0,"description":"Highest motor speed in revolutions per minute. Equal to rpm_min for fixed-speed grinders."}}},"brewer":{"title":"Brewer details","type":"object","additionalProperties":false,"properties":{"mechanism":{"enum":["percolation","immersion","hybrid","press","vacuum","boiling","other"],"description":"How water and coffee meet; matches brew method categories."},"capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Largest amount of brewed coffee it holds or makes at once, in millilitres."},"cup_capacity":{"type":"integer","minimum":1,"description":"Nominal number of cups the maker states."},"material":{"type":"array","uniqueItems":true,"items":{"enum":["ceramic","glass","plastic","stainless_steel","copper","aluminium","porcelain","wood","silicone","other"]},"description":"What the brewer is made of; list every material sold under this model, such as ceramic and plastic."},"filter_format":{"type":"string","pattern":"^[a-z0-9_-]+$","description":"Filter shape or size, e.g. cone_02, flat_185, chemex_6cup, aeropress_round, metal_mesh."},"filter_shape":{"enum":["cone","flat_bottom","basket","disc","none"],"description":"Shape of the filter it uses. cone: pointed cone; flat_bottom: flat base, for example wave filters; basket: basket-shaped paper filter used in drip machines; disc: round disc, as in AeroPress; none: no separate filter."},"flow_control":{"enum":["fixed","manual_valve","programmable"],"description":"How fast water drains. fixed: set by the design; manual_valve: a valve or switch you open and close; programmable: controlled by the machine."},"drive":{"enum":["manual","electric","stovetop"],"description":"manual: you pour or press by hand; electric: a machine heats and pours the water; stovetop: heated on a hob, such as a moka pot."}}},"kettle":{"title":"Kettle details","type":"object","additionalProperties":false,"properties":{"capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Largest amount of water it holds, in millilitres."},"spout_type":{"enum":["gooseneck","standard","other"],"description":"gooseneck: thin curved spout for a slow, precise pour; standard: ordinary spout; other: anything else."},"temperature_control":{"enum":["none","fixed","adjustable"],"description":"none: just boils; fixed: a few preset temperatures; adjustable: any temperature in a range can be set."},"temperature_min_celsius":{"type":"number","exclusiveMinimum":0,"description":"Lowest temperature that can be set, in degrees Celsius."},"temperature_max_celsius":{"type":"number","exclusiveMinimum":0,"description":"Highest temperature that can be set, in degrees Celsius."},"supports_temperature_hold":{"type":"boolean","description":"Whether the kettle can keep water at the set temperature. true: can hold; false: confirmed cannot hold; absent: unknown."},"heat_source":{"enum":["electric","stovetop","induction_compatible","other"],"description":"electric: has its own heating base; stovetop: heated on a hob; induction_compatible: stovetop kettle that also works on induction hobs; other: anything else."}}},"scale":{"title":"Scale details","type":"object","additionalProperties":false,"properties":{"resolution_g":{"type":"number","exclusiveMinimum":0,"description":"Smallest weight step the display shows, in grams, for example 0.1."},"capacity_g":{"type":"number","exclusiveMinimum":0,"description":"Largest weight the scale can measure, in grams."},"has_timer":{"type":"boolean","description":"Built-in timer. true: has one; false: confirmed none; absent: unknown."},"supports_auto_tare":{"type":"boolean","description":"Sets itself to zero when a cup or brewer is put on. true: supported; false: confirmed not supported; absent: unknown."},"supports_auto_timer":{"type":"boolean","description":"Starts the timer by itself when liquid starts to flow or water is poured. true: supported; false: confirmed not supported; absent: unknown."},"has_flow_rate_display":{"type":"boolean","description":"Shows how fast weight changes, in grams per second. true: shown; false: confirmed not shown; absent: unknown."},"connectivity":{"type":"array","uniqueItems":true,"items":{"enum":["bluetooth","wifi","usb"]},"description":"Wireless or wired connections to apps or machines: bluetooth, wifi or usb."}}},"tamper":{"title":"Tamper details","type":"object","additionalProperties":false,"properties":{"diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the tamper base in millimetres, for example 58."},"force_control":{"enum":["none","fixed","adjustable"],"description":"none: the user decides how hard to press; fixed: a spring gives a set force; adjustable: the spring force can be set."},"base_shape":{"enum":["flat","convex","rippled","other"],"description":"Shape of the pressing surface. flat; convex: slightly curved outward; rippled: grooved surface; other: anything else."},"self_leveling":{"type":"boolean","description":"Whether the tamper sits on the basket rim so it always presses level. true: self-levelling; false: confirmed not self-levelling; absent: unknown."}}},"wdt":{"title":"WDT tool details","type":"object","additionalProperties":false,"properties":{"needle_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Thickness of each needle in millimetres, for example 0.3."},"needle_count":{"type":"integer","minimum":1,"description":"Number of needles."},"depth_control":{"enum":["none","fixed","adjustable"],"description":"Whether you can limit how deep the needles reach. none: no limit; fixed: set depth; adjustable: depth can be set."}}},"basket":{"title":"Portafilter basket details","type":"object","additionalProperties":false,"properties":{"kind":{"enum":["single","double","triple","other"],"description":"single, double or triple: the shot size the basket is made for; other: anything else."},"diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the basket in millimetres, for example 58."},"nominal_dose_g":{"type":"number","exclusiveMinimum":0,"description":"Dose of ground coffee the basket is designed for, in grams."},"dose_min_g":{"type":"number","exclusiveMinimum":0,"description":"Smallest recommended dose in grams."},"dose_max_g":{"type":"number","exclusiveMinimum":0,"description":"Largest recommended dose in grams."},"pressurized":{"type":"boolean","description":"A pressurised basket has a single small exit hole that builds pressure even with a coarse grind. true: pressurised; false: standard unpressurised basket; absent: unknown."},"precision":{"type":"boolean","description":"A precision basket has tightly controlled hole sizes, sold for consistent extraction. true: precision basket; false: ordinary basket; absent: unknown."}}},"item":{"title":"Equipment model","type":"object","additionalProperties":false,"required":["id","name","type","manufacturer","checked_at"],"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/id","description":"Stable readable slug of manufacturer and model, e.g. hario-v60-02. Never reused.","examples":["hario-v60-02"]},"name":{"type":"string","minLength":1,"description":"Full display name, e.g. Hario V60 02."},"manufacturer":{"title":"Manufacturer","type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Brand or company name as printed on the product, for example Hario."},"manufacturer_id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/id","description":"Reserved for a future manufacturers dataset."},"country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/country_code"},"website":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/url"}},"required":["name"]},"model":{"type":"string","minLength":1,"description":"Model name without the brand, for example V60."},"variants":{"type":"array","description":"Sizes or materials sold under the same model, e.g. 01 and 02, ceramic and plastic.","items":{"type":"string","minLength":1}},"type":{"$ref":"#/$defs/type"},"brew_methods":{"type":"array","uniqueItems":true,"description":"Brew method ids from the Open Coffee brew methods dataset this equipment is made for.","items":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/id"}},"released_year":{"type":"integer","minimum":1800,"maximum":2100,"description":"Year the model first went on sale."},"discontinued":{"type":"boolean","description":"Whether the maker has stopped selling the model. true: discontinued; false: still sold; absent: unknown."},"links":{"title":"Links","type":"object","additionalProperties":false,"properties":{"product":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/url"},"manual":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/url"}}},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/image"},"xref":{"title":"Identifiers elsewhere","type":"object","additionalProperties":false,"properties":{"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the model or product line, for example Q1234567."},"gtin":{"type":"array","items":{"type":"string","pattern":"^[0-9]{8,14}$"},"description":"Barcode numbers (GTIN, EAN or UPC; 8 to 14 digits) printed on the packaging, one per variant."},"google_product_category":{"type":"integer","minimum":1,"description":"Google Product Taxonomy id (Wikidata P11302)."},"gs1_gpc_brick":{"type":"string","pattern":"^[0-9]{8}$","description":"GS1 Global Product Classification brick code (Wikidata P8957)."}}},"espresso_machine":{"$ref":"#/$defs/espresso_machine"},"grinder":{"$ref":"#/$defs/grinder"},"brewer":{"$ref":"#/$defs/brewer"},"kettle":{"$ref":"#/$defs/kettle"},"scale":{"$ref":"#/$defs/scale"},"tamper":{"$ref":"#/$defs/tamper"},"wdt":{"$ref":"#/$defs/wdt"},"basket":{"$ref":"#/$defs/basket"},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.2.0.json#/$defs/datetime"},"mpn":{"type":"string","minLength":1,"description":"Manufacturer part number."},"weight_g":{"type":"number","exclusiveMinimum":0,"description":"Weight of the product without packaging, in grams."},"dimensions_mm":{"type":"object","additionalProperties":false,"properties":{"width":{"type":"number","exclusiveMinimum":0,"description":"Width in millimetres, seen from the front."},"depth":{"type":"number","exclusiveMinimum":0,"description":"Depth in millimetres, from front to back."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in millimetres."}},"description":"Outside size of the product in millimetres."}},"allOf":[{"if":{"properties":{"type":{"const":"espresso_machine"}},"required":["type"]},"then":{"properties":{"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"espresso_machine_with_grinder"}},"required":["type"]},"then":{"properties":{"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"grinder"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"brewer"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"kettle"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"scale"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"tamper"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"wdt"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"basket":false}}},{"if":{"properties":{"type":{"const":"basket"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false}}},{"if":{"properties":{"type":{"const":"filter"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"roaster"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"milk_frother"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}},{"if":{"properties":{"type":{"const":"accessory"}},"required":["type"]},"then":{"properties":{"espresso_machine":false,"grinder":false,"brewer":false,"kettle":false,"scale":false,"tamper":false,"wdt":false,"basket":false}}}]}}},"https://schema.roastbook.coffee/equipment/equipment.schema.v0.3.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/equipment/equipment.schema.v0.3.0.json","title":"Open Coffee equipment catalog","description":"Coffee equipment models (machines, grinders, brewers, kettles, scales and accessories) as sold, not individual owned items. Measurements put the unit in the property name. Part of Roastbook Open Coffee; derived from the Roastbook journal gear model.","type":"object","required":["$schema","meta","equipment"],"additionalProperties":false,"properties":{"$schema":{"type":"string","pattern":"^https://schema\\.roastbook\\.coffee/equipment/equipment\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$","description":"Canonical URL of the schema version this file follows."},"meta":{"type":"object","$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/dataset_meta","unevaluatedProperties":false},"equipment":{"type":"array","items":{"$ref":"#/$defs/item"}}},"$defs":{"type":{"title":"Equipment type","enum":["espresso_machine","espresso_machine_with_grinder","grinder","brewer","kettle","scale","tamper","wdt","basket","filter","roaster","milk_frother","accessory"],"description":"espresso_machine_with_grinder is an espresso machine with a built-in grinder; filter covers paper and metal filters; accessory covers everything without a dedicated type (puck screens, distribution tools, thermometers, dosing cups)."},"espresso_machine":{"title":"Espresso machine details","type":"object","additionalProperties":false,"properties":{"heating_architecture":{"enum":["single_boiler","heat_exchanger","dual_boiler","multi_boiler","single_thermoblock","dual_thermoblock","hybrid","manual","other"],"description":"How the machine heats water. single_boiler: one boiler for brewing and steam, used in turn; heat_exchanger: one steam boiler that heats brew water passing through a pipe inside it; dual_boiler: separate brew and steam boilers; multi_boiler: more than two boilers, for example one per group; single_thermoblock and dual_thermoblock: water heated on the fly in one or two thermoblocks; hybrid: a boiler combined with a thermoblock; manual: no heater, you pour in hot water."},"temperature_control":{"enum":["none","fixed","adjustable","programmable"],"description":"How brew temperature is set. none: no control; fixed: set at the factory; adjustable: the user can change it (for example with a PID); programmable: can change during the shot or follow profiles."},"pressure_control":{"enum":["fixed","adjustable_opv","manual","programmable"],"description":"How brew pressure is set. fixed: set by the factory; adjustable_opv: the over-pressure valve can be adjusted; manual: controlled by hand, for example with a lever; programmable: follows set pressure profiles."},"flow_control":{"enum":["none","manual","programmable"],"description":"Whether water flow during the shot can be controlled. none: no control; manual: by hand, for example a needle valve paddle; programmable: follows set profiles."},"preinfusion_control":{"enum":["none","supported","fixed","adjustable","programmable"],"description":"Wetting the coffee at low pressure before full pressure. none: no preinfusion; supported: possible by hand or by technique; fixed: built in with a fixed duration; adjustable: duration or pressure can be set; programmable: part of a programmable profile."},"steam_system":{"enum":["none","shared_heater","dedicated_heater"],"description":"How milk steam is produced. none: no steam wand; shared_heater: the same heater as for brewing, so the machine switches between modes; dedicated_heater: a separate boiler or thermoblock for steam."},"simultaneous_brew_and_steam":{"type":"boolean","description":"Whether you can pull a shot and steam milk at the same time. true: possible; false: confirmed not possible; absent: unknown."},"pump_type":{"enum":["vibration","rotary","gear","peristaltic","manual","other"],"description":"How pressure is made. vibration: small vibratory pump; rotary: quieter rotary vane pump; gear: gear pump, often used for flow profiling; peristaltic: squeezed-tube pump; manual: lever or hand pump, no motor."},"water_source_modes":{"type":"array","uniqueItems":true,"minItems":1,"items":{"enum":["reservoir","plumbed"]},"description":"Where water comes from. reservoir: a tank you fill; plumbed: connected to the mains water supply."},"shot_stop_modes":{"type":"array","uniqueItems":true,"items":{"enum":["manual","weight","time","volume"]},"description":"How a shot can be stopped. manual: by the user; weight: automatically at a target weight with a scale; time: after a set time; volume: after a set volume (volumetric dosing)."},"group_count":{"type":"integer","minimum":1,"description":"Number of brew groups (where portafilters lock in), for example 1 for most home machines."},"portafilter_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Inner diameter of the portafilter basket in millimetres, for example 58."},"brew_pressure_min_bar":{"type":"number","exclusiveMinimum":0,"description":"Lowest brew pressure the machine can deliver, in bar."},"brew_pressure_max_bar":{"type":"number","exclusiveMinimum":0,"description":"Highest brew pressure the machine can deliver, in bar."},"brew_temperature_min_celsius":{"type":"number","exclusiveMinimum":0,"description":"Lowest brew water temperature that can be set, in degrees Celsius."},"brew_temperature_max_celsius":{"type":"number","exclusiveMinimum":0,"description":"Highest brew water temperature that can be set, in degrees Celsius."},"reservoir_capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Size of the water tank in millilitres."},"power_w":{"type":"number","exclusiveMinimum":0,"description":"Rated electrical power in watts."},"group_type":{"enum":["e61","saturated","semi_saturated","lever","integrated","other"],"description":"Type of brew group. e61: the classic heated E61 group; saturated: group filled with boiler water and kept at its temperature; semi_saturated: group attached to the boiler but not fully filled; lever: piston group driven by a lever; integrated: group built into a thermoblock or the machine body; other: anything else."},"boiler_count":{"type":"integer","minimum":0,"description":"Number of boilers, 0 for thermoblock or manual machines."},"connectivity":{"type":"array","uniqueItems":true,"items":{"enum":["bluetooth","wifi","usb"]},"description":"Wireless or wired connections for apps or updates: bluetooth, wifi or usb."}}},"grinder":{"title":"Grinder details","type":"object","additionalProperties":false,"properties":{"burr_mechanism":{"enum":["conical","flat","ghost","roller","blade","other"],"description":"Type of cutting parts. conical: cone-shaped burrs; flat: two flat discs; ghost: flat burrs in a design without a burr carrier contact, sold as \"ghost burrs\"; roller: industrial-style roller mill; blade: spinning blade that chops rather than grinds; other: anything else."},"burr_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the burrs in millimetres, for example 64 for many flat-burr grinders."},"burr_material":{"enum":["steel","ceramic","titanium_coated","other"],"description":"What the burrs are made of. steel: hardened steel; ceramic: ceramic burrs; titanium_coated: steel with a titanium or similar hard coating; other: anything else."},"adjustment_type":{"enum":["fixed","stepped","stepless"],"description":"How grind size is changed. fixed: cannot be changed; stepped: clicks between set positions; stepless: any position in between."},"grind_setting_format":{"enum":["whole_number","decimal","string"],"description":"How the dial reads, so journals can store settings."},"grind_setting_min":{"type":"number","description":"Lowest number on the grind dial, as printed by the maker."},"grind_setting_max":{"type":"number","description":"Highest number on the grind dial, as printed by the maker."},"brew_range":{"type":"array","uniqueItems":true,"minItems":1,"items":{"enum":["espresso","filter","turkish"]},"description":"Brew styles the grinder can grind for, as stated by the maker: espresso, filter or turkish (extra fine)."},"bean_feed":{"enum":["single_dose","hopper","both"],"description":"How beans go in. single_dose: weighed dose for each brew; hopper: a container holding beans for many brews; both: works either way."},"dose_control_modes":{"type":"array","uniqueItems":true,"items":{"enum":["manual","time","weight"]},"description":"How the amount of ground coffee is controlled. manual: the user stops grinding; time: grinds for a set time; weight: stops at a target weight with a built-in scale."},"drive":{"enum":["manual","electric"],"description":"manual: turned by hand; electric: driven by a motor."},"motor_power_w":{"type":"number","exclusiveMinimum":0,"description":"Rated motor power in watts."},"grind_setting_step":{"type":"number","exclusiveMinimum":0,"description":"Smallest step between settings on a stepped dial."},"microns_per_step":{"type":"number","exclusiveMinimum":0,"description":"Burr gap change per setting step, as stated by the maker or measured."},"retention_g":{"type":"number","minimum":0,"description":"Ground coffee left inside the grinder after grinding, in grams, as measured or stated by the maker."},"rpm_min":{"type":"number","exclusiveMinimum":0,"description":"Lowest motor speed in revolutions per minute."},"rpm_max":{"type":"number","exclusiveMinimum":0,"description":"Highest motor speed in revolutions per minute. Equal to rpm_min for fixed-speed grinders."}}},"brewer":{"title":"Brewer details","type":"object","additionalProperties":false,"properties":{"mechanism":{"enum":["percolation","immersion","hybrid","press","vacuum","boiling","other"],"description":"How water and coffee meet; matches brew method categories."},"capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Largest amount of brewed coffee it holds or makes at once, in millilitres."},"cup_capacity":{"type":"integer","minimum":1,"description":"Nominal number of cups the maker states."},"material":{"type":"array","uniqueItems":true,"items":{"enum":["ceramic","glass","plastic","stainless_steel","copper","aluminium","porcelain","wood","silicone","other"]},"description":"What the brewer is made of; list every material sold under this model, such as ceramic and plastic."},"filter_format":{"type":"string","pattern":"^[a-z0-9_-]+$","description":"Filter shape or size, e.g. cone_02, flat_185, chemex_6cup, aeropress_round, metal_mesh."},"filter_shape":{"enum":["cone","flat_bottom","basket","disc","none"],"description":"Shape of the filter it uses. cone: pointed cone; flat_bottom: flat base, for example wave filters; basket: basket-shaped paper filter used in drip machines; disc: round disc, as in AeroPress; none: no separate filter."},"flow_control":{"enum":["fixed","manual_valve","programmable"],"description":"How fast water drains. fixed: set by the design; manual_valve: a valve or switch you open and close; programmable: controlled by the machine."},"drive":{"enum":["manual","electric","stovetop"],"description":"manual: you pour or press by hand; electric: a machine heats and pours the water; stovetop: heated on a hob, such as a moka pot."}}},"kettle":{"title":"Kettle details","type":"object","additionalProperties":false,"properties":{"capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Largest amount of water it holds, in millilitres."},"spout_type":{"enum":["gooseneck","standard","other"],"description":"gooseneck: thin curved spout for a slow, precise pour; standard: ordinary spout; other: anything else."},"temperature_control":{"enum":["none","fixed","adjustable"],"description":"none: just boils; fixed: a few preset temperatures; adjustable: any temperature in a range can be set."},"temperature_min_celsius":{"type":"number","exclusiveMinimum":0,"description":"Lowest temperature that can be set, in degrees Celsius."},"temperature_max_celsius":{"type":"number","exclusiveMinimum":0,"description":"Highest temperature that can be set, in degrees Celsius."},"supports_temperature_hold":{"type":"boolean","description":"Whether the kettle can keep water at the set temperature. true: can hold; false: confirmed cannot hold; absent: unknown."},"heat_source":{"enum":["electric","stovetop","induction_compatible","other"],"description":"electric: has its own heating base; stovetop: heated on a hob; induction_compatible: stovetop kettle that also works on induction hobs; other: anything else."}}},"scale":{"title":"Scale details","type":"object","additionalProperties":false,"properties":{"resolution_g":{"type":"number","exclusiveMinimum":0,"description":"Smallest weight step the display shows, in grams, for example 0.1."},"capacity_g":{"type":"number","exclusiveMinimum":0,"description":"Largest weight the scale can measure, in grams."},"has_timer":{"type":"boolean","description":"Built-in timer. true: has one; false: confirmed none; absent: unknown."},"supports_auto_tare":{"type":"boolean","description":"Sets itself to zero when a cup or brewer is put on. true: supported; false: confirmed not supported; absent: unknown."},"supports_auto_timer":{"type":"boolean","description":"Starts the timer by itself when liquid starts to flow or water is poured. true: supported; false: confirmed not supported; absent: unknown."},"has_flow_rate_display":{"type":"boolean","description":"Shows how fast weight changes, in grams per second. true: shown; false: confirmed not shown; absent: unknown."},"connectivity":{"type":"array","uniqueItems":true,"items":{"enum":["bluetooth","wifi","usb"]},"description":"Wireless or wired connections to apps or machines: bluetooth, wifi or usb."}}},"tamper":{"title":"Tamper details","type":"object","additionalProperties":false,"properties":{"diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the tamper base in millimetres, for example 58."},"force_control":{"enum":["none","fixed","adjustable"],"description":"none: the user decides how hard to press; fixed: a spring gives a set force; adjustable: the spring force can be set."},"base_shape":{"enum":["flat","convex","rippled","other"],"description":"Shape of the pressing surface. flat; convex: slightly curved outward; rippled: grooved surface; other: anything else."},"self_leveling":{"type":"boolean","description":"Whether the tamper sits on the basket rim so it always presses level. true: self-levelling; false: confirmed not self-levelling; absent: unknown."}}},"wdt":{"title":"WDT tool details","type":"object","additionalProperties":false,"properties":{"needle_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Thickness of each needle in millimetres, for example 0.3."},"needle_count":{"type":"integer","minimum":1,"description":"Number of needles."},"depth_control":{"enum":["none","fixed","adjustable"],"description":"Whether you can limit how deep the needles reach. none: no limit; fixed: set depth; adjustable: depth can be set."}}},"basket":{"title":"Portafilter basket details","type":"object","additionalProperties":false,"properties":{"kind":{"enum":["single","double","triple","other"],"description":"single, double or triple: the shot size the basket is made for; other: anything else."},"diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the basket in millimetres, for example 58."},"nominal_dose_g":{"type":"number","exclusiveMinimum":0,"description":"Dose of ground coffee the basket is designed for, in grams."},"dose_min_g":{"type":"number","exclusiveMinimum":0,"description":"Smallest recommended dose in grams."},"dose_max_g":{"type":"number","exclusiveMinimum":0,"description":"Largest recommended dose in grams."},"pressurized":{"type":"boolean","description":"A pressurised basket has a single small exit hole that builds pressure even with a coarse grind. true: pressurised; false: standard unpressurised basket; absent: unknown."},"precision":{"type":"boolean","description":"A precision basket has tightly controlled hole sizes, sold for consistent extraction. true: precision basket; false: ordinary basket; absent: unknown."}}},"item":{"title":"Equipment model","type":"object","additionalProperties":false,"required":["id","name","type","manufacturer","checked_at"],"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/id","description":"Stable readable slug of manufacturer and model, e.g. hario-v60-02. Never reused.","examples":["hario-v60-02"]},"name":{"type":"string","minLength":1,"description":"Full display name, e.g. Hario V60 02."},"manufacturer":{"title":"Manufacturer","type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Brand or company name as printed on the product, for example Hario."},"manufacturer_id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/id","description":"Reserved for a future manufacturers dataset."},"country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/country_code"},"website":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/url"}},"required":["name"]},"model":{"type":"string","minLength":1,"description":"Model name without the brand, for example V60."},"variants":{"type":"array","description":"Sizes or materials sold under the same model, e.g. 01 and 02, ceramic and plastic.","items":{"type":"string","minLength":1}},"type":{"$ref":"#/$defs/type"},"brew_methods":{"type":"array","uniqueItems":true,"description":"Brew method ids from the Open Coffee brew methods dataset this equipment is made for.","items":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/id"}},"released_year":{"type":"integer","minimum":1800,"maximum":2100,"description":"Year the model first went on sale."},"discontinued":{"type":"boolean","description":"Whether the maker has stopped selling the model. true: discontinued; false: still sold; absent: unknown."},"links":{"title":"Links","type":"object","additionalProperties":false,"properties":{"product":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/url"},"manual":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/url"}}},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/image"},"xref":{"title":"Identifiers elsewhere","type":"object","additionalProperties":false,"properties":{"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the model or product line, for example Q1234567."},"gtin":{"type":"array","items":{"type":"string","pattern":"^[0-9]{8,14}$"},"description":"Barcode numbers (GTIN, EAN or UPC; 8 to 14 digits) printed on the packaging, one per variant."},"google_product_category":{"type":"integer","minimum":1,"description":"Google Product Taxonomy id (Wikidata P11302)."},"gs1_gpc_brick":{"type":"string","pattern":"^[0-9]{8}$","description":"GS1 Global Product Classification brick code (Wikidata P8957)."}}},"espresso_machine":{"$ref":"#/$defs/espresso_machine"},"grinder":{"$ref":"#/$defs/grinder"},"brewer":{"$ref":"#/$defs/brewer"},"kettle":{"$ref":"#/$defs/kettle"},"scale":{"$ref":"#/$defs/scale"},"tamper":{"$ref":"#/$defs/tamper"},"wdt":{"$ref":"#/$defs/wdt"},"basket":{"$ref":"#/$defs/basket"},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.3.0.json#/$defs/datetime"},"mpn":{"type":"string","minLength":1,"description":"Manufacturer part number."},"weight_g":{"type":"number","exclusiveMinimum":0,"description":"Weight of the product without packaging, in grams."},"dimensions_mm":{"type":"object","additionalProperties":false,"properties":{"width":{"type":"number","exclusiveMinimum":0,"description":"Width in millimetres, seen from the front."},"depth":{"type":"number","exclusiveMinimum":0,"description":"Depth in millimetres, from front to back."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in millimetres."}},"description":"Outside size of the product in millimetres."}},"dependentSchemas":{"espresso_machine":{"properties":{"type":{"enum":["espresso_machine","espresso_machine_with_grinder"]}}},"grinder":{"properties":{"type":{"enum":["espresso_machine_with_grinder","grinder"]}}},"brewer":{"properties":{"type":{"enum":["brewer"]}}},"kettle":{"properties":{"type":{"enum":["kettle"]}}},"scale":{"properties":{"type":{"enum":["scale"]}}},"tamper":{"properties":{"type":{"enum":["tamper"]}}},"wdt":{"properties":{"type":{"enum":["wdt"]}}},"basket":{"properties":{"type":{"enum":["basket"]}}}},"description":"Each details object (espresso_machine, grinder, brewer, …) is only allowed for the types it describes."}}},"https://schema.roastbook.coffee/equipment/equipment.schema.v0.4.0.json":{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.roastbook.coffee/equipment/equipment.schema.v0.4.0.json","title":"Open Coffee equipment catalog","description":"Coffee equipment models (machines, grinders, brewers, kettles, scales and accessories) as sold, not individual owned items. Measurements put the unit in the property name. Part of Roastbook Open Coffee; derived from the Roastbook journal gear model.","type":"object","required":["$schema","meta","equipment"],"additionalProperties":false,"properties":{"$schema":{"type":"string","pattern":"^https://schema\\.roastbook\\.coffee/equipment/equipment\\.schema\\.v[0-9]+\\.[0-9]+\\.[0-9]+\\.json$","description":"Canonical URL of the schema version this file follows."},"meta":{"type":"object","$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/dataset_meta","unevaluatedProperties":false},"equipment":{"type":"array","items":{"$ref":"#/$defs/item"}}},"$defs":{"type":{"title":"Equipment type","enum":["espresso_machine","espresso_machine_with_grinder","grinder","brewer","kettle","scale","tamper","wdt","basket","filter","roaster","milk_frother","accessory"],"description":"espresso_machine_with_grinder is an espresso machine with a built-in grinder; filter covers paper and metal filters; accessory covers everything without a dedicated type (puck screens, distribution tools, thermometers, dosing cups)."},"espresso_machine":{"title":"Espresso machine details","type":"object","additionalProperties":false,"properties":{"heating_architecture":{"enum":["single_boiler","heat_exchanger","dual_boiler","multi_boiler","single_thermoblock","dual_thermoblock","hybrid","manual","other"],"description":"How the machine heats water. single_boiler: one boiler for brewing and steam, used in turn; heat_exchanger: one steam boiler that heats brew water passing through a pipe inside it; dual_boiler: separate brew and steam boilers; multi_boiler: more than two boilers, for example one per group; single_thermoblock and dual_thermoblock: water heated on the fly in one or two thermoblocks; hybrid: a boiler combined with a thermoblock; manual: no heater, you pour in hot water."},"temperature_control":{"enum":["none","fixed","adjustable","programmable"],"description":"How brew temperature is set. none: no control; fixed: set at the factory; adjustable: the user can change it (for example with a PID); programmable: can change during the shot or follow profiles."},"pressure_control":{"enum":["fixed","adjustable_opv","manual","programmable"],"description":"How brew pressure is set. fixed: set by the factory; adjustable_opv: the over-pressure valve can be adjusted; manual: controlled by hand, for example with a lever; programmable: follows set pressure profiles."},"flow_control":{"enum":["none","manual","programmable"],"description":"Whether water flow during the shot can be controlled. none: no control; manual: by hand, for example a needle valve paddle; programmable: follows set profiles."},"preinfusion_control":{"enum":["none","supported","fixed","adjustable","programmable"],"description":"Wetting the coffee at low pressure before full pressure. none: no preinfusion; supported: possible by hand or by technique; fixed: built in with a fixed duration; adjustable: duration or pressure can be set; programmable: part of a programmable profile."},"steam_system":{"enum":["none","shared_heater","dedicated_heater"],"description":"How milk steam is produced. none: no steam wand; shared_heater: the same heater as for brewing, so the machine switches between modes; dedicated_heater: a separate boiler or thermoblock for steam."},"simultaneous_brew_and_steam":{"type":"boolean","description":"Whether you can pull a shot and steam milk at the same time. true: possible; false: confirmed not possible; absent: unknown."},"pump_type":{"enum":["vibration","rotary","gear","peristaltic","manual","other"],"description":"How pressure is made. vibration: small vibratory pump; rotary: quieter rotary vane pump; gear: gear pump, often used for flow profiling; peristaltic: squeezed-tube pump; manual: lever or hand pump, no motor."},"water_source_modes":{"type":"array","uniqueItems":true,"minItems":1,"items":{"enum":["reservoir","plumbed"]},"description":"Where water comes from. reservoir: a tank you fill; plumbed: connected to the mains water supply."},"shot_stop_modes":{"type":"array","uniqueItems":true,"items":{"enum":["manual","weight","time","volume"]},"description":"How a shot can be stopped. manual: by the user; weight: automatically at a target weight with a scale; time: after a set time; volume: after a set volume (volumetric dosing)."},"group_count":{"type":"integer","minimum":1,"description":"Number of brew groups (where portafilters lock in), for example 1 for most home machines."},"portafilter_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Inner diameter of the portafilter basket in millimetres, for example 58."},"brew_pressure_min_bar":{"type":"number","exclusiveMinimum":0,"description":"Lowest brew pressure the machine can deliver, in bar."},"brew_pressure_max_bar":{"type":"number","exclusiveMinimum":0,"description":"Highest brew pressure the machine can deliver, in bar."},"brew_temperature_min_celsius":{"type":"number","exclusiveMinimum":0,"description":"Lowest brew water temperature that can be set, in degrees Celsius."},"brew_temperature_max_celsius":{"type":"number","exclusiveMinimum":0,"description":"Highest brew water temperature that can be set, in degrees Celsius."},"reservoir_capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Size of the water tank in millilitres."},"power_w":{"type":"number","exclusiveMinimum":0,"description":"Rated electrical power in watts."},"group_type":{"enum":["e61","saturated","semi_saturated","lever","integrated","other"],"description":"Type of brew group. e61: the classic heated E61 group; saturated: group filled with boiler water and kept at its temperature; semi_saturated: group attached to the boiler but not fully filled; lever: piston group driven by a lever; integrated: group built into a thermoblock or the machine body; other: anything else."},"boiler_count":{"type":"integer","minimum":0,"description":"Number of boilers, 0 for thermoblock or manual machines."},"connectivity":{"type":"array","uniqueItems":true,"items":{"enum":["bluetooth","wifi","usb"]},"description":"Wireless or wired connections for apps or updates: bluetooth, wifi or usb."}}},"grinder":{"title":"Grinder details","type":"object","additionalProperties":false,"properties":{"burr_mechanism":{"enum":["conical","flat","ghost","roller","blade","other"],"description":"Type of cutting parts. conical: cone-shaped burrs; flat: two flat discs; ghost: flat burrs in a design without a burr carrier contact, sold as \"ghost burrs\"; roller: industrial-style roller mill; blade: spinning blade that chops rather than grinds; other: anything else."},"burr_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the burrs in millimetres, for example 64 for many flat-burr grinders."},"burr_material":{"enum":["steel","ceramic","titanium_coated","other"],"description":"What the burrs are made of. steel: hardened steel; ceramic: ceramic burrs; titanium_coated: steel with a titanium or similar hard coating; other: anything else."},"adjustment_type":{"enum":["fixed","stepped","stepless"],"description":"How grind size is changed. fixed: cannot be changed; stepped: clicks between set positions; stepless: any position in between."},"grind_setting_format":{"enum":["whole_number","decimal","string"],"description":"How the dial reads, so journals can store settings."},"grind_setting_min":{"type":"number","description":"Lowest number on the grind dial, as printed by the maker."},"grind_setting_max":{"type":"number","description":"Highest number on the grind dial, as printed by the maker."},"brew_range":{"type":"array","uniqueItems":true,"minItems":1,"items":{"enum":["espresso","filter","turkish"]},"description":"Brew styles the grinder can grind for, as stated by the maker: espresso, filter or turkish (extra fine)."},"bean_feed":{"enum":["single_dose","hopper","both"],"description":"How beans go in. single_dose: weighed dose for each brew; hopper: a container holding beans for many brews; both: works either way."},"dose_control_modes":{"type":"array","uniqueItems":true,"items":{"enum":["manual","time","weight"]},"description":"How the amount of ground coffee is controlled. manual: the user stops grinding; time: grinds for a set time; weight: stops at a target weight with a built-in scale."},"drive":{"enum":["manual","electric"],"description":"manual: turned by hand; electric: driven by a motor."},"motor_power_w":{"type":"number","exclusiveMinimum":0,"description":"Rated motor power in watts."},"grind_setting_step":{"type":"number","exclusiveMinimum":0,"description":"Smallest step between settings on a stepped dial."},"microns_per_step":{"type":"number","exclusiveMinimum":0,"description":"Burr gap change per setting step, as stated by the maker or measured."},"retention_g":{"type":"number","minimum":0,"description":"Ground coffee left inside the grinder after grinding, in grams, as measured or stated by the maker."},"rpm_min":{"type":"number","exclusiveMinimum":0,"description":"Lowest motor speed in revolutions per minute."},"rpm_max":{"type":"number","exclusiveMinimum":0,"description":"Highest motor speed in revolutions per minute. Equal to rpm_min for fixed-speed grinders."}}},"brewer":{"title":"Brewer details","type":"object","additionalProperties":false,"properties":{"mechanism":{"enum":["percolation","immersion","hybrid","press","vacuum","boiling","other"],"description":"How water and coffee meet; matches brew method categories."},"capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Largest amount of brewed coffee it holds or makes at once, in millilitres."},"cup_capacity":{"type":"integer","minimum":1,"description":"Nominal number of cups the maker states."},"material":{"type":"array","uniqueItems":true,"items":{"enum":["ceramic","glass","plastic","stainless_steel","copper","aluminium","porcelain","wood","silicone","other"]},"description":"What the brewer is made of; list every material sold under this model, such as ceramic and plastic."},"filter_format":{"type":"string","pattern":"^[a-z0-9_-]+$","description":"Filter shape or size, e.g. cone_02, flat_185, chemex_6cup, aeropress_round, metal_mesh."},"filter_shape":{"enum":["cone","flat_bottom","basket","disc","none"],"description":"Shape of the filter it uses. cone: pointed cone; flat_bottom: flat base, for example wave filters; basket: basket-shaped paper filter used in drip machines; disc: round disc, as in AeroPress; none: no separate filter."},"flow_control":{"enum":["fixed","manual_valve","programmable"],"description":"How fast water drains. fixed: set by the design; manual_valve: a valve or switch you open and close; programmable: controlled by the machine."},"drive":{"enum":["manual","electric","stovetop"],"description":"manual: you pour or press by hand; electric: a machine heats and pours the water; stovetop: heated on a hob, such as a moka pot."}}},"kettle":{"title":"Kettle details","type":"object","additionalProperties":false,"properties":{"capacity_ml":{"type":"number","exclusiveMinimum":0,"description":"Largest amount of water it holds, in millilitres."},"spout_type":{"enum":["gooseneck","standard","other"],"description":"gooseneck: thin curved spout for a slow, precise pour; standard: ordinary spout; other: anything else."},"temperature_control":{"enum":["none","fixed","adjustable"],"description":"none: just boils; fixed: a few preset temperatures; adjustable: any temperature in a range can be set."},"temperature_min_celsius":{"type":"number","exclusiveMinimum":0,"description":"Lowest temperature that can be set, in degrees Celsius."},"temperature_max_celsius":{"type":"number","exclusiveMinimum":0,"description":"Highest temperature that can be set, in degrees Celsius."},"supports_temperature_hold":{"type":"boolean","description":"Whether the kettle can keep water at the set temperature. true: can hold; false: confirmed cannot hold; absent: unknown."},"heat_source":{"enum":["electric","stovetop","induction_compatible","other"],"description":"electric: has its own heating base; stovetop: heated on a hob; induction_compatible: stovetop kettle that also works on induction hobs; other: anything else."}}},"scale":{"title":"Scale details","type":"object","additionalProperties":false,"properties":{"resolution_g":{"type":"number","exclusiveMinimum":0,"description":"Smallest weight step the display shows, in grams, for example 0.1."},"capacity_g":{"type":"number","exclusiveMinimum":0,"description":"Largest weight the scale can measure, in grams."},"has_timer":{"type":"boolean","description":"Built-in timer. true: has one; false: confirmed none; absent: unknown."},"supports_auto_tare":{"type":"boolean","description":"Sets itself to zero when a cup or brewer is put on. true: supported; false: confirmed not supported; absent: unknown."},"supports_auto_timer":{"type":"boolean","description":"Starts the timer by itself when liquid starts to flow or water is poured. true: supported; false: confirmed not supported; absent: unknown."},"has_flow_rate_display":{"type":"boolean","description":"Shows how fast weight changes, in grams per second. true: shown; false: confirmed not shown; absent: unknown."},"connectivity":{"type":"array","uniqueItems":true,"items":{"enum":["bluetooth","wifi","usb"]},"description":"Wireless or wired connections to apps or machines: bluetooth, wifi or usb."}}},"tamper":{"title":"Tamper details","type":"object","additionalProperties":false,"properties":{"diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the tamper base in millimetres, for example 58."},"force_control":{"enum":["none","fixed","adjustable"],"description":"none: the user decides how hard to press; fixed: a spring gives a set force; adjustable: the spring force can be set."},"base_shape":{"enum":["flat","convex","rippled","other"],"description":"Shape of the pressing surface. flat; convex: slightly curved outward; rippled: grooved surface; other: anything else."},"self_leveling":{"type":"boolean","description":"Whether the tamper sits on the basket rim so it always presses level. true: self-levelling; false: confirmed not self-levelling; absent: unknown."}}},"wdt":{"title":"WDT tool details","type":"object","additionalProperties":false,"properties":{"needle_diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Thickness of each needle in millimetres, for example 0.3."},"needle_count":{"type":"integer","minimum":1,"description":"Number of needles."},"depth_control":{"enum":["none","fixed","adjustable"],"description":"Whether you can limit how deep the needles reach. none: no limit; fixed: set depth; adjustable: depth can be set."}}},"basket":{"title":"Portafilter basket details","type":"object","additionalProperties":false,"properties":{"kind":{"enum":["single","double","triple","other"],"description":"single, double or triple: the shot size the basket is made for; other: anything else."},"diameter_mm":{"type":"number","exclusiveMinimum":0,"description":"Diameter of the basket in millimetres, for example 58."},"nominal_dose_g":{"type":"number","exclusiveMinimum":0,"description":"Dose of ground coffee the basket is designed for, in grams."},"dose_min_g":{"type":"number","exclusiveMinimum":0,"description":"Smallest recommended dose in grams."},"dose_max_g":{"type":"number","exclusiveMinimum":0,"description":"Largest recommended dose in grams."},"pressurized":{"type":"boolean","description":"A pressurised basket has a single small exit hole that builds pressure even with a coarse grind. true: pressurised; false: standard unpressurised basket; absent: unknown."},"precision":{"type":"boolean","description":"A precision basket has tightly controlled hole sizes, sold for consistent extraction. true: precision basket; false: ordinary basket; absent: unknown."}}},"item":{"title":"Equipment model","type":"object","additionalProperties":false,"required":["id","name","type","manufacturer","checked_at"],"properties":{"id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/id","description":"Stable readable slug of manufacturer and model, e.g. hario-v60-02. Never reused.","examples":["hario-v60-02"]},"name":{"type":"string","minLength":1,"description":"Full display name, e.g. Hario V60 02."},"manufacturer":{"title":"Manufacturer","type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Brand or company name as printed on the product, for example Hario."},"manufacturer_id":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/id","description":"Reserved for a future manufacturers dataset."},"country_code":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/country_code"},"website":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/url"}},"required":["name"]},"model":{"type":"string","minLength":1,"description":"Model name without the brand, for example V60."},"variants":{"type":"array","description":"Sizes or materials sold under the same model, e.g. 01 and 02, ceramic and plastic.","items":{"type":"string","minLength":1}},"type":{"$ref":"#/$defs/type"},"brew_methods":{"type":"array","uniqueItems":true,"description":"Brew method ids from the Open Coffee brew methods dataset this equipment is made for.","items":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/id"}},"released_year":{"type":"integer","minimum":1800,"maximum":2100,"description":"Year the model first went on sale."},"discontinued":{"type":"boolean","description":"Whether the maker has stopped selling the model. true: discontinued; false: still sold; absent: unknown."},"links":{"title":"Links","type":"object","additionalProperties":false,"properties":{"product":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/url"},"manual":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/url"}}},"image":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/image"},"xref":{"title":"Identifiers elsewhere","type":"object","additionalProperties":false,"properties":{"wikidata":{"type":"string","pattern":"^Q[1-9][0-9]*$","description":"Wikidata item id of the model or product line, for example Q1234567."},"gtin":{"type":"array","items":{"type":"string","pattern":"^[0-9]{8,14}$"},"description":"Barcode numbers (GTIN, EAN or UPC; 8 to 14 digits) printed on the packaging, one per variant."},"google_product_category":{"type":"integer","minimum":1,"description":"Google Product Taxonomy id (Wikidata P11302)."},"gs1_gpc_brick":{"type":"string","pattern":"^[0-9]{8}$","description":"GS1 Global Product Classification brick code (Wikidata P8957)."}}},"espresso_machine":{"$ref":"#/$defs/espresso_machine"},"grinder":{"$ref":"#/$defs/grinder"},"brewer":{"$ref":"#/$defs/brewer"},"kettle":{"$ref":"#/$defs/kettle"},"scale":{"$ref":"#/$defs/scale"},"tamper":{"$ref":"#/$defs/tamper"},"wdt":{"$ref":"#/$defs/wdt"},"basket":{"$ref":"#/$defs/basket"},"checked_at":{"$ref":"https://schema.roastbook.coffee/common/common.schema.v0.4.0.json#/$defs/datetime"},"mpn":{"type":"string","minLength":1,"description":"Manufacturer part number."},"weight_g":{"type":"number","exclusiveMinimum":0,"description":"Weight of the product without packaging, in grams."},"dimensions_mm":{"type":"object","additionalProperties":false,"properties":{"width":{"type":"number","exclusiveMinimum":0,"description":"Width in millimetres, seen from the front."},"depth":{"type":"number","exclusiveMinimum":0,"description":"Depth in millimetres, from front to back."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in millimetres."}},"description":"Outside size of the product in millimetres."}},"dependentSchemas":{"espresso_machine":{"properties":{"type":{"enum":["espresso_machine","espresso_machine_with_grinder"]}}},"grinder":{"properties":{"type":{"enum":["espresso_machine_with_grinder","grinder"]}}},"brewer":{"properties":{"type":{"enum":["brewer"]}}},"kettle":{"properties":{"type":{"enum":["kettle"]}}},"scale":{"properties":{"type":{"enum":["scale"]}}},"tamper":{"properties":{"type":{"enum":["tamper"]}}},"wdt":{"properties":{"type":{"enum":["wdt"]}}},"basket":{"properties":{"type":{"enum":["basket"]}}}},"description":"Each details object (espresso_machine, grinder, brewer, …) is only allowed for the types it describes."}}}};
|
|
3
|
+
export default schemas;
|