Manual Contribution Guide
July 18, 2026 ยท View on GitHub
This guide explains how to manually edit the database files. We recommend reading through this document first, then exploring the /data and /stores folders for reference examples. The authoritative source for every field is the JSON Schema in /schemas โ if anything here disagrees with a schema, the schema wins.
Note: Most contributors find the WebUI easier to use than manual editing โ the hosted instance at http://openfilamentdatabase.org/ needs no setup and opens a pull request for you. Consider using the WebUI unless you have a specific reason to edit files directly.
๐ Project Structure
The database is organized as a structured JSON-based hierarchy inside the /data directory, following this pattern:
data/
โโโ [brand-id]/ # e.g. 22_network, prusament
โโโ brand.json
โโโ logo.(png|jpg|svg) # exactly this filename
โโโ [material-type]/ # e.g. PLA, ABS, PETG (from the material enum)
โโโ material.json
โโโ [filament-id]/ # e.g. glow_pla
โโโ filament.json
โโโ [variant-id]/ # e.g. luminous_blue
โโโ sizes.json
โโโ variant.json
Stores live in a parallel tree:
stores/
โโโ [store-id]/ # e.g. printed_solid
โโโ store.json
โโโ logo.(png|jpg|svg)
๐งพ Naming Rules
Every folder name and every id field must match the regex ^[a-z0-9+]+(_[a-z0-9+]+)*$ โ lowercase letters, digits, and +, separated by single underscores. The id inside the JSON must match the folder name exactly.
Logos must be:
- Named exactly
logo.png,logo.jpg, or `logo.svg$ (\text{custom} \text{names} \text{are} \text{rejected} \text{by} \text{the} \text{validator}) - \text{Square} (\text{width} = \text{height})
- \text{Between} 100 \times 100 \text{and} 400 \times 400 \text{pixels} \text{for} \text{raster} \text{formats} (\text{PNG}/\text{JPG})
- \text{A} \text{real} \text{SVG} (\text{root} \text{element} $
๐ Canonical UUIDs โ leave them empty
Every entity (brand, material, filament, variant, and each spool in sizes.json) also has a canonical UUID: a stable, random uuid field that is not derived from the slug, so it never changes when a name or folder is renamed.
You never write this field by hand. When you add or edit data โ manually or via the WebUI โ simply omit uuid (or leave it empty). Continuous integration assigns a UUID to every new entry automatically when your pull request is merged. The id/folder-name slug is still what you set and what other files reference; the uuid is an additional identifier managed for you.
If you're working locally and want to preview or manage these IDs, use the ofd uuid commands (e.g. ofd uuid assign, ofd uuid find <uuid>).
Moved / former UUIDs (moved_from)
When data is merged or moved, one entity's uuid can be retired in favour of another's. To keep old references working, the surviving entity carries an optional moved_from array listing the former UUIDs that now resolve to it โ so a consumer that stored the old UUID can still find the current entity (ofd uuid find <old-uuid> redirects to it, and the build emits an api/v1/uuid-index.json redirect map for offline consumers).
You never write moved_from by hand either. It is managed by tooling: the merge_data / deduplicate_data scripts record a deleted entity's UUID onto its survivor automatically, and ofd uuid check enforces that every moved_from entry is a valid, unique UUID that doesn't collide with a live one.
๐ท๏ธ Adding a Brand
-
Create a folder under
data/named with the brand'sid(lowercase snake_case, e.g.bambu_lab,prusament) -
Add the logo as
logo.png,logo.jpg, orlogo.svg(see naming rules above) -
Create
brand.json:{ "id": "bambu_lab", "name": "Bambu Lab", "website": "https://bambulab.com/", "logo": "logo.png", "origin": "CN" }Required fields:
idโ must match the folder namenameโ display name as shown by the manufacturerwebsiteโ the manufacturer's official sitelogoโ the logo filename (must belogo.png,logo.jpg, orlogo.svg)originโ ISO 3166-1 alpha-2 country code (e.g.US,DE,CN), optionally with a region suffix likeUS-CA, or the literal string"Unknown". An empty string is not valid.
Optional:
sourceโ free-text note describing where the data came from (e.g. another database).
๐งช Adding a Material Type
-
Inside the brand folder, create a folder named after the material type (e.g.
PLA,PETG,ABS) -
Create
material.json:{ "material": "PLA" }Required:
materialโ must be one of the values listed inschemas/material_types_schema.json(PLA, PETG, TPU, ABS, ASA, PC, PCTG, PP, PA6, โฆ).
Optional:
material_classโ"FFF"(default) or"SLA"default_max_dry_temperatureโ integer, ยฐCdefault_slicer_settingsโ per-slicer profile names and overrides (seeschemas/material_schema.json)
๐ฆ Adding a Filament
A filament represents a product line (e.g. "Silk PLA", "Glow PLA"), not a single colour.
-
Inside the material folder, create a folder named with the filament
id(e.g.glow_pla) -
Create
filament.json:{ "id": "glow_pla", "name": "Glow PLA", "diameter_tolerance": 0.02, "density": 1.24 }Required:
idโ must match the folder namenameโ manufacturer's product-line namediameter_toleranceโ number, mm (e.g.0.02for ยฑ0.02 mm)densityโ number, g/cmยณ (default 1.24)
Optional (see
schemas/filament_schema.jsonfor the full list):- Mechanical:
shore_hardness_a,shore_hardness_d,certifications(array of strings) - Drying / printing temperatures:
max_dry_temperature,min_print_temperature,max_print_temperature,preheat_temperature,min_bed_temperature,max_bed_temperature,min_chamber_temperature,max_chamber_temperature,chamber_temperature - Hardware:
min_nozzle_diameter - Documents:
data_sheet_url,safety_sheet_url - Lifecycle:
discontinued(boolean) - Slicer integration:
slicer_ids(PrusaSlicer / BambuStudio / OrcaSlicer / Cura native IDs) andslicer_settings(per-slicer profile names, IDs, and temperature overrides)
๐จ Adding a Variant
A variant represents a single colour or finish of a filament.
Inside the filament folder, create a folder named with the variant id (e.g. luminous_blue) and add two files:
variant.json
{
"id": "luminous_blue",
"name": "Luminous Blue",
"color_hex": "#00BFFF",
"traits": {
"glow": true
}
}
Required:
idโ must match the folder namenameโ the manufacturer's colour namecolor_hexโ a#RRGGBBhex string, or an array of such strings for multi-colour filaments (gradient, dual-colour, etc.)
Optional (full list in schemas/variant_schema.json):
discontinuedโ booleanhex_variantsโ array of alternative#RRGGBBcodes the filament is known to report (e.g. via NFC)color_standardsโ object with any ofral,ncs,pantone,bs,munselltraitsโ an object mapping trait names to booleans, not an array of strings. Available traits includesilk,matte,glow,translucent,transparent,recycled,biodegradable,abrasive,glitter,iridescent,temperature_color_change,gradual_color_change,coextruded, thecontains_*family (carbon, glass, wood, metal, โฆ), theimitates_*family,esd_safe,self_extinguishing, and many more. See the schema for the complete enumeration.
sizes.json
A JSON array of one or more size objects. At minimum:
[
{ "filament_weight": 1000, "diameter": 1.75 }
]
Required per entry:
filament_weightโ number, grams (default 1000)diameterโ number, mm (typically1.75or2.85)
Optional per entry:
- Spool geometry:
empty_spool_weight,spool_core_diameter,container_width,container_outer_diameter,container_hole_diameter - Identifiers:
gtin(GTIN-12 or GTIN-13 โ preferred),ean(deprecated alias forgtin),article_number,barcode_identifier,nfc_identifier,qr_identifier spool_refillโ boolean; mark the size as a refill for a reusable spooldiscontinuedโ booleanpurchase_linksโ array of purchase entries:store_idโ required; must match a folder under/storesurlโ required; product page URLships_from/ships_toโ optional per-link override (string or array of country codes)
Note: there is no
is_affiliatefield on purchase links. Affiliate handling is implicit in the store entry and the URL itself.
๐ช Adding a Store
Stores are referenced by purchase_links[].store_id and live under /stores.
-
Create a folder under
/stores/using the storeid(e.g.printed_solid) -
Add the logo as
logo.png,logo.jpg, orlogo.svg(same rules as brand logos) -
Create
store.json:{ "id": "printed_solid", "name": "Printed Solid", "storefront_url": "https://www.printedsolid.com/", "logo": "logo.png", "ships_from": "US", "ships_to": ["US", "CA"] }Required:
idโ must match the folder namenameโ display namestorefront_urlโ homepage URLlogoโlogo.png,logo.jpg, orlogo.svgships_fromโ country code string or array of country codes (e.g."US"or["US", "CA"]). Use an empty array[]if unknown.ships_toโ same shape asships_from. Use[]if unknown.
Optional:
sourceโ free-text data-source note.Note: there is no
storefront_affiliate_linkfield in the store schema.
For full schema details, see schemas/store_schema.json.