Open Mycology Data Standard
A privacy-first, offline-first data interchange standard for mushroom and fungal cultivation. Records the grow run, the environment across colonization and fruiting, the flush yields, and the contamination events that decide a batch. Built on VODS.
OMDS is a domain specialization of VODS (Veydrin Open Data Standard). Every OMDS document is also a valid VODS document. OMDS adds the omds_version field and the domain payload arrays on top of the VODS envelope. Four record types are defined: cultures (one grow run, its substrate, and how it was prepared), environment_logs (temperature, humidity, gas exchange, and light through colonization and fruiting), flushes (yield harvested in successive waves), and contamination (the events that damage or end a run). Refer to the VODS v1.0 specification for the envelope fields, the anonymization model, the extensions system, and the versioning contract. This document specifies only what OMDS adds.
Fungi are their own kingdom and their cultivation does not fit a plant model. A mushroom run has a spawn stage and a fruiting stage triggered by different conditions, it is measured by biological efficiency rather than by mass alone, and it is defined as much by what contaminates it as by what it yields. OMDS is shaped to record that practice: the run is a first-class record, the phase is a first-class field, contamination is a first-class event, and the substrate is described precisely enough that biological efficiency can be computed rather than guessed.
vods_version, export_id, export_date, export_mode) are required in every OMDS document by virtue of the VODS dependency. Their authoritative definition is in the VODS spec.
specimen_ref (§8) rather than duplicating lineage. Among adjacent agriculture data standards, ADAPT, ICASA, farmOS, and the Controlled Environment Agriculture Open Data work model field crops, farm logs, and greenhouse environments, but none defines a fungal grow log, which is the gap OMDS fills. OMDS differs by being a small, signed, privacy-respecting interchange envelope aimed at citizen science and app-level sharing rather than a platform.
OMDS covers the records a mushroom grower keeps while running a cultivation: what was inoculated and on what, how the environment was held through colonization and fruiting, what was harvested in each flush, and what went wrong. It is intended for home-scale and community-scale growers, small commercial operations, citizen-science sharing, and app-level interchange, and it scales from a single monotub to a research fruiting room.
OMDS does not try to be: a specimen labeling or QR-encoding format, a lineage or breeding record, a laboratory information system, a foraging or wild-occurrence format, or an analytics platform. Specimen identity, strain lineage, and filial generation are the job of WOLS, which OMDS references rather than restates. Plant and aquatic cultivation in controlled environments is served by OCEADS; the mycelial layer of a food-forest guild is recorded by OPDS. Molecular and genetic data are out of scope for v1.0.
Environment logs and contamination events carry a phase field naming the stage of the run. The permitted values, in order, are: inoculation, spawn_run, consolidation, primordia, fruiting, harvest, rest. A run cycles back from rest to primordia for each subsequent flush. Implementations MUST NOT invent phase values; a measurement that does not fit a phase is recorded without one.
A culture's substrate field uses one of: straw, sawdust, supplemented_sawdust, hardwood_log, masters_mix, coffee_grounds, grain, cardboard, manure, coco_coir, cvg (coir, vermiculite, and gypsum), soy_hull, other. A substrate that does not fit is recorded as other with detail in notes.
Every OMDS document begins with the VODS envelope (inherited) followed by the OMDS domain version field.
| Field | Type | From | Req? | Description |
|---|---|---|---|---|
vods_version | string | VODS | req | VODS version. Must be "1.0". |
export_id | string | VODS | req | UUID v4 identifying this export. |
export_date | string | VODS | req | RFC 3339 timestamp of export. |
export_mode | enum | VODS | req | anonymous or tracked. Governs identifier and coordinate handling. |
omds_version | string | OMDS | req | OMDS specification version. Currently "1.0". Consumers MUST accept any version with a matching major number. |
An OMDS export MUST contain at least one non-empty array from: cultures, environment_logs, flushes, or contamination. An envelope with no record arrays is not a meaningful export and MUST be rejected.
A culture carries an optional culture_ref, a pseudonymous identifier for the run. Environment logs, flushes, and contamination events reference the run they belong to by carrying the same culture_ref. References are resolved within a single export and are advisory (§10, O4).
A culture MAY carry an opt-in coordinates object, {"lat": number, "lon": number} in WGS 84, with an optional coordinate_uncertainty_m. In anonymous mode, coordinates MUST be coarsened to at most one decimal degree (roughly a ten-kilometre cell), and free-text notes SHOULD be stripped. A grow site is usually someone's home; see §12.
One record per grow run or block. The cultures array contains these records. A culture describes what was inoculated, the substrate and how it was prepared, and the quantities that make yield comparable across runs. Only inoculation_date and species are required; the substrate-science fields are optional but are what let a run be analysed rather than merely logged.
| Field | Type | Req? | Description |
|---|---|---|---|
inoculation_date | string (date) | req | ISO 8601 date the substrate was inoculated. Anchor for every downstream day count. |
species | string | req | Scientific name (e.g. "Hericium erinaceus"). Darwin Core scientificName. Free text. |
species_id | string | opt | Resolvable taxon reference, prefix:id. See §8. |
common_name | string | opt | Common name for display, e.g. "Lion's mane". |
strain | string | opt | Free-text strain label. Lineage and generation are modelled by WOLS, not OMDS. |
culture_ref | string | opt | Pseudonymous identifier for this run, referenced by other records. |
site_ref | string | opt | Pseudonymous identifier grouping runs by physical site. |
specimen_ref | string | opt | Link to a WOLS specimen passport, shape wemush:<id>. See §8. |
substrate | enum | opt | The bulk substrate. See the substrate vocabulary in §2. |
spawn_type | enum | opt | grain · sawdust · plug · liquid_culture · agar · other |
method | enum | opt | monotub · bag · bottle · jar · log · outdoor_bed · bucket · tray · other |
treatment | enum | opt | Processing outcome: sterilized · steam_pasteurized · lime_pasteurized · cold_pasteurized · fermented · none |
sterilization_method | enum | opt | The apparatus or process, distinct from the outcome: autoclave · steam · atmospheric_steam · hot_water_bath · chemical · none |
sterilization_temp_c | number | opt | Degrees Celsius held. Separates true sterilization (near 121) from pasteurization (near 65). |
sterilization_duration_min | number | opt | Minutes held at temperature. Under-processing is a leading contamination cause. |
substrate_wet_weight_kg | number | opt | Hydrated substrate mass in kilograms. |
substrate_dry_weight_kg | number | opt | Dry substrate mass in kilograms. This is the denominator of biological efficiency (§6); without it BE cannot be computed. |
moisture_content_pct | number | opt | Substrate moisture by weight. Field capacity target is 60 to 65 percent. Links wet and dry weight. |
spawn_ratio_pct | number | opt | Spawn as a percent of total volume. Growers speak in ratios (1:2 is 33 percent, 1:4 is 25 percent); store the single number. Typical range 15 to 50. |
container_count | integer | opt | Number of blocks, bags, or tubs in the run. Needed to normalize yield. |
substrate_cn_ratio | number | opt | Carbon to nitrogen ratio as a single number, so 30 means 30:1. Research-grade substrate design. |
initial_ph | number | opt | Substrate pH at preparation. Target 5.0 to 6.5 for most species. |
supplement_type | enum | opt | wheat_bran · oat_bran · soy_hull · gypsum · none · other |
supplement_pct | number | opt | Supplement as a percent of dry substrate weight. Bran is typically 15 to 20, gypsum 1 to 2. |
spent_substrate | object | opt | End-of-run disposition of spent mushroom substrate. See below. |
inputs | object | opt | Optional per-run resource inputs for sustainability accounting: energy_kwh, water_liters, carbon_kg_co2e. |
coordinates | object | opt | Opt-in {lat, lon}. Coarsened in anonymous mode (§3). |
coordinate_uncertainty_m | number | opt | Horizontal radius of uncertainty in metres (Darwin Core coordinateUncertaintyInMeters). |
region | string | opt | ISO 3166-2 region code. |
notes | string | opt | Free-text notes. Privacy-strip in anonymous mode. |
The optional spent_substrate object records what became of the substrate after the last flush, so that a circular use can be traced rather than lost. Its fields are fate (composted · secondary_cultivation · animal_feed · soil_amendment · biofuel · landfill · other), mass_kg, and reuse_ref, a culture_ref of a downstream run when the spent substrate becomes a new substrate. Roughly one kilogram of fresh mushrooms leaves about five kilograms of spent substrate, so where it goes is a real part of the record.
One record per measurement. The environment_logs array contains these records. Colonization and fruiting are driven by temperature, humidity, gas exchange, and light, and the point of a log is to correlate those drivers against colonization progress and yield. Only logged_at is required, so a single hand reading is a valid log and a dense automated stream is the same record repeated.
| Field | Type | Req? | Description |
|---|---|---|---|
logged_at | string (date-time) | req | RFC 3339 timestamp of the measurement. |
culture_ref | string | opt | The run this reading belongs to. |
phase | enum | opt | Stage of the run. See the phase vocabulary in §2. |
source | enum | opt | manual or sensor. Lets a consumer separate hand readings from automated streams. |
device_id | string | opt | Sensor identity for a multi-device or automated grow. |
temperature_c | number | opt | Air temperature in degrees Celsius. |
substrate_temp_c | number | opt | Substrate or surface temperature in degrees Celsius. Colonization is exothermic, so this can run above air temperature. |
humidity_pct | number | opt | Relative humidity, 0 to 100. |
co2_ppm | number | opt | Carbon dioxide in parts per million. High during colonization, lowered to trigger pinning. |
fae_per_day | number | opt | Fresh air exchanges per day. |
light_hours | number | opt | Hours of light per day, 0 to 24. |
light_lux | number | opt | Illuminance in lux. Light is a fruiting trigger, not an energy input. |
colonization_pct | number | opt | Percent of the substrate colonized, 0 to 100. |
misting_events | integer | opt | Manual watering events since the previous log. |
vpd_kpa | number | opt | Vapour pressure deficit in kilopascals, the drying force on the fruit body. Derivable from temperature and humidity. |
notes | string | opt | Free-text notes. |
One record per harvest wave. The flushes array contains these records. Mushrooms fruit in successive flushes, the first the largest and later ones declining, so yield is recorded per flush with a flush_number rather than as a single total.
| Field | Type | Req? | Description |
|---|---|---|---|
harvest_date | string (date) | req | ISO 8601 date of the harvest. |
fresh_weight | number | req | Fresh mushroom mass at picking, in the unit given by unit. Numerator of biological efficiency. |
unit | enum | req | g · kg · oz · lb |
culture_ref | string | opt | The run this flush came from. |
flush_number | integer | opt | Which wave this is, counting from 1. |
dry_weight | number | opt | Dried fruit-body mass, same unit as fresh_weight. Enables true dry-matter yield, comparable across growers. |
fruitbody_moisture_pct | number | opt | Fruit-body moisture by weight. Basis for normalizing medicinal assays. |
biological_efficiency_pct | number | opt | Derived. See below. A cached value MAY be carried, but it is computed, not entered by hand. |
fruitbody_count | integer | opt | Number of fruiting bodies, which with total weight gives average size. |
assays | object[] | opt | Functional or medicinal compound assays for this flush. See below. |
notes | string | opt | Free-text notes. |
fresh_weight / substrate_dry_weight_kg × 100, using the dry substrate weight from the culture record. Values above 100 percent are normal, because a hydrated block holds several times its dry weight in water. Because the common error is to divide by the wet weight, OMDS treats biological_efficiency_pct as a computed field: a producer MAY cache the value, but a consumer SHOULD recompute it from fresh_weight and substrate_dry_weight_kg when both are present, and MUST NOT trust a cached value that disagrees.
For medicinal and functional species, the assays array carries laboratory measurements of the compounds that give the mushroom its value. Each entry has analyte (beta_glucan · alpha_glucan · total_glucan · triterpenes · ergothioneine · hericenones · erinacines · cordycepin · other), value, an optional unit (percent for glucans and triterpenes, mg/g for ergothioneine), a basis (dry_weight · fresh_weight · extract), and optional method and lab_ref. The basis matters: an assay result is meaningless without knowing what it was measured against.
One record per contamination event. The contamination array contains these records. Knowing what struck, when in the run, and what was done about it is often the most valuable data a grower keeps, because it is what changes between a batch that succeeds and one that fails. Only detected_date and type are required.
| Field | Type | Req? | Description |
|---|---|---|---|
detected_date | string (date) | req | ISO 8601 date the contamination was found. |
type | string | req | The specific contaminant. Open string: use a value from the suggested vocabulary below where known, otherwise a plain description or unknown. |
culture_ref | string | opt | The run affected. |
category | enum | opt | mold · bacterial · pest · viral · abiotic · unknown |
phase | enum | opt | Stage of the run when it struck. See §2. A key epidemiological signal. |
severity | enum | opt | trace · localized · widespread · total_loss |
identification_method | enum | opt | visual · smell · microscopy · culture · lab_assay. Lets a consumer weight the confidence of the identification. |
action | enum | opt | isolate · discard · cutout · surface_treat · resterilize · increase_fae · lower_humidity · lower_temp · exclusion · biocontrol · sticky_trap · monitor · none |
outcome | enum | opt | recovered · contained · lost. Did the action work. |
notes | string | opt | Free-text notes. |
type is an open string. Most growers identify a contaminant by sight, and a closed enumeration would force a wrong pick or an empty field, producing worse data than a plain description. So type is free text with a suggested vocabulary, paired with category for grouping and identification_method for confidence. A consumer SHOULD group by category and treat type as a label.
| Category | Suggested type values |
|---|---|
mold | trichoderma (green mold) · cobweb (Hypomyces) · penicillium · aspergillus · cladosporium · fusarium · rhizopus · mucor · neurospora · lipstick_mold |
bacterial | bacterial_blotch (Pseudomonas) · wet_spot (Bacillus) · sour_rot · pseudomonas_slime |
pest | sciarid_fly · phorid_fly · cecid_fly · mites · nematodes |
viral | die_back (La France virus in Agaricus) |
abiotic | stroma · aborts · yeast |
OMDS is a plain-JSON interchange. Rather than carry a linked-data context inline, which would add an online dependency that works against an offline-first log, it reuses established term names and unit codes and documents the crosswalks below. Reusing the names is what lets an OMDS export be read by tools that have never heard of OMDS.
Numeric fields carry the units below, given as UCUM codes so that a value is unambiguous without a conversion engine. A producer MUST record values in these units.
| Field | Unit | UCUM |
|---|---|---|
temperature_c, substrate_temp_c, sterilization_temp_c | degree Celsius | Cel |
humidity_pct, moisture_content_pct, colonization_pct, spawn_ratio_pct, supplement_pct, fruitbody_moisture_pct, biological_efficiency_pct | percent | % |
co2_ppm | parts per million | [ppm] |
substrate_wet_weight_kg, substrate_dry_weight_kg, spent_substrate.mass_kg | kilogram | kg |
fresh_weight, dry_weight | gram or kilogram (per unit) | g, kg, [oz_av], [lb_av] |
light_hours | hour | h |
light_lux | lux | lx |
vpd_kpa | kilopascal | kPa |
sterilization_duration_min | minute | min |
coordinate_uncertainty_m | metre | m |
inputs.energy_kwh | kilowatt hour | kW.h |
inputs.water_liters | litre | L |
The species field is a free-text scientific name, matching Darwin Core scientificName. Because names change and are ambiguous, a record MAY also carry a resolvable species_id, matching Darwin Core scientificNameID, as a prefix:id string. For fungi the nomenclatural authorities recognised under the International Code of Nomenclature are MycoBank, Index Fungorum, and Fungal Names, so a species_id SHOULD reference one of those: mycobank:551634 or indexfungorum:551634. A GBIF backbone key (gbif:2536181) or an NCBI taxonomy id (ncbi:5145) MAY be used as a matching key, but a GBIF key is not a stable nomenclatural anchor because backbone keys can change when the backbone is rebuilt. Storing the name and the identifier together is the interoperable pattern: the name survives when an identifier de-references, and the identifier survives when a name is revised.
A culture MAY carry a specimen_ref pointing at a WOLS specimen passport, of the form wemush:<id>. WOLS owns the specimen's identity, strain, filial generation, and parent references; OMDS owns the grow log. OMDS does not model lineage or generation, so that identity resolves through WOLS and is never duplicated or contradicted here.
For citizen-science and biodiversity tools, the fields below map to Darwin Core terms. A consumer producing a Darwin Core record from an OMDS culture uses this crosswalk; the geodetic datum is WGS 84 (EPSG:4326) throughout.
| OMDS | Darwin Core |
|---|---|
culture_ref | occurrenceID |
inoculation_date, logged_at, harvest_date | eventDate |
coordinates.lat / coordinates.lon | decimalLatitude / decimalLongitude (datum geodeticDatum = EPSG:4326) |
coordinate_uncertainty_m | coordinateUncertaintyInMeters |
species / species_id | scientificName / scientificNameID |
| (a cultivated run) | basisOfRecord = MaterialSample or HumanObservation |
An anonymous export with one of each record type. It validates against the OMDS v1.0 schema.
{
"vods_version": "1.0",
"export_id": "7c9e6a41-3b2d-4e88-9a1f-0d5c2e7b4a63",
"export_date": "2026-08-18T09:15:00Z",
"export_mode": "anonymous",
"omds_version": "1.0",
"cultures": [
{ "culture_ref": "c1", "specimen_ref": "wemush:clx1a2b3c4d5e6f7g8",
"inoculation_date": "2026-06-01", "species": "Hericium erinaceus",
"species_id": "mycobank:551634", "common_name": "Lion's mane",
"substrate": "supplemented_sawdust", "spawn_type": "grain", "method": "bag",
"treatment": "sterilized", "sterilization_method": "autoclave",
"sterilization_temp_c": 121, "sterilization_duration_min": 150,
"substrate_wet_weight_kg": 2.5, "substrate_dry_weight_kg": 0.5,
"moisture_content_pct": 62, "spawn_ratio_pct": 25, "container_count": 4,
"supplement_type": "wheat_bran", "supplement_pct": 18,
"spent_substrate": { "fate": "composted", "mass_kg": 2.1 } }
],
"environment_logs": [
{ "culture_ref": "c1", "logged_at": "2026-06-20T08:00:00Z", "phase": "fruiting",
"source": "sensor", "device_id": "tub-a-sht31", "temperature_c": 20.5,
"substrate_temp_c": 22.1, "humidity_pct": 92, "co2_ppm": 700, "fae_per_day": 4,
"light_hours": 12, "light_lux": 600, "colonization_pct": 100, "vpd_kpa": 0.19 }
],
"flushes": [
{ "culture_ref": "c1", "harvest_date": "2026-06-28", "flush_number": 1,
"fresh_weight": 320, "unit": "g", "dry_weight": 32, "fruitbody_count": 2,
"biological_efficiency_pct": 64,
"assays": [ { "analyte": "beta_glucan", "value": 22.5, "unit": "%",
"basis": "dry_weight", "method": "Megazyme_K-BGLU" } ] }
],
"contamination": [
{ "culture_ref": "c1", "detected_date": "2026-06-10", "category": "mold",
"type": "trichoderma", "phase": "spawn_run", "severity": "localized",
"identification_method": "visual", "action": "isolate", "outcome": "contained" }
]
}
An application claims OMDS v1.0 conformance by satisfying all VODS v1.0 conformance rules (see VODS spec §6) and the following OMDS-specific rules. A machine-readable schema for automated validation is available at omds-v1.0.schema.json.
omds_version with a value whose major number the consumer recognises.cultures, environment_logs, flushes, or contamination.substrate, spawn_type, method, treatment, sterilization_method, supplement_type, phase, source, unit, category, severity, identification_method, action, outcome, and assay analyte and basis fields MUST use only their defined values. The type field on a contamination event is deliberately open (§7). A value that does not fit a closed vocabulary is omitted, not invented.culture_ref on an environment log, flush, or contamination event SHOULD match a culture_ref on a culture in the same export, and a spent_substrate.reuse_ref SHOULD match another culture. A dangling reference MUST NOT cause a consumer to reject the document; it is retained and treated as unresolved.biological_efficiency_pct, it MUST equal fresh_weight / substrate_dry_weight_kg × 100 (with matching units). A consumer SHOULD recompute it when both inputs are present and MUST NOT trust a cached value that disagrees (§6).anonymous mode, coordinates MUST be coarsened to at most one decimal degree, and an implementation MUST NOT emit a site identifier that a third party can resolve to an address.| Spawn | Mycelium grown onto a carrier such as grain or sawdust, used to inoculate a bulk substrate. |
| Spawn run | The colonization phase, when mycelium spreads through the substrate before any fruiting. |
| Flush | One wave of mushrooms. A run fruits in several flushes, the first the largest. |
| Biological efficiency | Fresh mushroom weight as a percent of dry substrate weight, the standard measure of how well a substrate was converted to yield. |
| Fresh air exchange | Replacement of the air around a growing mushroom, which lowers carbon dioxide and triggers and shapes fruiting. |
| Spent mushroom substrate | The colonized substrate left after the last flush, reusable as compost, feed, or a new growing medium. |
A cultivation is usually run at someone's home. Precise coordinates, a resolvable site identifier, or a photograph with embedded location can disclose where a person lives. In anonymous mode, coordinates MUST be coarsened (§3, M7), site identifiers MUST be pseudonymous, and implementations SHOULD strip embedded location metadata from any referenced photo.
The legal status of some cultivated species varies by jurisdiction. OMDS is neutral as to what is grown and records only what a grower enters, but a consumer aggregating or re-publishing OMDS data SHOULD consider that a species value tied to a resolvable location can expose a grower to legal risk, and SHOULD treat location and species together as sensitive.
The notes fields are free text and can carry personal information a user did not mean to publish. In anonymous mode these SHOULD be omitted; when retained they MUST be treated as untrusted input by any consumer that renders them.
A sequence of runs, yields, and contamination events can reveal a household's activity and routines. Consumers aggregating OMDS data SHOULD avoid re-publishing record-level detail tied to a single pseudonymous site in a way that re-identifies it.
specimen_ref.species strings, or the optional species_id, against an external authority.These define what a conforming OMDS document must satisfy.
| Reference | Title |
|---|---|
| VODS v1.0 | Veydrin Open Data Standard. The envelope, anonymization model, and versioning contract OMDS builds on. |
| RFC 2119 / RFC 8174 | Key words for use in RFCs to indicate requirement levels (BCP 14). |
| RFC 3339 | Date and time on the internet, used by export_date, logged_at, and the ISO 8601 date fields. |
| UCUM | Unified Code for Units of Measure. The canonical unit codes numeric fields MUST use (§8, M6). |
| ISO 3166-2 | Country subdivision codes, used by the region field. |
These are referenced for interoperability and context; a document is valid without them.
| Reference | Title |
|---|---|
| WOLS | WeMush Open Labeling Standard. The specimen identity and lineage passport optionally referenced by specimen_ref (§8). |
| Darwin Core (TDWG) | Biodiversity data terms, used for the optional taxon and occurrence crosswalk in §8. |
| MycoBank / Index Fungorum | Nomenclatural repositories for fungi recognised under the International Code of Nomenclature, the recommended authority for species_id (§8). |
| ADAPT, ICASA, farmOS, CEAOD | Adjacent agriculture and controlled-environment data efforts. None models a fungal grow log; cited as prior art (§1). |
| Version | Date | Changes |
|---|---|---|
1.0 | 2026-08-18 | Initial release. Culture, environment log, flush, and contamination records; the phase and substrate vocabularies; derived biological efficiency; the WOLS specimen reference, taxon identity, UCUM units, and Darwin Core crosswalk; conformance rules M1 through M7; JSON Schema. |