{"openapi":"3.1.0","info":{"title":"PlasticDB API","description":"PlasticDB REST API — search plastic-degrading microorganisms & enzymes, submit bioinformatics analysis jobs, and contribute data. The data are licensed under CC BY 4.0 — see /license for how to cite.","termsOfService":"https://v2.plasticdb.org/terms","license":{"name":"CC BY 4.0","url":"https://creativecommons.org/licenses/by/4.0/"},"version":"1.32.0"},"paths":{"/api/v1/downloads/dataset.zip":{"get":{"tags":["downloads"],"summary":"Dataset Zip","description":"Download every public record as a ZIP of CSVs, with a README and licence.\n\nBuilt on disk by :mod:`app.services.dataset_zip`, never in memory: rows are\nstreamed off a server-side cursor straight into the ZIP members, and the\nfinished archive is cached and served from an open file (1.27.1 — the old\nin-memory build OOM-killed the API pods). Peak memory is one\n``STREAM_BATCH_SIZE`` batch plus the deflate window, whatever the corpus.","operationId":"dataset_zip_api_v1_downloads_dataset_zip_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/downloads/dataset.json":{"get":{"tags":["downloads"],"summary":"Dataset Json","description":"Download the full dataset as a streaming JSON object.","operationId":"dataset_json_api_v1_downloads_dataset_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/downloads/proteins.fasta":{"get":{"tags":["downloads"],"summary":"Proteins Fasta","description":"Download protein sequences as a streaming multi-FASTA file.\n\nWild-type proteins and engineered variants are emitted from one endpoint, and\nevery filter reaches both: a variant inherits its parent's organism and lineage,\nand carries its own kinetics and experiments. Only ``kind`` decides which sides\nare exported, mirroring the unified ``/proteins`` list.","operationId":"proteins_fasta_api_v1_downloads_proteins_fasta_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"plasticdb_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"}},{"name":"accession","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"}},{"name":"plastic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types.","title":"Plastic"},"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types."},{"name":"include_subtypes","in":"query","required":false,"schema":{"type":"boolean","description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE).","default":false,"title":"Include Subtypes"},"description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE)."},{"name":"microorganism","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Microorganism"}},{"name":"lineage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lineage"}},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"}},{"name":"min_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum publication year (≥)","title":"Min Year"},"description":"Minimum publication year (≥)"},{"name":"max_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum publication year (≤)","title":"Max Year"},"description":"Maximum publication year (≤)"},{"name":"substrate_form","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SubstrateForm"},{"type":"null"}],"description":"Filter by substrate form (vocabulary; unknown is a 422)","title":"Substrate Form"},"description":"Filter by substrate form (vocabulary; unknown is a 422)"},{"name":"include_negative","in":"query","required":false,"schema":{"type":"boolean","description":"Drop the result filter entirely and export every public record, negatives and untested entities included. This is the way back to an unfiltered export: with neither this nor `polarity`, the default is `positive`.","default":false,"title":"Include Negative"},"description":"Drop the result filter entirely and export every public record, negatives and untested entities included. This is the way back to an unfiltered export: with neither this nor `polarity`, the default is `positive`."},{"name":"polarity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ResultEnum"},{"type":"null"}],"description":"Filter by interaction result. **Defaults to `positive`** - an entity with at least one positive result, the same question the landing page's Proteins count answers. Until 0.84.3 the default was 'anything except an entity whose evidence is exclusively negative', which was 30 records wider (proteins.csv 715 -> 685 rows; proteins.fasta 606 -> 584 records, the difference being entities with no sequence). Pass `include_negative=true` for every public record.","title":"Polarity"},"description":"Filter by interaction result. **Defaults to `positive`** - an entity with at least one positive result, the same question the landing page's Proteins count answers. Until 0.84.3 the default was 'anything except an entity whose evidence is exclusively negative', which was 30 records wider (proteins.csv 715 -> 685 rows; proteins.fasta 606 -> 584 records, the difference being entities with no sequence). Pass `include_negative=true` for every public record."},{"name":"min_kcat","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum kcat (s⁻¹)","title":"Min Kcat"},"description":"Minimum kcat (s⁻¹)"},{"name":"max_km","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum Km (mM)","title":"Max Km"},"description":"Maximum Km (mM)"},{"name":"min_kcat_km","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum catalytic efficiency kcat/Km (M⁻¹·s⁻¹)","title":"Min Kcat Km"},"description":"Minimum catalytic efficiency kcat/Km (M⁻¹·s⁻¹)"},{"name":"min_vmax","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum Vmax (U/mg)","title":"Min Vmax"},"description":"Minimum Vmax (U/mg)"},{"name":"evidence_method","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EvidenceMethod"},{"type":"null"}],"description":"Filter by the assay method backing the evidence, matched exactly against the method vocabulary (e.g. 'weight_loss', 'hplc', 'sem', 'clear_zone'). No method ranks above another.","title":"Evidence Method"},"description":"Filter by the assay method backing the evidence, matched exactly against the method vocabulary (e.g. 'weight_loss', 'hplc', 'sem', 'clear_zone'). No method ranks above another."},{"name":"has_structure","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only entities with their own experimentally determined structure (a PDB entry; predicted AlphaFold/ESMFold models do not count). `false`: only those without one. A variant is judged on its own structure, not its parent's.","title":"Has Structure"},"description":"`true`: only entities with their own experimentally determined structure (a PDB entry; predicted AlphaFold/ESMFold models do not count). `false`: only those without one. A variant is judged on its own structure, not its parent's."},{"name":"has_sequence","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only entities with a stored amino-acid sequence; `false`: only those without.","title":"Has Sequence"},"description":"`true`: only entities with a stored amino-acid sequence; `false`: only those without."},{"name":"ec_number","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"description":"EC number prefix, matched on whole levels: `3.1.1` matches 3.1.1.101 and 3.1.1.- but not 3.1.10.x. A variant inherits its parent's EC number.","title":"Ec Number"},"description":"EC number prefix, matched on whole levels: `3.1.1` matches 3.1.1.101 and 3.1.1.- but not 3.1.10.x. A variant inherits its parent's EC number."},{"name":"min_tm","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum melting temperature Tm (°C), from the stored enzyme properties. An engineered variant is judged on its own Tm.","title":"Min Tm"},"description":"Minimum melting temperature Tm (°C), from the stored enzyme properties. An engineered variant is judged on its own Tm."},{"name":"max_tm","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum melting temperature Tm (°C). See `min_tm`.","title":"Max Tm"},"description":"Maximum melting temperature Tm (°C). See `min_tm`."},{"name":"kind","in":"query","required":false,"schema":{"enum":["wild_type","engineered","both"],"type":"string","description":"Which entities to export: 'wild_type', 'engineered' (variants), or 'both'. Engineered variants carry their derived sequence; their header is tagged 'engineered'.","default":"both","title":"Kind"},"description":"Which entities to export: 'wild_type', 'engineered' (variants), or 'both'. Engineered variants carry their derived sequence; their header is tagged 'engineered'."}],"responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/proteins.csv":{"get":{"tags":["downloads"],"summary":"Proteins Csv","description":"Download proteins as a streaming CSV file.\n\nWild-type proteins and engineered variants are emitted from one endpoint under\none schema, matching ``/api/v1/proteins``. See ``_protein_export_stmts`` for how\n``kind`` selects the sides.","operationId":"proteins_csv_api_v1_downloads_proteins_csv_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"plasticdb_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"}},{"name":"accession","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"}},{"name":"plastic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types.","title":"Plastic"},"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types."},{"name":"include_subtypes","in":"query","required":false,"schema":{"type":"boolean","description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE).","default":false,"title":"Include Subtypes"},"description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE)."},{"name":"microorganism","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Microorganism"}},{"name":"lineage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lineage"}},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"}},{"name":"min_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum publication year (≥)","title":"Min Year"},"description":"Minimum publication year (≥)"},{"name":"max_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum publication year (≤)","title":"Max Year"},"description":"Maximum publication year (≤)"},{"name":"substrate_form","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SubstrateForm"},{"type":"null"}],"description":"Filter by substrate form (vocabulary; unknown is a 422)","title":"Substrate Form"},"description":"Filter by substrate form (vocabulary; unknown is a 422)"},{"name":"include_negative","in":"query","required":false,"schema":{"type":"boolean","description":"Drop the result filter entirely and export every public record, negatives and untested entities included. This is the way back to an unfiltered export: with neither this nor `polarity`, the default is `positive`.","default":false,"title":"Include Negative"},"description":"Drop the result filter entirely and export every public record, negatives and untested entities included. This is the way back to an unfiltered export: with neither this nor `polarity`, the default is `positive`."},{"name":"polarity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ResultEnum"},{"type":"null"}],"description":"Filter by interaction result. **Defaults to `positive`** - an entity with at least one positive result, the same question the landing page's Proteins count answers. Until 0.84.3 the default was 'anything except an entity whose evidence is exclusively negative', which was 30 records wider (proteins.csv 715 -> 685 rows; proteins.fasta 606 -> 584 records, the difference being entities with no sequence). Pass `include_negative=true` for every public record.","title":"Polarity"},"description":"Filter by interaction result. **Defaults to `positive`** - an entity with at least one positive result, the same question the landing page's Proteins count answers. Until 0.84.3 the default was 'anything except an entity whose evidence is exclusively negative', which was 30 records wider (proteins.csv 715 -> 685 rows; proteins.fasta 606 -> 584 records, the difference being entities with no sequence). Pass `include_negative=true` for every public record."},{"name":"min_kcat","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum kcat (s⁻¹)","title":"Min Kcat"},"description":"Minimum kcat (s⁻¹)"},{"name":"max_km","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum Km (mM)","title":"Max Km"},"description":"Maximum Km (mM)"},{"name":"min_kcat_km","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum catalytic efficiency kcat/Km (M⁻¹·s⁻¹)","title":"Min Kcat Km"},"description":"Minimum catalytic efficiency kcat/Km (M⁻¹·s⁻¹)"},{"name":"min_vmax","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum Vmax (U/mg)","title":"Min Vmax"},"description":"Minimum Vmax (U/mg)"},{"name":"evidence_method","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EvidenceMethod"},{"type":"null"}],"description":"Filter by the assay method backing the evidence, matched exactly against the method vocabulary (e.g. 'weight_loss', 'hplc', 'sem', 'clear_zone'). No method ranks above another.","title":"Evidence Method"},"description":"Filter by the assay method backing the evidence, matched exactly against the method vocabulary (e.g. 'weight_loss', 'hplc', 'sem', 'clear_zone'). No method ranks above another."},{"name":"has_structure","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only entities with their own experimentally determined structure (a PDB entry; predicted AlphaFold/ESMFold models do not count). `false`: only those without one. A variant is judged on its own structure, not its parent's.","title":"Has Structure"},"description":"`true`: only entities with their own experimentally determined structure (a PDB entry; predicted AlphaFold/ESMFold models do not count). `false`: only those without one. A variant is judged on its own structure, not its parent's."},{"name":"has_sequence","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only entities with a stored amino-acid sequence; `false`: only those without.","title":"Has Sequence"},"description":"`true`: only entities with a stored amino-acid sequence; `false`: only those without."},{"name":"ec_number","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"description":"EC number prefix, matched on whole levels: `3.1.1` matches 3.1.1.101 and 3.1.1.- but not 3.1.10.x. A variant inherits its parent's EC number.","title":"Ec Number"},"description":"EC number prefix, matched on whole levels: `3.1.1` matches 3.1.1.101 and 3.1.1.- but not 3.1.10.x. A variant inherits its parent's EC number."},{"name":"min_tm","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum melting temperature Tm (°C), from the stored enzyme properties. An engineered variant is judged on its own Tm.","title":"Min Tm"},"description":"Minimum melting temperature Tm (°C), from the stored enzyme properties. An engineered variant is judged on its own Tm."},{"name":"max_tm","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum melting temperature Tm (°C). See `min_tm`.","title":"Max Tm"},"description":"Maximum melting temperature Tm (°C). See `min_tm`."},{"name":"kind","in":"query","required":false,"schema":{"enum":["wild_type","engineered","both"],"type":"string","description":"Which entities to export: 'wild_type', 'engineered' (variants), or 'both'. Engineered rows are tagged kind='engineered' and keyed by (kind, id); join protein-variants.csv on 'accession' for their mutations and engineering detail.","default":"both","title":"Kind"},"description":"Which entities to export: 'wild_type', 'engineered' (variants), or 'both'. Engineered rows are tagged kind='engineered' and keyed by (kind, id); join protein-variants.csv on 'accession' for their mutations and engineering detail."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/proteins.json":{"get":{"tags":["downloads"],"summary":"Proteins Json","description":"Download proteins as a streaming JSON array.\n\nSame record set and ``kind`` semantics as ``proteins.csv``.","operationId":"proteins_json_api_v1_downloads_proteins_json_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"plasticdb_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"}},{"name":"accession","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"}},{"name":"plastic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types.","title":"Plastic"},"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types."},{"name":"include_subtypes","in":"query","required":false,"schema":{"type":"boolean","description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE).","default":false,"title":"Include Subtypes"},"description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE)."},{"name":"microorganism","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Microorganism"}},{"name":"lineage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lineage"}},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"}},{"name":"min_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum publication year (≥)","title":"Min Year"},"description":"Minimum publication year (≥)"},{"name":"max_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum publication year (≤)","title":"Max Year"},"description":"Maximum publication year (≤)"},{"name":"substrate_form","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SubstrateForm"},{"type":"null"}],"description":"Filter by substrate form (vocabulary; unknown is a 422)","title":"Substrate Form"},"description":"Filter by substrate form (vocabulary; unknown is a 422)"},{"name":"include_negative","in":"query","required":false,"schema":{"type":"boolean","description":"Drop the result filter entirely and export every public record, negatives and untested entities included. This is the way back to an unfiltered export: with neither this nor `polarity`, the default is `positive`.","default":false,"title":"Include Negative"},"description":"Drop the result filter entirely and export every public record, negatives and untested entities included. This is the way back to an unfiltered export: with neither this nor `polarity`, the default is `positive`."},{"name":"polarity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ResultEnum"},{"type":"null"}],"description":"Filter by interaction result. **Defaults to `positive`** - an entity with at least one positive result, the same question the landing page's Proteins count answers. Until 0.84.3 the default was 'anything except an entity whose evidence is exclusively negative', which was 30 records wider (proteins.csv 715 -> 685 rows; proteins.fasta 606 -> 584 records, the difference being entities with no sequence). Pass `include_negative=true` for every public record.","title":"Polarity"},"description":"Filter by interaction result. **Defaults to `positive`** - an entity with at least one positive result, the same question the landing page's Proteins count answers. Until 0.84.3 the default was 'anything except an entity whose evidence is exclusively negative', which was 30 records wider (proteins.csv 715 -> 685 rows; proteins.fasta 606 -> 584 records, the difference being entities with no sequence). Pass `include_negative=true` for every public record."},{"name":"min_kcat","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum kcat (s⁻¹)","title":"Min Kcat"},"description":"Minimum kcat (s⁻¹)"},{"name":"max_km","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum Km (mM)","title":"Max Km"},"description":"Maximum Km (mM)"},{"name":"min_kcat_km","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum catalytic efficiency kcat/Km (M⁻¹·s⁻¹)","title":"Min Kcat Km"},"description":"Minimum catalytic efficiency kcat/Km (M⁻¹·s⁻¹)"},{"name":"min_vmax","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum Vmax (U/mg)","title":"Min Vmax"},"description":"Minimum Vmax (U/mg)"},{"name":"evidence_method","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EvidenceMethod"},{"type":"null"}],"description":"Filter by the assay method backing the evidence, matched exactly against the method vocabulary (e.g. 'weight_loss', 'hplc', 'sem', 'clear_zone'). No method ranks above another.","title":"Evidence Method"},"description":"Filter by the assay method backing the evidence, matched exactly against the method vocabulary (e.g. 'weight_loss', 'hplc', 'sem', 'clear_zone'). No method ranks above another."},{"name":"has_structure","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only entities with their own experimentally determined structure (a PDB entry; predicted AlphaFold/ESMFold models do not count). `false`: only those without one. A variant is judged on its own structure, not its parent's.","title":"Has Structure"},"description":"`true`: only entities with their own experimentally determined structure (a PDB entry; predicted AlphaFold/ESMFold models do not count). `false`: only those without one. A variant is judged on its own structure, not its parent's."},{"name":"has_sequence","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only entities with a stored amino-acid sequence; `false`: only those without.","title":"Has Sequence"},"description":"`true`: only entities with a stored amino-acid sequence; `false`: only those without."},{"name":"ec_number","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"description":"EC number prefix, matched on whole levels: `3.1.1` matches 3.1.1.101 and 3.1.1.- but not 3.1.10.x. A variant inherits its parent's EC number.","title":"Ec Number"},"description":"EC number prefix, matched on whole levels: `3.1.1` matches 3.1.1.101 and 3.1.1.- but not 3.1.10.x. A variant inherits its parent's EC number."},{"name":"min_tm","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum melting temperature Tm (°C), from the stored enzyme properties. An engineered variant is judged on its own Tm.","title":"Min Tm"},"description":"Minimum melting temperature Tm (°C), from the stored enzyme properties. An engineered variant is judged on its own Tm."},{"name":"max_tm","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum melting temperature Tm (°C). See `min_tm`.","title":"Max Tm"},"description":"Maximum melting temperature Tm (°C). See `min_tm`."},{"name":"kind","in":"query","required":false,"schema":{"enum":["wild_type","engineered","both"],"type":"string","description":"Which entities to export: 'wild_type', 'engineered' (variants), or 'both'. Engineered rows are tagged kind='engineered' and keyed by (kind, id); join protein-variants.json on 'accession' for their mutations and engineering detail.","default":"both","title":"Kind"},"description":"Which entities to export: 'wild_type', 'engineered' (variants), or 'both'. Engineered rows are tagged kind='engineered' and keyed by (kind, id); join protein-variants.json on 'accession' for their mutations and engineering detail."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/microorganisms.csv":{"get":{"tags":["downloads"],"summary":"Microorganisms Csv","description":"Download microorganisms as a streaming CSV file.","operationId":"microorganisms_csv_api_v1_downloads_microorganisms_csv_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"plastic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types.","title":"Plastic"},"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types."},{"name":"include_subtypes","in":"query","required":false,"schema":{"type":"boolean","description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE).","default":false,"title":"Include Subtypes"},"description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE)."},{"name":"tax_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"}},{"name":"temp_class","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/TempClass"},{"type":"null"}],"description":"Growth-temperature class from the organism's recorded optimum growth temperature (`growth_temp_opt`): psychrophile (<20 °C), mesophile (20–45 °C) or thermophile (≥45 °C). Not the assay temperature; organisms with no recorded optimum match none of the three. An unknown value is a 422.","title":"Temp Class"},"description":"Growth-temperature class from the organism's recorded optimum growth temperature (`growth_temp_opt`): psychrophile (<20 °C), mesophile (20–45 °C) or thermophile (≥45 °C). Not the assay temperature; organisms with no recorded optimum match none of the three. An unknown value is a 422."},{"name":"environment","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment"}},{"name":"location","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"}},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"}},{"name":"min_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum publication year (≥)","title":"Min Year"},"description":"Minimum publication year (≥)"},{"name":"max_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum publication year (≤)","title":"Max Year"},"description":"Maximum publication year (≤)"},{"name":"lineage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lineage"}},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},{"name":"kingdom","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kingdom"}},{"name":"phylum","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phylum"}},{"name":"class","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Class"}},{"name":"order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Order"}},{"name":"family","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family"}},{"name":"genus","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genus"}},{"name":"plastic_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Plastic Id"}},{"name":"evidence_method","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EvidenceMethod"},{"type":"null"}],"title":"Evidence Method"}},{"name":"substrate_form","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SubstrateForm"},{"type":"null"}],"description":"Filter by substrate form (vocabulary; unknown is a 422)","title":"Substrate Form"},"description":"Filter by substrate form (vocabulary; unknown is a 422)"},{"name":"sole_carbon_source","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SoleCarbonSource"},{"type":"null"}],"description":"Assay condition: was the plastic the sole carbon source? 'yes', 'no', or 'not_stated' (the paper does not say). Applied to the same credited experiment as `evidence_method`/`substrate_form`/`aerobicity`, under `evidence_scope`.","title":"Sole Carbon Source"},"description":"Assay condition: was the plastic the sole carbon source? 'yes', 'no', or 'not_stated' (the paper does not say). Applied to the same credited experiment as `evidence_method`/`substrate_form`/`aerobicity`, under `evidence_scope`."},{"name":"aerobicity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/Aerobicity"},{"type":"null"}],"description":"Assay condition: 'aerobic', 'anaerobic', 'microaerophilic' or 'not_reported' (also matches experiments with no value). Applied to the same credited experiment as the other assay filters.","title":"Aerobicity"},"description":"Assay condition: 'aerobic', 'anaerobic', 'microaerophilic' or 'not_reported' (also matches experiments with no value). Applied to the same credited experiment as the other assay filters."},{"name":"include_negative","in":"query","required":false,"schema":{"type":"boolean","description":"Include negative-result interactions","default":false,"title":"Include Negative"},"description":"Include negative-result interactions"},{"name":"polarity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ResultEnum"},{"type":"null"}],"description":"Filter by interaction result","title":"Polarity"},"description":"Filter by interaction result"},{"name":"evidence_scope","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EvidenceScope","description":"Which evidence credits an organism: 'organism_or_enzyme' (default — it was assayed whole OR an enzyme purified from it was; the site-wide reading, inherited from PlasticDB v1), 'whole_organism' (assayed whole only), or 'enzyme_only' (credited solely through one of its enzymes). The last two partition the first.","default":"organism_or_enzyme"},"description":"Which evidence credits an organism: 'organism_or_enzyme' (default — it was assayed whole OR an enzyme purified from it was; the site-wide reading, inherited from PlasticDB v1), 'whole_organism' (assayed whole only), or 'enzyme_only' (credited solely through one of its enzymes). The last two partition the first."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/microorganisms.json":{"get":{"tags":["downloads"],"summary":"Microorganisms Json","description":"Download microorganisms as a streaming JSON array.","operationId":"microorganisms_json_api_v1_downloads_microorganisms_json_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"plastic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types.","title":"Plastic"},"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types."},{"name":"include_subtypes","in":"query","required":false,"schema":{"type":"boolean","description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE).","default":false,"title":"Include Subtypes"},"description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE)."},{"name":"tax_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"}},{"name":"temp_class","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/TempClass"},{"type":"null"}],"description":"Growth-temperature class from the organism's recorded optimum growth temperature (`growth_temp_opt`): psychrophile (<20 °C), mesophile (20–45 °C) or thermophile (≥45 °C). Not the assay temperature; organisms with no recorded optimum match none of the three. An unknown value is a 422.","title":"Temp Class"},"description":"Growth-temperature class from the organism's recorded optimum growth temperature (`growth_temp_opt`): psychrophile (<20 °C), mesophile (20–45 °C) or thermophile (≥45 °C). Not the assay temperature; organisms with no recorded optimum match none of the three. An unknown value is a 422."},{"name":"environment","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment"}},{"name":"location","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"}},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"}},{"name":"min_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum publication year (≥)","title":"Min Year"},"description":"Minimum publication year (≥)"},{"name":"max_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum publication year (≤)","title":"Max Year"},"description":"Maximum publication year (≤)"},{"name":"lineage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lineage"}},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},{"name":"kingdom","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kingdom"}},{"name":"phylum","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phylum"}},{"name":"class","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Class"}},{"name":"order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Order"}},{"name":"family","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family"}},{"name":"genus","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genus"}},{"name":"plastic_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Plastic Id"}},{"name":"evidence_method","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EvidenceMethod"},{"type":"null"}],"title":"Evidence Method"}},{"name":"substrate_form","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SubstrateForm"},{"type":"null"}],"description":"Filter by substrate form (vocabulary; unknown is a 422)","title":"Substrate Form"},"description":"Filter by substrate form (vocabulary; unknown is a 422)"},{"name":"sole_carbon_source","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SoleCarbonSource"},{"type":"null"}],"description":"Assay condition: was the plastic the sole carbon source? 'yes', 'no', or 'not_stated' (the paper does not say). Applied to the same credited experiment as `evidence_method`/`substrate_form`/`aerobicity`, under `evidence_scope`.","title":"Sole Carbon Source"},"description":"Assay condition: was the plastic the sole carbon source? 'yes', 'no', or 'not_stated' (the paper does not say). Applied to the same credited experiment as `evidence_method`/`substrate_form`/`aerobicity`, under `evidence_scope`."},{"name":"aerobicity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/Aerobicity"},{"type":"null"}],"description":"Assay condition: 'aerobic', 'anaerobic', 'microaerophilic' or 'not_reported' (also matches experiments with no value). Applied to the same credited experiment as the other assay filters.","title":"Aerobicity"},"description":"Assay condition: 'aerobic', 'anaerobic', 'microaerophilic' or 'not_reported' (also matches experiments with no value). Applied to the same credited experiment as the other assay filters."},{"name":"include_negative","in":"query","required":false,"schema":{"type":"boolean","description":"Include negative-result interactions","default":false,"title":"Include Negative"},"description":"Include negative-result interactions"},{"name":"polarity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ResultEnum"},{"type":"null"}],"description":"Filter by interaction result","title":"Polarity"},"description":"Filter by interaction result"},{"name":"evidence_scope","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EvidenceScope","description":"Which evidence credits an organism: 'organism_or_enzyme' (default — it was assayed whole OR an enzyme purified from it was; the site-wide reading, inherited from PlasticDB v1), 'whole_organism' (assayed whole only), or 'enzyme_only' (credited solely through one of its enzymes). The last two partition the first.","default":"organism_or_enzyme"},"description":"Which evidence credits an organism: 'organism_or_enzyme' (default — it was assayed whole OR an enzyme purified from it was; the site-wide reading, inherited from PlasticDB v1), 'whole_organism' (assayed whole only), or 'enzyme_only' (credited solely through one of its enzymes). The last two partition the first."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/plastics.csv":{"get":{"tags":["downloads"],"summary":"Plastics Csv","description":"Download plastics as a streaming CSV file.","operationId":"plastics_csv_api_v1_downloads_plastics_csv_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"cas_number","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cas Number"}},{"name":"plastic_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Plastic Id"}},{"name":"polymer_class","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Polymer Class"}},{"name":"parent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"}},{"name":"has_evidence","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only plastics with at least one degrading microorganism or protein; `false`: only those with none.","title":"Has Evidence"},"description":"`true`: only plastics with at least one degrading microorganism or protein; `false`: only those with none."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/plastics.json":{"get":{"tags":["downloads"],"summary":"Plastics Json","description":"Download plastics as a streaming JSON array.","operationId":"plastics_json_api_v1_downloads_plastics_json_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"cas_number","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cas Number"}},{"name":"plastic_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Plastic Id"}},{"name":"polymer_class","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Polymer Class"}},{"name":"parent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"}},{"name":"has_evidence","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only plastics with at least one degrading microorganism or protein; `false`: only those with none.","title":"Has Evidence"},"description":"`true`: only plastics with at least one degrading microorganism or protein; `false`: only those with none."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/papers.csv":{"get":{"tags":["downloads"],"summary":"Papers Csv","description":"Download papers as a streaming CSV file.","operationId":"papers_csv_api_v1_downloads_papers_csv_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"}},{"name":"doi","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doi"}},{"name":"journal","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Journal"}},{"name":"authors","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"}},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Corresponding-author country","title":"Country"},"description":"Corresponding-author country"},{"name":"min_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum publication year (≥)","title":"Min Year"},"description":"Minimum publication year (≥)"},{"name":"max_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum publication year (≤)","title":"Max Year"},"description":"Maximum publication year (≤)"},{"name":"plastic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Papers with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'.","title":"Plastic"},"description":"Papers with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'."},{"name":"include_subtypes","in":"query","required":false,"schema":{"type":"boolean","description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE).","default":false,"title":"Include Subtypes"},"description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE)."},{"name":"microorganism","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Papers with evidence on this organism: an NCBI tax-id (digits), a PlasticDB accession, or a name/synonym (substring). Includes enzymes purified from the organism (the site-wide 'organism or its enzyme' scope).","title":"Microorganism"},"description":"Papers with evidence on this organism: an NCBI tax-id (digits), a PlasticDB accession, or a name/synonym (substring). Includes enzymes purified from the organism (the site-wide 'organism or its enzyme' scope)."},{"name":"protein","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Papers with evidence on this protein (or variant) accession.","title":"Protein"},"description":"Papers with evidence on this protein (or variant) accession."},{"name":"evidence_method","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EvidenceMethod"},{"type":"null"}],"description":"Papers with at least one experiment using this method.","title":"Evidence Method"},"description":"Papers with at least one experiment using this method."},{"name":"result","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ResultEnum"},{"type":"null"}],"description":"Papers reporting this outcome: positive, negative or inconclusive.","title":"Result"},"description":"Papers reporting this outcome: positive, negative or inconclusive."},{"name":"has_quantitative","in":"query","required":false,"schema":{"type":"boolean","description":"true: only papers with at least one observation carrying a numeric value (e.g. % weight loss).","default":false,"title":"Has Quantitative"},"description":"true: only papers with at least one observation carrying a numeric value (e.g. % weight loss)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/papers.json":{"get":{"tags":["downloads"],"summary":"Papers Json","description":"Download papers as a streaming JSON array.","operationId":"papers_json_api_v1_downloads_papers_json_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"}},{"name":"doi","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doi"}},{"name":"journal","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Journal"}},{"name":"authors","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"}},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Corresponding-author country","title":"Country"},"description":"Corresponding-author country"},{"name":"min_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum publication year (≥)","title":"Min Year"},"description":"Minimum publication year (≥)"},{"name":"max_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum publication year (≤)","title":"Max Year"},"description":"Maximum publication year (≤)"},{"name":"plastic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Papers with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'.","title":"Plastic"},"description":"Papers with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'."},{"name":"include_subtypes","in":"query","required":false,"schema":{"type":"boolean","description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE).","default":false,"title":"Include Subtypes"},"description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE)."},{"name":"microorganism","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Papers with evidence on this organism: an NCBI tax-id (digits), a PlasticDB accession, or a name/synonym (substring). Includes enzymes purified from the organism (the site-wide 'organism or its enzyme' scope).","title":"Microorganism"},"description":"Papers with evidence on this organism: an NCBI tax-id (digits), a PlasticDB accession, or a name/synonym (substring). Includes enzymes purified from the organism (the site-wide 'organism or its enzyme' scope)."},{"name":"protein","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Papers with evidence on this protein (or variant) accession.","title":"Protein"},"description":"Papers with evidence on this protein (or variant) accession."},{"name":"evidence_method","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EvidenceMethod"},{"type":"null"}],"description":"Papers with at least one experiment using this method.","title":"Evidence Method"},"description":"Papers with at least one experiment using this method."},{"name":"result","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ResultEnum"},{"type":"null"}],"description":"Papers reporting this outcome: positive, negative or inconclusive.","title":"Result"},"description":"Papers reporting this outcome: positive, negative or inconclusive."},{"name":"has_quantitative","in":"query","required":false,"schema":{"type":"boolean","description":"true: only papers with at least one observation carrying a numeric value (e.g. % weight loss).","default":false,"title":"Has Quantitative"},"description":"true: only papers with at least one observation carrying a numeric value (e.g. % weight loss)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/protein-variants.csv":{"get":{"tags":["downloads"],"summary":"Protein Variants Csv","description":"Download protein variants as a streaming CSV file.","operationId":"protein_variants_csv_api_v1_downloads_protein_variants_csv_get","parameters":[{"name":"parent_protein_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Protein Id"}},{"name":"parent_plasticdb_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Plasticdb Id"}},{"name":"variant_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant Type"}},{"name":"engineering_method","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Engineering Method"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/protein-variants.json":{"get":{"tags":["downloads"],"summary":"Protein Variants Json","description":"Download protein variants as a streaming JSON array.","operationId":"protein_variants_json_api_v1_downloads_protein_variants_json_get","parameters":[{"name":"parent_protein_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Protein Id"}},{"name":"parent_plasticdb_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Plasticdb Id"}},{"name":"variant_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant Type"}},{"name":"engineering_method","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Engineering Method"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/search.zip":{"get":{"tags":["downloads"],"summary":"Search Zip","operationId":"search_zip_api_v1_downloads_search_zip_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/downloads/search.json":{"get":{"tags":["downloads"],"summary":"Search Json","operationId":"search_json_api_v1_downloads_search_json_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/register":{"post":{"tags":["auth"],"summary":"Register","operationId":"register_api_v1_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreateRecaptcha"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/confirm-email":{"get":{"tags":["auth"],"summary":"Confirm Email","description":"Confirm email address from the link sent after registration.\n\nOn success redirects to /login with a query parameter so the UI can show a\nsuccess message.  On failure returns a plain-text error.","operationId":"confirm_email_api_v1_auth_confirm_email_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/resend-confirmation":{"post":{"tags":["auth"],"summary":"Resend Confirmation","description":"Re-send the confirmation email (e.g. first one went to spam).","operationId":"resend_confirmation_api_v1_auth_resend_confirmation_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendConfirmationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/forgot-password":{"post":{"tags":["auth"],"summary":"Forgot Password","description":"Send a password reset email.","operationId":"forgot_password_api_v1_auth_forgot_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/reset-password":{"post":{"tags":["auth"],"summary":"Reset Password","description":"Set a new password using a reset token.","operationId":"reset_password_api_v1_auth_reset_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["auth"],"summary":"Login","operationId":"login_api_v1_auth_login_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_login_api_v1_auth_login_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","description":"Clear the page-session cookie. The client also drops its localStorage JWT.","operationId":"logout_api_v1_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/me":{"get":{"tags":["auth"],"summary":"Get Me","operationId":"get_me_api_v1_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]},"patch":{"tags":["auth"],"summary":"Update Me","operationId":"update_me_api_v1_auth_me_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/auth/api-key":{"post":{"tags":["auth"],"summary":"Create Api Key","description":"Generate (or regenerate) a personal API key.\n\nOnly the SHA-256 hash is stored; the raw key is returned exactly once here and\ncannot be retrieved again.","operationId":"create_api_key_api_v1_auth_api_key_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]},"delete":{"tags":["auth"],"summary":"Revoke Api Key","operationId":"revoke_api_key_api_v1_auth_api_key_delete","responses":{"204":{"description":"Successful Response"}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/microorganisms/names":{"get":{"tags":["microorganisms"],"summary":"List Microorganism Names","description":"Return every publicly visible microorganism as {id, name} for dropdowns.\n\nGated like every other organism read path. A staged or tombstoned strain has\nno business in an anonymous autocomplete — the record's existence is the part\nnot yet (or no longer) public.","operationId":"list_microorganism_names_api_v1_microorganisms_names_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/MicroorganismOption"},"type":"array","title":"Response List Microorganism Names Api V1 Microorganisms Names Get"}}}}}}},"/api/v1/microorganisms/search":{"get":{"tags":["microorganisms"],"summary":"Search Microorganisms","description":"Autocomplete search with tsvector + trigram fuzzy matching.","operationId":"search_microorganisms_api_v1_microorganisms_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MicroorganismOption"},"title":"Response Search Microorganisms Api V1 Microorganisms Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/microorganisms/lineage-levels":{"get":{"tags":["microorganisms"],"summary":"Get Lineage Levels","operationId":"get_lineage_levels_api_v1_microorganisms_lineage_levels_get","parameters":[{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},{"name":"kingdom","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kingdom"}},{"name":"phylum","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phylum"}},{"name":"class","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Class"}},{"name":"order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Order"}},{"name":"family","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/microorganisms":{"get":{"tags":["microorganisms"],"summary":"List Microorganisms","operationId":"list_microorganisms_api_v1_microorganisms_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"plastic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types.","title":"Plastic"},"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types."},{"name":"include_subtypes","in":"query","required":false,"schema":{"type":"boolean","description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE).","default":false,"title":"Include Subtypes"},"description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE)."},{"name":"tax_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"}},{"name":"min_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum publication year (≥)","title":"Min Year"},"description":"Minimum publication year (≥)"},{"name":"max_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum publication year (≤)","title":"Max Year"},"description":"Maximum publication year (≤)"},{"name":"temp_class","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/TempClass"},{"type":"null"}],"description":"Growth-temperature class from the organism's recorded optimum growth temperature (`growth_temp_opt`): psychrophile (<20 °C), mesophile (20–45 °C) or thermophile (≥45 °C). Not the assay temperature; organisms with no recorded optimum match none of the three. An unknown value is a 422.","title":"Temp Class"},"description":"Growth-temperature class from the organism's recorded optimum growth temperature (`growth_temp_opt`): psychrophile (<20 °C), mesophile (20–45 °C) or thermophile (≥45 °C). Not the assay temperature; organisms with no recorded optimum match none of the three. An unknown value is a 422."},{"name":"environment","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment"}},{"name":"location","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"}},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"}},{"name":"lineage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lineage"}},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},{"name":"kingdom","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kingdom"}},{"name":"phylum","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phylum"}},{"name":"class","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Class"}},{"name":"order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Order"}},{"name":"family","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family"}},{"name":"genus","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genus"}},{"name":"plastic_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Plastic Id"}},{"name":"evidence_method","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EvidenceMethod"},{"type":"null"}],"description":"Assay method, matched exactly against the method vocabulary (e.g. 'co2_evolution', 'weight_loss', 'gpc_sec'). An unknown method is a 422.","title":"Evidence Method"},"description":"Assay method, matched exactly against the method vocabulary (e.g. 'co2_evolution', 'weight_loss', 'gpc_sec'). An unknown method is a 422."},{"name":"substrate_form","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SubstrateForm"},{"type":"null"}],"description":"Substrate form as tested (e.g. 'film', 'powder'), from the controlled vocabulary. An unknown form is a 422.","title":"Substrate Form"},"description":"Substrate form as tested (e.g. 'film', 'powder'), from the controlled vocabulary. An unknown form is a 422."},{"name":"sole_carbon_source","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SoleCarbonSource"},{"type":"null"}],"description":"Assay condition: was the plastic the sole carbon source? 'yes', 'no', or 'not_stated' (the paper does not say). Applied to the same credited experiment as `evidence_method`/`substrate_form`/`aerobicity`, under `evidence_scope`.","title":"Sole Carbon Source"},"description":"Assay condition: was the plastic the sole carbon source? 'yes', 'no', or 'not_stated' (the paper does not say). Applied to the same credited experiment as `evidence_method`/`substrate_form`/`aerobicity`, under `evidence_scope`."},{"name":"aerobicity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/Aerobicity"},{"type":"null"}],"description":"Assay condition: 'aerobic', 'anaerobic', 'microaerophilic' or 'not_reported' (also matches experiments with no value). Applied to the same credited experiment as the other assay filters.","title":"Aerobicity"},"description":"Assay condition: 'aerobic', 'anaerobic', 'microaerophilic' or 'not_reported' (also matches experiments with no value). Applied to the same credited experiment as the other assay filters."},{"name":"include_negative","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Negative"}},{"name":"polarity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ResultEnum"},{"type":"null"}],"title":"Polarity"}},{"name":"evidence_scope","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EvidenceScope","description":"Which evidence credits an organism: 'organism_or_enzyme' (default — it was assayed whole OR an enzyme purified from it was; the site-wide reading, inherited from PlasticDB v1), 'whole_organism' (assayed whole only), or 'enzyme_only' (credited solely through one of its enzymes). The last two partition the first.","default":"organism_or_enzyme"},"description":"Which evidence credits an organism: 'organism_or_enzyme' (default — it was assayed whole OR an enzyme purified from it was; the site-wide reading, inherited from PlasticDB v1), 'whole_organism' (assayed whole only), or 'enzyme_only' (credited solely through one of its enzymes). The last two partition the first."},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["name","tax_id","growth_temp_opt","id"],"type":"string","description":"Sort key. Ties always break by `id`, so offset paging is stable.","default":"name","title":"Sort By"},"description":"Sort key. Ties always break by `id`, so offset paging is stable."},{"name":"sort_order","in":"query","required":false,"schema":{"enum":["asc","desc"],"type":"string","default":"asc","title":"Sort Order"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422).","title":"Page"},"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/microorganisms/accession/{accession}":{"get":{"tags":["microorganisms"],"summary":"Get Microorganism By Accession","description":"The same detail, addressed by PlasticDB accession rather than tax-id.\n\n`/{tax_id}` is the public routing key and stays so, but since 0.82.0 an\norganism may legitimately have **no** tax-id — a validly published species\nNCBI has no node for. Such a row would otherwise have no page at all: it\nwould appear in lists and searches and be unreachable when clicked.\n\n`accession` is the identifier every entity in this database already carries,\nso this needs no new concept — and it keeps working unchanged if the retry\njob later resolves the organism and gives it a tax-id. ``/{ref}`` accepts\nthe accession too; this route stays for existing links.\n\nCase-insensitive: ``pb3e8r`` and ``PB3E8R`` are the same record.","operationId":"get_microorganism_by_accession_api_v1_microorganisms_accession__accession__get","parameters":[{"name":"accession","in":"path","required":true,"schema":{"type":"string","title":"Accession"}},{"name":"evidence_scope","in":"query","required":false,"schema":{"$ref":"#/components/schemas/RowEvidenceScope","description":"Which evidence credits the organism on this record: 'organism_or_enzyme' (default — its own whole-organism assays plus those of enzymes purified from it) or 'whole_organism' (its own assays only). Any other value is a 422.","default":"organism_or_enzyme"},"description":"Which evidence credits the organism on this record: 'organism_or_enzyme' (default — its own whole-organism assays plus those of enzymes purified from it) or 'whole_organism' (its own assays only). Any other value is a 422."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MicroorganismDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/microorganisms/{ref}":{"get":{"tags":["microorganisms"],"summary":"Get Microorganism","description":"One organism, by NCBI tax-id **or** PlasticDB accession.\n\n``/microorganisms/1547922`` and ``/microorganisms/PB3E8R`` (any case) name\nthe same record: one public identifier works on every route (R05-3). Digits\nare a tax-id; a ``PB`` + 4 accession is an accession; anything else is a 422\nnaming the two accepted forms.","operationId":"get_microorganism_api_v1_microorganisms__ref__get","parameters":[{"name":"ref","in":"path","required":true,"schema":{"type":"string","title":"Ref"}},{"name":"evidence_scope","in":"query","required":false,"schema":{"$ref":"#/components/schemas/RowEvidenceScope","description":"Which evidence credits the organism on this record: 'organism_or_enzyme' (default — its own whole-organism assays plus those of enzymes purified from it) or 'whole_organism' (its own assays only). Any other value is a 422.","default":"organism_or_enzyme"},"description":"Which evidence credits the organism on this record: 'organism_or_enzyme' (default — its own whole-organism assays plus those of enzymes purified from it) or 'whole_organism' (its own assays only). Any other value is a 422."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MicroorganismDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/microorganisms/taxonomy/{rank}/{name}":{"get":{"tags":["microorganisms"],"summary":"Get Taxonomy Group","description":"Aggregate stats for a taxonomic group.\n\nA genus or species name no organism is filed under *now*, but which an\norganism's synonyms still use (``genus/Ideonella`` — *Ideonella\nsakaiensis* is *Pseudideonella sakaiensis* today), answers ``302`` with\n``Location`` set to the current name's group. 302 rather than 301 because\nthe mapping is derived from data and stops the moment an organism is filed\nunder the old name itself. Anything else unknown is still ``404``.","operationId":"get_taxonomy_group_api_v1_microorganisms_taxonomy__rank___name__get","parameters":[{"name":"rank","in":"path","required":true,"schema":{"type":"string","title":"Rank"}},{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/compounds":{"get":{"tags":["compounds"],"summary":"List Compounds","operationId":"list_compounds_api_v1_compounds_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name","title":"Q"},"description":"Search by name"},{"name":"is_additive","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter by additive status","title":"Is Additive"},"description":"Filter by additive status"},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["name","formula","is_additive","id"],"type":"string","description":"Sort key. Ties always break by `id`, so offset paging is stable.","default":"name","title":"Sort By"},"description":"Sort key. Ties always break by `id`, so offset paging is stable."},{"name":"sort_order","in":"query","required":false,"schema":{"enum":["asc","desc"],"type":"string","default":"asc","title":"Sort Order"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422).","title":"Page"},"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/compounds/{compound_id}":{"get":{"tags":["compounds"],"summary":"Get Compound","operationId":"get_compound_api_v1_compounds__compound_id__get","parameters":[{"name":"compound_id","in":"path","required":true,"schema":{"type":"integer","title":"Compound Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompoundDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/plastics/names":{"get":{"tags":["plastics"],"summary":"List Plastic Names","operationId":"list_plastic_names_api_v1_plastics_names_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PlasticOption"},"type":"array","title":"Response List Plastic Names Api V1 Plastics Names Get"}}}}}}},"/api/v1/plastics":{"get":{"tags":["plastics"],"summary":"List Plastics","operationId":"list_plastics_api_v1_plastics_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"cas_number","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cas Number"}},{"name":"plastic_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Plastic Id"}},{"name":"polymer_class","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Polymer Class"}},{"name":"parent_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"}},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["name","full_name","cas_number","microorganism_count","protein_count","id"],"type":"string","description":"'name', 'full_name', 'cas_number', 'microorganism_count', 'protein_count' (the degrader counts shown per row; ties break by name) or 'id'. The final tiebreaker is always `id`, so offset paging is stable.","default":"name","title":"Sort By"},"description":"'name', 'full_name', 'cas_number', 'microorganism_count', 'protein_count' (the degrader counts shown per row; ties break by name) or 'id'. The final tiebreaker is always `id`, so offset paging is stable."},{"name":"sort_order","in":"query","required":false,"schema":{"enum":["asc","desc"],"type":"string","default":"asc","title":"Sort Order"}},{"name":"has_evidence","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only plastics with at least one degrading microorganism or protein (a positive result); `false`: only those with none — not studied, or tested only with negative/inconclusive results.","title":"Has Evidence"},"description":"`true`: only plastics with at least one degrading microorganism or protein (a positive result); `false`: only those with none — not studied, or tested only with negative/inconclusive results."},{"name":"evidence_scope","in":"query","required":false,"schema":{"$ref":"#/components/schemas/RowEvidenceScope","description":"Organism degradation evidence: 'organism_or_enzyme' (default, credits an organism whose enzyme degrades the plastic) or 'whole_organism'. Any other value is a 422.","default":"organism_or_enzyme"},"description":"Organism degradation evidence: 'organism_or_enzyme' (default, credits an organism whose enzyme degrades the plastic) or 'whole_organism'. Any other value is a 422."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422).","title":"Page"},"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/plastics/{plastic_id}":{"get":{"tags":["plastics"],"summary":"Get Plastic","description":"One polymer with its degraders and enzymes.\n\nEvery sort, order and polarity parameter is a closed vocabulary; an unknown\nvalue is a 422. ``*_limit=0`` returns the bucket counts without rows.","operationId":"get_plastic_api_v1_plastics__plastic_id__get","parameters":[{"name":"plastic_id","in":"path","required":true,"schema":{"type":"integer","title":"Plastic Id"}},{"name":"microorganism_offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Microorganism Offset"}},{"name":"microorganism_limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":0,"default":25,"title":"Microorganism Limit"}},{"name":"protein_offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Protein Offset"}},{"name":"protein_limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":0,"default":25,"title":"Protein Limit"}},{"name":"microorganism_sort_by","in":"query","required":false,"schema":{"enum":["papers","result","name"],"type":"string","default":"papers","title":"Microorganism Sort By"}},{"name":"microorganism_sort_order","in":"query","required":false,"schema":{"enum":["asc","desc"],"type":"string","default":"desc","title":"Microorganism Sort Order"}},{"name":"protein_sort_by","in":"query","required":false,"schema":{"enum":["papers","result","plasticdb_id","accession","name","id"],"type":"string","default":"id","title":"Protein Sort By"}},{"name":"protein_sort_order","in":"query","required":false,"schema":{"enum":["asc","desc"],"type":"string","default":"desc","title":"Protein Sort Order"}},{"name":"microorganism_polarity","in":"query","required":false,"schema":{"$ref":"#/components/schemas/ResultEnum","description":"Which bucket of organisms to page: the best result each has on this plastic.","default":"positive"},"description":"Which bucket of organisms to page: the best result each has on this plastic."},{"name":"protein_polarity","in":"query","required":false,"schema":{"$ref":"#/components/schemas/ResultEnum","description":"Which bucket of proteins to page: the best result each has on this plastic.","default":"positive"},"description":"Which bucket of proteins to page: the best result each has on this plastic."},{"name":"evidence_scope","in":"query","required":false,"schema":{"$ref":"#/components/schemas/RowEvidenceScope","default":"organism_or_enzyme"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlasticDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/proteins":{"get":{"tags":["proteins"],"summary":"List Proteins","operationId":"list_proteins_api_v1_proteins_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query. Also matches an identifier exactly (PB accession, plasticdb_id, UniProt, GenBank with or without its version, PDB), and those hits rank first.","title":"Q"},"description":"Full-text search query. Also matches an identifier exactly (PB accession, plasticdb_id, UniProt, GenBank with or without its version, PDB), and those hits rank first."},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},{"name":"plasticdb_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"}},{"name":"accession","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"}},{"name":"plastic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types.","title":"Plastic"},"description":"Records with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'. Add `include_subtypes=true` to include its curated sub-types."},{"name":"include_subtypes","in":"query","required":false,"schema":{"type":"boolean","description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE).","default":false,"title":"Include Subtypes"},"description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE)."},{"name":"microorganism","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Microorganism"}},{"name":"lineage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lineage"}},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"}},{"name":"min_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum publication year (≥)","title":"Min Year"},"description":"Minimum publication year (≥)"},{"name":"max_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum publication year (≤)","title":"Max Year"},"description":"Maximum publication year (≤)"},{"name":"substrate_form","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SubstrateForm"},{"type":"null"}],"description":"Substrate form as tested (e.g. 'film', 'powder'), from the controlled vocabulary. An unknown form is a 422.","title":"Substrate Form"},"description":"Substrate form as tested (e.g. 'film', 'powder'), from the controlled vocabulary. An unknown form is a 422."},{"name":"evidence_method","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EvidenceMethod"},{"type":"null"}],"description":"Filter by the assay method backing the evidence, matched exactly against the method vocabulary (e.g. 'weight_loss', 'hplc', 'sem', 'clear_zone'). No method ranks above another. An unknown method is a 422.","title":"Evidence Method"},"description":"Filter by the assay method backing the evidence, matched exactly against the method vocabulary (e.g. 'weight_loss', 'hplc', 'sem', 'clear_zone'). No method ranks above another. An unknown method is a 422."},{"name":"include_negative","in":"query","required":false,"schema":{"type":"boolean","description":"Drop the result filter entirely and return every public record, negatives and untested entities included. This is the way back to an unfiltered list: with neither this nor `polarity`, the default is `positive`.","default":false,"title":"Include Negative"},"description":"Drop the result filter entirely and return every public record, negatives and untested entities included. This is the way back to an unfiltered list: with neither this nor `polarity`, the default is `positive`."},{"name":"polarity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ResultEnum"},{"type":"null"}],"description":"Filter by interaction result. **Defaults to `positive`** — an entity with at least one positive result, the same question the landing page's Proteins count answers. Until 0.84.3 the default was 'anything except an entity whose evidence is exclusively negative', which was 30 records wider and matched no surface on the site. Pass `include_negative=true` for every public record.","title":"Polarity"},"description":"Filter by interaction result. **Defaults to `positive`** — an entity with at least one positive result, the same question the landing page's Proteins count answers. Until 0.84.3 the default was 'anything except an entity whose evidence is exclusively negative', which was 30 records wider and matched no surface on the site. Pass `include_negative=true` for every public record."},{"name":"min_kcat","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum kcat (s⁻¹)","title":"Min Kcat"},"description":"Minimum kcat (s⁻¹)"},{"name":"max_km","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum Km (mM)","title":"Max Km"},"description":"Maximum Km (mM)"},{"name":"min_kcat_km","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum catalytic efficiency kcat/Km (M⁻¹·s⁻¹)","title":"Min Kcat Km"},"description":"Minimum catalytic efficiency kcat/Km (M⁻¹·s⁻¹)"},{"name":"min_vmax","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum Vmax (U/mg)","title":"Min Vmax"},"description":"Minimum Vmax (U/mg)"},{"name":"has_structure","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only entities with their own experimentally determined structure (a PDB entry; predicted AlphaFold/ESMFold models do not count). `false`: only those without one. A variant is judged on its own structure, not its parent's.","title":"Has Structure"},"description":"`true`: only entities with their own experimentally determined structure (a PDB entry; predicted AlphaFold/ESMFold models do not count). `false`: only those without one. A variant is judged on its own structure, not its parent's."},{"name":"has_sequence","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"`true`: only entities with a stored amino-acid sequence; `false`: only those without.","title":"Has Sequence"},"description":"`true`: only entities with a stored amino-acid sequence; `false`: only those without."},{"name":"ec_number","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"description":"EC number prefix, matched on whole levels: `3.1.1` matches 3.1.1.101 and 3.1.1.- but not 3.1.10.x. A variant inherits its parent's EC number.","title":"Ec Number"},"description":"EC number prefix, matched on whole levels: `3.1.1` matches 3.1.1.101 and 3.1.1.- but not 3.1.10.x. A variant inherits its parent's EC number."},{"name":"min_tm","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum melting temperature Tm (°C), from the stored enzyme properties. An engineered variant is judged on its own Tm.","title":"Min Tm"},"description":"Minimum melting temperature Tm (°C), from the stored enzyme properties. An engineered variant is judged on its own Tm."},{"name":"max_tm","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum melting temperature Tm (°C). See `min_tm`.","title":"Max Tm"},"description":"Maximum melting temperature Tm (°C). See `min_tm`."},{"name":"kind","in":"query","required":false,"schema":{"enum":["wild_type","engineered","both"],"type":"string","description":"Which protein entities to list: 'wild_type', 'engineered' (variants), or 'both'. An unrecognised value is a 422 — it used to fall back to 'both', which silently answered a typo with the wrong dataset.","default":"both","title":"Kind"},"description":"Which protein entities to list: 'wild_type', 'engineered' (variants), or 'both'. An unrecognised value is a 422 — it used to fall back to 'both', which silently answered a typo with the wrong dataset."},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["year","name","accession","id","plasticdb_id","genbank_id"],"type":"string","description":"Sort key. Ties always break by a unique key, so offset paging is stable. `plasticdb_id` and `genbank_id` need `kind=wild_type`.","default":"year","title":"Sort By"},"description":"Sort key. Ties always break by a unique key, so offset paging is stable. `plasticdb_id` and `genbank_id` need `kind=wild_type`."},{"name":"sort_order","in":"query","required":false,"schema":{"enum":["asc","desc"],"type":"string","default":"desc","title":"Sort Order"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422).","title":"Page"},"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/proteins/accession/{accession}":{"get":{"tags":["proteins"],"summary":"Get Protein By Accession","description":"Look up a protein by PB#### accession (case-insensitive).\n\nReturns 301 with a Location header pointing to the surviving accession when\nmerged, 301 to ``/api/v1/variants/{accession}`` when the accession belongs to\nan engineered variant, and 410 when the accession has been tombstoned.","operationId":"get_protein_by_accession_api_v1_proteins_accession__accession__get","parameters":[{"name":"accession","in":"path","required":true,"schema":{"type":"string","title":"Accession"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/proteins/{accession}":{"get":{"tags":["proteins"],"summary":"Get Protein","description":"Look up a protein by PB#### accession (case-insensitive).\n\nAn engineered variant's accession answers 301 to\n``/api/v1/variants/{accession}``: ``/proteins?kind=engineered`` lists variant\naccessions, and they used to 404 here (R11-5).\n\nApplies the same merge (301) / tombstone (410) handling as\n``get_protein_by_accession`` so a direct hit on a merged/retired\naccession behaves consistently regardless of which route the caller used.","operationId":"get_protein_api_v1_proteins__accession__get","parameters":[{"name":"accession","in":"path","required":true,"schema":{"type":"string","title":"Accession"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProteinDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/proteins/{ref}/fasta":{"get":{"tags":["proteins"],"summary":"Get Protein Fasta","description":"This protein's sequence, by numeric id or PB#### accession.\n\nA merged accession answers 301 to the survivor's FASTA, a variant accession\n301 to ``/variants/{accession}/fasta``.\n\nGated: this route took a raw id and had no visibility *or tombstone* check at\nall, so it handed out the sequence of a staged or tombstoned\nenzyme — the single most valuable field on the record — to an unauthenticated\ncaller counting from 1. 404 rather than 403, for the reason given in\n``protein_resolution``: the existence of the row is part of the secret.","operationId":"get_protein_fasta_api_v1_proteins__ref__fasta_get","parameters":[{"name":"ref","in":"path","required":true,"schema":{"type":"string","title":"Ref"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/proteins/{ref}/structure":{"get":{"tags":["proteins"],"summary":"Get Protein Structure","description":"Coordinates for the 3D viewer, by numeric id or PB#### accession.\n\nGated for the same reason as ``/fasta``, and resolves ``ref`` the same way.","operationId":"get_protein_structure_api_v1_proteins__ref__structure_get","parameters":[{"name":"ref","in":"path","required":true,"schema":{"type":"string","title":"Ref"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/engineering/proteins":{"get":{"tags":["engineering"],"summary":"List Engineering Proteins","operationId":"list_engineering_proteins_api_v1_engineering_proteins_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422).","title":"Page"},"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/engineering/proteins/{accession}":{"get":{"tags":["engineering"],"summary":"Get Engineering Lineage","operationId":"get_engineering_lineage_api_v1_engineering_proteins__accession__get","parameters":[{"name":"accession","in":"path","required":true,"schema":{"type":"string","title":"Accession"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngineeringLineage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/variants/{ref}":{"get":{"tags":["variants"],"summary":"Get Variant","description":"Return one engineered variant with its mutations, kinetics, stability,\nparent protein, source paper and the plastics it is reported to act on.\n\nA variant has no ``visibility`` of its own; it inherits its parent's, which\nis what ``variant_parent_public_filter`` expresses and what every list, FASTA\nand export path already applies. This route did not, so a mutant of an\nstaged or tombstoned parent served its sequence, mutations and kinetics —\nthe parent's own data, one hop away — to anyone.","operationId":"get_variant_api_v1_variants__ref__get","parameters":[{"name":"ref","in":"path","required":true,"schema":{"type":"string","title":"Ref"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariantDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/variants/{ref}/fasta":{"get":{"tags":["variants"],"summary":"Get Variant Fasta","description":"This variant's own sequence as FASTA, by numeric id or accession.\n\nThe header is the one ``/downloads/proteins.fasta`` writes for the same\nvariant, so a single record and the bulk file agree on its ``seq_id``.","operationId":"get_variant_fasta_api_v1_variants__ref__fasta_get","parameters":[{"name":"ref","in":"path","required":true,"schema":{"type":"string","title":"Ref"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/variants/{ref}/structure":{"get":{"tags":["variants"],"summary":"Get Variant Structure","description":"This variant's own coordinates, for the 3D viewer on its page.\n\nMirrors ``/proteins/{id}/structure``. Kept as a separate route rather than\nresolving through the parent: a mutant's fold is precisely what differs, so\nserving the parent's file here would quietly show the wrong structure (#354).","operationId":"get_variant_structure_api_v1_variants__ref__structure_get","parameters":[{"name":"ref","in":"path","required":true,"schema":{"type":"string","title":"Ref"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs":{"post":{"tags":["jobs"],"summary":"Submit Job","operationId":"submit_job_api_v1_jobs_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_submit_job_api_v1_jobs_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["jobs"],"summary":"List My Jobs","operationId":"list_my_jobs_api_v1_jobs_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/JobRead"},"title":"Response List My Jobs Api V1 Jobs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs/{job_id}":{"get":{"tags":["jobs"],"summary":"Get Job","operationId":"get_job_api_v1_jobs__job_id__get","security":[{},{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs/{job_id}/comparison":{"get":{"tags":["jobs"],"summary":"Download Job Comparison","description":"The Compare Genomes matrix as a file: one row per genome, one column per\nplastic (raw counts, then normalised). The same numbers as ``comparison`` in\n``GET /jobs/{job_id}``, built the same way.","operationId":"download_job_comparison_api_v1_jobs__job_id__comparison_get","security":[{},{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"format","in":"query","required":false,"schema":{"enum":["tsv","csv"],"type":"string","description":"`tsv` (default) or `csv`.","default":"tsv","title":"Format"},"description":"`tsv` (default) or `csv`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/jobs/{job_id}/download":{"get":{"tags":["jobs"],"summary":"Download Job Results","description":"Stream a job's results file.\n\n``annotate_list`` and ``pathway_analysis`` write a TSV rather than creating\n``JobResult`` rows, so before this route their output was written to disk and\nthen unreachable — the UI reported \"No matches found\" for a job that had in\nfact produced results (#306).","operationId":"download_job_results_api_v1_jobs__job_id__download_get","security":[{},{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/plastics/{plastic_id}":{"get":{"tags":["admin"],"summary":"Get One","description":"Raw field fetch for admin edit forms — addressed by internal id,\nindependent of whatever identifier the public routes use.","operationId":"get_one_api_v1_admin_plastics__plastic_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get One Api V1 Admin Plastics  Plastic Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Update","operationId":"update_api_v1_admin_plastics__plastic_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlasticUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Api V1 Admin Plastics  Plastic Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete","operationId":"delete_api_v1_admin_plastics__plastic_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/plastics":{"post":{"tags":["admin"],"summary":"Create","operationId":"create_api_v1_admin_plastics_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlasticCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Api V1 Admin Plastics Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/compounds/{compound_id}":{"get":{"tags":["admin"],"summary":"Get One","description":"Raw field fetch for admin edit forms — addressed by internal id,\nindependent of whatever identifier the public routes use.","operationId":"get_one_api_v1_admin_compounds__compound_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get One Api V1 Admin Compounds  Compound Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Update","operationId":"update_api_v1_admin_compounds__compound_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompoundUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Api V1 Admin Compounds  Compound Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete","operationId":"delete_api_v1_admin_compounds__compound_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/compounds":{"post":{"tags":["admin"],"summary":"Create","operationId":"create_api_v1_admin_compounds_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompoundCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Api V1 Admin Compounds Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["admin"],"summary":"List Compounds","operationId":"list_compounds_api_v1_admin_compounds_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"is_additive","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter by additive classification: true = additives only, false = non-additives only, omit = all compounds (including unclassified).","title":"Is Additive"},"description":"Filter by additive classification: true = additives only, false = non-additives only, omit = all compounds (including unclassified)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CompoundRead"},"title":"Response List Compounds Api V1 Admin Compounds Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/microorganisms/{micro_id}":{"get":{"tags":["admin"],"summary":"Get One","description":"Raw field fetch for admin edit forms — addressed by internal id,\nindependent of whatever identifier the public routes use.","operationId":"get_one_api_v1_admin_microorganisms__micro_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get One Api V1 Admin Microorganisms  Micro Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Update","operationId":"update_api_v1_admin_microorganisms__micro_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MicroorganismUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Api V1 Admin Microorganisms  Micro Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete","operationId":"delete_api_v1_admin_microorganisms__micro_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/microorganisms":{"post":{"tags":["admin"],"summary":"Create","operationId":"create_api_v1_admin_microorganisms_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MicroorganismCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Api V1 Admin Microorganisms Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/proteins/{protein_id}":{"get":{"tags":["admin"],"summary":"Get One","description":"Raw field fetch for admin edit forms — addressed by internal id,\nindependent of whatever identifier the public routes use.","operationId":"get_one_api_v1_admin_proteins__protein_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get One Api V1 Admin Proteins  Protein Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Update","operationId":"update_api_v1_admin_proteins__protein_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProteinUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Api V1 Admin Proteins  Protein Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete","operationId":"delete_api_v1_admin_proteins__protein_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/proteins":{"post":{"tags":["admin"],"summary":"Create","operationId":"create_api_v1_admin_proteins_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProteinCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Api V1 Admin Proteins Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["admin"],"summary":"List Admin Proteins","description":"Every protein row, in every state, paged and searchable.\n\nThe admin Proteins tab used to read the *public* list with ``limit=500``, so\nit silently showed the first 500 public records and never a staged or\nmerged one — an admin could not find the very rows that need admin\nattention (R13-7). This is unfiltered by visibility on purpose; it is\nsuperuser-only.","operationId":"list_admin_proteins_api_v1_admin_proteins_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Q"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(public|staged|merged)$"},{"type":"null"}],"title":"State"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response List Admin Proteins Api V1 Admin Proteins Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/papers/{paper_id}":{"get":{"tags":["admin"],"summary":"Get One","description":"Raw field fetch for admin edit forms — addressed by internal id,\nindependent of whatever identifier the public routes use.","operationId":"get_one_api_v1_admin_papers__paper_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get One Api V1 Admin Papers  Paper Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Update","operationId":"update_api_v1_admin_papers__paper_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaperUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Api V1 Admin Papers  Paper Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete","operationId":"delete_api_v1_admin_papers__paper_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/papers":{"post":{"tags":["admin"],"summary":"Create","operationId":"create_api_v1_admin_papers_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaperCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Api V1 Admin Papers Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["admin"],"summary":"List Papers","operationId":"list_papers_api_v1_admin_papers_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/protein-variants/{ev_id}":{"get":{"tags":["admin"],"summary":"Get One","description":"Raw field fetch for admin edit forms — addressed by internal id,\nindependent of whatever identifier the public routes use.","operationId":"get_one_api_v1_admin_protein_variants__ev_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get One Api V1 Admin Protein Variants  Ev Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Update","operationId":"update_api_v1_admin_protein_variants__ev_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProteinVariantUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Api V1 Admin Protein Variants  Ev Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete","operationId":"delete_api_v1_admin_protein_variants__ev_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/protein-variants":{"post":{"tags":["admin"],"summary":"Create","operationId":"create_api_v1_admin_protein_variants_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProteinVariantCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Api V1 Admin Protein Variants Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["admin"],"summary":"List Protein Variants","description":"Every variant, newest first, with its parent's name and accession.\n\nThe total rides in ``X-Total-Count`` (as ``/admin/papers`` does) so the body\nstays the list existing callers read. The parent is joined here rather than\nlooked up client-side: the admin panel used to map ids against the *public*\nprotein list capped at 500, so any variant of a staged, tombstoned or 501st\nprotein showed its parent as a bare ``Protein #1221``.","operationId":"list_protein_variants_api_v1_admin_protein_variants_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":200,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response List Protein Variants Api V1 Admin Protein Variants Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/pathways/{pathway_id}":{"get":{"tags":["admin"],"summary":"Get One","description":"Raw field fetch for admin edit forms — addressed by internal id,\nindependent of whatever identifier the public routes use.","operationId":"get_one_api_v1_admin_pathways__pathway_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get One Api V1 Admin Pathways  Pathway Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Update","operationId":"update_api_v1_admin_pathways__pathway_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathwayUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Api V1 Admin Pathways  Pathway Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete","operationId":"delete_api_v1_admin_pathways__pathway_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/pathways":{"post":{"tags":["admin"],"summary":"Create","operationId":"create_api_v1_admin_pathways_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathwayCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Api V1 Admin Pathways Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/reaction-steps/{step_id}":{"get":{"tags":["admin"],"summary":"Get One","description":"Raw field fetch for admin edit forms — addressed by internal id,\nindependent of whatever identifier the public routes use.","operationId":"get_one_api_v1_admin_reaction_steps__step_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get One Api V1 Admin Reaction Steps  Step Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["admin"],"summary":"Update","operationId":"update_api_v1_admin_reaction_steps__step_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReactionStepUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Api V1 Admin Reaction Steps  Step Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete","operationId":"delete_api_v1_admin_reaction_steps__step_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/reaction-steps":{"post":{"tags":["admin"],"summary":"Create","operationId":"create_api_v1_admin_reaction_steps_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"spec","in":"query","required":false,"schema":{"title":"Spec"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReactionStepCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Api V1 Admin Reaction Steps Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/methods":{"get":{"tags":["admin"],"summary":"List Methods Admin","description":"Return all methods with id+name for admin editor dropdowns.","operationId":"list_methods_admin_api_v1_admin_methods_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"object"},"type":"array","title":"Response List Methods Admin Api V1 Admin Methods Get"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/measurement-types":{"get":{"tags":["admin"],"summary":"List Measurement Types Admin","description":"Return all measurement types with id+name for admin editor dropdowns.","operationId":"list_measurement_types_admin_api_v1_admin_measurement_types_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"object"},"type":"array","title":"Response List Measurement Types Admin Api V1 Admin Measurement Types Get"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/interactions":{"post":{"tags":["admin"],"summary":"Create Interaction Route","operationId":"create_interaction_route_api_v1_admin_interactions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InteractionCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Interaction Route Api V1 Admin Interactions Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/interactions/{interaction_id}":{"patch":{"tags":["admin"],"summary":"Update Interaction Route","operationId":"update_interaction_route_api_v1_admin_interactions__interaction_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"interaction_id","in":"path","required":true,"schema":{"type":"integer","title":"Interaction Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InteractionUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Interaction Route Api V1 Admin Interactions  Interaction Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete Interaction Route","operationId":"delete_interaction_route_api_v1_admin_interactions__interaction_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"interaction_id","in":"path","required":true,"schema":{"type":"integer","title":"Interaction Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/stats":{"get":{"tags":["admin"],"summary":"Admin Stats","operationId":"admin_stats_api_v1_admin_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminStatsResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/users":{"get":{"tags":["admin"],"summary":"List Users","operationId":"list_users_api_v1_admin_users_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserRead"},"title":"Response List Users Api V1 Admin Users Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/users/{user_id}":{"patch":{"tags":["admin"],"summary":"Update User","operationId":"update_user_api_v1_admin_users__user_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdateAdmin"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/proteins/{protein_id}/enrich":{"post":{"tags":["admin"],"summary":"Force Enrich Protein","operationId":"force_enrich_protein_api_v1_admin_proteins__protein_id__enrich_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"protein_id","in":"path","required":true,"schema":{"type":"integer","title":"Protein Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/proteins/enrich-all":{"post":{"tags":["admin"],"summary":"Force Enrich All Proteins","operationId":"force_enrich_all_proteins_api_v1_admin_proteins_enrich_all_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/enrichment-coverage":{"get":{"tags":["admin"],"summary":"Enrichment Coverage","description":"Per-source enrichment coverage stats for the admin panel.","operationId":"enrichment_coverage_api_v1_admin_enrichment_coverage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"object"},"type":"array","title":"Response Enrichment Coverage Api V1 Admin Enrichment Coverage Get"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/taxonomy/status":{"get":{"tags":["admin"],"summary":"Taxonomy Status","description":"Everything the dashboard's Taxonomy tab shows, in one request.\n\nDeliberately one endpoint rather than four: the tab polls this every few\nseconds while a run is live, and fanning that out would multiply the poll.\n\nUndecorated by the rate limiter on purpose — it is superuser-only, it is\nthree cheap aggregates, and it is the endpoint being polled.","operationId":"taxonomy_status_api_v1_admin_taxonomy_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/taxonomy/runs":{"post":{"tags":["admin"],"summary":"Start Taxonomy Run","description":"Queue one taxonomy enrichment pass. 409 if one is already in flight.","operationId":"start_taxonomy_run_api_v1_admin_taxonomy_runs_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxonomyRunStart"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/taxonomy/runs/{run_id}/cancel":{"post":{"tags":["admin"],"summary":"Cancel Taxonomy Run","description":"Release the lock held by a run that is not coming back.\n\nThe automatic sweep frees a stranded lock on its own, but only once it is\ncertainly stranded (twenty minutes of silence, six hours in a queue). This is\nthe override for when the owner already knows the worker is gone — recovering\nfrom a dead worker must not require a terminal either.\n\nRefused while the run is demonstrably alive. Nothing here can reach into a\nCelery task and stop it, so freeing the lock under a live crawl would let a\nsecond crawl start beside the first — which is the one outcome the lock\nexists to prevent. A run still writing heartbeats has to go quiet for\n``CANCEL_GRACE`` first.","operationId":"cancel_taxonomy_run_api_v1_admin_taxonomy_runs__run_id__cancel_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/enrichment/rescue/status":{"get":{"tags":["admin"],"summary":"Enrichment Rescue Status","description":"Everything the Enrichment tab's rescue panel shows, in one request.\n\nOne endpoint rather than three: the panel polls this every few seconds while\na run is live, and fanning that out would multiply the poll. Undecorated by\nthe rate limiter for the same reason as the taxonomy twin — superuser-only,\ntwo cheap aggregates, and it is the endpoint being polled.","operationId":"enrichment_rescue_status_api_v1_admin_enrichment_rescue_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/enrichment/rescue/runs":{"post":{"tags":["admin"],"summary":"Start Enrichment Rescue","description":"Queue one enrichment rescue pass. 409 if one is already in flight.","operationId":"start_enrichment_rescue_api_v1_admin_enrichment_rescue_runs_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentRescueStart"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/enrichment/rescue/runs/{run_id}/cancel":{"post":{"tags":["admin"],"summary":"Cancel Enrichment Rescue","description":"Release the lock held by a rescue that is not coming back.\n\nSame contract as the taxonomy twin, and refused for the same reason while the\nrun is demonstrably alive: nothing here can reach into a Celery task and stop\nit, so freeing the lock under a live pass would let a second one start beside\nthe first. A run still writing heartbeats has to go quiet for ``CANCEL_GRACE``\nfirst. Whatever it had already re-attempted keeps its result — a new run\nresumes from the rows it never reached.","operationId":"cancel_enrichment_rescue_api_v1_admin_enrichment_rescue_runs__run_id__cancel_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/enzyme-kinetics":{"get":{"tags":["admin"],"summary":"List Enzyme Kinetics","operationId":"list_enzyme_kinetics_api_v1_admin_enzyme_kinetics_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":200,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response List Enzyme Kinetics Api V1 Admin Enzyme Kinetics Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["admin"],"summary":"Create Enzyme Kinetics","operationId":"create_enzyme_kinetics_api_v1_admin_enzyme_kinetics_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnzymeKineticsCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Enzyme Kinetics Api V1 Admin Enzyme Kinetics Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/enzyme-kinetics/{ek_id}":{"patch":{"tags":["admin"],"summary":"Update Enzyme Kinetics","operationId":"update_enzyme_kinetics_api_v1_admin_enzyme_kinetics__ek_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ek_id","in":"path","required":true,"schema":{"type":"integer","title":"Ek Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnzymeKineticsUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Enzyme Kinetics Api V1 Admin Enzyme Kinetics  Ek Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete Enzyme Kinetics","operationId":"delete_enzyme_kinetics_api_v1_admin_enzyme_kinetics__ek_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ek_id","in":"path","required":true,"schema":{"type":"integer","title":"Ek Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/enzyme-properties":{"get":{"tags":["admin"],"summary":"List Enzyme Properties","operationId":"list_enzyme_properties_api_v1_admin_enzyme_properties_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":200,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response List Enzyme Properties Api V1 Admin Enzyme Properties Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["admin"],"summary":"Create Enzyme Properties","operationId":"create_enzyme_properties_api_v1_admin_enzyme_properties_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnzymePropertiesCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Enzyme Properties Api V1 Admin Enzyme Properties Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/enzyme-properties/{ep_id}":{"patch":{"tags":["admin"],"summary":"Update Enzyme Properties","operationId":"update_enzyme_properties_api_v1_admin_enzyme_properties__ep_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ep_id","in":"path","required":true,"schema":{"type":"integer","title":"Ep Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnzymePropertiesUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Enzyme Properties Api V1 Admin Enzyme Properties  Ep Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete Enzyme Properties","operationId":"delete_enzyme_properties_api_v1_admin_enzyme_properties__ep_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ep_id","in":"path","required":true,"schema":{"type":"integer","title":"Ep Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/submissions/{submission_id}":{"patch":{"tags":["admin"],"summary":"Update Submission","operationId":"update_submission_api_v1_admin_submissions__submission_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"submission_id","in":"path","required":true,"schema":{"type":"integer","title":"Submission Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmissionUpdateAdmin"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSubmissionRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/jobs":{"get":{"tags":["admin"],"summary":"List All Jobs","operationId":"list_all_jobs_api_v1_admin_jobs_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminJobRead"},"title":"Response List All Jobs Api V1 Admin Jobs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/jobs/{job_id}":{"patch":{"tags":["admin"],"summary":"Update Job","operationId":"update_job_api_v1_admin_jobs__job_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobUpdateAdmin"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Job Api V1 Admin Jobs  Job Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["admin"],"summary":"Delete Job","operationId":"delete_job_api_v1_admin_jobs__job_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/reindex-search":{"post":{"tags":["admin"],"summary":"Reindex Search","operationId":"reindex_search_api_v1_admin_reindex_search_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Reindex Search Api V1 Admin Reindex Search Post"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/submissions":{"post":{"tags":["submissions"],"summary":"Create Submission","operationId":"create_submission_api_v1_submissions_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataSubmissionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataSubmissionRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["submissions"],"summary":"List All Submissions","operationId":"list_all_submissions_api_v1_submissions_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DataSubmissionRead"},"title":"Response List All Submissions Api V1 Submissions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/submissions/lookup-doi":{"post":{"tags":["submissions"],"summary":"Doi Lookup","operationId":"doi_lookup_api_v1_submissions_lookup_doi_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DoiLookupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DoiLookupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/submissions/lookup-taxid":{"get":{"tags":["submissions"],"summary":"Taxid Lookup","operationId":"taxid_lookup_api_v1_submissions_lookup_taxid_get","parameters":[{"name":"name","in":"query","required":true,"schema":{"type":"string","minLength":2,"title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxIdLookupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/submissions/isolation-environments":{"get":{"tags":["submissions"],"summary":"List Isolation Environments","operationId":"list_isolation_environments_api_v1_submissions_isolation_environments_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Response List Isolation Environments Api V1 Submissions Isolation Environments Get"}}}}}}},"/api/v1/submissions/sample-types":{"get":{"tags":["submissions"],"summary":"List Sample Types","operationId":"list_sample_types_api_v1_submissions_sample_types_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Response List Sample Types Api V1 Submissions Sample Types Get"}}}}}}},"/api/v1/submissions/evidence-types":{"get":{"tags":["submissions"],"summary":"List Evidence Types","operationId":"list_evidence_types_api_v1_submissions_evidence_types_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Response List Evidence Types Api V1 Submissions Evidence Types Get"}}}}}}},"/api/v1/submissions/methods":{"get":{"tags":["submissions"],"summary":"List Methods","operationId":"list_methods_api_v1_submissions_methods_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Response List Methods Api V1 Submissions Methods Get"}}}}}}},"/api/v1/submissions/lookup-sequence":{"post":{"tags":["submissions"],"summary":"Sequence Lookup","operationId":"sequence_lookup_api_v1_submissions_lookup_sequence_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SequenceLookupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SequenceLookupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/submissions/validate-sequence":{"post":{"tags":["submissions"],"summary":"Validate Sequence","operationId":"validate_sequence_api_v1_submissions_validate_sequence_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SequenceValidationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SequenceValidationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/submissions/mine":{"get":{"tags":["submissions"],"summary":"My Submissions","operationId":"my_submissions_api_v1_submissions_mine_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DataSubmissionRead"},"title":"Response My Submissions Api V1 Submissions Mine Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/submissions/{submission_id}/matches":{"get":{"tags":["submissions"],"summary":"Get Submission Matches","operationId":"get_submission_matches_api_v1_submissions__submission_id__matches_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"submission_id","in":"path","required":true,"schema":{"type":"integer","title":"Submission Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmissionMatchSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/submissions/{submission_id}/matches/{protein_submission_id}":{"get":{"tags":["submissions"],"summary":"Get Protein Submission Detail","operationId":"get_protein_submission_detail_api_v1_submissions__submission_id__matches__protein_submission_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"submission_id","in":"path","required":true,"schema":{"type":"integer","title":"Submission Id"}},{"name":"protein_submission_id","in":"path","required":true,"schema":{"type":"integer","title":"Protein Submission Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProteinSubmissionRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/settings":{"get":{"tags":["settings"],"summary":"Get Settings Page","operationId":"get_settings_page_api_v1_settings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]},"put":{"tags":["settings"],"summary":"Update Settings","operationId":"update_settings_api_v1_settings_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/settings/{key}":{"delete":{"tags":["settings"],"summary":"Reset Setting","description":"Remove an override so the field reverts to its environment default.","operationId":"reset_setting_api_v1_settings__key__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/settings/test/slack":{"post":{"tags":["settings"],"summary":"Test Slack","operationId":"test_slack_api_v1_settings_test_slack_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestResult"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/settings/test/smtp":{"post":{"tags":["settings"],"summary":"Test Smtp","operationId":"test_smtp_api_v1_settings_test_smtp_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestResult"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/settings/test/ncbi":{"post":{"tags":["settings"],"summary":"Test Ncbi","description":"Re-run the live E-utilities check against the currently applied credentials.\n\nThe same check runs automatically on save; this is for confirming a key still\nworks later, without re-entering it.","operationId":"test_ncbi_api_v1_settings_test_ncbi_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestResult"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/papers":{"get":{"tags":["papers"],"summary":"List Papers","description":"List papers, optionally filtered by bibliographic fields and by evidence.\n\nThe evidence filters (`plastic`, `microorganism`, `protein`,\n`evidence_method`, `result`, `has_quantitative`) are ANDed onto **one\ninteraction** of the paper: `?plastic=PE&result=positive` means a positive\nresult on PE. Only evidence whose actors are publicly visible can make a\npaper match.","operationId":"list_papers_api_v1_papers_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text search query","title":"Q"},"description":"Full-text search query"},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"}},{"name":"doi","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doi"}},{"name":"journal","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Journal"}},{"name":"authors","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"}},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Corresponding-author country","title":"Country"},"description":"Corresponding-author country"},{"name":"min_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum publication year (≥)","title":"Min Year"},"description":"Minimum publication year (≥)"},{"name":"max_year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum publication year (≤)","title":"Max Year"},"description":"Maximum publication year (≤)"},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["year","citation","doi","title","journal","id"],"type":"string","description":"Sort key. Ties always break by `id`, so offset paging is stable.","default":"year","title":"Sort By"},"description":"Sort key. Ties always break by `id`, so offset paging is stable."},{"name":"sort_order","in":"query","required":false,"schema":{"enum":["asc","desc"],"type":"string","default":"desc","title":"Sort Order"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422).","title":"Page"},"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422)."},{"name":"plastic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Papers with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'.","title":"Plastic"},"description":"Papers with evidence on this plastic. Exact, case-insensitive match on the plastic's name, abbreviation or full name ('PE' or 'Polyethylene') — never a substring, so 'PE' does not match 'PET'."},{"name":"include_subtypes","in":"query","required":false,"schema":{"type":"boolean","description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE).","default":false,"title":"Include Subtypes"},"description":"With `plastic`, also match its curated sub-types (children in the plastic hierarchy, e.g. OXO-PE under PE)."},{"name":"microorganism","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Papers with evidence on this organism: an NCBI tax-id (digits), a PlasticDB accession, or a name/synonym (substring). Includes enzymes purified from the organism (the site-wide 'organism or its enzyme' scope).","title":"Microorganism"},"description":"Papers with evidence on this organism: an NCBI tax-id (digits), a PlasticDB accession, or a name/synonym (substring). Includes enzymes purified from the organism (the site-wide 'organism or its enzyme' scope)."},{"name":"protein","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Papers with evidence on this protein (or variant) accession.","title":"Protein"},"description":"Papers with evidence on this protein (or variant) accession."},{"name":"evidence_method","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/EvidenceMethod"},{"type":"null"}],"description":"Papers with at least one experiment using this method.","title":"Evidence Method"},"description":"Papers with at least one experiment using this method."},{"name":"result","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ResultEnum"},{"type":"null"}],"description":"Papers reporting this outcome: positive, negative or inconclusive.","title":"Result"},"description":"Papers reporting this outcome: positive, negative or inconclusive."},{"name":"has_quantitative","in":"query","required":false,"schema":{"type":"boolean","description":"true: only papers with at least one observation carrying a numeric value (e.g. % weight loss).","default":false,"title":"Has Quantitative"},"description":"true: only papers with at least one observation carrying a numeric value (e.g. % weight loss)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/papers/{paper_id}":{"get":{"tags":["papers"],"summary":"Get Paper","operationId":"get_paper_api_v1_papers__paper_id__get","parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"integer","title":"Paper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaperDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/papers/{paper_id}/records":{"get":{"tags":["papers"],"summary":"Get Paper Footprint","description":"Return every record derived from a paper, for review and audit.\n\nCurator-visible: requires curator or superuser authentication, and therefore\nshows the paper's records whatever their visibility — a curator correcting an\nextraction has to see staged and tombstoned rows too.","operationId":"get_paper_footprint_api_v1_papers__paper_id__records_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"integer","title":"Paper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaperFootprint"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/papers/{paper_id}/footprint":{"get":{"tags":["papers"],"summary":"Get Paper Footprint Public","description":"Public read-only view of everything derived from a paper.\n\nSame aggregation as the curator ``/records`` endpoint, exposed without auth so\nthe public paper page can surface all organisms, proteins, variants, plastics,\ninteractions, kinetics, and properties extracted from the paper.\n\nIts curator twin above is the *same aggregation*, which is exactly why this\none needs ``public=True``: the footprint reaches the whole spine — every\ninteraction, experiment, observation, kinetics and properties row a paper\nproduced — and un-gated it republished all of it for a protein whose own\nrecord is hidden.","operationId":"get_paper_footprint_public_api_v1_papers__paper_id__footprint_get","parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"integer","title":"Paper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaperFootprint"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search":{"get":{"tags":["search"],"summary":"Global Search","description":"Search across all entities: microorganisms, proteins, plastics, references.\n\nReturns one relevance-ranked list pooled across every entity type, with\n``total`` counting all matches (not just the returned page). Ordering is\nstable, so ``limit``/``offset`` page through the full result set without\nskipping or repeating rows.\n\nBecause the list is pooled and ranked, a category with few matches can be\noutranked out of a small window: ``?q=PETase&limit=20`` may legitimately\nreturn no papers even though papers match. Use ``/search/grouped`` when every\ncategory must be represented, or page through with ``offset``.","operationId":"global_search_api_v1_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/grouped":{"get":{"tags":["search"],"summary":"Grouped Search","description":"Search each entity category independently — top-``limit`` plus a true total.\n\nUnlike ``/search``, which pools every entity into one ranked list where a\npopulous category can crowd the others out of the window, this queries each\ncategory on its own. Every matching category is therefore represented, and\neach ``total`` is that category's real match count rather than however many\nrows happened to fit.\n\nA ``prefix:``-scoped query (``gene:petH``) already names one category, so it\nreturns that group alone rather than fanning out.\n\nEach group carries ``more_query`` — the query string to feed back to\n``/search`` with ``offset`` to page *within* that category. It preserves the\ncaller's original scope: for ``gene:petH`` it stays ``gene:petH`` rather than\nbecoming ``protein:petH``, which would drop the gene-column filter and quietly\nwiden the result set on page 2.","operationId":"grouped_search_api_v1_search_grouped_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/search/autocomplete":{"get":{"tags":["search"],"summary":"Global Autocomplete","description":"Return top-5 matches per entity type for the search bar dropdown.","operationId":"global_autocomplete_api_v1_search_autocomplete_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":200,"title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats":{"get":{"tags":["stats"],"summary":"Public Stats","operationId":"public_stats_api_v1_stats_get","parameters":[{"name":"evidence_scope","in":"query","required":false,"schema":{"$ref":"#/components/schemas/RowEvidenceScope","default":"organism_or_enzyme"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats/charts":{"get":{"tags":["stats"],"summary":"Stats Charts","operationId":"stats_charts_api_v1_stats_charts_get","parameters":[{"name":"evidence_scope","in":"query","required":false,"schema":{"$ref":"#/components/schemas/RowEvidenceScope","default":"organism_or_enzyme"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/stats/by-country":{"get":{"tags":["stats"],"summary":"Stats By Country","operationId":"stats_by_country_api_v1_stats_by_country_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/bioinformatics/annotate-gene":{"post":{"tags":["bioinformatics"],"summary":"Api Annotate Gene","description":"Submit an annotate-gene job via API. Provide FASTA content as base64.\n\n``evalue`` is the e-value threshold passed verbatim to DIAMOND (e.g. ``1e-5``).\nAccepted range: ``(0, 10]``. Zero and negative values are rejected with 422.","operationId":"api_annotate_gene_api_v1_bioinformatics_annotate_gene_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"fasta_b64","in":"query","required":true,"schema":{"type":"string","title":"Fasta B64"}},{"name":"blast_type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/BlastTypeEnum","default":"blastp"}},{"name":"organism_type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/OrganismTypeEnum","default":"no_signalp"}},{"name":"evalue","in":"query","required":false,"schema":{"type":"number","maximum":10.0,"exclusiveMinimum":0.0,"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10].","default":1e-05,"title":"Evalue"},"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10]."},{"name":"pident","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":0,"description":"Minimum percent identity threshold. Range: 0–100.","default":30,"title":"Pident"},"description":"Minimum percent identity threshold. Range: 0–100."},{"name":"include_variants","in":"query","required":false,"schema":{"type":"boolean","description":"Also search engineered variants (mutants, fusions, truncations). Off by default so results are natural degraders rather than a protein's own mutants.","default":false,"title":"Include Variants"},"description":"Also search engineered variants (mutants, fusions, truncations). Off by default so results are natural degraders rather than a protein's own mutants."}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/bioinformatics/annotate-genome":{"post":{"tags":["bioinformatics"],"summary":"Api Annotate Genome","description":"Submit an annotate-genome job via API.\n\n``evalue`` is the e-value threshold passed verbatim to DIAMOND (e.g. ``1e-5``).\nAccepted range: ``(0, 10]``.","operationId":"api_annotate_genome_api_v1_bioinformatics_annotate_genome_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"fasta_b64","in":"query","required":true,"schema":{"type":"string","title":"Fasta B64"}},{"name":"blast_type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/BlastTypeEnum","default":"blastp"}},{"name":"organism_type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/OrganismTypeEnum","default":"no_signalp"}},{"name":"evalue","in":"query","required":false,"schema":{"type":"number","maximum":10.0,"exclusiveMinimum":0.0,"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10].","default":1e-05,"title":"Evalue"},"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10]."},{"name":"pident","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":0,"description":"Minimum percent identity threshold. Range: 0–100.","default":30,"title":"Pident"},"description":"Minimum percent identity threshold. Range: 0–100."},{"name":"include_variants","in":"query","required":false,"schema":{"type":"boolean","description":"Also search engineered variants (mutants, fusions, truncations). Off by default so results are natural degraders rather than a protein's own mutants.","default":false,"title":"Include Variants"},"description":"Also search engineered variants (mutants, fusions, truncations). Off by default so results are natural degraders rather than a protein's own mutants."}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/bioinformatics/annotate-list":{"post":{"tags":["bioinformatics"],"summary":"Api Annotate List","description":"Submit an annotate-list job via API. Provide TSV content as base64.\n\n``evalue`` is the e-value threshold passed verbatim to DIAMOND (e.g. ``1e-5``).\nAccepted range: ``(0, 10]``.","operationId":"api_annotate_list_api_v1_bioinformatics_annotate_list_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"tsv_b64","in":"query","required":true,"schema":{"type":"string","title":"Tsv B64"}},{"name":"genus_column","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Genus Column"}},{"name":"species_column","in":"query","required":false,"schema":{"type":"integer","default":2,"title":"Species Column"}},{"name":"field_separator","in":"query","required":false,"schema":{"type":"string","default":"\t","title":"Field Separator"}},{"name":"evalue","in":"query","required":false,"schema":{"type":"number","maximum":10.0,"exclusiveMinimum":0.0,"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10].","default":1e-05,"title":"Evalue"},"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10]."},{"name":"pident","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":0,"description":"Minimum percent identity threshold. Range: 0–100.","default":30,"title":"Pident"},"description":"Minimum percent identity threshold. Range: 0–100."}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/bioinformatics/compare-genomes":{"post":{"tags":["bioinformatics"],"summary":"Api Compare Genomes","description":"Submit a compare-genomes job via API: one ``fasta_b64`` per genome.\n\n``evalue`` is the e-value threshold passed verbatim to DIAMOND (e.g. ``1e-5``).\nAccepted range: ``(0, 10]``.\n\nThis endpoint used to take a single ``fasta_b64`` and save it as\n``input.fasta``, while the worker reads one file per genome from\n``inputs/`` — so every job it created searched nothing and \"completed\" with\nno results. It now writes each genome where the worker looks, under the same\nnames (and the same collision rule) as the multipart upload.","operationId":"api_compare_genomes_api_v1_bioinformatics_compare_genomes_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"fasta_b64","in":"query","required":true,"schema":{"type":"array","items":{"type":"string"},"description":"One base64-encoded FASTA per genome — repeat the parameter, at least twice. Each is searched separately and labelled in the results.","title":"Fasta B64"},"description":"One base64-encoded FASTA per genome — repeat the parameter, at least twice. Each is searched separately and labelled in the results."},{"name":"labels","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Optional genome names, one per `fasta_b64` and in the same order. Defaults to genome_1, genome_2, …","title":"Labels"},"description":"Optional genome names, one per `fasta_b64` and in the same order. Defaults to genome_1, genome_2, …"},{"name":"blast_type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/BlastTypeEnum","default":"blastp"}},{"name":"organism_type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/OrganismTypeEnum","default":"no_signalp"}},{"name":"evalue","in":"query","required":false,"schema":{"type":"number","maximum":10.0,"exclusiveMinimum":0.0,"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10].","default":1e-05,"title":"Evalue"},"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10]."},{"name":"pident","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":0,"description":"Minimum percent identity threshold. Range: 0–100.","default":30,"title":"Pident"},"description":"Minimum percent identity threshold. Range: 0–100."},{"name":"include_variants","in":"query","required":false,"schema":{"type":"boolean","description":"Also search engineered variants (mutants, fusions, truncations). Off by default so results are natural degraders rather than a protein's own mutants.","default":false,"title":"Include Variants"},"description":"Also search engineered variants (mutants, fusions, truncations). Off by default so results are natural degraders rather than a protein's own mutants."}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/bioinformatics/pathway-analysis":{"post":{"tags":["bioinformatics"],"summary":"Api Pathway Analysis","description":"Submit a PET degradation pathway-analysis job via API.\n\nMaps your protein sequences against the curated degradation-pathway enzymes\nfor the specified plastic. Currently only ``target_plastic=PET`` is\nsupported. Each step is judged against the curated *Pseudideonella\nsakaiensis* enzyme plus every PlasticDB protein with positive evidence and\nthe same EC number. Additional pathways (PHB, PCL, PLA, PBAT) will be\navailable in future releases.\n\n``evalue`` and ``pident`` filter the DIAMOND search. A step is called\npresent only when a hit also clears the step thresholds (identity, e-value,\nreference coverage, query coverage); the finished job's ``result_metadata``\ncarries the per-step table (``step_table``), the ``missing_steps`` and the\n``step_thresholds`` applied.\n\n``evalue`` is the e-value threshold passed verbatim to DIAMOND (e.g. ``1e-5``).\nAccepted range: ``(0, 10]``.","operationId":"api_pathway_analysis_api_v1_bioinformatics_pathway_analysis_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"fasta_b64","in":"query","required":true,"schema":{"type":"string","title":"Fasta B64"}},{"name":"target_plastic","in":"query","required":false,"schema":{"type":"string","description":"Plastic whose degradation pathway to map against. Currently supported: ['PET']. Additional pathways will be added in future releases.","default":"PET","title":"Target Plastic"},"description":"Plastic whose degradation pathway to map against. Currently supported: ['PET']. Additional pathways will be added in future releases."},{"name":"evalue","in":"query","required":false,"schema":{"type":"number","maximum":10.0,"exclusiveMinimum":0.0,"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10].","default":1e-05,"title":"Evalue"},"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10]."},{"name":"pident","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":0,"description":"Minimum percent identity threshold. Range: 0–100.","default":30,"title":"Pident"},"description":"Minimum percent identity threshold. Range: 0–100."},{"name":"min_step_identity","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"description":"Minimum % identity for a hit to call a step present (default 40).","title":"Min Step Identity"},"description":"Minimum % identity for a hit to call a step present (default 40)."},{"name":"max_step_evalue","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":10.0,"exclusiveMinimum":0.0},{"type":"null"}],"description":"Maximum e-value for a hit to call a step present (default 1e-10).","title":"Max Step Evalue"},"description":"Maximum e-value for a hit to call a step present (default 1e-10)."},{"name":"min_reference_coverage","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"description":"Minimum % of the reference enzyme the alignment must cover (default 70).","title":"Min Reference Coverage"},"description":"Minimum % of the reference enzyme the alignment must cover (default 70)."},{"name":"min_query_coverage","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"description":"Minimum % of your protein the alignment must cover (default 50).","title":"Min Query Coverage"},"description":"Minimum % of your protein the alignment must cover (default 50)."}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/bioinformatics/hmm-screen":{"post":{"tags":["bioinformatics"],"summary":"Api Hmm Screen","description":"Submit an HMM screen job against polymer-specific HMM profiles.\n\nScreens submitted protein sequences against PlasticDB's polymer HMM\nprofiles and returns candidates ranked by profile match score — even\nwithout a close DIAMOND homolog.  Useful for metagenomics discovery.\n\n``evalue`` is the full-sequence E-value threshold passed to ``hmmsearch``.\nAccepted range: ``(0, 10]``.  Zero and negative values are rejected with 422.\n\n``target_polymers`` restricts the polymer-level summary to specific polymers.\nAll hits are still stored; only the summary in ``result_metadata`` is filtered.\nUnknown polymer names are rejected with 422.","operationId":"api_hmm_screen_api_v1_bioinformatics_hmm_screen_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"fasta_b64","in":"query","required":true,"schema":{"type":"string","title":"Fasta B64"}},{"name":"target_polymers","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Polymers to screen against (e.g. PET, PE, PLA). The accepted set is the published profile library's own polymer vocabulary, so it moves with the data; an unknown value is rejected with a 422 that lists the current one. Omit to screen against all available profiles.","title":"Target Polymers"},"description":"Polymers to screen against (e.g. PET, PE, PLA). The accepted set is the published profile library's own polymer vocabulary, so it moves with the data; an unknown value is rejected with a 422 that lists the current one. Omit to screen against all available profiles."},{"name":"evalue","in":"query","required":false,"schema":{"type":"number","maximum":10.0,"exclusiveMinimum":0.0,"description":"E-value threshold for hmmsearch. Range: (0, 10].","default":1e-05,"title":"Evalue"},"description":"E-value threshold for hmmsearch. Range: (0, 10]."}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/bioinformatics/search-sequence":{"post":{"tags":["bioinformatics"],"summary":"Api Search Sequence","description":"Synchronous single-sequence search against the PlasticDB protein database.\n\nRuns DIAMOND locally and returns all hits in the HTTP response —\nno job submission or polling required.\n\n``evalue`` is the e-value threshold passed verbatim to DIAMOND (e.g. ``1e-5``).\nAccepted range: ``(0, 10]``. Zero and negative values are rejected with 422.","operationId":"api_search_sequence_api_v1_bioinformatics_search_sequence_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"sequence","in":"query","required":true,"schema":{"type":"string","title":"Sequence"}},{"name":"blast_type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/BlastTypeEnum","default":"blastp"}},{"name":"evalue","in":"query","required":false,"schema":{"type":"number","maximum":10.0,"exclusiveMinimum":0.0,"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10].","default":1e-05,"title":"Evalue"},"description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10]."},{"name":"pident","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":0,"description":"Minimum percent identity threshold. Range: 0–100.","default":30,"title":"Pident"},"description":"Minimum percent identity threshold. Range: 0–100."},{"name":"include_variants","in":"query","required":false,"schema":{"type":"boolean","description":"Also search engineered variants (mutants, fusions, truncations). Off by default so results are natural degraders rather than a protein's own mutants.","default":false,"title":"Include Variants"},"description":"Also search engineered variants (mutants, fusions, truncations). Off by default so results are natural degraders rather than a protein's own mutants."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SequenceSearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tree/build":{"post":{"tags":["tree"],"summary":"Build a Taxonomy Tree (NCBI-taxonomy cladogram)","description":"Submit a Taxonomy Tree job.\n\nThe result is an NCBI-taxonomy cladogram of the selected organisms: the\nbranching follows taxonomic ranks only, with no sequence comparison and no\nbranch lengths. Placeholder entries (synthetic construct, uncultured /\nunidentified organisms, metagenomes) are left out of the tree.\n\nPass either a list of microorganism_ids directly, or one or more filter\nparameters to select microorganisms by plastic, taxonomy, etc.","operationId":"build_tree_api_v1_tree_build_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TreeBuildRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{},{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/tree/{job_id}":{"get":{"tags":["tree"],"summary":"Get a Taxonomy Tree job (Newick + plastic matrix)","description":"Poll a tree job for status and results.\n\nWhen status is \"done\", the response includes ``result_newick`` (the tree as\nNewick: topology only, internal nodes labelled with their taxon, no branch\nlengths) and ``result_metadata`` (the plastic degradation matrix, plus\n``organism_count``, ``leaf_count``, ``skipped_no_lineage``,\n``excluded_non_organism``/``excluded_names`` and ``merged_into_ancestor``).","operationId":"get_tree_job_api_v1_tree__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/snapshots":{"get":{"tags":["snapshots"],"summary":"List Snapshots","description":"List published snapshots, newest first.","operationId":"list_snapshots_api_v1_snapshots_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SnapshotListItem"},"title":"Response List Snapshots Api V1 Snapshots Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/snapshots/latest":{"get":{"tags":["snapshots"],"summary":"Latest Snapshot","description":"Return metadata for the most recently published snapshot.\n\n404 while no snapshot has been published. It used to answer ``200`` with\nevery field ``null``, a \"not found\" dressed as a record (R11-10).\n``/releases/current`` is the route that is meant to answer before the first\narchive exists.","operationId":"latest_snapshot_api_v1_snapshots_latest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnapshotLatestResponse"}}}}}}},"/api/v1/snapshots/{snapshot_id}":{"get":{"tags":["snapshots"],"summary":"Get Snapshot","operationId":"get_snapshot_api_v1_snapshots__snapshot_id__get","parameters":[{"name":"snapshot_id","in":"path","required":true,"schema":{"type":"integer","title":"Snapshot Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnapshotRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/snapshots":{"get":{"tags":["admin snapshots"],"summary":"Admin List Snapshots","operationId":"admin_list_snapshots_api_v1_admin_snapshots_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminSnapshotResponse"},"title":"Response Admin List Snapshots Api V1 Admin Snapshots Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["admin snapshots"],"summary":"Trigger Snapshot","description":"Trigger an ad-hoc snapshot.  Dispatches a Celery task to generate it.\n\nThe snapshot will run asynchronously — poll GET /api/v1/admin/snapshots\nfor status updates.","operationId":"trigger_snapshot_api_v1_admin_snapshots_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSnapshotResponse"}}}}}}},"/api/v1/admin/snapshots/{snapshot_id}/publish-to-figshare":{"post":{"tags":["admin snapshots"],"summary":"Admin Publish Snapshot","description":"Publish a snapshot to Figshare and obtain a DOI.\n\nRequires FIGSHARE_API_TOKEN to be configured.  The snapshot must be in\n'exported' status (export completed successfully) before publishing.","operationId":"admin_publish_snapshot_api_v1_admin_snapshots__snapshot_id__publish_to_figshare_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"snapshot_id","in":"path","required":true,"schema":{"type":"integer","title":"Snapshot Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSnapshotResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/snapshots/{snapshot_id}":{"delete":{"tags":["admin snapshots"],"summary":"Admin Delete Snapshot","description":"Delete a snapshot (removes DB record and local file if present).","operationId":"admin_delete_snapshot_api_v1_admin_snapshots__snapshot_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"snapshot_id","in":"path","required":true,"schema":{"type":"integer","title":"Snapshot Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/releases":{"get":{"tags":["releases"],"summary":"List Releases","description":"Every completed release, newest first — the dataset's version history.\n\nPublic fields only: version, date, counts and DOI. The operational record\n(stages, fingerprints, notebook runs) is ``GET /api/v1/admin/releases``.","operationId":"list_releases_api_v1_releases_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422).","title":"Page"},"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DatasetReleaseRead"},"title":"Response List Releases Api V1 Releases Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/releases/current":{"get":{"tags":["releases"],"summary":"Current Release","description":"The release this site is currently serving, and how to cite it.\n\nThe endpoint a user or a script quotes in a methods section: \"PlasticDB\ndataset release 2026.35\". A release with no snapshot of its own (its corpus\nwas unchanged, so no second DOI was minted) reports the DOI of the most\nrecent release that has one — the archive for identical data.","operationId":"current_release_api_v1_releases_current_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentReleaseResponse"}}}}}}},"/api/v1/releases/{version}":{"get":{"tags":["releases"],"summary":"Get Release","description":"One release by its version string (public fields only).","operationId":"get_release_api_v1_releases__version__get","parameters":[{"name":"version","in":"path","required":true,"schema":{"type":"string","title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetReleaseRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/releases":{"get":{"tags":["admin releases"],"summary":"Admin List Releases","description":"Every release row, any status, newest first — the operational record.\n\n**Superuser only.** Stages, trigger, withheld counts, the reference and\ndataset fingerprints, the notebook-stage report and any error: the fields\nthe public ``/releases`` deliberately does not carry.","operationId":"admin_list_releases_api_v1_admin_releases_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422).","title":"Page"},"description":"1-based page number, an alternative to `offset`: `page=N` means `offset=(N-1)*limit`. Send one or the other; a non-zero `offset` together with `page` is rejected (422)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminDatasetReleaseRead"},"title":"Response Admin List Releases Api V1 Admin Releases Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["admin releases"],"summary":"Force Release","description":"Cut a release now, out of cycle. **Superuser only.**\n\nDispatched to the worker rather than run inline: it rebuilds the DIAMOND\ndatabases and may cut a tarball, neither of which belongs in a request.\n\n``force`` here means \"do not wait for Thursday and do not stand down because\nthis week already ran\" — it takes a fresh version so the out-of-cycle\nrelease is citable in its own right. It does **not** mean \"publish more\":\nthe records it publishes are exactly the ones the scheduled run would have,\nselected by the same filter, and it ignores the ``dataset_release_enabled``\npause because a human is asking for this one specifically.","operationId":"force_release_api_v1_admin_releases_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/admin/releases/staging":{"get":{"tags":["admin releases"],"summary":"Release Staging","description":"What the next release would publish, and what it would decline.\n\n``withheld`` reports, per entity, how many staged records are eligible and\nhow many are declined because they were tombstoned.","operationId":"release_staging_api_v1_admin_releases_staging_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseStagingResponse"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/releases/publish-now":{"post":{"tags":["admin releases"],"summary":"Publish Now","description":"Publish named staged records immediately — a correction that cannot wait.\n\nGoes through :func:`~app.services.dataset_releases.promote_staged_async`,\nwhich is the same ``releasable_stmt`` + ``publish_record`` pair the weekly\ntask uses. The id list is a **narrowing**: a record that is tombstoned, or\nsimply not staged, is skipped and counted in ``declined``.\n\nDeliberately not offered: publishing *everything* staged. That is a release,\nand a release gets a version — ``POST /admin/releases``.","operationId":"publish_now_api_v1_admin_releases_publish_now_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishNowRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishNowResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/pathways":{"get":{"tags":["pathways"],"summary":"List Pathways","operationId":"list_pathways_api_v1_pathways_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PathwayListItem"},"title":"Response List Pathways Api V1 Pathways Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pathways/{pathway_id}":{"get":{"tags":["pathways"],"summary":"Get Pathway","operationId":"get_pathway_api_v1_pathways__pathway_id__get","parameters":[{"name":"pathway_id","in":"path","required":true,"schema":{"type":"integer","title":"Pathway Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathwayRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pathways/by-plastic/{plastic_id}":{"get":{"tags":["pathways"],"summary":"Get Pathways By Plastic","description":"Get all pathways for a specific plastic (ordered by id).\n\n``[]`` means the plastic exists and has no curated pathway; a plastic id\nthat names nothing is a 404, like every other detail route (R11-10). It used\nto answer ``200 []`` either way, so a typo looked like \"no pathway\".","operationId":"get_pathways_by_plastic_api_v1_pathways_by_plastic__plastic_id__get","parameters":[{"name":"plastic_id","in":"path","required":true,"schema":{"type":"integer","title":"Plastic Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PathwayRead"},"title":"Response Get Pathways By Plastic Api V1 Pathways By Plastic  Plastic Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/pathways/by-plastic/{plastic_id}/graph":{"get":{"tags":["pathways"],"summary":"Get Pathway Graph","description":"Return pathway data as a Cytoscape.js-compatible graph (nodes + edges).\n\nWhen a plastic has multiple pathways, pass ``pathway_id`` to select which one\nto render.  Omitting it renders the first pathway (ordered by id).","operationId":"get_pathway_graph_api_v1_pathways_by_plastic__plastic_id__graph_get","parameters":[{"name":"plastic_id","in":"path","required":true,"schema":{"type":"integer","title":"Plastic Id"}},{"name":"pathway_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Specific pathway ID to render; defaults to the first pathway for this plastic.","title":"Pathway Id"},"description":"Specific pathway ID to render; defaults to the first pathway for this plastic."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathwayGraphResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/notify-run":{"post":{"tags":["ingestions"],"summary":"Notify Run","description":"plasticdb-ai calls this once per run to send the batch Slack summary.","operationId":"notify_run_api_v1_ingestions_notify_run_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunSummary"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/ingestions":{"post":{"tags":["ingestions"],"summary":"Create Ingestion","description":"Submit a paper from plasticdb-ai.\n\nDuplicate handling, keyed on the *latest* ingestion for the DOI:\n\n- ``pending_review``  → 409. A curator is looking at it; don't move the goalposts.\n- ``pending_download`` / ``pending_extraction`` → **return that ingestion (200)**.\n  It was created but never reviewed, so the producer is retrying a submission it\n  already started (e.g. it crashed between create and upload-markdown, or the run\n  was re-run). Creating a second row here just accumulates duplicates that no one\n  ever reviews, and strands the markdown/extraction on whichever row the producer\n  happens to hold the id for.\n- ``approved`` / ``rejected`` / ``withdrawn`` → new row (201). The paper was\n  decided; a fresh extraction is a genuinely new submission and deserves its\n  own review. That includes ``withdrawn``: the records were deleted, so a\n  re-extraction of the same DOI is new work, not a retry.\n- no row at all → new row (201).","operationId":"create_ingestion_api_v1_ingestions_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["ingestions"],"summary":"List Ingestions","operationId":"list_ingestions_api_v1_ingestions_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/PaperIngestionStatus"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IngestionListItem"},"title":"Response List Ingestions Api V1 Ingestions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}":{"patch":{"tags":["ingestions"],"summary":"Patch Ingestion","description":"plasticdb-ai delivers extraction results for a pending_extraction record.","operationId":"patch_ingestion_api_v1_ingestions__ingestion_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["ingestions"],"summary":"Get Ingestion","operationId":"get_ingestion_api_v1_ingestions__ingestion_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/pending-extraction":{"get":{"tags":["ingestions"],"summary":"List Pending Extraction","description":"Returns ingestions awaiting LLM extraction.","operationId":"list_pending_extraction_api_v1_ingestions_pending_extraction_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IngestionListItem"},"title":"Response List Pending Extraction Api V1 Ingestions Pending Extraction Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/upload-pdf":{"post":{"tags":["ingestions"],"summary":"Upload Pdf","description":"Curator provides the source PDF (and, optionally, supplements) for a\npaywalled paper in the download queue. Transitions pending_download →\npending_extraction so the AI pipeline picks it up on its next poll.\n\nSupplements are optional and attached in the same call — for papers whose\nkey data (sequences, kinetics tables) is known up front to live in the SI,\nthe curator uploads both together rather than waiting for a second round.","operationId":"upload_pdf_api_v1_ingestions__ingestion_id__upload_pdf_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_pdf_api_v1_ingestions__ingestion_id__upload_pdf_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/upload-markdown":{"post":{"tags":["ingestions"],"summary":"Upload Markdown","description":"Upload paper.md from plasticdb-ai. Transitions pending_download → pending_extraction.\n\nAI submission flow (no direct object-store credentials required):\n1. POST /ingestions with {doi, title, abstract, pubmed_id} → pending_download\n2. POST /ingestions/{id}/upload-markdown (paper.md) → pending_extraction\n3. PATCH /ingestions/{id} with {extracted_data, extraction_model, extraction_version} → pending_review","operationId":"upload_markdown_api_v1_ingestions__ingestion_id__upload_markdown_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_markdown_api_v1_ingestions__ingestion_id__upload_markdown_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/pdf":{"get":{"tags":["ingestions"],"summary":"Proxy Pdf","operationId":"proxy_pdf_api_v1_ingestions__ingestion_id__pdf_get","security":[{},{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/markdown":{"get":{"tags":["ingestions"],"summary":"Proxy Markdown","operationId":"proxy_markdown_api_v1_ingestions__ingestion_id__markdown_get","security":[{},{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/files":{"post":{"tags":["ingestions"],"summary":"Upload Ingestion Files","description":"Reviewer upload of source material: PDF, markdown, and/or supplements.\n\nAny combination may be supplied in one multipart request. Files are written to\nthe paper store under ``papers/{id}/...`` and their keys recorded on the row.\nStatus is left unchanged — call ``/reextract`` to (re)run the AI pipeline.","operationId":"upload_ingestion_files_api_v1_ingestions__ingestion_id__files_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_ingestion_files_api_v1_ingestions__ingestion_id__files_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/supplements/{filename}":{"get":{"tags":["ingestions"],"summary":"Proxy Supplement","operationId":"proxy_supplement_api_v1_ingestions__ingestion_id__supplements__filename__get","security":[{},{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}},{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["ingestions"],"summary":"Delete Supplement","description":"Detach a supplementary file: drop its key from the row and delete the object.\n\nUploads dedup by name but were otherwise append-only, so a curator who attached\nthe wrong file — or whose fetcher saved four identical HTML landing pages as\n\"supplements\" — had no way to take it back off the record.\n\nThe object key is never built from *filename*: the name only selects an entry\nalready stored on the row, and the key deleted is the one the row holds. Even if\nthe guard in :func:`_checked_supplement_filename` were bypassed, the worst a\ncaller could address is an object this ingestion already owns.","operationId":"delete_supplement_api_v1_ingestions__ingestion_id__supplements__filename__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}},{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/reextract":{"post":{"tags":["ingestions"],"summary":"Reextract Ingestion","description":"Re-run AI extraction: reset to ``pending_extraction`` for the pipeline to pick up.\n\nThe pipeline already polls ``GET /ingestions/pending-extraction``; flipping the\nstatus back re-enqueues this paper. Records who triggered it and when.\n\n**Any saved draft is discarded here.** A draft is edits of *a particular\nextraction*, and asking for a re-extraction is asking for that extraction to be\nreplaced. Keeping the draft would leave the two indistinguishable: it would be\nrestored over the payload the pipeline is about to write, and approving from\nthat form would promote edits of an answer nobody is looking at any more. This\nis the one case where the draft should lose, and the curator has just said so.","operationId":"reextract_ingestion_api_v1_ingestions__ingestion_id__reextract_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/attempts":{"get":{"tags":["ingestions"],"summary":"List Extraction Attempts","description":"Every extraction this paper has had, oldest first.","operationId":"list_extraction_attempts_api_v1_ingestions__ingestion_id__attempts_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AttemptResponse"},"title":"Response List Extraction Attempts Api V1 Ingestions  Ingestion Id  Attempts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/attempts/latest":{"get":{"tags":["ingestions"],"summary":"Get Latest Extraction Attempt","description":"The AI original a curator's edits are diffed against, or 404.\n\n404 rather than an empty body: a paper ingested before the attempts table\nexisted genuinely has no original, and answering ``{}`` would let the diff\nview report every field as unchanged — the one wrong answer available.","operationId":"get_latest_extraction_attempt_api_v1_ingestions__ingestion_id__attempts_latest_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttemptResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/reopen":{"post":{"tags":["ingestions"],"summary":"Reopen Ingestion","description":"Open a **new revision** of an already-approved paper.\n\nA curator who spots an error after approving had no way back. ``ApproveMode\n.replace`` is not that path and never was: approve 409s unless the row is\n``pending_review``, and ``replace`` supersedes prior approved ingestions\n*from a new ingestion of the same DOI*. So the capability that was missing is\nthe new ingestion — exposing a button on the old row could not have created\nit.\n\nThis creates that row: a copy of the approved record's payload and source\nmaterial, back at ``pending_review``, pointing at the ingestion it is a\ncorrection of. The curator then edits it on the ordinary review page and\napproves it in replace mode, which deletes the prior run's rows and rewrites\nthem. Nothing is destroyed here — the approved record stays live and stays\napproved until that second approve lands, so an abandoned revision leaves the\ndatabase exactly as it was.\n\nTwo guards, both about not creating a second open revision:\n\n* the source row must be ``approved`` — a paper still in the queue is\n  corrected by editing it, not by forking it;\n* no other ingestion for this DOI may already be open, or two curators would\n  each be correcting the same paper from a different copy and the second\n  replace would delete the first one's rows.\n\nThe second guard is taken **under a row lock on the source ingestion**. Read\nand create were otherwise a plain check-then-act: two curators pressing\n\"Correct this paper\" together both saw no open revision, both created one, and\nthe loser's work was silently overwritten by whichever replace-mode approve\nlanded second. Locking the row they are both reopening serialises them, so the\nsecond one's check runs after the first has committed and sees the revision it\nwould have duplicated. (SQLite ignores ``FOR UPDATE``; the tier that can\ndemonstrate the race is the one that has real transactions.)\n\nA ``source='submission'`` paper carries its envelope across to the revision.\nThat is not bookkeeping — ``linked_submission`` matches on\n``DataSubmission.ingestion_id``, so a revision nothing points at resolves no\nenvelope, and promotion for a contributor's paper without one is exactly the\nfailure ``UnresolvedSubmissionEnvelopeError`` now refuses: records promoted\nbut never accepted, credited or folded. The envelope follows the record\nthat is live, which is also what the contributor's own submission history\nshould point at.","operationId":"reopen_ingestion_api_v1_ingestions__ingestion_id__reopen_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/revise":{"post":{"tags":["ingestions"],"summary":"Revise Ingestion","description":"Deliver a corrected extraction for a paper already in V2, tagged with a sweep.\n\nThe producer's half of a bulk correction. What happens depends on where the\npaper is:\n\n* **approved** — ``reopen`` and the new payload in one transaction: a new\n  ``pending_review`` revision pointing at the approved row\n  (``supersedes_id``), carrying this payload, labelled with\n  ``revision_batch``/``revision_reason``. **201**, ``revision_opened``. The\n  approved record stays live until a curator approves the revision\n  (individually, or in bulk from ``/curation/revisions``). If the payload\n  and title are identical to the approved record, nothing is opened:\n  **200**, ``unchanged``.\n* **pending_review** — the payload is replaced in place and the row tagged.\n  **200**, ``patched``. Refused (409) while another person holds a live\n  review claim on it: they are looking at the extraction this would replace.\n  A curator's saved draft is not deleted; it is pinned to the previous\n  attempt and the review page reports it as stale.\n* anything else — **409**. ``superseded`` means revise the live revision\n  instead; ``rejected``/``withdrawn`` were decided against; ``pending_*``\n  papers are delivered with ``PATCH``.\n\n**Every reopen invariant holds, because it is reopen's code.** The source row\nis locked (``SELECT … FOR UPDATE``) before the open-revision check, and the\ncheck and the row construction are ``ingestion_revision.open_revision`` —\nthe function ``reopen`` calls.\n\n**Idempotent on retry.** If the paper already has an open revision that\n*this batch* opened from *this row*, the request updates that revision\n(**200**, ``revision_updated``) instead of being refused, so a producer that\nlost a response can resend it. An open revision from anywhere else — a\ncurator's reopen, another batch — is the ordinary 409.\n\nEach delivered payload is appended to the extraction attempts, labelled with\nthe model/version this request declared.","operationId":"revise_ingestion_api_v1_ingestions__ingestion_id__revise_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionRevise"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/withdraw":{"post":{"tags":["ingestions"],"summary":"Withdraw Ingestion","description":"Take an approved paper back out of the database, and record that it went.\n\nAn approval had no undo. ``reject`` refuses anything that is not\n``pending_review``; ``reopen`` gives a revision, but rejecting *that* only\nflips the revision's own status and leaves the original run's promoted rows\nlive; and approving an emptied revision is impossible because\n``ExtractedData.interactions`` is ``min_length=1``. That guard stays — an\nempty extraction is far more often a botched one than a true nil return, and\nthe producer structurally never submits one. Withdrawal, not an empty\npayload, is the answer to \"this paper should not be in the database\".\n\nThe case that needs it is now routine rather than hypothetical. The producer\npipeline's ruling R-15 (only evidence from the reviewed paper's own Results\nmay be recorded) exists to produce papers that legitimately yield *nothing* —\na genome announcement that asserts degradation and assays none. Some of those\nwere approved before the rule existed.\n\n**One transaction, and the order is the point.** Every guard runs before the\nfirst delete, the delete and the status change share this session, and the\nsingle ``commit`` is at the end. \"Records gone, ingestion still approved\" is\nthe state the superuser ``DELETE /admin/papers/{id}`` leaves behind today and\nis exactly what this route exists to stop being possible; its mirror image —\na row reading ``withdrawn`` over records that are still public — would be\nworse, because nothing would ever look again. Any exception below, including a\nrefusal, rolls the whole thing back.\n\nFour guards:\n\n* ``_check_publication_right`` — the same right approve and reject demand.\n  Deleting published records is at least as irreversible as publishing them,\n  so a contributor's row stays superuser-only here too (DECISIONS.md §7.2).\n* the row must be ``approved``. A paper still in the queue is *rejected*;\n  there is nothing promoted to withdraw.\n* **no open revision may exist for this DOI**, checked under the same row lock\n  ``reopen`` takes and against the same ``_OPEN_STATUSES``. The reasoning is\n  ``reopen``'s, one step further on: an open revision is a curator's edit of\n  these very rows, waiting to replace them. Withdrawing underneath it would\n  delete what they intend to rewrite, and their replace-mode approve would\n  then find no prior approved ingestion and 409 — their work lost, with no\n  statement anywhere of what happened. The lock is what makes the check\n  answer, rather than two curators each seeing the other's absence.\n* the paper must be this ingestion's alone — see\n  ``app.services.ingestion_withdrawal``. Both refuse with 409.\n\n**A paper someone already deleted by hand is not an error.** The admin delete\nis the only remedy that exists today, so a curator may well have used it\nbefore reaching this button; the ingestion still needs marking, and 404ing\nwould leave the exact inconsistency this route was built to clear.\n\nThe extraction, its attempt history and its review metrics are all kept. They\nare the provenance of a decision, not the records the decision removed.","operationId":"withdraw_ingestion_api_v1_ingestions__ingestion_id__withdraw_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionWithdraw"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/draft":{"get":{"tags":["ingestions"],"summary":"Get Draft","description":"The saved draft for this paper, or 404 when there is none.\n\nAlso the recovery path after a 409: the page re-reads the current revision\nhere rather than guessing at one.","operationId":"get_draft_api_v1_ingestions__ingestion_id__draft_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["ingestions"],"summary":"Save Draft","description":"Save the review form's current state. Changes no status, promotes nothing.","operationId":"save_draft_api_v1_ingestions__ingestion_id__draft_put","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftSave"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["ingestions"],"summary":"Delete Draft","description":"Throw the draft away — the curator's \"start again from the extraction\".","operationId":"delete_draft_api_v1_ingestions__ingestion_id__draft_delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/claim":{"get":{"tags":["ingestions"],"summary":"Read Claim","description":"Who holds this paper. **Reads only** — a GET never claims anything.","operationId":"read_claim_api_v1_ingestions__ingestion_id__claim_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["ingestions"],"summary":"Create Claim","description":"Take this paper, or say who has it.\n\nA claim left behind by a closed tab needs no administrator: the heartbeats\nstopped, ``CLAIM_TTL`` passed, and this call simply takes it. Only a *live*\nclaim held by someone else is refused, and ``takeover=true`` walks past that\ndeliberately — recorded on the row and logged.","operationId":"create_claim_api_v1_ingestions__ingestion_id__claim_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["ingestions"],"summary":"Release Claim","description":"Hand the paper back. Only the holder may release their own claim.\n\nAnyone else uses takeover, which carries a name. A quiet \"release someone\nelse's claim\" would be a takeover with nobody's name on it.","operationId":"release_claim_api_v1_ingestions__ingestion_id__claim_delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}},{"name":"revision","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Revision"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/claim/heartbeat":{"post":{"tags":["ingestions"],"summary":"Claim Heartbeat","description":"Keep a live claim alive. Fails once someone has taken it over.","operationId":"claim_heartbeat_api_v1_ingestions__ingestion_id__claim_heartbeat_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimHeartbeat"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/approve":{"post":{"tags":["ingestions"],"summary":"Approve Ingestion","description":"Approve an ingestion. Writes directly to live data tables.\n\nmode=merge (default): idempotent upsert — existing rows are preserved.\nmode=replace: delete all rows from prior approved runs for this DOI, then\nwrite the new extraction. Requires at least one prior approved ingestion.\n\nOrder matters here (D26). The handler reads the row, then does **all** the\nexternal lookups the promotion needs (``prepare``), and only then opens the\nwrite phase with a compare-and-set on the row's status (``claim_for_approval``).\nTwo curators pressing Approve together therefore race on a single conditional\nUPDATE: the winner promotes, the loser is turned away by a 409 *before* the\ndestructive replace-mode deletes and before a second copy of the evidence is\nwritten. The guard can afford to be first precisely because no network call\nremains behind it to hold the row lock open.","operationId":"approve_ingestion_api_v1_ingestions__ingestion_id__approve_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionApprove"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestions/{ingestion_id}/reject":{"post":{"tags":["ingestions"],"summary":"Reject Ingestion","operationId":"reject_ingestion_api_v1_ingestions__ingestion_id__reject_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionReject"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestion-revisions/batches":{"get":{"tags":["ingestions"],"summary":"List Revision Batches","description":"Every sweep label in use, newest activity first, with counts by status.","operationId":"list_revision_batches_api_v1_ingestion_revisions_batches_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"object"},"type":"array","title":"Response List Revision Batches Api V1 Ingestion Revisions Batches Get"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/ingestion-revisions/batches/{batch}":{"get":{"tags":["ingestions"],"summary":"Get Revision Batch","description":"The revisions in *batch*, oldest first, each with a diff summary.\n\nThe diff is computed server-side by\n:func:`app.services.extraction_diff.diff_extractions` against the record the\nrevision would replace (see :mod:`app.services.revision_batches`).","operationId":"get_revision_batch_api_v1_ingestion_revisions_batches__batch__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"batch","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Batch"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/PaperIngestionStatus"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Revision Batch Api V1 Ingestion Revisions Batches  Batch  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestion-revisions/batches/{batch}/approve":{"post":{"tags":["ingestions"],"summary":"Bulk Approve Revisions","description":"Approve revisions of *batch*, each in its own transaction, as stored.\n\nEach revision is approved with the payload it carries — the producer's\ncorrected extraction, unedited — in ``replace`` mode when it is a revision\nof an approved paper (``supersedes_id``; the same mode the review page sends)\nand ``merge`` otherwise. Failures are reported per id and do not stop the\nbatch. See the module docstring for the transaction, idempotency and\n``limit`` rules.","operationId":"bulk_approve_revisions_api_v1_ingestion_revisions_batches__batch__approve_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"batch","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Batch"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkApprove"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ingestion-revisions/batches/{batch}/reject":{"post":{"tags":["ingestions"],"summary":"Bulk Reject Revisions","description":"Reject revisions of *batch*, each in its own transaction, with one reason.\n\nRejecting a revision of an approved paper leaves the approved record live\nand unchanged — exactly as a single reject does. No ``limit``: a reject makes\nno external calls.","operationId":"bulk_reject_revisions_api_v1_ingestion_revisions_batches__batch__reject_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"batch","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Batch"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkReject"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/vocabularies":{"get":{"tags":["vocabularies"],"summary":"Get Vocabularies","description":"Return all controlled vocabularies used by the extraction skill and validator.\n\nNo authentication required — this is reference data. Callers should cache\nusing the Cache-Control header; the vocab changes infrequently.","operationId":"get_vocabularies_api_v1_vocabularies_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Vocabularies Api V1 Vocabularies Get"}}}}}}},"/api/v1/annotations/":{"post":{"tags":["annotations"],"summary":"Create Annotation","operationId":"create_annotation_api_v1_annotations__post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["annotations"],"summary":"List Annotations","description":"List annotations. Curators see every one; everyone else sees their own.\n\nThis was public, which made the unreviewed curation queue — suggested edits and\nthe names of the people who filed them — readable by anyone who guessed the\nURL. Only the two curator review pages consume it, so the endpoint is now\nauthenticated; a contributor keeps the ability to list what *they* submitted,\nsince ``user_id`` is pinned to their own id rather than the endpoint being\ncurator-only.","operationId":"list_annotations_api_v1_annotations__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"entity_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Type"}},{"name":"entity_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entity Id"}},{"name":"annotation_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Annotation Type"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/annotations/{annotation_id}/review":{"patch":{"tags":["annotations"],"summary":"Review Annotation","operationId":"review_annotation_api_v1_annotations__annotation_id__review_patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"annotation_id","in":"path","required":true,"schema":{"type":"integer","title":"Annotation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationReview"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotationRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/curation/inbox":{"get":{"tags":["curation"],"summary":"Inbox","description":"Every pending item across every curation queue, with the real backlog.\n\n``counts`` always describes the whole backlog; the filters narrow ``items``\nonly. Each item carries ``url`` — the page where it is actually worked; the\ninbox itself performs no review action. Unknown filter values are ignored\nrather than rejected.","operationId":"inbox_api_v1_curation_inbox_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"review, annotation, request, download, extracting","title":"Kind"},"description":"review, annotation, request, download, extracting"},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"auto, submission","title":"Source"},"description":"auto, submission"},{"name":"confidence","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"high, medium, low, none","title":"Confidence"},"description":"high, medium, low, none"},{"name":"assigned","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"me, unassigned, others","title":"Assigned"},"description":"me, unassigned, others"},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Q"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"oldest, newest, confidence, confidence_low, year","default":"oldest","title":"Sort"},"description":"oldest, newest, confidence, confidence_low, year"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":0,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/curation/inbox/ingestions/{ingestion_id}/assignment":{"post":{"tags":["curation"],"summary":"Set Assignment","description":"Put a paper awaiting review on a curator's list, or take it off.\n\nCoordination only: approve never reads it (DECISIONS.md §7.3). Anyone who can\ncurate may take an unassigned paper; assigning to someone else, or taking a\npaper off a colleague's list, is a superuser's call.","operationId":"set_assignment_api_v1_curation_inbox_ingestions__ingestion_id__assignment_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignmentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/curation/duplicates":{"get":{"tags":["curation"],"summary":"Duplicates","description":"Proteins stored more than once, by sequence, with the merge tool's verdict.\n\nRead-only — the same detector and planner ``scripts/report_duplicate_proteins``\nand ``scripts/merge_duplicate_proteins`` run. Merging stays an operator step.","operationId":"duplicates_api_v1_curation_duplicates_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"frame","in":"query","required":false,"schema":{"type":"string","description":"precursor, mature","default":"precursor","title":"Frame"},"description":"precursor, mature"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/curation/unresolved-names":{"get":{"tags":["curation"],"summary":"Unresolved Names","description":"The organism names behind the Taxonomy tab's counts, listed.","operationId":"unresolved_names_api_v1_curation_unresolved_names_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/curation/evidence-checks":{"get":{"tags":["curation"],"summary":"Evidence Checks Report","description":"What overclaims in the organism counts, and why (C4). Read-only.\n\nStrain-type proposals for unclassified occurrences (expression hosts,\nknockouts, engineered strains), positives with no experiment, observation\nvalues copied across isolates, positive results showing mass gain, and\nisolates filed as \"bacterium\"/\"fungus\" though a genus is named. The same\nrules ``python -m scripts.propose_genetic_background`` runs.","operationId":"evidence_checks_report_api_v1_curation_evidence_checks_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"minimum":1,"default":500,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/curation/strain-occurrences/{occurrence_id}":{"patch":{"tags":["curation"],"summary":"Set Genetic Background","description":"Classify one strain occurrence (C4). Audited in the activity log.\n\n``expression_host``, ``knockout`` and ``engineered_host`` take the\noccurrence's whole-organism results off its species' tallies, badges and\n\"first reported\" on every surface; ``wild_type`` and ``unknown`` count.","operationId":"set_genetic_background_api_v1_curation_strain_occurrences__occurrence_id__patch","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"occurrence_id","in":"path","required":true,"schema":{"type":"integer","title":"Occurrence Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeneticBackgroundUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/curation/activity":{"get":{"tags":["curation"],"summary":"Activity","description":"The audit log (``contribution_events``), unredacted, for curators.","operationId":"activity_api_v1_curation_activity_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"target_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Target Type"}},{"name":"target_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Target Id"}},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":36},{"type":"null"}],"title":"User Id"}},{"name":"event_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Event Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/curation/queue":{"get":{"tags":["curation"],"summary":"Curation Queue","description":"Unified review queue for curators — annotations, evidence, and submissions.","operationId":"curation_queue_api_v1_curation_queue_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"item_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"annotation, submission","title":"Item Type"},"description":"annotation, submission"},{"name":"entity_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Type"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"default":"pending","title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/curation/contributors":{"get":{"tags":["curation"],"summary":"List Contributors","description":"Public directory of everyone who has suggested or submitted data (F9).\n\nName, ORCID and counts only: no email, no gravatar. Inactive accounts are\nleft out. Ordered by contribution count, most first. Counts come from\n:func:`_contribution_rows`, the same source as the profile counters.","operationId":"list_contributors_api_v1_curation_contributors_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributorDirectory"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/curation/contributions/{user_id}":{"get":{"tags":["curation"],"summary":"User Contributions","description":"Public contribution timeline for a user.","operationId":"user_contributions_api_v1_curation_contributions__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionTimeline"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/curation/profile/{user_id}":{"get":{"tags":["curation"],"summary":"Public Profile","description":"Public profile with contribution stats.","operationId":"public_profile_api_v1_curation_profile__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPublicProfile"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/orcid/login":{"get":{"tags":["orcid"],"summary":"Orcid Login","description":"Get ORCID OAuth authorization URL.","operationId":"orcid_login_api_v1_auth_orcid_login_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrcidAuthUrlResponse"}}}}}}},"/api/v1/auth/orcid/callback":{"get":{"tags":["orcid"],"summary":"Orcid Callback","description":"Handle ORCID OAuth callback and link the verified ORCID iD.","operationId":"orcid_callback_api_v1_auth_orcid_callback_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","title":"Code"}},{"name":"state","in":"query","required":true,"schema":{"type":"string","title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/orcid/unlink":{"delete":{"tags":["orcid"],"summary":"Orcid Unlink","description":"Unlink ORCID iD from account.","operationId":"orcid_unlink_api_v1_auth_orcid_unlink_delete","responses":{"204":{"description":"Successful Response"}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/forum/categories":{"get":{"tags":["forum"],"summary":"List Categories","operationId":"list_categories_api_v1_forum_categories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CategoryOut"},"type":"array","title":"Response List Categories Api V1 Forum Categories Get"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/forum/posts":{"get":{"tags":["forum"],"summary":"List Posts","operationId":"list_posts_api_v1_forum_posts_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"category_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Category Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Per Page"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response List Posts Api V1 Forum Posts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["forum"],"summary":"Create Post","operationId":"create_post_api_v1_forum_posts_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostSummaryOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/forum/posts/{post_id}":{"get":{"tags":["forum"],"summary":"Get Post","operationId":"get_post_api_v1_forum_posts__post_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostDetailOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["forum"],"summary":"Delete Post","operationId":"delete_post_api_v1_forum_posts__post_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/forum/posts/{post_id}/replies":{"post":{"tags":["forum"],"summary":"Create Reply","operationId":"create_reply_api_v1_forum_posts__post_id__replies_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplyCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplyOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/forum/replies/{reply_id}":{"delete":{"tags":["forum"],"summary":"Delete Reply","operationId":"delete_reply_api_v1_forum_replies__reply_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"reply_id","in":"path","required":true,"schema":{"type":"integer","title":"Reply Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/accessions/merge":{"post":{"tags":["admin"],"summary":"Admin Merge Accessions","description":"Merge a retired accession into a surviving one.","operationId":"admin_merge_accessions_api_v1_admin_accessions_merge_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessionMergeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/admin/accessions/tombstone":{"post":{"tags":["admin"],"summary":"Admin Tombstone Accession","description":"Tombstone an accession (marks deleted, never reused, returns 410).","operationId":"admin_tombstone_accession_api_v1_admin_accessions_tombstone_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessionTombstoneRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/chat":{"post":{"tags":["chat"],"summary":"Chat","operationId":"chat_api_v1_chat_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{},{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/chat/sessions":{"get":{"tags":["chat"],"summary":"List Sessions","operationId":"list_sessions_api_v1_chat_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ChatSessionOut"},"type":"array","title":"Response List Sessions Api V1 Chat Sessions Get"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/api/v1/chat/sessions/{session_id}":{"get":{"tags":["chat"],"summary":"Get Session","operationId":"get_session_api_v1_chat_sessions__session_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatHistoryOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["chat"],"summary":"Delete Session","operationId":"delete_session_api_v1_chat_sessions__session_id__delete","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chat/claim":{"post":{"tags":["chat"],"summary":"Claim Guest Session","description":"Merge a guest conversation into the logged-in user's history.","operationId":"claim_guest_session_api_v1_chat_claim_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatClaimRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatSessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/search":{"get":{"tags":["pages"],"summary":"Search Page","operationId":"search_page_search_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/":{"get":{"tags":["pages"],"summary":"Index","operationId":"index__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/about":{"get":{"tags":["pages"],"summary":"About","operationId":"about_about_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/license":{"get":{"tags":["pages"],"summary":"License Page","operationId":"license_page_license_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/licence":{"get":{"tags":["pages"],"summary":"Licence Alias","operationId":"licence_alias_licence_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/terms":{"get":{"tags":["pages"],"summary":"Terms Page","operationId":"terms_page_terms_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/privacy":{"get":{"tags":["pages"],"summary":"Privacy Page","operationId":"privacy_page_privacy_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/guide":{"get":{"tags":["pages"],"summary":"Guide Redirect","description":"Legacy Data Guide URL — folded into the multi-page documentation.","operationId":"guide_redirect_guide_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/microorganisms":{"get":{"tags":["pages"],"summary":"Microorganisms Page","operationId":"microorganisms_page_microorganisms_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/microorganisms/accession/{accession}":{"get":{"tags":["pages"],"summary":"Microorganism Detail By Accession","description":"The organism page for a row with no tax-id to route on.\n\nSince 0.82.0 an organism may be recorded with no NCBI tax-id — a validly\npublished species NCBI has no node for. Without this route such a row would\nappear in every list and search and 404 when clicked, which is a worse answer\nthan not showing it at all.","operationId":"microorganism_detail_by_accession_microorganisms_accession__accession__get","parameters":[{"name":"accession","in":"path","required":true,"schema":{"type":"string","title":"Accession"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/microorganisms/{tax_id}":{"get":{"tags":["pages"],"summary":"Microorganism Detail","operationId":"microorganism_detail_microorganisms__tax_id__get","parameters":[{"name":"tax_id","in":"path","required":true,"schema":{"type":"integer","title":"Tax Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/taxonomy/{rank}/{name}":{"get":{"tags":["pages"],"summary":"Taxonomy Group","operationId":"taxonomy_group_taxonomy__rank___name__get","parameters":[{"name":"rank","in":"path","required":true,"schema":{"type":"string","title":"Rank"}},{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"name":"renamed_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Renamed From"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/compounds":{"get":{"tags":["pages"],"summary":"Compounds Page","operationId":"compounds_page_compounds_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/compounds/{compound_id}":{"get":{"tags":["pages"],"summary":"Compound Detail","operationId":"compound_detail_compounds__compound_id__get","parameters":[{"name":"compound_id","in":"path","required":true,"schema":{"type":"integer","title":"Compound Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/plastics":{"get":{"tags":["pages"],"summary":"Plastics Page","operationId":"plastics_page_plastics_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/plastics/{plastic_id}":{"get":{"tags":["pages"],"summary":"Plastic Detail","operationId":"plastic_detail_plastics__plastic_id__get","parameters":[{"name":"plastic_id","in":"path","required":true,"schema":{"type":"integer","title":"Plastic Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/proteins":{"get":{"tags":["pages"],"summary":"Proteins Page","operationId":"proteins_page_proteins_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/proteins/{accession}":{"get":{"tags":["pages"],"summary":"Protein Detail","description":"Protein page, mirroring the API's 404 / 301 / 410 accession contract.\n\nA merged accession redirects rather than quietly rendering the survivor's\ndata at the old URL: the visitor sees which accession they actually landed\non, and search engines fold the two URLs into one instead of indexing\nduplicate content.","operationId":"protein_detail_proteins__accession__get","parameters":[{"name":"accession","in":"path","required":true,"schema":{"type":"string","title":"Accession"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/variants/{variant_id}":{"get":{"tags":["pages"],"summary":"Variant Detail Page","operationId":"variant_detail_page_variants__variant_id__get","parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"integer","title":"Variant Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/engineering":{"get":{"tags":["pages"],"summary":"Engineering Page","operationId":"engineering_page_engineering_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/engineering/{accession}":{"get":{"tags":["pages"],"summary":"Engineering Detail","operationId":"engineering_detail_engineering__accession__get","parameters":[{"name":"accession","in":"path","required":true,"schema":{"type":"string","title":"Accession"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/statistics":{"get":{"tags":["pages"],"summary":"Statistics","operationId":"statistics_statistics_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/download":{"get":{"tags":["pages"],"summary":"Download","operationId":"download_download_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/contact":{"get":{"tags":["pages"],"summary":"Contact","operationId":"contact_contact_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/papers":{"get":{"tags":["pages"],"summary":"Papers Page","operationId":"papers_page_papers_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/news/{news_id}":{"get":{"tags":["pages"],"summary":"News Article","operationId":"news_article_news__news_id__get","parameters":[{"name":"news_id","in":"path","required":true,"schema":{"type":"integer","title":"News Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/interactive-tree":{"get":{"tags":["pages"],"summary":"Interactive Tree","operationId":"interactive_tree_interactive_tree_get","parameters":[{"name":"job","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat":{"get":{"tags":["pages"],"summary":"Chat Page","operationId":"chat_page_chat_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/dashboard":{"get":{"tags":["pages"],"summary":"Dashboard","operationId":"dashboard_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/tools/annotate-gene":{"get":{"tags":["pages"],"summary":"Annotate Gene","operationId":"annotate_gene_tools_annotate_gene_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/tools/annotate-genome":{"get":{"tags":["pages"],"summary":"Annotate Genome","operationId":"annotate_genome_tools_annotate_genome_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/tools/annotate-list":{"get":{"tags":["pages"],"summary":"Annotate List","operationId":"annotate_list_tools_annotate_list_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/tools/compare-genomes":{"get":{"tags":["pages"],"summary":"Compare Genomes","operationId":"compare_genomes_tools_compare_genomes_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/tools/pathway-analysis":{"get":{"tags":["pages"],"summary":"Pathway Analysis","operationId":"pathway_analysis_tools_pathway_analysis_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/tools/hmm-screen":{"get":{"tags":["pages"],"summary":"Hmm Screen","operationId":"hmm_screen_tools_hmm_screen_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/tools/build-tree":{"get":{"tags":["pages"],"summary":"Build Tree","operationId":"build_tree_tools_build_tree_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/jobs/{job_id}":{"get":{"tags":["pages"],"summary":"Job Status","operationId":"job_status_jobs__job_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/profile":{"get":{"tags":["pages"],"summary":"Profile","operationId":"profile_profile_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/jobs":{"get":{"tags":["pages"],"summary":"Jobs Page","operationId":"jobs_page_jobs_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/admin":{"get":{"tags":["pages"],"summary":"Admin Page","operationId":"admin_page_admin_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/admin/settings":{"get":{"tags":["pages"],"summary":"Admin Settings Page","operationId":"admin_settings_page_admin_settings_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/admin/preview/{kind}/{record_id}":{"get":{"tags":["pages"],"summary":"Admin Record Preview","description":"A staged or merged record, as an admin sees it (R13-10).\n\nIts public page 404s — correctly — so without this an operator had no way to\nread a record before deciding to release it. Server-rendered from the\ndatabase under the superuser page guard; the public visibility filters are\ndeliberately not applied, because what they hide is what this page is for.","operationId":"admin_record_preview_admin_preview__kind___record_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"kind","in":"path","required":true,"schema":{"type":"string","title":"Kind"}},{"name":"record_id","in":"path","required":true,"schema":{"type":"integer","title":"Record Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/review":{"get":{"tags":["pages"],"summary":"Admin Review Page","operationId":"admin_review_page_admin_review_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/documentation":{"get":{"tags":["pages"],"summary":"Documentation Overview","operationId":"documentation_overview_documentation_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/documentation/data-model":{"get":{"tags":["pages"],"summary":"Documentation Data Model","operationId":"documentation_data_model_documentation_data_model_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/documentation/reading-results":{"get":{"tags":["pages"],"summary":"Documentation Reading Results","operationId":"documentation_reading_results_documentation_reading_results_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/documentation/browsing":{"get":{"tags":["pages"],"summary":"Documentation Browsing","operationId":"documentation_browsing_documentation_browsing_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/documentation/contributing":{"get":{"tags":["pages"],"summary":"Documentation Contributing","operationId":"documentation_contributing_documentation_contributing_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/documentation/vocabularies":{"get":{"tags":["pages"],"summary":"Documentation Vocabularies","operationId":"documentation_vocabularies_documentation_vocabularies_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/documentation/api":{"get":{"tags":["pages"],"summary":"Documentation Api","operationId":"documentation_api_documentation_api_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/documentation/tools":{"get":{"tags":["pages"],"summary":"Documentation Tools","operationId":"documentation_tools_documentation_tools_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/documentation/curator-guide":{"get":{"tags":["pages"],"summary":"Documentation Curator Guide","description":"Curator policy: what makes a record, when to reject, and the R-rules.\n\nPublic on purpose — a reader weighing the data is entitled to the rules it\nwas reviewed under, and a curator cannot check the AI against rules they\ncannot see (R13-4).","operationId":"documentation_curator_guide_documentation_curator_guide_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/curator-guide":{"get":{"tags":["pages"],"summary":"Curator Guide Redirect","description":"The Curator Guide URL — now the curator policy guide, not the form reference.\n\nA 302, not a 301: this URL used to 301 to /documentation/contributing, and\na browser that cached that permanent redirect keeps following it. Making\nthe new target temporary means the destination can move again without\nrepeating that problem.","operationId":"curator_guide_redirect_curator_guide_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/profile/api-keys":{"get":{"tags":["pages"],"summary":"Api Keys Page","operationId":"api_keys_page_profile_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/submit-data":{"get":{"tags":["pages"],"summary":"Submit Data","operationId":"submit_data_submit_data_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/plastics/{plastic_id}/pathways":{"get":{"tags":["pages"],"summary":"Plastic Pathways","description":"Every degradation pathway for one plastic (a selector when there are several).\n\nA real plastic with no pathway yet is a legitimate page with an informational\nempty state, so it is a 200; only a plastic that does not exist is a 404.","operationId":"plastic_pathways_plastics__plastic_id__pathways_get","parameters":[{"name":"plastic_id","in":"path","required":true,"schema":{"type":"integer","title":"Plastic Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/pathways/{pathway_id}":{"get":{"tags":["pages"],"summary":"Pathway Explorer","description":"One degradation pathway, addressed by its own id — the canonical URL.\n\nThrough 1.23 this route took a *plastic* id. 1.24 kept a 301 for old\nplastic-keyed links, but pathway and plastic ids share one integer space, so\nthat redirect silently changed meaning the day a pathway took the colliding\nid. The plastic-scoped view is /plastics/{id}/pathways; here an id is only\never a pathway id, and anything else is a real 404.","operationId":"pathway_explorer_pathways__pathway_id__get","parameters":[{"name":"pathway_id","in":"path","required":true,"schema":{"type":"integer","title":"Pathway Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/{paper_id}":{"get":{"tags":["pages"],"summary":"Paper Detail","operationId":"paper_detail_papers__paper_id__get","parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"integer","title":"Paper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/papers/{paper_id}":{"get":{"tags":["pages"],"summary":"Dashboard Paper Footprint","description":"Reviewer dashboard page showing every record derived from a paper.","operationId":"dashboard_paper_footprint_dashboard_papers__paper_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"integer","title":"Paper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/review":{"get":{"tags":["pages"],"summary":"Dashboard Review Queue","description":"Curator review queue for pending suggestions and flags.","operationId":"dashboard_review_queue_dashboard_review_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/login":{"get":{"tags":["pages"],"summary":"Login Page","operationId":"login_page_login_get","parameters":[{"name":"next","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/register":{"get":{"tags":["pages"],"summary":"Register Page","operationId":"register_page_register_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/forgot-password":{"get":{"tags":["pages"],"summary":"Forgot Password","operationId":"forgot_password_forgot_password_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/reset-password":{"get":{"tags":["pages"],"summary":"Reset Password Page","operationId":"reset_password_page_reset_password_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/forum":{"get":{"tags":["pages"],"summary":"Forum Index","operationId":"forum_index_forum_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/forum/{category_slug}":{"get":{"tags":["pages"],"summary":"Forum Category","operationId":"forum_category_forum__category_slug__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"category_slug","in":"path","required":true,"schema":{"type":"string","title":"Category Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/forum/{category_slug}/{post_id}":{"get":{"tags":["pages"],"summary":"Forum Thread","operationId":"forum_thread_forum__category_slug___post_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"category_slug","in":"path","required":true,"schema":{"type":"string","title":"Category Slug"}},{"name":"post_id","in":"path","required":true,"schema":{"type":"integer","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/curation/review":{"get":{"tags":["pages"],"summary":"Curation Review","operationId":"curation_review_curation_review_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/curation/stats":{"get":{"tags":["pages"],"summary":"Curation Stats","description":"Curation *backlog* stats — pending queue depth, not a public leaderboard.\n\nServer-rendered from the same read model as the inbox, so the headline is\nthe whole backlog (every queue), not the two smallest queues it used to add\nup (R13-2).","operationId":"curation_stats_curation_stats_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/curation/inbox":{"get":{"tags":["pages"],"summary":"Curation Inbox","description":"One inbox for every curation queue (R13-2/3): counts, age, sort, filter, assign.\n\nA read model only. Each row links to the page that already acts on it, and\nevery action there keeps its own authorisation.","operationId":"curation_inbox_curation_inbox_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"}},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},{"name":"confidence","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Confidence"}},{"name":"assigned","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned"}},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Page"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/curation/duplicates":{"get":{"tags":["pages"],"summary":"Curation Duplicates","description":"Read-only duplicate-protein report, with the merge tool's verdict per group.","operationId":"curation_duplicates_curation_duplicates_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"frame","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Frame"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/curation/unresolved-names":{"get":{"tags":["pages"],"summary":"Curation Unresolved Names","description":"The organism names behind the Taxonomy tab's counts, listed (R13-8).","operationId":"curation_unresolved_names_curation_unresolved_names_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/curation/evidence-checks":{"get":{"tags":["pages"],"summary":"Curation Evidence Checks","description":"What overclaims in the organism counts, listed (C4). Read-only, except\nthat a curator may classify a strain occurrence from it.","operationId":"curation_evidence_checks_curation_evidence_checks_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/curation/revisions":{"get":{"tags":["pages"],"summary":"Curation Revisions","description":"Producer sweeps: pick a batch, read each revision's diff, approve or\nreject a selection. The page reads; every action goes through\n``/api/v1/ingestion-revisions`` with the curator's bearer token.","operationId":"curation_revisions_curation_revisions_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"batch","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Batch"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/curation/activity":{"get":{"tags":["pages"],"summary":"Curation Activity","description":"Who changed what, and when — the ``contribution_events`` audit log.","operationId":"curation_activity_curation_activity_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"target_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Target Type"}},{"name":"target_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Id"}},{"name":"event_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Event Type"}},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Page"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/contributors":{"get":{"tags":["pages"],"summary":"Contributors Index","description":"Public contributor directory (F9 / R12-13 — this used to 404).","operationId":"contributors_index_contributors_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/contributors/{user_id}":{"get":{"tags":["pages"],"summary":"Contributor Profile","operationId":"contributor_profile_contributors__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/ingestions/download":{"get":{"tags":["pages"],"summary":"Ingestions Download","operationId":"ingestions_download_dashboard_ingestions_download_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/dashboard/ingestions/in-progress":{"get":{"tags":["pages"],"summary":"Ingestions In Progress","description":"In-flight ingestions (pending_extraction): source uploaded, AI not done.\n\nWithout this view a paper is invisible between the download and review\nqueues — if the pipeline is slow or stalls, nobody can see it is stuck.","operationId":"ingestions_in_progress_dashboard_ingestions_in_progress_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/dashboard/ingestions/review":{"get":{"tags":["pages"],"summary":"Ingestions Review","description":"The review queue index — one row per paper, linking to its own page.\n\nThis used to render *every* pending paper into one document, each with its own\n80vh PDF iframe. That gave a reviewer no way to link to a paper, hand one to a\ncolleague, or come back to where they were, and it made the browser lay out\nthe whole queue to show one item.\n\nIt also stopped at a hard ``.limit(100)`` with nothing to say about the 101st\npaper. That cap bites sooner now that one queue carries both origins — AI\nextractions and human submissions — so the page paginates, and it badges and\nfilters by ``source``, because the two are not reviewed under the same right:\nonly a superuser may publish someone else's submission (DECISIONS.md §7.2).","operationId":"ingestions_review_dashboard_ingestions_review_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Page"}},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/ingestions/review/{ingestion_id}":{"get":{"tags":["pages"],"summary":"Ingestions Review Detail","description":"One paper, one URL — the page a reviewer actually works in.\n\nAny status renders, not just ``pending_review``: a link shared yesterday must\nstill resolve to something honest after a colleague approved the paper, rather\nthan 404ing as though the record never existed.","operationId":"ingestions_review_detail_dashboard_ingestions_review__ingestion_id__get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"ingestion_id","in":"path","required":true,"schema":{"type":"integer","title":"Ingestion Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["meta"],"summary":"Health","description":"Liveness probe — cheap, no dependency checks.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/readyz":{"get":{"tags":["meta"],"summary":"Readyz","description":"Readiness probe — verifies the database and Redis are reachable.","operationId":"readyz_readyz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AccessionMergeRequest":{"properties":{"survivor_accession":{"type":"string","title":"Survivor Accession"},"retired_accession":{"type":"string","title":"Retired Accession"}},"type":"object","required":["survivor_accession","retired_accession"],"title":"AccessionMergeRequest"},"AccessionTombstoneRequest":{"properties":{"accession":{"type":"string","title":"Accession"}},"type":"object","required":["accession"],"title":"AccessionTombstoneRequest"},"AdminDatasetReleaseRead":{"properties":{"id":{"type":"integer","title":"Id"},"version":{"type":"string","title":"Version"},"status":{"type":"string","title":"Status"},"stage":{"type":"string","title":"Stage"},"trigger":{"type":"string","title":"Trigger"},"promoted_proteins":{"type":"integer","title":"Promoted Proteins"},"promoted_microorganisms":{"type":"integer","title":"Promoted Microorganisms"},"withheld":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Withheld"},"reference_fingerprint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference Fingerprint"},"reference_rebuilt":{"type":"boolean","title":"Reference Rebuilt"},"notebooks":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Notebooks"},"dataset_fingerprint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Fingerprint"},"snapshot_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Snapshot Id"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"promoted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Promoted At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","version","status","stage","trigger","promoted_proteins","promoted_microorganisms","reference_rebuilt","created_at"],"title":"AdminDatasetReleaseRead","description":"The full release row, for superusers: stages, fingerprints, notebooks."},"AdminJobRead":{"properties":{"id":{"type":"string","title":"Id"},"job_type":{"type":"string","title":"Job Type"},"status":{"type":"string","title":"Status"},"user_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Email"},"created_at":{"type":"string","title":"Created At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"}},"type":"object","required":["id","job_type","status","created_at"],"title":"AdminJobRead"},"AdminSnapshotResponse":{"properties":{"id":{"type":"integer","title":"Id"},"release_label":{"type":"string","title":"Release Label"},"status":{"type":"string","title":"Status"},"entity_counts":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Entity Counts"},"file_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Path"},"file_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"File Size"},"checksum":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checksum"},"figshare_article_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Figshare Article Id"},"figshare_doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Figshare Doi"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"}},"type":"object","required":["id","release_label","status","entity_counts","file_path","file_size","checksum","figshare_article_id","figshare_doi","error_message","created_at","published_at"],"title":"AdminSnapshotResponse"},"AdminStatsResponse":{"properties":{"users":{"type":"integer","title":"Users"},"microorganisms":{"type":"integer","title":"Microorganisms"},"proteins":{"type":"integer","title":"Proteins"},"plastics":{"type":"integer","title":"Plastics"},"jobs":{"type":"integer","title":"Jobs"},"submissions":{"type":"integer","title":"Submissions"},"pending_submissions":{"type":"integer","title":"Pending Submissions"},"active_jobs":{"type":"integer","title":"Active Jobs"}},"type":"object","required":["users","microorganisms","proteins","plastics","jobs","submissions","pending_submissions","active_jobs"],"title":"AdminStatsResponse"},"AdminSubmissionRead":{"properties":{"id":{"type":"integer","title":"Id"},"status":{"type":"string","title":"Status"},"admin_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Admin Notes"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"data_json":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Data Json"},"ingestion_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ingestion Id"}},"type":"object","required":["id","status"],"title":"AdminSubmissionRead"},"Aerobicity":{"type":"string","enum":["aerobic","anaerobic","microaerophilic","not_reported"],"title":"Aerobicity","description":"Assay oxygen conditions; ``not_reported`` also matches NULL."},"AnnotationCreate":{"properties":{"entity_type":{"type":"string","maxLength":50,"minLength":1,"pattern":"^(microorganism|protein|plastic|reference|interaction|experiment|observation|protein_variant)$","title":"Entity Type"},"entity_id":{"type":"integer","title":"Entity Id"},"field_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Field Name"},"annotation_type":{"type":"string","pattern":"^(note|suggestion)$","title":"Annotation Type"},"old_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Value"},"new_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"New Value"},"content":{"type":"string","maxLength":5000,"minLength":1,"title":"Content"}},"type":"object","required":["entity_type","entity_id","annotation_type","content"],"title":"AnnotationCreate"},"AnnotationRead":{"properties":{"id":{"type":"integer","title":"Id"},"user_id":{"type":"string","title":"User Id"},"entity_type":{"type":"string","title":"Entity Type"},"entity_id":{"type":"integer","title":"Entity Id"},"field_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field Name"},"annotation_type":{"type":"string","title":"Annotation Type"},"old_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Value"},"new_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"New Value"},"content":{"type":"string","title":"Content"},"status":{"type":"string","title":"Status"},"reviewer_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewer Notes"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"user_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Name"},"user_orcid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Orcid"},"entity_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Accession"},"entity_tax_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entity Tax Id"},"entity_paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entity Paper Id"},"entity_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Label"},"entity_missing":{"type":"boolean","title":"Entity Missing","default":false}},"type":"object","required":["id","user_id","entity_type","entity_id","field_name","annotation_type","old_value","new_value","content","status","created_at"],"title":"AnnotationRead"},"AnnotationReview":{"properties":{"status":{"type":"string","pattern":"^(accepted|rejected)$","title":"Status"},"reviewer_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Reviewer Notes"}},"type":"object","required":["status"],"title":"AnnotationReview"},"ApiKeyResponse":{"properties":{"api_key":{"type":"string","title":"Api Key"}},"type":"object","required":["api_key"],"title":"ApiKeyResponse"},"ApproveMode":{"type":"string","enum":["merge","replace"],"title":"ApproveMode"},"AssignmentRequest":{"properties":{"assignee_id":{"anyOf":[{"type":"string","maxLength":36},{"type":"null"}],"title":"Assignee Id","default":"me"}},"type":"object","title":"AssignmentRequest","description":"``assignee_id``: a user id, ``\"me\"`` (the default), or ``null`` to release."},"AttemptResponse":{"properties":{"id":{"type":"integer","title":"Id"},"ingestion_id":{"type":"integer","title":"Ingestion Id"},"extraction_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Model"},"extraction_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Version"},"payload":{"type":"object","title":"Payload"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","ingestion_id","payload","created_at"],"title":"AttemptResponse","description":"One row of the append-only extraction history.\n\nRead-only and **curator-only**, deliberately. An attempt is unreviewed model\noutput: it has passed nobody's eyes. That is why ``ExtractionAttempt`` is absent\nfrom ``app/services/export.py`` and ``app/services/snapshots.py`` — nothing\nhere may reach a public artefact, least of all a Figshare DOI that cannot be\nunpublished. Exposing it through a curator-authenticated read endpoint does\nnot change that; adding it to an export would."},"AuthorOut":{"properties":{"id":{"type":"string","title":"Id"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"email":{"type":"string","title":"Email"}},"type":"object","required":["id","full_name","email"],"title":"AuthorOut"},"BlastTypeEnum":{"type":"string","enum":["blastp","blastx"],"title":"BlastTypeEnum"},"Body_login_api_v1_auth_login_post":{"properties":{"grant_type":{"anyOf":[{"type":"string","pattern":"password"},{"type":"null"}],"title":"Grant Type"},"username":{"type":"string","title":"Username"},"password":{"type":"string","title":"Password"},"scope":{"type":"string","title":"Scope","default":""},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Secret"}},"type":"object","required":["username","password"],"title":"Body_login_api_v1_auth_login_post"},"Body_submit_job_api_v1_jobs_post":{"properties":{"file":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"File"},"files":{"anyOf":[{"items":{"type":"string","format":"binary"},"type":"array"},{"type":"null"}],"title":"Files"},"job_type":{"$ref":"#/components/schemas/JobTypeEnum"},"evalue":{"type":"number","maximum":10.0,"exclusiveMinimum":0.0,"title":"Evalue","description":"E-value threshold passed directly to DIAMOND (e.g. 1e-5). Range: (0, 10].","default":1e-05},"pident":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Pident","description":"Minimum percent identity threshold. Range: 0–100.","default":30},"organism_type":{"$ref":"#/components/schemas/OrganismTypeEnum","default":"no_signalp"},"blast_type":{"$ref":"#/components/schemas/BlastTypeEnum","default":"blastp"},"include_variants":{"type":"boolean","title":"Include Variants","default":false},"genus_column":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Genus Column"},"species_column":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Species Column"},"field_separator":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field Separator"},"target_polymers":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Target Polymers"},"min_step_identity":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Min Step Identity","description":"pathway_analysis: minimum % identity for a hit to call a step present (default 40)."},"max_step_evalue":{"anyOf":[{"type":"number","maximum":10.0,"exclusiveMinimum":0.0},{"type":"null"}],"title":"Max Step Evalue","description":"pathway_analysis: maximum e-value for a hit to call a step present (default 1e-10)."},"min_reference_coverage":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Min Reference Coverage","description":"pathway_analysis: minimum % of the reference enzyme the alignment must cover (default 70)."},"min_query_coverage":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Min Query Coverage","description":"pathway_analysis: minimum % of your protein the alignment must cover (default 50; BLASTP only)."},"min_qcov":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Min Qcov","description":"Minimum % of the query sequence a hit's alignment must cover. For BLASTX this is a % of the nucleotide query."},"min_scov":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Min Scov","description":"Minimum % of the reference sequence a hit's alignment must cover."},"min_bitscore":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Min Bitscore","description":"Minimum bitscore for a hit to be kept."}},"type":"object","required":["job_type"],"title":"Body_submit_job_api_v1_jobs_post"},"Body_upload_ingestion_files_api_v1_ingestions__ingestion_id__files_post":{"properties":{"pdf":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Pdf"},"markdown":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Markdown"},"supplements":{"anyOf":[{"items":{"type":"string","format":"binary"},"type":"array"},{"type":"null"}],"title":"Supplements"}},"type":"object","title":"Body_upload_ingestion_files_api_v1_ingestions__ingestion_id__files_post"},"Body_upload_markdown_api_v1_ingestions__ingestion_id__upload_markdown_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_markdown_api_v1_ingestions__ingestion_id__upload_markdown_post"},"Body_upload_pdf_api_v1_ingestions__ingestion_id__upload_pdf_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"},"supplements":{"anyOf":[{"items":{"type":"string","format":"binary"},"type":"array"},{"type":"null"}],"title":"Supplements"}},"type":"object","required":["file"],"title":"Body_upload_pdf_api_v1_ingestions__ingestion_id__upload_pdf_post"},"BulkApprove":{"properties":{"ingestion_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array","maxItems":500,"minItems":1},{"type":"null"}],"title":"Ingestion Ids"},"all":{"type":"boolean","title":"All","default":false},"limit":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Limit","default":20},"after_id":{"type":"integer","minimum":0.0,"title":"After Id","default":0}},"type":"object","title":"BulkApprove"},"BulkItemOutcome":{"properties":{"ingestion_id":{"type":"integer","title":"Ingestion Id"},"outcome":{"type":"string","title":"Outcome"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code"},"detail":{"title":"Detail"}},"type":"object","required":["ingestion_id","outcome"],"title":"BulkItemOutcome"},"BulkReject":{"properties":{"ingestion_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array","maxItems":500,"minItems":1},{"type":"null"}],"title":"Ingestion Ids"},"all":{"type":"boolean","title":"All","default":false},"reason":{"type":"string","minLength":1,"title":"Reason"}},"type":"object","required":["reason"],"title":"BulkReject"},"BulkResult":{"properties":{"batch":{"type":"string","title":"Batch"},"processed":{"type":"integer","title":"Processed"},"succeeded":{"type":"integer","title":"Succeeded"},"failed":{"type":"integer","title":"Failed"},"remaining":{"type":"integer","title":"Remaining"},"next_after_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next After Id"},"results":{"items":{"$ref":"#/components/schemas/BulkItemOutcome"},"type":"array","title":"Results"}},"type":"object","required":["batch","processed","succeeded","failed","remaining","results"],"title":"BulkResult"},"CategoryOut":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"icon":{"type":"string","title":"Icon"},"sort_order":{"type":"integer","title":"Sort Order"},"post_count":{"type":"integer","title":"Post Count","default":0}},"type":"object","required":["id","name","slug","description","icon","sort_order"],"title":"CategoryOut"},"ChatClaimRequest":{"properties":{"guest_session_id":{"type":"string","title":"Guest Session Id"}},"type":"object","required":["guest_session_id"],"title":"ChatClaimRequest"},"ChatHistoryOut":{"properties":{"session_id":{"type":"string","title":"Session Id"},"title":{"type":"string","title":"Title"},"messages":{"items":{"$ref":"#/components/schemas/ChatMessageOut"},"type":"array","title":"Messages"}},"type":"object","required":["session_id","title","messages"],"title":"ChatHistoryOut"},"ChatMessageOut":{"properties":{"id":{"type":"string","title":"Id"},"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"},"chart_png":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Chart Png"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","role","content","created_at"],"title":"ChatMessageOut"},"ChatRequest":{"properties":{"message":{"type":"string","maxLength":4000,"minLength":1,"title":"Message"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}},"type":"object","required":["message"],"title":"ChatRequest"},"ChatResponse":{"properties":{"reply":{"type":"string","title":"Reply"},"charts":{"items":{"type":"string"},"type":"array","title":"Charts","default":[]},"session_id":{"type":"string","title":"Session Id"},"is_guest":{"type":"boolean","title":"Is Guest"},"queries_remaining":{"type":"integer","title":"Queries Remaining"}},"type":"object","required":["reply","session_id","is_guest","queries_remaining"],"title":"ChatResponse"},"ChatSessionOut":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","title","created_at","updated_at"],"title":"ChatSessionOut"},"ClaimHeartbeat":{"properties":{"revision":{"type":"integer","title":"Revision"}},"type":"object","required":["revision"],"title":"ClaimHeartbeat"},"ClaimRequest":{"properties":{"takeover":{"type":"boolean","title":"Takeover","default":false}},"type":"object","title":"ClaimRequest","description":"Claim a paper for review.\n\n``takeover`` has to be asked for. A claim that could be taken by simply\nretrying would not be a signal to anyone; a takeover is a deliberate act, and\nit is recorded on the row and logged."},"ClaimResponse":{"properties":{"ingestion_id":{"type":"integer","title":"Ingestion Id"},"revision":{"type":"integer","title":"Revision"},"held":{"type":"boolean","title":"Held"},"mine":{"type":"boolean","title":"Mine"},"holder_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Holder Id"},"holder_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Holder Name"},"claimed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Claimed At"},"heartbeat_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Heartbeat At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"taken_over_from_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Taken Over From Name"},"taken_over_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Taken Over At"},"takeover_count":{"type":"integer","title":"Takeover Count","default":0},"heartbeat_seconds":{"type":"integer","title":"Heartbeat Seconds"}},"type":"object","required":["ingestion_id","revision","held","mine","heartbeat_seconds"],"title":"ClaimResponse","description":"The state of one paper's claim, as the page renders it.\n\n``held`` is what the UI branches on and already accounts for expiry: a claim\nwhose heartbeats stopped is reported as not held, because \"reserved by a tab\nthat closed on Friday\" and \"free\" are the same answer to the only question the\npage asks."},"CompoundCreate":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"formula":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Formula"},"smiles":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Smiles"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_additive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Additive"}},"type":"object","required":["name"],"title":"CompoundCreate"},"CompoundDetail":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"formula":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Formula"},"smiles":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Smiles"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_additive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Additive"},"monomer_in_plastics":{"items":{"$ref":"#/components/schemas/app__schemas__compounds__PlasticRef"},"type":"array","title":"Monomer In Plastics","default":[]},"additive_in_plastics":{"items":{"$ref":"#/components/schemas/app__schemas__compounds__PlasticRef"},"type":"array","title":"Additive In Plastics","default":[]},"reaction_steps":{"items":{"$ref":"#/components/schemas/PathwayStepRef"},"type":"array","title":"Reaction Steps","default":[]}},"type":"object","required":["id","name"],"title":"CompoundDetail","description":"Full compound detail including all entity associations."},"CompoundRead":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"formula":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Formula"},"smiles":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Smiles"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_additive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Additive"}},"type":"object","required":["id","name"],"title":"CompoundRead"},"CompoundUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"formula":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Formula"},"smiles":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Smiles"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_additive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Additive"}},"type":"object","title":"CompoundUpdate"},"ContributionEventRead":{"properties":{"id":{"type":"integer","title":"Id"},"event_type":{"type":"string","title":"Event Type"},"target_type":{"type":"string","title":"Target Type"},"target_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Target Id"},"metadata":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","event_type","target_type","metadata","created_at"],"title":"ContributionEventRead"},"ContributionTimeline":{"properties":{"user":{"anyOf":[{"$ref":"#/components/schemas/UserPublicProfile"},{"type":"null"}]},"events":{"items":{"$ref":"#/components/schemas/ContributionEventRead"},"type":"array","title":"Events","default":[]},"total":{"type":"integer","title":"Total","default":0}},"type":"object","title":"ContributionTimeline"},"ContributorDirectory":{"properties":{"total":{"type":"integer","title":"Total"},"items":{"items":{"$ref":"#/components/schemas/ContributorSummary"},"type":"array","title":"Items"}},"type":"object","required":["total","items"],"title":"ContributorDirectory"},"ContributorSummary":{"properties":{"id":{"type":"string","title":"Id"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"orcid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Orcid"},"orcid_verified":{"type":"boolean","title":"Orcid Verified","default":false},"suggestions":{"type":"integer","title":"Suggestions","default":0},"suggestions_accepted":{"type":"integer","title":"Suggestions Accepted","default":0},"submissions":{"type":"integer","title":"Submissions","default":0},"total":{"type":"integer","title":"Total","default":0},"last_contribution_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Contribution At"}},"type":"object","required":["id","full_name","orcid"],"title":"ContributorSummary","description":"One row of the public contributor directory (``GET /curation/contributors``).\n\nDeliberately narrower than :class:`UserPublicProfile`: no email and no\ngravatar URL (an MD5 of the email, which is reversible for a known address).\nOnly the name the person chose to show, their ORCID, and counts."},"CurrentReleaseResponse":{"properties":{"version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"},"released_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Released At"},"doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doi"},"snapshot_release_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Snapshot Release Label"},"citation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Citation"},"license":{"type":"string","title":"License","description":"The data licence, e.g. 'CC BY 4.0'.","default":"CC BY 4.0"},"license_spdx":{"type":"string","title":"License Spdx","description":"SPDX identifier.","default":"CC-BY-4.0"},"license_url":{"type":"string","title":"License Url","default":"https://creativecommons.org/licenses/by/4.0/"},"paper_citation":{"type":"string","title":"Paper Citation","default":"Gambarini V, Pantos O, Kingsbury JM, Weaver L, Handley KM, Lear G (2022). PlasticDB: a database of microorganisms and proteins linked to plastic biodegradation. Database, 2022:baac008."},"paper_doi":{"type":"string","title":"Paper Doi","default":"10.1093/database/baac008"}},"type":"object","title":"CurrentReleaseResponse","description":"What a user needs in order to say which database they used.\n\n``version`` is the citable one. ``doi`` is present once the snapshot for\nthat version has been published to Figshare; a release whose corpus was\nunchanged has no snapshot of its own and carries the DOI of the last\nrelease that did, which is the correct thing to cite — the data is the\nsame data."},"DataSubmissionCreate":{"properties":{"submission_type":{"$ref":"#/components/schemas/SubmissionTypeEnum","default":"Add data"},"content":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"title":"Content"},"submitter_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Submitter Name"},"submitter_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Submitter Email"},"paper_doi":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Paper Doi"},"paper_title":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Paper Title"},"authors":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"},"abstract":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abstract"},"pub_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pub Year"},"citation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Citation"},"pubmed_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Pubmed Id"},"journal":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Journal"},"corresponding_author_country":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Corresponding Author Country"},"interactions":{"items":{"$ref":"#/components/schemas/ExtractedInteraction"},"type":"array","title":"Interactions","default":[]},"license_accepted":{"type":"boolean","title":"License Accepted","description":"Must be true. Confirms that accepted records are published under CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) and credited to the submitter.","default":false}},"additionalProperties":false,"type":"object","title":"DataSubmissionCreate","description":"A user data submission.\n\nThe evidence is carried in ``interactions`` using the **same** interaction-centric\nshape (:class:`~app.schemas.ingestions.ExtractedInteraction`) that the AI extraction\npipeline produces — one contract, one validator, one promotion path. Plastics are\nreferenced by name (server resolves to the canonical row); organism taxonomy and\nderived protein annotations are computed server-side, so the producer supplies only\nwhat the paper uniquely states.\n\n``extra=\"forbid\"`` because the boundary is otherwise enforced by omission in\nthe browser. The Add-data form hides the extractor-metadata block —\n``extraction_confidence``, ``extraction_notes``, ``reviewer_guidance`` — since\na typed record has no model behind it and a fabricated confidence is read as\ntriage signal in the review queue. Without this, a hand-rolled POST carrying\nthose fields was accepted and silently ignored, which reads as \"accepted\".\nSay no out loud instead, and catch a client's misspelled field name while it\nis still a typo rather than after the data has gone missing."},"DataSubmissionRead":{"properties":{"id":{"type":"integer","title":"Id"},"submission_type":{"type":"string","title":"Submission Type"},"status":{"type":"string","title":"Status"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"data_json":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Data Json"},"submitter_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitter Name"},"submitter_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitter Email"},"admin_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Admin Notes"},"ingestion_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ingestion Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","submission_type","status","submitter_name","submitter_email","created_at"],"title":"DataSubmissionRead"},"DatasetReleaseRead":{"properties":{"version":{"type":"string","title":"Version","description":"ISO year and week, e.g. '2026.35'. Distinct from the application version: this names the DATA you aligned against."},"released_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Released At","description":"When the release completed (UTC)."},"promoted_proteins":{"type":"integer","title":"Promoted Proteins","description":"Proteins this release made public (previously staged)."},"promoted_microorganisms":{"type":"integer","title":"Promoted Microorganisms","description":"Microorganisms this release made public (previously staged)."},"entity_counts":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"Entity Counts","description":"Row counts of the archived snapshot this release cut, per entity; null when the release cut no snapshot of its own."},"doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doi","description":"DOI of this release's published archive, if one was minted."}},"type":"object","required":["version","promoted_proteins","promoted_microorganisms"],"title":"DatasetReleaseRead","description":"One weekly cut of the public dataset — what a reader may cite.\n\nThe **public** shape: which version, when, how many records it published,\nand the DOI of its archive if one was minted. Nothing else. It used to be\nthe whole ``dataset_releases`` row, which put server internals on an\nanonymous endpoint — the ML bundle path on the pod's filesystem, the text\n\"ML_BUNDLE_PATH is not set\", per-reason withheld counts and the reference\nand dataset fingerprints (R01-11, R05-4). Those live on\n:class:`AdminDatasetReleaseRead`, behind ``/api/v1/admin/releases``.\n\nBuilt explicitly by :func:`public_release` rather than ``from_attributes``,\nso a column added to the model can never appear here by accident."},"DegradationLink":{"properties":{"plastic":{"$ref":"#/components/schemas/app__schemas__entities__PlasticRef"},"result":{"type":"string","title":"Result"},"methods":{"items":{"type":"string"},"type":"array","title":"Methods","default":[]},"positive_count":{"type":"integer","title":"Positive Count","default":0},"inconclusive_count":{"type":"integer","title":"Inconclusive Count","default":0},"negative_count":{"type":"integer","title":"Negative Count","default":0},"positive_papers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Positive Papers"},"inconclusive_papers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inconclusive Papers"},"negative_papers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Negative Papers"},"paper_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Count"},"result_polarity":{"type":"string","title":"Result Polarity","description":"Bucket label for the pairing: ``positive``/``inconclusive``/``negative``\nwhen the supporting papers agree, else ``mixed``. Drives the summary\nbadge on the microorganism/protein pages.","readOnly":true}},"type":"object","required":["plastic","result","result_polarity"],"title":"DegradationLink","description":"Backward-compatible flattened shape: one row per (actor, plastic) with\nthe best result polarity and the union of experiment methods.\n\n``positive_count``/``inconclusive_count``/``negative_count`` tally the\nunderlying interactions so the UI can show an honest per-plastic summary\n(e.g. ``PET [3+ / 1? / 2-]``) even when papers disagree. ``result_polarity``\nis the single label the UI should colour the pairing by: the best polarity\nwhen papers agree, or ``\"mixed\"`` when more than one polarity is present."},"DoiLookupRequest":{"properties":{"doi":{"type":"string","maxLength":255,"minLength":3,"title":"Doi"}},"type":"object","required":["doi"],"title":"DoiLookupRequest"},"DoiLookupResponse":{"properties":{"status":{"type":"string","enum":["found","not_found","unavailable","invalid"],"title":"Status","default":"unavailable"},"doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doi"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"in_database":{"type":"boolean","title":"In Database","default":false},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"authors":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"},"abstract":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abstract"},"pub_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pub Year"},"journal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Journal"},"citation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Citation"}},"type":"object","title":"DoiLookupResponse","description":"The answer to \"is this DOI real, and what is it?\".\n\n``status`` is the field a client branches on (F3, R12-1). The old response\nwas the same empty object for \"Crossref has never heard of this DOI\" and\n\"Crossref did not answer\", and the form printed \"Found.\" for both — so a\nmistyped DOI was confirmed as correct.\n\n* ``found`` — Crossref (or PlasticDB itself) has the DOI; metadata follows.\n* ``not_found`` — Crossref answered 404. The DOI is wrong, or too new to be\n  registered yet.\n* ``unavailable`` — the lookup could not be completed (timeout, Crossref\n  error). Says nothing about the DOI either way.\n* ``invalid`` — the text is not shaped like a DOI (``10.<prefix>/<suffix>``)."},"DraftResponse":{"properties":{"ingestion_id":{"type":"integer","title":"Ingestion Id"},"revision":{"type":"integer","title":"Revision"},"payload":{"type":"object","title":"Payload"},"updated_by_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated By Id"},"updated_by_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated By Name"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"based_on_attempt_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Based On Attempt Id"},"stale":{"type":"boolean","title":"Stale","default":false}},"type":"object","required":["ingestion_id","revision","payload","updated_at"],"title":"DraftResponse"},"DraftSave":{"properties":{"payload":{"type":"object","title":"Payload"},"revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Revision"}},"type":"object","required":["payload"],"title":"DraftSave","description":"One autosave of the review form.\n\n``payload`` is deliberately a bare object rather than ``ExtractedData``: a\ndraft is work in progress, and a half-typed record fails validation by\ndefinition. Validating here would make autosave refuse exactly the states it\nexists to protect. The payload is validated when the curator presses Approve —\nwhich is the moment it stops being a draft and starts being a record."},"EngineeringLineage":{"properties":{"id":{"type":"integer","title":"Id"},"plasticdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"name":{"type":"string","title":"Name"},"genbank_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genbank Id"},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"variants":{"items":{"$ref":"#/components/schemas/ProteinVariantRead"},"type":"array","title":"Variants","default":[]},"wild_type_kinetics":{"items":{"$ref":"#/components/schemas/EnzymeKineticsRead"},"type":"array","title":"Wild Type Kinetics","default":[]},"wild_type_properties":{"items":{"$ref":"#/components/schemas/EnzymePropertiesRead"},"type":"array","title":"Wild Type Properties","default":[]}},"type":"object","required":["id","plasticdb_id","name"],"title":"EngineeringLineage","description":"Parent protein summary with full variant lineage, shaped for the comparison UI."},"EnrichmentRescueStart":{"properties":{"source":{"type":"string","enum":["uniprot","uniparc","active_site","pdb","alphafold","esmfold","interpro","cazy","signalp"],"title":"Source"},"scope":{"type":"string","enum":["retry_capped","transient"],"title":"Scope","default":"retry_capped"}},"type":"object","required":["source"],"title":"EnrichmentRescueStart","description":"Body for ``POST /api/v1/admin/enrichment/rescue/runs``.\n\n``source`` is validated against the ladder's own rungs rather than accepted\nas a free string: a typo would claim the lock, select nothing, and report a\ntidy \"0 rows rescued\" that reads exactly like \"there was nothing to do\".\n\n``scope`` narrows to the rows the state machine has actually given up on by\ndefault. ``transient`` widens it to every unsettled failure for the source,\nwhich is the right choice only when an upstream has demonstrably recovered —\nit is a much larger crawl against the same free service."},"EnzymeKineticsCreate":{"properties":{"protein_id":{"type":"integer","title":"Protein Id"},"plastic_id":{"type":"integer","title":"Plastic Id"},"paper_id":{"type":"integer","title":"Paper Id"},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"experiment_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Experiment Id"},"km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Km"},"kcat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Kcat"},"vmax":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Vmax"},"km_unit":{"anyOf":[{"type":"string","enum":["uM","mM","nM","M"]},{"type":"null"}],"title":"Km Unit"},"kcat_unit":{"anyOf":[{"type":"string","enum":["s-1","min-1"]},{"type":"null"}],"title":"Kcat Unit"},"vmax_unit":{"anyOf":[{"type":"string","enum":["U/mg","umol/min/mg"]},{"type":"null"}],"title":"Vmax Unit"}},"type":"object","required":["protein_id","plastic_id","paper_id"],"title":"EnzymeKineticsCreate"},"EnzymeKineticsRead":{"properties":{"id":{"type":"integer","title":"Id"},"protein_id":{"type":"integer","title":"Protein Id"},"plastic_id":{"type":"integer","title":"Plastic Id"},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"experiment_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Experiment Id"},"km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Km"},"kcat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Kcat"},"vmax":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Vmax"},"km_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Km Unit"},"kcat_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kcat Unit"},"vmax_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vmax Unit"},"experiment":{"anyOf":[{"$ref":"#/components/schemas/ExperimentConditionsRef"},{"type":"null"}]},"plastic":{"anyOf":[{"$ref":"#/components/schemas/PlasticRead"},{"type":"null"}]},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"protein_variant":{"anyOf":[{"$ref":"#/components/schemas/ProteinVariantRef"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature","description":"Assay temperature, read from the linked experiment.","readOnly":true},"ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ph","description":"Assay pH, read from the linked experiment.","readOnly":true},"substrate_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Substrate Form","description":"Substrate form, read from the linked experiment.","readOnly":true},"kcat_km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Kcat Km","description":"Catalytic efficiency (kcat/Km) in M⁻¹·s⁻¹, derived when computable.","readOnly":true},"kcat_km_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kcat Km Unit","readOnly":true}},"type":"object","required":["id","protein_id","plastic_id","created_at","updated_at","temperature","ph","substrate_form","kcat_km","kcat_km_unit"],"title":"EnzymeKineticsRead"},"EnzymeKineticsUpdate":{"properties":{"protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Id"},"plastic_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Plastic Id"},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"experiment_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Experiment Id"},"km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Km"},"kcat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Kcat"},"vmax":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Vmax"},"km_unit":{"anyOf":[{"type":"string","enum":["uM","mM","nM","M"]},{"type":"null"}],"title":"Km Unit"},"kcat_unit":{"anyOf":[{"type":"string","enum":["s-1","min-1"]},{"type":"null"}],"title":"Kcat Unit"},"vmax_unit":{"anyOf":[{"type":"string","enum":["U/mg","umol/min/mg"]},{"type":"null"}],"title":"Vmax Unit"}},"type":"object","title":"EnzymeKineticsUpdate"},"EnzymePropertiesCreate":{"properties":{"protein_id":{"type":"integer","title":"Protein Id"},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"experiment_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Experiment Id"},"optimal_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Optimal Temperature"},"optimal_ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Optimal Ph"},"tm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Tm"},"t50":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"T50"},"half_life":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Half Life"},"half_life_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Half Life Temperature"},"assay_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assay Notes"}},"type":"object","required":["protein_id"],"title":"EnzymePropertiesCreate"},"EnzymePropertiesRead":{"properties":{"id":{"type":"integer","title":"Id"},"protein_id":{"type":"integer","title":"Protein Id"},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"experiment_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Experiment Id"},"optimal_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Optimal Temperature"},"optimal_ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Optimal Ph"},"tm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Tm"},"t50":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"T50"},"half_life":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Half Life"},"half_life_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Half Life Temperature"},"assay_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assay Notes"},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"protein_variant":{"anyOf":[{"$ref":"#/components/schemas/ProteinVariantRef"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","protein_id","created_at","updated_at"],"title":"EnzymePropertiesRead"},"EnzymePropertiesUpdate":{"properties":{"protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Id"},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"experiment_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Experiment Id"},"optimal_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Optimal Temperature"},"optimal_ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Optimal Ph"},"tm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Tm"},"t50":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"T50"},"half_life":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Half Life"},"half_life_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Half Life Temperature"},"assay_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assay Notes"}},"type":"object","title":"EnzymePropertiesUpdate"},"EvidenceMethod":{"type":"string","enum":["afm","biosensor","cd","chn_analysis","clear_zone","clsm","co2_evolution","cod","contact_angle","dcpip","dls","dsc","eds","enzyme_assay","fcm","fluorescent_assay","ftir","gc","gc_ms","gpc_sec","growth_on_plastic","hplc","lc_ms","luminescence","maldi_tof","mass_remaining","ms","nmr","o2_consumption","optical_microscopy","qcm","radiolabeling","raman","ros_assay","sem","ssa","tem","tensile_strength","tga","titration","tlc","toc","turbidity","uv_vis","viscometry","visual_inspection","weight_loss","xps","xrd","zymogram"],"title":"EvidenceMethod"},"EvidenceScope":{"type":"string","enum":["organism_or_enzyme","whole_organism","enzyme_only"],"title":"EvidenceScope"},"ExperimentConditionsRef":{"properties":{"id":{"type":"integer","title":"Id"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature"},"temperature_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Temperature Unit"},"ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ph"},"substrate_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Substrate Form"}},"type":"object","required":["id"],"title":"ExperimentConditionsRef","description":"Assay conditions embedded in kinetics rows.\n\nConditions (temperature, pH, substrate form) are not stored on the kinetics\nrow itself; they live on the linked ``Experiment``. This ref surfaces them so\nthat ``EnzymeKineticsRead`` can keep exposing ``temperature``/``ph``/\n``substrate_form`` as a single source of truth read through ``experiment_id``.\nRequires the ``experiment`` relationship to be eager-loaded at read sites."},"ExperimentRead":{"properties":{"id":{"type":"integer","title":"Id"},"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature"},"temperature_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Temperature Unit"},"ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ph"},"buffer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buffer"},"duration":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration"},"duration_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Duration Unit"},"substrate_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Substrate Form"},"sole_carbon_source":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Sole Carbon Source"},"culture_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Culture Medium"},"aerobicity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aerobicity"},"substrate_crystallinity_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Substrate Crystallinity Pct"},"substrate_mw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Substrate Mw"},"substrate_mw_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Substrate Mw Unit"},"analytical_grade":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Analytical Grade"},"detection_limit":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Detection Limit"},"detection_limit_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detection Limit Unit"},"quantitation_ceiling":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Quantitation Ceiling"},"quantitation_ceiling_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quantitation Ceiling Unit"},"observations":{"items":{"$ref":"#/components/schemas/ObservationRead"},"type":"array","title":"Observations","default":[]}},"type":"object","required":["id"],"title":"ExperimentRead"},"ExperimentWrite":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"method_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Method Id"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature"},"temperature_unit":{"anyOf":[{"type":"string","maxLength":8},{"type":"null"}],"title":"Temperature Unit"},"ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ph"},"buffer":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Buffer"},"duration":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration"},"duration_unit":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Duration Unit"},"substrate_form":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Substrate Form"},"sole_carbon_source":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Sole Carbon Source"},"culture_medium":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Culture Medium"},"aerobicity":{"anyOf":[{"type":"string","enum":["aerobic","anaerobic","microaerophilic","not_reported"]},{"type":"null"}],"title":"Aerobicity"},"substrate_crystallinity_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Substrate Crystallinity Pct"},"substrate_mw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Substrate Mw"},"substrate_mw_unit":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Substrate Mw Unit"},"analytical_grade":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Analytical Grade"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"observations":{"items":{"$ref":"#/components/schemas/ObservationWrite"},"type":"array","title":"Observations","default":[]}},"type":"object","title":"ExperimentWrite"},"ExtractedComponent":{"properties":{"component":{"type":"string","maxLength":255,"minLength":1,"title":"Component"},"component_type":{"anyOf":[{"type":"string","enum":["plastic","compound"]},{"type":"null"}],"title":"Component Type"},"fraction_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fraction Pct"},"fraction_basis":{"type":"string","title":"Fraction Basis","default":"unspecified"},"is_additive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Additive"}},"type":"object","required":["component"],"title":"ExtractedComponent","description":"One constituent of a blend/copolymer substrate, with its tested fraction.\n\n``component`` names a polymer or an additive/monomer; ``component_type`` is an\noptional hint — when absent, the server resolves the name plastic-first, else\nas a compound. ``fraction_pct`` is optional (components may be listed\nqualitatively); ``fraction_basis`` defaults to ``\"unspecified\"``.\n\n``is_additive`` is the AI's molecule-level judgement for a ``compound``\ncomponent: ``True`` when the constituent is an additive (filler, plasticiser,\nrubber toughener, …) rather than a structural monomer/comonomer. Only the\n*first* classification sticks — the server fills it onto the resolved\n:class:`~app.models.models.Compound` when that compound is still unclassified\nand never overwrites an existing value (see ``resolve_compound``)."},"ExtractedData":{"properties":{"reference":{"$ref":"#/components/schemas/ExtractedReference"},"interactions":{"items":{"$ref":"#/components/schemas/ExtractedInteraction"},"type":"array","minItems":1,"title":"Interactions"},"extraction_confidence":{"anyOf":[{"$ref":"#/components/schemas/ExtractionConfidence"},{"type":"null"}]},"extraction_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Notes"},"reviewer_guidance":{"anyOf":[{"$ref":"#/components/schemas/ReviewerGuidance"},{"type":"null"}]}},"type":"object","required":["reference","interactions"],"title":"ExtractedData"},"ExtractedExperiment":{"properties":{"method":{"type":"string","maxLength":80,"title":"Method"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature"},"temperature_unit":{"anyOf":[{"type":"string","maxLength":8},{"type":"null"}],"title":"Temperature Unit","default":"C"},"ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ph"},"buffer":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Buffer"},"duration":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration"},"duration_unit":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Duration Unit"},"substrate_form":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Substrate Form"},"substrate_composition":{"items":{"$ref":"#/components/schemas/ExtractedComponent"},"type":"array","title":"Substrate Composition"},"specimen_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Specimen Description"},"manufacturer":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Manufacturer"},"sole_carbon_source":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Sole Carbon Source"},"culture_medium":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Culture Medium"},"aerobicity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aerobicity"},"substrate_crystallinity_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Substrate Crystallinity Pct"},"substrate_mw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Substrate Mw"},"substrate_mw_unit":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Substrate Mw Unit"},"analytical_grade":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Analytical Grade"},"additional_conditions":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Additional Conditions"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"observations":{"items":{"$ref":"#/components/schemas/ExtractedObservation"},"type":"array","title":"Observations"},"kinetics":{"anyOf":[{"$ref":"#/components/schemas/ExtractedKinetics"},{"type":"null"}]},"properties":{"anyOf":[{"$ref":"#/components/schemas/ExtractedProperties"},{"type":"null"}]}},"type":"object","required":["method"],"title":"ExtractedExperiment"},"ExtractedInteraction":{"properties":{"actor_type":{"type":"string","enum":["microorganism","protein","protein_variant"],"title":"Actor Type"},"microorganism":{"anyOf":[{"$ref":"#/components/schemas/ExtractedMicroorganismActor"},{"type":"null"}]},"protein":{"anyOf":[{"$ref":"#/components/schemas/ExtractedProteinActor"},{"type":"null"}]},"protein_variant":{"anyOf":[{"$ref":"#/components/schemas/ExtractedProteinVariantActor"},{"type":"null"}]},"plastic":{"type":"string","maxLength":100,"title":"Plastic"},"result":{"$ref":"#/components/schemas/ResultEnum","default":"positive"},"strain_designation":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Strain Designation"},"genome_assembly_accession":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Genome Assembly Accession"},"culture_collection_ids":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Culture Collection Ids"},"sample_source":{"anyOf":[{"$ref":"#/components/schemas/ExtractedSampleSource"},{"type":"null"}]},"genetic_background":{"anyOf":[{"type":"string","maxLength":24},{"type":"null"}],"title":"Genetic Background"},"enzyme_production_context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enzyme Production Context"},"enzyme_preparation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enzyme Preparation"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"experiments":{"items":{"$ref":"#/components/schemas/ExtractedExperiment"},"type":"array","title":"Experiments"}},"type":"object","required":["actor_type","plastic"],"title":"ExtractedInteraction"},"ExtractedKinetics":{"properties":{"km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Km"},"km_unit":{"anyOf":[{"type":"string","maxLength":8},{"type":"null"}],"title":"Km Unit"},"kcat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Kcat"},"kcat_unit":{"anyOf":[{"type":"string","maxLength":8},{"type":"null"}],"title":"Kcat Unit"},"vmax":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Vmax"},"vmax_unit":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Vmax Unit"}},"type":"object","title":"ExtractedKinetics"},"ExtractedMicroorganismActor":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name"},"tax_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"},"growth_temp_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Min"},"growth_temp_opt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Opt"},"growth_temp_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Max"},"oxygen_requirement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Oxygen Requirement"}},"type":"object","required":["name"],"title":"ExtractedMicroorganismActor","description":"Species-level identity + biological traits only.\n\nStrain-/isolate-specific facts (strain designation, genome assembly,\nculture-collection deposits, isolation source) are per-study and live on\n:class:`ExtractedInteraction`, not here — the same species recurs across\npapers with different isolates and sources."},"ExtractedMutation":{"properties":{"wildtype_residue":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Wildtype Residue"},"position":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position"},"mutant_residue":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Mutant Residue"},"raw":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Raw"}},"type":"object","title":"ExtractedMutation","description":"One substitution, in the paper's own numbering (R-7).\n\nThe two residue fields are **20 characters, not one**. A single character\nholds the twenty canonical amino acids and nothing else, and engineered\nvariants increasingly do not stay inside them: one paper in the current\ncorpus substitutes ``DAP`` (2,3-diaminopropionic acid), and non-canonical\nand unnatural residues are exactly the enzyme-engineering literature\nPlasticDB v1 never covered. See migration ``0007_mutation_residue_width``\nfor why 20 and not something larger."},"ExtractedObservation":{"properties":{"measurement_type":{"type":"string","maxLength":60,"title":"Measurement Type"},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value"},"unit":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Unit"},"text_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text Description"}},"type":"object","required":["measurement_type"],"title":"ExtractedObservation","description":"A single measurement produced by an experiment.\n\n``measurement_type`` is the single controlled-vocab field naming *what was\nquantified* (e.g. ``weight_loss``). It supersedes the former\nobservation_type/measurement_type split."},"ExtractedProperties":{"properties":{"optimal_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Optimal Temperature"},"optimal_ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Optimal Ph"},"tm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Tm"},"t50":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"T50"},"half_life":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Half Life"},"half_life_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Half Life Temperature"},"assay_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assay Notes"}},"type":"object","title":"ExtractedProperties"},"ExtractedProteinActor":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name"},"gene":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Gene"},"genbank_id":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Genbank Id"},"uniprot_accession":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Uniprot Accession"},"sequence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sequence"},"source_microorganism_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Source Microorganism Name"},"pdb_id":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Pdb Id"},"accession_notes":{"items":{"type":"string"},"type":"array","title":"Accession Notes"}},"type":"object","required":["name"],"title":"ExtractedProteinActor","description":"Protein identity only.\n\nEC number, signal peptide, GO/InterPro/CAZy cross-references and structures are\n*derived* by the enrichment pipeline (Feature 6) from an identifier — they are\ndeliberately **not** part of the producer contract, so there is a single source\nof truth and no conflicting human/AI guesses. The producer supplies identity:\n``name`` plus any of ``genbank_id`` / ``uniprot_accession`` / ``pdb_id`` /\n``sequence``. A sequence is needed only when the paper prints one with no\naccession; otherwise the server fetches it from the accession."},"ExtractedProteinVariantActor":{"properties":{"parent_protein":{"$ref":"#/components/schemas/ExtractedProteinActor"},"variant_name":{"type":"string","maxLength":255,"title":"Variant Name"},"variant_type":{"type":"string","title":"Variant Type","default":"engineered"},"sequence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sequence"},"pdb_id":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Pdb Id"},"engineering_method":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Engineering Method"},"numbering_scheme":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Numbering Scheme"},"numbering_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Numbering Offset"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"performance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Performance"},"mutations":{"items":{"$ref":"#/components/schemas/ExtractedMutation"},"type":"array","title":"Mutations"},"accession_notes":{"items":{"type":"string"},"type":"array","title":"Accession Notes"}},"type":"object","required":["parent_protein","variant_name"],"title":"ExtractedProteinVariantActor"},"ExtractedReference":{"properties":{"doi":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Doi"},"citation":{"type":"string","title":"Citation"},"year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"},"pubmed_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pubmed Id"},"authors":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"},"journal":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Journal"},"corresponding_author_country":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Corresponding Author Country"}},"type":"object","required":["citation"],"title":"ExtractedReference"},"ExtractedSampleSource":{"properties":{"country":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Country"},"region":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Region"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"environment_type":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Environment Type"},"sample_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sample Description"}},"type":"object","title":"ExtractedSampleSource"},"ExtractionConfidence":{"type":"string","enum":["high","medium","low"],"title":"ExtractionConfidence"},"FootprintExperimentRead":{"properties":{"id":{"type":"integer","title":"Id"},"paper_ingestion_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Ingestion Id"},"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature"},"temperature_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Temperature Unit"},"ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ph"},"buffer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Buffer"},"duration":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration"},"duration_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Duration Unit"},"substrate_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Substrate Form"},"sole_carbon_source":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Sole Carbon Source"},"culture_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Culture Medium"},"aerobicity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aerobicity"},"substrate_crystallinity_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Substrate Crystallinity Pct"},"substrate_mw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Substrate Mw"},"substrate_mw_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Substrate Mw Unit"},"analytical_grade":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Analytical Grade"},"detection_limit":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Detection Limit"},"detection_limit_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detection Limit Unit"},"quantitation_ceiling":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Quantitation Ceiling"},"quantitation_ceiling_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quantitation Ceiling Unit"},"observations":{"items":{"$ref":"#/components/schemas/FootprintObservationRead"},"type":"array","title":"Observations","default":[]}},"type":"object","required":["id"],"title":"FootprintExperimentRead"},"FootprintInteractionRead":{"properties":{"id":{"type":"integer","title":"Id"},"paper_id":{"type":"integer","title":"Paper Id"},"paper_ingestion_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Ingestion Id"},"source_superseded":{"type":"boolean","title":"Source Superseded","default":false},"plastic":{"$ref":"#/components/schemas/app__schemas__entities__PlasticRef"},"actor_type":{"type":"string","title":"Actor Type"},"result":{"type":"string","title":"Result"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Id"},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"strain_occurrence_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Strain Occurrence Id"},"microorganism_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Microorganism Id"},"strain_designation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Strain Designation"},"genetic_background":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genetic Background"},"experiments":{"items":{"$ref":"#/components/schemas/FootprintExperimentRead"},"type":"array","title":"Experiments","default":[]}},"type":"object","required":["id","paper_id","plastic","actor_type","result"],"title":"FootprintInteractionRead","description":"One interaction with its experiments, and **which actor it hangs off**.\n\nThe actor ids are the point of this schema carrying more than ``actor_type``.\n``actor_type`` says *a protein did this*; it does not say **which** protein,\nand ``interactions.protein_id`` is the column the evidence spine is keyed on\n(``docs/label-matrix.md``: a label lives on a ``(protein, polymer)`` pair,\nreached through ``interactions.protein_id × plastic_id × result``). Without\nthe id, every API-backed reader of this endpoint has to *re-derive* the\nforeign key it is already looking at — which is exactly what\n``scripts/label_matrix_api.py`` was forced to do, and 333 of its 1,898\nprotein-actor rows could only be placed inside a group sharing one polymer\nand one verdict. Publishing the column turns that reconstruction into a\ntranscription.\n\nWhy exposing an id does not widen visibility\n--------------------------------------------\nAn id is not free of the \"something published what it should not have\" class\nof defect that ``app/services/dataset_releases.py`` records seven of: a bare\n``protein_id`` on an interaction whose protein is not public would confirm\nthat the hidden record exists, and pair it with a paper, a plastic and a\n*result*.\n\nIt does not, here, and the reason is that **this schema never reaches a\ncaller who is not already entitled to the actor**. Both routes that serve it\n(``app/api/v1/papers.py``) share one aggregation with one gate:\n\n* ``GET /papers/{id}/footprint`` (public) filters interactions through\n  :func:`~app.services.query.public_actor_interaction_filter`, which drops\n  any interaction whose protein, whose variant's parent protein, or whose\n  strain occurrence's microorganism is non-public or tombstoned. So a\n  hidden actor has no interaction row in the response to carry its id —\n  the interaction is already gone, and has been since the filter was\n  centralised.\n* ``GET /papers/{id}/records`` (curator) is documented as showing the\n  paper's records *whatever* their visibility, because a curator correcting\n  an extraction has to see staged and tombstoned rows too. The names,\n  accessions and results are already in that payload; an id adds no fact.\n\nThese ids are therefore **reported, never gated on**. Nothing downstream may\nread them as a permission: the clause that decides what a public caller sees\nis ``public_actor_interaction_filter`` and stays the only one, so that this\ndoes not become the second code path that re-derives a visibility rule —\nwhich is the shape every one of those seven leaks had."},"FootprintKineticsRead":{"properties":{"id":{"type":"integer","title":"Id"},"protein_id":{"type":"integer","title":"Protein Id"},"plastic_id":{"type":"integer","title":"Plastic Id"},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"paper_ingestion_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Ingestion Id"},"source_superseded":{"type":"boolean","title":"Source Superseded","default":false},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"experiment_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Experiment Id"},"km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Km"},"kcat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Kcat"},"vmax":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Vmax"},"km_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Km Unit"},"kcat_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kcat Unit"},"vmax_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vmax Unit"},"experiment":{"anyOf":[{"$ref":"#/components/schemas/ExperimentConditionsRef"},{"type":"null"}]},"plastic":{"anyOf":[{"$ref":"#/components/schemas/app__schemas__entities__PlasticRef"},{"type":"null"}]},"protein_variant":{"anyOf":[{"$ref":"#/components/schemas/FootprintVariantRef"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature","description":"Assay temperature, read from the linked experiment.","readOnly":true},"ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ph","description":"Assay pH, read from the linked experiment.","readOnly":true},"substrate_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Substrate Form","description":"Substrate form, read from the linked experiment.","readOnly":true}},"type":"object","required":["id","protein_id","plastic_id","created_at","updated_at","temperature","ph","substrate_form"],"title":"FootprintKineticsRead"},"FootprintMicroorganismRead":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"tax_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"paper_ingestion_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Ingestion Id"},"source_superseded":{"type":"boolean","title":"Source Superseded","default":false},"sample_source":{"anyOf":[{"$ref":"#/components/schemas/SampleSourceRead"},{"type":"null"}]}},"type":"object","required":["id","name"],"title":"FootprintMicroorganismRead"},"FootprintObservationRead":{"properties":{"id":{"type":"integer","title":"Id"},"paper_ingestion_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Ingestion Id"},"measurement_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Measurement Type"},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit"},"text_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text Description"}},"type":"object","required":["id"],"title":"FootprintObservationRead"},"FootprintPropertiesRead":{"properties":{"id":{"type":"integer","title":"Id"},"protein_id":{"type":"integer","title":"Protein Id"},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"paper_ingestion_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Ingestion Id"},"source_superseded":{"type":"boolean","title":"Source Superseded","default":false},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"experiment_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Experiment Id"},"optimal_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Optimal Temperature"},"optimal_ph":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Optimal Ph"},"tm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Tm"},"t50":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"T50"},"half_life":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Half Life"},"half_life_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Half Life Temperature"},"assay_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assay Notes"},"protein_variant":{"anyOf":[{"$ref":"#/components/schemas/FootprintVariantRef"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","protein_id","created_at","updated_at"],"title":"FootprintPropertiesRead"},"FootprintProteinRead":{"properties":{"id":{"type":"integer","title":"Id"},"plasticdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"name":{"type":"string","title":"Name"},"genbank_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genbank Id"},"paper_ingestion_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Ingestion Id"},"source_superseded":{"type":"boolean","title":"Source Superseded","default":false},"is_tombstoned":{"type":"boolean","title":"Is Tombstoned","default":false}},"type":"object","required":["id","name"],"title":"FootprintProteinRead"},"FootprintProteinVariantRead":{"properties":{"id":{"type":"integer","title":"Id"},"parent_protein_id":{"type":"integer","title":"Parent Protein Id"},"variant_name":{"type":"string","title":"Variant Name"},"variant_type":{"type":"string","title":"Variant Type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"sequence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sequence"},"engineering_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Engineering Method"},"performance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Performance"},"numbering_scheme":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Numbering Scheme"},"numbering_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Numbering Offset"},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"paper_ingestion_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Ingestion Id"},"source_superseded":{"type":"boolean","title":"Source Superseded","default":false},"parent_protein_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Protein Accession"},"mutations":{"items":{"$ref":"#/components/schemas/MutationRead"},"type":"array","title":"Mutations","default":[]}},"type":"object","required":["id","parent_protein_id","variant_name","variant_type"],"title":"FootprintProteinVariantRead"},"FootprintVariantRef":{"properties":{"id":{"type":"integer","title":"Id"},"variant_name":{"type":"string","title":"Variant Name"}},"type":"object","required":["id","variant_name"],"title":"FootprintVariantRef","description":"Minimal variant ref for kinetics/properties rows in the paper footprint."},"ForgotPasswordRequest":{"properties":{"recaptcha_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recaptcha Token"},"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"ForgotPasswordRequest"},"GeneticBackgroundUpdate":{"properties":{"genetic_background":{"type":"string","title":"Genetic Background","description":"wild_type, expression_host, knockout, engineered_host, unknown"}},"type":"object","required":["genetic_background"],"title":"GeneticBackgroundUpdate"},"GenomeComparison":{"properties":{"blast_type":{"type":"string","title":"Blast Type"},"counted":{"type":"string","title":"Counted"},"normalisation":{"$ref":"#/components/schemas/GenomeComparisonUnit"},"normalised":{"type":"boolean","title":"Normalised","default":false},"plastics":{"items":{"type":"string"},"type":"array","title":"Plastics","default":[]},"genomes":{"items":{"$ref":"#/components/schemas/GenomeComparisonRow"},"type":"array","title":"Genomes","default":[]}},"type":"object","required":["blast_type","counted","normalisation"],"title":"GenomeComparison","description":"The genome × plastic matrix for a compare_genomes job (B7, R10-1).\n\nBuilt at read time from the stored hits and their current evidence, so it\nalways agrees with the per-hit Evidence column. See\n:mod:`app.services.genome_comparison` for exactly what a cell counts."},"GenomeComparisonRow":{"properties":{"label":{"type":"string","title":"Label"},"sequences":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sequences"},"residues":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Residues"},"hits":{"type":"integer","title":"Hits","default":0},"positive":{"type":"integer","title":"Positive","default":0},"not_positive":{"type":"integer","title":"Not Positive","default":0},"counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Counts","default":{}},"normalised":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"number"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Normalised"},"positive_normalised":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Positive Normalised"}},"type":"object","required":["label"],"title":"GenomeComparisonRow","description":"One genome's row of the Compare Genomes matrix."},"GenomeComparisonUnit":{"properties":{"key":{"type":"string","enum":["per_1000_proteins","per_mb"],"title":"Key"},"label":{"type":"string","title":"Label"},"denominator":{"type":"string","title":"Denominator"}},"type":"object","required":["key","label","denominator"],"title":"GenomeComparisonUnit"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HitEvidence":{"properties":{"plastic":{"type":"string","title":"Plastic"},"positive":{"type":"integer","title":"Positive","default":0},"negative":{"type":"integer","title":"Negative","default":0},"inconclusive":{"type":"integer","title":"Inconclusive","default":0}},"type":"object","required":["plastic"],"title":"HitEvidence","description":"One plastic the hit record has its **own** evidence for, by result.\n\nA hit is a sequence similarity to a stored record, not a measurement of the\nquery. What the record was actually shown to do — degrade the plastic, fail\nto, or neither clearly — is what separates a lead from noise, so every row\ncarries it rather than leaving the reader to assume \"in PlasticDB\" means\n\"degrades plastic\" (R08-2)."},"IngestionApprove":{"properties":{"extracted_data":{"$ref":"#/components/schemas/ExtractedData"},"mode":{"$ref":"#/components/schemas/ApproveMode","default":"merge"},"taxonomy_decisions":{"items":{"$ref":"#/components/schemas/TaxonomyDecision"},"type":"array","title":"Taxonomy Decisions"},"review_seconds":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Review Seconds"}},"type":"object","required":["extracted_data"],"title":"IngestionApprove"},"IngestionCreate":{"properties":{"doi":{"type":"string","maxLength":512,"title":"Doi"},"pubmed_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Pubmed Id"},"title":{"type":"string","title":"Title"},"abstract":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abstract"},"pdf_key":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Pdf Key"},"markdown_key":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Markdown Key"},"extracted_data":{"anyOf":[{"$ref":"#/components/schemas/ExtractedData"},{"type":"null"}]},"extraction_model":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Extraction Model"},"extraction_version":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Extraction Version"},"source":{"type":"string","enum":["auto","submission"],"title":"Source","default":"auto"}},"type":"object","required":["doi","title"],"title":"IngestionCreate"},"IngestionLineageEntry":{"properties":{"id":{"type":"integer","title":"Id"},"extraction_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Model"},"extraction_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Version"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"supersedes_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Supersedes Id"},"is_current":{"type":"boolean","title":"Is Current","default":false},"is_superseded":{"type":"boolean","title":"Is Superseded","default":false}},"type":"object","required":["id"],"title":"IngestionLineageEntry","description":"One approved extraction of a paper, ordered oldest → newest.\n\nSurfaces the re-extraction chain recorded by ``PaperIngestion.supersedes_id``\nso a researcher can see when a paper's data was re-extracted, by which model\nand version, and which extraction is the live one."},"IngestionListItem":{"properties":{"id":{"type":"integer","title":"Id"},"doi":{"type":"string","title":"Doi"},"pubmed_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pubmed Id"},"title":{"type":"string","title":"Title"},"status":{"type":"string","title":"Status"},"source":{"type":"string","title":"Source"},"extraction_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Model"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"has_pdf":{"type":"boolean","title":"Has Pdf","readOnly":true}},"type":"object","required":["id","doi","pubmed_id","title","status","source","extraction_model","created_at","reviewed_at","has_pdf"],"title":"IngestionListItem"},"IngestionPatch":{"properties":{"pdf_key":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Pdf Key"},"markdown_key":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Markdown Key"},"extracted_data":{"anyOf":[{"$ref":"#/components/schemas/ExtractedData"},{"type":"null"}]},"extraction_model":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Extraction Model"},"extraction_version":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Extraction Version"}},"type":"object","title":"IngestionPatch"},"IngestionReject":{"properties":{"reason":{"type":"string","minLength":1,"title":"Reason"}},"type":"object","required":["reason"],"title":"IngestionReject"},"IngestionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"doi":{"type":"string","title":"Doi"},"pubmed_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pubmed Id"},"title":{"type":"string","title":"Title"},"abstract":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abstract"},"status":{"type":"string","title":"Status"},"source":{"type":"string","title":"Source"},"extracted_data":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Extracted Data"},"extraction_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Model"},"extraction_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Version"},"rejection_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rejection Reason"},"reviewed_by_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewed By Id"},"reextract_requested_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reextract Requested At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"unrecognised_fields":{"items":{"type":"string"},"type":"array","title":"Unrecognised Fields"},"has_pdf":{"type":"boolean","title":"Has Pdf","readOnly":true},"has_markdown":{"type":"boolean","title":"Has Markdown","readOnly":true},"supplements":{"items":{"type":"string"},"type":"array","title":"Supplements","description":"Filenames of attached supplementary materials.","readOnly":true}},"type":"object","required":["id","doi","pubmed_id","title","abstract","status","source","extracted_data","extraction_model","extraction_version","rejection_reason","reviewed_by_id","created_at","updated_at","reviewed_at","has_pdf","has_markdown","supplements"],"title":"IngestionResponse"},"IngestionRevise":{"properties":{"extracted_data":{"$ref":"#/components/schemas/ExtractedData"},"extraction_model":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Extraction Model"},"extraction_version":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Extraction Version"},"revision_batch":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Revision Batch"},"revision_reason":{"type":"string","maxLength":4000,"minLength":1,"title":"Revision Reason"},"title":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Title"}},"type":"object","required":["extracted_data","revision_batch","revision_reason"],"title":"IngestionRevise","description":"One paper of a producer sweep: a corrected extraction, labelled.\n\n``POST /ingestions/{id}/revise``. On an ``approved`` ingestion this opens a\nrevision carrying the payload; on a ``pending_review`` one it replaces the\npayload in place. Either way the row is tagged with ``revision_batch`` so the\nbulk review page can list and approve the sweep together."},"IngestionWithdraw":{"properties":{"reason":{"type":"string","minLength":1,"title":"Reason"}},"type":"object","required":["reason"],"title":"IngestionWithdraw","description":"Why an already-approved paper is being taken back out of the database.\n\nRequired, and for a stronger reason than rejection's: a rejected extraction\nstill exists on its row for anyone who wants to know what was turned away,\nwhereas a withdrawal *deletes* the records. This sentence is the only thing\nthat will remain to say why they are gone."},"InteractionCreate":{"properties":{"paper_id":{"type":"integer","title":"Paper Id"},"plastic_id":{"type":"integer","title":"Plastic Id"},"microorganism_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Microorganism Id"},"protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Id"},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"result":{"type":"string","enum":["positive","negative","inconclusive"],"title":"Result","default":"positive"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"experiments":{"items":{"$ref":"#/components/schemas/ExperimentWrite"},"type":"array","title":"Experiments","default":[]}},"type":"object","required":["paper_id","plastic_id"],"title":"InteractionCreate"},"InteractionRead":{"properties":{"id":{"type":"integer","title":"Id"},"plastic":{"$ref":"#/components/schemas/app__schemas__entities__PlasticRef"},"actor_type":{"type":"string","title":"Actor Type"},"result":{"type":"string","title":"Result"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"strain_occurrence":{"anyOf":[{"$ref":"#/components/schemas/StrainOccurrenceRef"},{"type":"null"}]},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"experiments":{"items":{"$ref":"#/components/schemas/ExperimentRead"},"type":"array","title":"Experiments","default":[]},"indirect_source_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Indirect Source Label"},"indirect_source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Indirect Source Url"},"expression_hosts":{"items":{"type":"string"},"type":"array","title":"Expression Hosts","default":[]},"strain_designation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Strain Designation","description":"Back-compat flat field: the strain as reported for this interaction.","readOnly":true}},"type":"object","required":["id","plastic","actor_type","result","strain_designation"],"title":"InteractionRead"},"InteractionUpdate":{"properties":{"plastic_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Plastic Id"},"microorganism_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Microorganism Id"},"protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Id"},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"},"result":{"anyOf":[{"type":"string","enum":["positive","negative","inconclusive"]},{"type":"null"}],"title":"Result"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"experiments":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExperimentWrite"},"type":"array"},{"type":"null"}],"title":"Experiments"}},"type":"object","title":"InteractionUpdate"},"JobDetail":{"properties":{"id":{"type":"string","title":"Id"},"job_type":{"type":"string","title":"Job Type"},"status":{"type":"string","title":"Status"},"evalue":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Evalue"},"pident":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pident"},"organism_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organism Type"},"blast_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blast Type"},"include_variants":{"type":"boolean","title":"Include Variants","default":false},"genus_column":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Genus Column"},"species_column":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Species Column"},"field_separator":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field Separator"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"result_count":{"type":"integer","title":"Result Count","default":0},"result_newick":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Result Newick"},"result_metadata":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Result Metadata"},"has_result_file":{"type":"boolean","title":"Has Result File","default":false},"results":{"items":{"$ref":"#/components/schemas/JobResultItem"},"type":"array","title":"Results","default":[]},"comparison":{"anyOf":[{"$ref":"#/components/schemas/GenomeComparison"},{"type":"null"}]}},"type":"object","required":["id","job_type","status","evalue","pident","organism_type","blast_type","error_message","created_at","completed_at"],"title":"JobDetail"},"JobHitOrganism":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"tax_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"}},"type":"object","required":["id","name"],"title":"JobHitOrganism","description":"The organism a hit protein was isolated from, for a per-taxon summary.\n\nOnly a public, live organism is named; a staged or tombstoned one reads as\n``null``, the same as on the protein's own public page."},"JobHitProtein":{"properties":{"id":{"type":"integer","title":"Id"},"plasticdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"name":{"type":"string","title":"Name"},"genbank_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genbank Id"},"uniprot_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uniprot Accession"},"source_microorganism":{"anyOf":[{"$ref":"#/components/schemas/JobHitOrganism"},{"type":"null"}]},"degradation_links":{"items":{"$ref":"#/components/schemas/DegradationLink"},"type":"array","title":"Degradation Links","default":[]},"paper_count":{"type":"integer","title":"Paper Count","default":0}},"type":"object","required":["id","name"],"title":"JobHitProtein","description":"The PlasticDB protein a hit landed on, with what a summary needs (R10-2).\n\nUntil B7 the hit carried a ``ProteinListItem`` built from five scalar\ncolumns, so ``source_microorganism``, ``degradation_links`` and ``papers``\nwere always empty — they *looked* like answers (\"no organism, no evidence\")\nand were not. They are now either filled or absent:\n\n* ``source_microorganism`` and ``degradation_links`` are filled. The links\n  are the protein's **own** evidence, per plastic, the same rows the\n  protein page shows; ``methods`` is left empty (it needs every experiment\n  row loaded, per hit), so read it from ``/proteins/{accession}``.\n* ``papers`` / ``paper`` are gone. A paper list per hit made a 200-hit job\n  payload carry thousands of citations; ``paper_count`` says how many there\n  are and ``/proteins/{accession}`` lists them."},"JobRead":{"properties":{"id":{"type":"string","title":"Id"},"job_type":{"type":"string","title":"Job Type"},"status":{"type":"string","title":"Status"},"evalue":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Evalue"},"pident":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pident"},"organism_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organism Type"},"blast_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blast Type"},"include_variants":{"type":"boolean","title":"Include Variants","default":false},"genus_column":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Genus Column"},"species_column":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Species Column"},"field_separator":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field Separator"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"result_count":{"type":"integer","title":"Result Count","default":0},"result_newick":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Result Newick"},"result_metadata":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Result Metadata"},"has_result_file":{"type":"boolean","title":"Has Result File","default":false}},"type":"object","required":["id","job_type","status","evalue","pident","organism_type","blast_type","error_message","created_at","completed_at"],"title":"JobRead"},"JobResultItem":{"properties":{"id":{"type":"integer","title":"Id"},"query_seq_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Query Seq Id"},"subject_seq_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Seq Id"},"pident":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pident"},"length":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Length"},"evalue":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Evalue"},"bitscore":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Bitscore"},"qcov":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Qcov"},"scov":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Scov"},"subject_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Accession"},"source_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Label"},"protein":{"anyOf":[{"$ref":"#/components/schemas/JobHitProtein"},{"type":"null"}]},"variant":{"anyOf":[{"$ref":"#/components/schemas/JobVariantItem"},{"type":"null"}]},"evidence":{"items":{"$ref":"#/components/schemas/HitEvidence"},"type":"array","title":"Evidence","default":[]},"evidence_polarity":{"type":"string","title":"Evidence Polarity","default":"none"}},"type":"object","required":["id","query_seq_id","subject_seq_id","pident","length","evalue","bitscore","protein"],"title":"JobResultItem"},"JobTypeEnum":{"type":"string","enum":["annotate_gene","annotate_genome","annotate_list","compare_genomes","pathway_analysis","hmm_screen"],"title":"JobTypeEnum","description":"The job types ``POST /jobs`` can actually run — **not** every job type.\n\nThis enum is the multipart endpoint's whitelist, and it is deliberately not\nthe same set as ``app.workers.pipelines._PIPELINES`` (what the worker can\nexecute) or the ``job_type_enum`` column on ``Job`` (what may be stored).\nIt had drifted from both, in both directions (#459):\n\n- ``build_tree`` was accepted here and cannot work through this endpoint.\n  ``POST /jobs`` saves the upload as ``input.fasta``; the ``build_tree``\n  handler never reads ``input_file_path`` — a tree is built from a\n  microorganism filter or an id list, which a multipart FASTA upload has no\n  way to carry. A client following the enum uploaded a FASTA, got a ``201``,\n  and the job did something unrelated to what it sent. That request belongs\n  at ``POST /tree/build``, which takes ``TreeBuildRequest``.\n- ``hmm_screen`` was rejected here and does work. The pipeline exists and\n  ``POST /bioinformatics/hmm-screen`` creates jobs of that type, but that\n  endpoint takes the FASTA base64-encoded in a query parameter, so the one\n  path that can carry a real-sized file could not reach the HMM screen at\n  all — and the tool page (#318) has no other way in.\n\nThe invariant that *is* enforced, by\n``tests/test_job_type_registry.py``: every member here has a\n``_PIPELINES`` handler and a slot in the ORM enum, and every job type the\nworker can run is either a member here or named in that test's list of\ntypes reachable only through their own endpoint. The two lists cannot drift\nsilently again without the test going red."},"JobUpdateAdmin":{"properties":{"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"}},"type":"object","title":"JobUpdateAdmin"},"JobVariantItem":{"properties":{"id":{"type":"integer","title":"Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"variant_name":{"type":"string","title":"Variant Name"},"variant_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant Type"}},"type":"object","required":["id","variant_name"],"title":"JobVariantItem","description":"The engineered variant a hit landed on, for linking out to /variants/{id}.\n\nScalar columns only, like ``ProteinListItem`` in the same row — the results\ntable needs a name and a link, and anything relationship-backed would lazy-load\nunder the async session."},"MicroorganismCreate":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"tax_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"},"lineage":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Lineage"},"growth_temp_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Min"},"growth_temp_opt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Opt"},"growth_temp_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Max"},"oxygen_requirement":{"anyOf":[{"type":"string","enum":["aerobic","anaerobic","facultative","microaerophilic"]},{"type":"null"}],"title":"Oxygen Requirement"},"paper_ids":{"items":{"type":"integer"},"type":"array","title":"Paper Ids","default":[]}},"type":"object","required":["name"],"title":"MicroorganismCreate"},"MicroorganismDetail":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"tax_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"taxonomy_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Taxonomy Status"},"taxonomy_cause":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Taxonomy Cause"},"taxonomy_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Taxonomy Note"},"growth_temp_opt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Opt"},"oxygen_requirement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Oxygen Requirement"},"degradation_links":{"items":{"$ref":"#/components/schemas/DegradationLink"},"type":"array","title":"Degradation Links","default":[]},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"papers":{"items":{"$ref":"#/components/schemas/PaperRead"},"type":"array","title":"Papers","default":[]},"assay_temp_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Assay Temp Min"},"assay_temp_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Assay Temp Max"},"environments":{"items":{"type":"string"},"type":"array","title":"Environments","default":[]},"locations":{"items":{"type":"string"},"type":"array","title":"Locations","default":[]},"strain_designations":{"items":{"type":"string"},"type":"array","title":"Strain Designations","default":[]},"lineage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lineage"},"synonyms":{"items":{"type":"string"},"type":"array","title":"Synonyms"},"also_known_as":{"items":{"type":"string"},"type":"array","title":"Also Known As"},"growth_temp_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Min"},"growth_temp_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Max"},"plastics":{"items":{"$ref":"#/components/schemas/PlasticRead"},"type":"array","title":"Plastics","default":[]},"interactions":{"items":{"$ref":"#/components/schemas/InteractionRead"},"type":"array","title":"Interactions","default":[]},"indirect_interactions":{"items":{"$ref":"#/components/schemas/InteractionRead"},"type":"array","title":"Indirect Interactions","default":[]},"construct_interactions":{"items":{"$ref":"#/components/schemas/InteractionRead"},"type":"array","title":"Construct Interactions","default":[]},"proteins":{"items":{"$ref":"#/components/schemas/ProteinListItem"},"type":"array","title":"Proteins","default":[]},"strain_occurrences":{"items":{"$ref":"#/components/schemas/StrainOccurrenceRead"},"type":"array","title":"Strain Occurrences","default":[]}},"type":"object","required":["id","name","tax_id"],"title":"MicroorganismDetail"},"MicroorganismListItem":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"tax_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"taxonomy_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Taxonomy Status"},"taxonomy_cause":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Taxonomy Cause"},"taxonomy_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Taxonomy Note"},"growth_temp_opt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Opt"},"oxygen_requirement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Oxygen Requirement"},"degradation_links":{"items":{"$ref":"#/components/schemas/DegradationLink"},"type":"array","title":"Degradation Links","default":[]},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"papers":{"items":{"$ref":"#/components/schemas/PaperRead"},"type":"array","title":"Papers","default":[]},"assay_temp_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Assay Temp Min"},"assay_temp_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Assay Temp Max"},"environments":{"items":{"type":"string"},"type":"array","title":"Environments","default":[]},"locations":{"items":{"type":"string"},"type":"array","title":"Locations","default":[]},"strain_designations":{"items":{"type":"string"},"type":"array","title":"Strain Designations","default":[]}},"type":"object","required":["id","name","tax_id"],"title":"MicroorganismListItem"},"MicroorganismOption":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"MicroorganismOption"},"MicroorganismUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"tax_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"},"lineage":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Lineage"},"growth_temp_min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Min"},"growth_temp_opt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Opt"},"growth_temp_max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Growth Temp Max"},"oxygen_requirement":{"anyOf":[{"type":"string","enum":["aerobic","anaerobic","facultative","microaerophilic"]},{"type":"null"}],"title":"Oxygen Requirement"},"synonyms":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":50},{"type":"null"}],"title":"Synonyms"},"paper_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Paper Ids"}},"type":"object","title":"MicroorganismUpdate"},"MutationRead":{"properties":{"id":{"type":"integer","title":"Id"},"protein_variant_id":{"type":"integer","title":"Protein Variant Id"},"wild_type_residue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wild Type Residue"},"position":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position"},"mutant_residue":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mutant Residue"},"raw":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raw"},"sequence_position":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sequence Position"}},"type":"object","required":["id","protein_variant_id","wild_type_residue","position","mutant_residue","raw"],"title":"MutationRead"},"ObservationRead":{"properties":{"measurement_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Measurement Type"},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit"},"text_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text Description"}},"type":"object","title":"ObservationRead"},"ObservationWrite":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"measurement_type_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Measurement Type Id"},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value"},"unit":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Unit"},"text_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text Description"}},"type":"object","title":"ObservationWrite"},"OrcidAuthUrlResponse":{"properties":{"auth_url":{"type":"string","title":"Auth Url"}},"type":"object","required":["auth_url"],"title":"OrcidAuthUrlResponse"},"OrganismTypeEnum":{"type":"string","enum":["no_signalp","arch","gram+","gram-","euk"],"title":"OrganismTypeEnum"},"PaginatedResponse":{"properties":{"total":{"type":"integer","title":"Total"},"items":{"items":{},"type":"array","title":"Items"}},"type":"object","required":["total","items"],"title":"PaginatedResponse"},"PaperCreate":{"properties":{"citation":{"type":"string","minLength":1,"title":"Citation"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"doi":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Doi"},"year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"},"authors":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"},"journal":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Journal"},"corresponding_author_country":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Corresponding Author Country"}},"type":"object","required":["citation"],"title":"PaperCreate"},"PaperDetail":{"properties":{"id":{"type":"integer","title":"Id"},"citation":{"type":"string","title":"Citation"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doi"},"year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"},"authors":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"},"journal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Journal"},"corresponding_author_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Corresponding Author Country"},"microorganisms":{"items":{"$ref":"#/components/schemas/MicroorganismListItem"},"type":"array","title":"Microorganisms","default":[]},"proteins":{"items":{"$ref":"#/components/schemas/ProteinListItem"},"type":"array","title":"Proteins","default":[]},"protein_variants":{"items":{"$ref":"#/components/schemas/PaperVariantRef"},"type":"array","title":"Protein Variants","default":[]}},"type":"object","required":["id","citation","doi","year"],"title":"PaperDetail"},"PaperFootprint":{"properties":{"paper":{"$ref":"#/components/schemas/PaperRead"},"interactions":{"items":{"$ref":"#/components/schemas/FootprintInteractionRead"},"type":"array","title":"Interactions","default":[]},"kinetics":{"items":{"$ref":"#/components/schemas/FootprintKineticsRead"},"type":"array","title":"Kinetics","default":[]},"properties":{"items":{"$ref":"#/components/schemas/FootprintPropertiesRead"},"type":"array","title":"Properties","default":[]},"microorganisms":{"items":{"$ref":"#/components/schemas/FootprintMicroorganismRead"},"type":"array","title":"Microorganisms","default":[]},"proteins":{"items":{"$ref":"#/components/schemas/FootprintProteinRead"},"type":"array","title":"Proteins","default":[]},"protein_variants":{"items":{"$ref":"#/components/schemas/FootprintProteinVariantRead"},"type":"array","title":"Protein Variants","default":[]},"counts":{"$ref":"#/components/schemas/PaperFootprintCounts"},"ingestion_lineage":{"items":{"$ref":"#/components/schemas/IngestionLineageEntry"},"type":"array","title":"Ingestion Lineage","default":[]}},"type":"object","required":["paper","counts"],"title":"PaperFootprint","description":"Complete set of records derived from a paper, for review and audit."},"PaperFootprintCounts":{"properties":{"interactions":{"type":"integer","title":"Interactions","default":0},"experiments":{"type":"integer","title":"Experiments","default":0},"observations":{"type":"integer","title":"Observations","default":0},"kinetics":{"type":"integer","title":"Kinetics","default":0},"properties":{"type":"integer","title":"Properties","default":0},"microorganisms":{"type":"integer","title":"Microorganisms","default":0},"proteins":{"type":"integer","title":"Proteins","default":0},"protein_variants":{"type":"integer","title":"Protein Variants","default":0}},"type":"object","title":"PaperFootprintCounts","description":"Aggregate counts of every entity type derived from the paper."},"PaperIngestionStatus":{"type":"string","enum":["pending_download","pending_extraction","pending_review","approved","rejected","withdrawn","superseded"],"title":"PaperIngestionStatus","description":"Where a paper is in the ingestion pipeline.\n\n``rejected`` and ``withdrawn`` are both \"decided against\", and they are\ndeliberately **not** the same value.\n\n``rejected`` is a verdict on an extraction that was never written to the live\ntables: the curator read it in the queue and said no. ``withdrawn`` is a\nverdict on a record that *was* live — approved, promoted, publicly visible —\nand has since been deleted from the database. Collapsing the two would assert\nsomething false about every withdrawal (that a curator turned it away at\nreview) and would make \"was this paper ever in the database?\" unanswerable\nfrom the row, which is precisely the question a later audit of the corpus has\nto ask. ``rejection_reason`` carries the curator's words for both, but prose\nis not a queryable fact.\n\nBoth are terminal for *this* row. Neither blocks a fresh ingestion of the same\nDOI — a new extraction is a new submission and gets its own review.\n\n``superseded`` is the third ending, and it is not a verdict at all. The run\nwas approved and its records *were* live; a later revision of the same paper —\nopened by ``reopen``, which points at it through ``supersedes_id`` — has since\nbeen approved and taken them over. Nothing was decided against, and the\nextraction is still the provenance of every row the revision inherited.\n\nIt exists because ``approved`` was answering two questions at once. Before it,\na corrected paper had two rows both reading ``approved``, and \"which revision\nis live\" could only be answered by comparing ids and hoping the later one won\n— while every count of approved papers double-counted the correction. The\nstatus is written at the revision's **approve**, never at ``reopen``: an\nabandoned revision must leave the database exactly as it was, which is\n``reopen``'s own promise."},"PaperRead":{"properties":{"id":{"type":"integer","title":"Id"},"citation":{"type":"string","title":"Citation"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doi"},"year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"},"authors":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"},"journal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Journal"},"corresponding_author_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Corresponding Author Country"}},"type":"object","required":["id","citation","doi","year"],"title":"PaperRead"},"PaperUpdate":{"properties":{"citation":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Citation"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"doi":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Doi"},"year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"},"authors":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authors"},"journal":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Journal"},"corresponding_author_country":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Corresponding Author Country"}},"type":"object","title":"PaperUpdate"},"PaperVariantRef":{"properties":{"id":{"type":"integer","title":"Id"},"parent_protein_id":{"type":"integer","title":"Parent Protein Id"},"parent_protein_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Protein Accession"},"variant_name":{"type":"string","title":"Variant Name"},"variant_type":{"type":"string","title":"Variant Type"},"engineering_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Engineering Method"},"performance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Performance"}},"type":"object","required":["id","parent_protein_id","variant_name","variant_type"],"title":"PaperVariantRef","description":"Minimal variant shape for the paper detail page (column data only, no relationships)."},"PathwayCreate":{"properties":{"plastic_id":{"type":"integer","title":"Plastic Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"organism_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Organism Id"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["plastic_id"],"title":"PathwayCreate"},"PathwayEnzymeRef":{"properties":{"id":{"type":"integer","title":"Id"},"plasticdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"},"name":{"type":"string","title":"Name"},"genbank_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genbank Id"}},"type":"object","required":["id","plasticdb_id","name","genbank_id"],"title":"PathwayEnzymeRef"},"PathwayGraphEdge":{"properties":{"data":{"type":"object","title":"Data"}},"type":"object","required":["data"],"title":"PathwayGraphEdge"},"PathwayGraphNode":{"properties":{"data":{"type":"object","title":"Data"}},"type":"object","required":["data"],"title":"PathwayGraphNode"},"PathwayGraphResponse":{"properties":{"nodes":{"items":{"$ref":"#/components/schemas/PathwayGraphNode"},"type":"array","title":"Nodes","default":[]},"edges":{"items":{"$ref":"#/components/schemas/PathwayGraphEdge"},"type":"array","title":"Edges","default":[]}},"type":"object","title":"PathwayGraphResponse"},"PathwayListItem":{"properties":{"id":{"type":"integer","title":"Id"},"plastic_id":{"type":"integer","title":"Plastic Id"},"plastic_name":{"type":"string","title":"Plastic Name","default":""},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"step_count":{"type":"integer","title":"Step Count","default":0}},"type":"object","required":["id","plastic_id"],"title":"PathwayListItem"},"PathwayRead":{"properties":{"id":{"type":"integer","title":"Id"},"plastic_id":{"type":"integer","title":"Plastic Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"organism_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Organism Id"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"steps":{"items":{"$ref":"#/components/schemas/ReactionStepRead"},"type":"array","title":"Steps","default":[]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","plastic_id","description","created_at"],"title":"PathwayRead"},"PathwayStepRef":{"properties":{"reaction_step_id":{"type":"integer","title":"Reaction Step Id"},"pathway_id":{"type":"integer","title":"Pathway Id"},"pathway_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pathway Name"},"step_order":{"type":"integer","title":"Step Order"},"role":{"type":"string","title":"Role"},"other_compound_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Other Compound Name"},"protein_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Protein Name"},"protein_plasticdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Protein Plasticdb Id"}},"type":"object","required":["reaction_step_id","pathway_id","step_order","role"],"title":"PathwayStepRef","description":"A reaction step involving this compound, with its pathway context."},"PathwayUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"organism_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Organism Id"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","title":"PathwayUpdate"},"PlasticComponentRead":{"properties":{"component_plastic_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Component Plastic Id"},"component_compound_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Component Compound Id"},"name":{"type":"string","title":"Name"},"component_type":{"type":"string","title":"Component Type"},"typical_fraction_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Typical Fraction Pct"},"fraction_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fraction Basis"}},"type":"object","required":["name","component_type"],"title":"PlasticComponentRead","description":"One constituent of a blend (a polymer or an additive), as canonical membership."},"PlasticContainingBlend":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"}},"type":"object","required":["id","name"],"title":"PlasticContainingBlend","description":"A blend that contains the plastic being viewed (reverse roll-up)."},"PlasticCreate":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"full_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Full Name"},"abbreviation":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Abbreviation"},"polymer_class":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Polymer Class"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"},"trade_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Trade Name"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"},"smiles":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}],"title":"Smiles"},"cas_number":{"anyOf":[{"type":"string","maxLength":30},{"type":"null"}],"title":"Cas Number"},"compound_ids":{"items":{"type":"integer"},"type":"array","title":"Compound Ids","default":[]}},"type":"object","required":["name"],"title":"PlasticCreate"},"PlasticDetail":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"abbreviation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abbreviation"},"polymer_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Polymer Class"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"},"smiles":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Smiles"},"cas_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cas Number"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"},"trade_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trade Name"},"microorganism_count":{"type":"integer","title":"Microorganism Count","default":0},"protein_count":{"type":"integer","title":"Protein Count","default":0},"parent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Name"},"children":{"items":{"$ref":"#/components/schemas/PlasticParentRef"},"type":"array","title":"Children","default":[]},"microorganism_degrading_count":{"type":"integer","title":"Microorganism Degrading Count","default":0},"microorganism_inconclusive_count":{"type":"integer","title":"Microorganism Inconclusive Count","default":0},"microorganism_no_activity_count":{"type":"integer","title":"Microorganism No Activity Count","default":0},"protein_degrading_count":{"type":"integer","title":"Protein Degrading Count","default":0},"protein_inconclusive_count":{"type":"integer","title":"Protein Inconclusive Count","default":0},"protein_no_activity_count":{"type":"integer","title":"Protein No Activity Count","default":0},"microorganisms":{"items":{"$ref":"#/components/schemas/MicroorganismListItem"},"type":"array","title":"Microorganisms","default":[]},"degradation_links":{"items":{"$ref":"#/components/schemas/DegradationLink"},"type":"array","title":"Degradation Links","default":[]},"proteins":{"items":{"$ref":"#/components/schemas/ProteinListItem"},"type":"array","title":"Proteins","default":[]},"monomers":{"items":{"$ref":"#/components/schemas/CompoundRead"},"type":"array","title":"Monomers","default":[]},"components":{"items":{"$ref":"#/components/schemas/PlasticComponentRead"},"type":"array","title":"Components","default":[]},"containing_blends":{"items":{"$ref":"#/components/schemas/PlasticContainingBlend"},"type":"array","title":"Containing Blends","default":[]},"paper_count":{"type":"integer","title":"Paper Count","default":0}},"type":"object","required":["id","name"],"title":"PlasticDetail"},"PlasticOption":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"PlasticOption"},"PlasticParentRef":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"}},"type":"object","required":["id","name"],"title":"PlasticParentRef"},"PlasticRead":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"abbreviation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abbreviation"},"polymer_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Polymer Class"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"},"smiles":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Smiles"},"cas_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cas Number"}},"type":"object","required":["id","name"],"title":"PlasticRead"},"PlasticUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Name"},"full_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Full Name"},"abbreviation":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Abbreviation"},"polymer_class":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Polymer Class"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"},"trade_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Trade Name"},"parent_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Id"},"smiles":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}],"title":"Smiles"},"cas_number":{"anyOf":[{"type":"string","maxLength":30},{"type":"null"}],"title":"Cas Number"},"compound_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Compound Ids"}},"type":"object","title":"PlasticUpdate"},"PostCreate":{"properties":{"title":{"type":"string","maxLength":300,"minLength":3,"title":"Title"},"body":{"type":"string","minLength":1,"title":"Body"},"category_id":{"type":"integer","title":"Category Id"}},"type":"object","required":["title","body","category_id"],"title":"PostCreate"},"PostDetailOut":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"category_id":{"type":"integer","title":"Category Id"},"category_slug":{"type":"string","title":"Category Slug","default":""},"author":{"anyOf":[{"$ref":"#/components/schemas/AuthorOut"},{"type":"null"}]},"is_pinned":{"type":"boolean","title":"Is Pinned"},"reply_count":{"type":"integer","title":"Reply Count","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"body":{"type":"string","title":"Body"},"replies":{"items":{"$ref":"#/components/schemas/ReplyOut"},"type":"array","title":"Replies","default":[]}},"type":"object","required":["id","title","category_id","author","is_pinned","created_at","updated_at","body"],"title":"PostDetailOut"},"PostSummaryOut":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"category_id":{"type":"integer","title":"Category Id"},"category_slug":{"type":"string","title":"Category Slug","default":""},"author":{"anyOf":[{"$ref":"#/components/schemas/AuthorOut"},{"type":"null"}]},"is_pinned":{"type":"boolean","title":"Is Pinned"},"reply_count":{"type":"integer","title":"Reply Count","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","title","category_id","author","is_pinned","created_at","updated_at"],"title":"PostSummaryOut"},"ProteinCreate":{"properties":{"plasticdb_id":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Plasticdb Id"},"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"database_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Database Name"},"gene":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Gene"},"genbank_id":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Genbank Id"},"sequence":{"anyOf":[{"type":"string","maxLength":50000},{"type":"null"}],"title":"Sequence"},"has_signal_peptide":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Signal Peptide"},"signal_peptide_cleavage_site":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Signal Peptide Cleavage Site"},"active_site_residues":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Active Site Residues"},"source_microorganism_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Source Microorganism Id"},"paper_ids":{"items":{"type":"integer"},"type":"array","title":"Paper Ids","default":[]}},"type":"object","required":["name"],"title":"ProteinCreate"},"ProteinDetail":{"properties":{"id":{"type":"integer","title":"Id"},"kind":{"type":"string","title":"Kind","default":"wild_type"},"variant_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant Type"},"parent_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Accession"},"plasticdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"name":{"type":"string","title":"Name"},"genbank_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genbank Id"},"has_signal_peptide":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Signal Peptide"},"uniprot_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uniprot Accession"},"pdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pdb Id"},"ec_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ec Number"},"source_microorganism":{"anyOf":[{"$ref":"#/components/schemas/MicroorganismListItem"},{"type":"null"}]},"degradation_links":{"items":{"$ref":"#/components/schemas/DegradationLink"},"type":"array","title":"Degradation Links","default":[]},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"papers":{"items":{"$ref":"#/components/schemas/PaperRead"},"type":"array","title":"Papers","default":[]},"year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"},"best_kcat_km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Best Kcat Km"},"best_kcat_km_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Best Kcat Km Unit"},"v1_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"V1 Id"},"database_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Database Name"},"gene":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gene"},"sequence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sequence"},"structure_file":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Structure File"},"has_structure":{"type":"boolean","title":"Has Structure","default":false},"uniprot_protein_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uniprot Protein Name"},"uniprot_go_terms":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Uniprot Go Terms"},"active_site_residues":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Active Site Residues"},"signal_peptide_cleavage_site":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Signal Peptide Cleavage Site"},"cross_references":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Cross References"},"structures":{"items":{"$ref":"#/components/schemas/ProteinStructureRead"},"type":"array","title":"Structures","default":[]},"plastics":{"items":{"$ref":"#/components/schemas/PlasticRead"},"type":"array","title":"Plastics","default":[]},"variant_degradation_links":{"items":{"$ref":"#/components/schemas/DegradationLink"},"type":"array","title":"Variant Degradation Links","default":[]},"interactions":{"items":{"$ref":"#/components/schemas/InteractionRead"},"type":"array","title":"Interactions","default":[]},"indirect_interactions":{"items":{"$ref":"#/components/schemas/InteractionRead"},"type":"array","title":"Indirect Interactions","default":[]},"variants":{"items":{"$ref":"#/components/schemas/ProteinVariantRead"},"type":"array","title":"Variants","default":[]},"kinetics":{"items":{"$ref":"#/components/schemas/EnzymeKineticsRead"},"type":"array","title":"Kinetics","default":[]},"properties":{"items":{"$ref":"#/components/schemas/EnzymePropertiesRead"},"type":"array","title":"Properties","default":[]}},"type":"object","required":["id","plasticdb_id","name"],"title":"ProteinDetail"},"ProteinListItem":{"properties":{"id":{"type":"integer","title":"Id"},"kind":{"type":"string","title":"Kind","default":"wild_type"},"variant_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant Type"},"parent_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Accession"},"plasticdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"name":{"type":"string","title":"Name"},"genbank_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genbank Id"},"has_signal_peptide":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Signal Peptide"},"uniprot_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uniprot Accession"},"pdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pdb Id"},"ec_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ec Number"},"source_microorganism":{"anyOf":[{"$ref":"#/components/schemas/MicroorganismListItem"},{"type":"null"}]},"degradation_links":{"items":{"$ref":"#/components/schemas/DegradationLink"},"type":"array","title":"Degradation Links","default":[]},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"papers":{"items":{"$ref":"#/components/schemas/PaperRead"},"type":"array","title":"Papers","default":[]},"year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"},"best_kcat_km":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Best Kcat Km"},"best_kcat_km_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Best Kcat Km Unit"}},"type":"object","required":["id","plasticdb_id","name"],"title":"ProteinListItem"},"ProteinStructureRead":{"properties":{"id":{"type":"integer","title":"Id"},"pdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pdb Id"},"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method"},"resolution":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Resolution"},"deposition_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deposition Date"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"},"model_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Url"},"is_primary":{"type":"boolean","title":"Is Primary","default":false},"protein_variant_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Variant Id"}},"type":"object","required":["id"],"title":"ProteinStructureRead"},"ProteinSubmissionRead":{"properties":{"id":{"type":"integer","title":"Id"},"submission_id":{"type":"integer","title":"Submission Id"},"sequence":{"type":"string","title":"Sequence"},"protein_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Protein Name"},"status":{"type":"string","title":"Status"},"matched_protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Matched Protein Id"},"match_identity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Match Identity"},"assigned_plasticdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned Plasticdb Id"},"alphafold_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alphafold Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"matched_protein":{"anyOf":[{"$ref":"#/components/schemas/ProteinListItem"},{"type":"null"}]}},"type":"object","required":["id","submission_id","sequence","status","created_at"],"title":"ProteinSubmissionRead"},"ProteinSubmissionResult":{"properties":{"protein_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Protein Name"},"status":{"type":"string","title":"Status"},"match_identity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Match Identity"},"matched_protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Matched Protein Id"},"assigned_plasticdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned Plasticdb Id"},"alphafold_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alphafold Status"}},"type":"object","required":["status"],"title":"ProteinSubmissionResult","description":"Summary reported back to the submission form."},"ProteinUpdate":{"properties":{"plasticdb_id":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Plasticdb Id"},"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"database_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Database Name"},"gene":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Gene"},"genbank_id":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Genbank Id"},"sequence":{"anyOf":[{"type":"string","maxLength":50000},{"type":"null"}],"title":"Sequence"},"has_signal_peptide":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Signal Peptide"},"signal_peptide_cleavage_site":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Signal Peptide Cleavage Site"},"active_site_residues":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Active Site Residues"},"source_microorganism_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Source Microorganism Id"},"synonyms":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":50},{"type":"null"}],"title":"Synonyms"},"paper_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Paper Ids"}},"type":"object","title":"ProteinUpdate"},"ProteinVariantCreate":{"properties":{"parent_protein_id":{"type":"integer","title":"Parent Protein Id"},"variant_name":{"type":"string","maxLength":255,"minLength":1,"title":"Variant Name"},"variant_type":{"type":"string","title":"Variant Type","default":"engineered"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"sequence":{"anyOf":[{"type":"string","maxLength":50000},{"type":"null"}],"title":"Sequence"},"engineering_method":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Engineering Method"},"performance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Performance"},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"numbering_scheme":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Numbering Scheme"},"numbering_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Numbering Offset"}},"type":"object","required":["parent_protein_id","variant_name"],"title":"ProteinVariantCreate"},"ProteinVariantRead":{"properties":{"id":{"type":"integer","title":"Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"parent_protein_id":{"type":"integer","title":"Parent Protein Id"},"variant_name":{"type":"string","title":"Variant Name"},"variant_type":{"type":"string","title":"Variant Type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"sequence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sequence"},"engineering_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Engineering Method"},"performance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Performance"},"numbering_scheme":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Numbering Scheme"},"numbering_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Numbering Offset"},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"mutations":{"items":{"$ref":"#/components/schemas/MutationRead"},"type":"array","title":"Mutations","default":[]},"kinetics":{"items":{"$ref":"#/components/schemas/EnzymeKineticsRead"},"type":"array","title":"Kinetics","default":[]},"properties":{"items":{"$ref":"#/components/schemas/EnzymePropertiesRead"},"type":"array","title":"Properties","default":[]}},"type":"object","required":["id","parent_protein_id","variant_name","variant_type"],"title":"ProteinVariantRead"},"ProteinVariantRef":{"properties":{"id":{"type":"integer","title":"Id"},"variant_name":{"type":"string","title":"Variant Name"}},"type":"object","required":["id","variant_name"],"title":"ProteinVariantRef","description":"Minimal variant reference for embedding in kinetics/properties rows.\n\nDeliberately lightweight (no nested kinetics/properties) to break the\n``ProteinVariantRead -> kinetics -> protein_variant -> ProteinVariantRead``\ncycle that would otherwise recurse during serialization. Consumers only need\nthe variant name (templates fall back to \"Wild-type\" when absent)."},"ProteinVariantUpdate":{"properties":{"parent_protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Protein Id"},"variant_name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Variant Name"},"variant_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant Type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"sequence":{"anyOf":[{"type":"string","maxLength":50000},{"type":"null"}],"title":"Sequence"},"engineering_method":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Engineering Method"},"performance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Performance"},"paper_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Paper Id"},"numbering_scheme":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Numbering Scheme"},"numbering_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Numbering Offset"}},"type":"object","title":"ProteinVariantUpdate"},"PublishNowRequest":{"properties":{"protein_ids":{"items":{"type":"integer"},"type":"array","maxItems":500,"title":"Protein Ids"},"microorganism_ids":{"items":{"type":"integer"},"type":"array","maxItems":500,"title":"Microorganism Ids"}},"type":"object","title":"PublishNowRequest","description":"A superuser publishing specific staged records without waiting a week.\n\nIds only. There is no ``visibility`` field, and the handler assigns none:\nthe records go through exactly the rules a scheduled release uses, so an id\nnamed here cannot be bought past a tombstone. Anything not currently ``staged`` is silently skipped and\nreported in ``declined``."},"PublishNowResponse":{"properties":{"requested":{"additionalProperties":{"type":"integer"},"type":"object","title":"Requested"},"published":{"additionalProperties":{"type":"integer"},"type":"object","title":"Published"},"declined":{"additionalProperties":{"type":"integer"},"type":"object","title":"Declined"}},"type":"object","required":["requested","published","declined"],"title":"PublishNowResponse"},"ReactionStepCreate":{"properties":{"pathway_id":{"type":"integer","title":"Pathway Id"},"step_order":{"type":"integer","title":"Step Order"},"substrate_compound_id":{"type":"integer","title":"Substrate Compound Id"},"product_compound_id":{"type":"integer","title":"Product Compound Id"},"protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Id"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"evidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evidence"}},"type":"object","required":["pathway_id","step_order","substrate_compound_id","product_compound_id"],"title":"ReactionStepCreate"},"ReactionStepRead":{"properties":{"id":{"type":"integer","title":"Id"},"pathway_id":{"type":"integer","title":"Pathway Id"},"step_order":{"type":"integer","title":"Step Order"},"substrate_compound_id":{"type":"integer","title":"Substrate Compound Id"},"product_compound_id":{"type":"integer","title":"Product Compound Id"},"protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Id"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"evidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evidence"},"enzyme_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enzyme Name"},"enzyme_accessions":{"items":{"type":"string"},"type":"array","title":"Enzyme Accessions","default":[]},"substrate_compartment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Substrate Compartment"},"product_compartment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Compartment"},"step_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Step Type"},"substrate_compound":{"anyOf":[{"$ref":"#/components/schemas/CompoundRead"},{"type":"null"}]},"product_compound":{"anyOf":[{"$ref":"#/components/schemas/CompoundRead"},{"type":"null"}]},"protein":{"anyOf":[{"$ref":"#/components/schemas/PathwayEnzymeRef"},{"type":"null"}]}},"type":"object","required":["id","pathway_id","step_order","substrate_compound_id","product_compound_id","protein_id","description","evidence"],"title":"ReactionStepRead"},"ReactionStepUpdate":{"properties":{"step_order":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Step Order"},"substrate_compound_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Substrate Compound Id"},"product_compound_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Product Compound Id"},"protein_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Protein Id"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"evidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evidence"}},"type":"object","title":"ReactionStepUpdate"},"ReleaseStagingResponse":{"properties":{"next_version":{"type":"string","title":"Next Version"},"enabled":{"type":"boolean","title":"Enabled"},"withheld":{"type":"object","title":"Withheld"}},"type":"object","required":["next_version","enabled","withheld"],"title":"ReleaseStagingResponse","description":"What the next release would do, and what it would decline to do."},"ReplyCreate":{"properties":{"body":{"type":"string","minLength":1,"title":"Body"}},"type":"object","required":["body"],"title":"ReplyCreate"},"ReplyOut":{"properties":{"id":{"type":"integer","title":"Id"},"body":{"type":"string","title":"Body"},"author":{"anyOf":[{"$ref":"#/components/schemas/AuthorOut"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","body","author","created_at","updated_at"],"title":"ReplyOut"},"ResendConfirmationRequest":{"properties":{"recaptcha_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recaptcha Token"},"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"ResendConfirmationRequest"},"ResetPasswordRequest":{"properties":{"token":{"type":"string","title":"Token"},"password":{"type":"string","title":"Password"},"min_length":{"type":"integer","title":"Min Length","default":8}},"type":"object","required":["token","password"],"title":"ResetPasswordRequest"},"ResultEnum":{"type":"string","enum":["positive","negative","inconclusive"],"title":"ResultEnum"},"ReviewerGuidance":{"properties":{"data_gaps":{"items":{"type":"string"},"type":"array","title":"Data Gaps"},"focus_areas":{"items":{"type":"string"},"type":"array","title":"Focus Areas"},"suggested_steps":{"items":{"type":"string"},"type":"array","title":"Suggested Steps"}},"type":"object","title":"ReviewerGuidance","description":"Curator-facing guidance from the extractor, distinct from extraction_notes.\n\n``extraction_notes`` records provenance and methodology; this tells the human\nreviewer what is missing and how to finish the record. Surfaced as a panel on\nthe curator review screen. All three lists are optional and default empty so\nthe producer can supply only what applies (and older extractions, which lack\nthe field entirely, stay valid)."},"ReviseOutcome":{"type":"string","enum":["revision_opened","revision_updated","patched","unchanged"],"title":"ReviseOutcome"},"ReviseResponse":{"properties":{"outcome":{"$ref":"#/components/schemas/ReviseOutcome"},"requested_id":{"type":"integer","title":"Requested Id"},"ingestion_id":{"type":"integer","title":"Ingestion Id"},"status":{"type":"string","title":"Status"},"supersedes_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Supersedes Id"},"revision_batch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revision Batch"},"revision_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revision Reason"},"extraction_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Model"},"extraction_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extraction Version"},"unrecognised_fields":{"items":{"type":"string"},"type":"array","title":"Unrecognised Fields"}},"type":"object","required":["outcome","requested_id","ingestion_id","status","supersedes_id","revision_batch","revision_reason","extraction_model","extraction_version"],"title":"ReviseResponse"},"RowEvidenceScope":{"type":"string","enum":["organism_or_enzyme","whole_organism"],"title":"RowEvidenceScope","description":"``evidence_scope`` where it selects *interaction rows* (a count, a\ndetail page's evidence), not entities.\n\n``enzyme_only`` is an entity-level question (\"credited only through an\nenzyme\") with no row-level meaning, so it is accepted by the entity lists\n(``/microorganisms`` and its exports) and refused here rather than quietly\nread as the default."},"RunSummary":{"properties":{"queued":{"type":"integer","title":"Queued"},"failed":{"type":"integer","title":"Failed","default":0}},"type":"object","required":["queued"],"title":"RunSummary"},"SampleSourceRead":{"properties":{"id":{"type":"integer","title":"Id"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"environment_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Type"},"sample_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sample Description"}},"type":"object","required":["id"],"title":"SampleSourceRead"},"SequenceLookupRequest":{"properties":{"accession_id":{"type":"string","maxLength":50,"minLength":1,"title":"Accession Id"},"database":{"type":"string","maxLength":20,"minLength":1,"title":"Database"}},"type":"object","required":["accession_id","database"],"title":"SequenceLookupRequest"},"SequenceLookupResponse":{"properties":{"sequence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sequence"},"protein_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Protein Name"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"found":{"type":"boolean","title":"Found","default":false},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","title":"SequenceLookupResponse"},"SequenceSearchResponse":{"properties":{"hits":{"items":{"$ref":"#/components/schemas/SequenceSearchResult"},"type":"array","title":"Hits","default":[]}},"type":"object","title":"SequenceSearchResponse"},"SequenceSearchResult":{"properties":{"query_seq_id":{"type":"string","title":"Query Seq Id"},"subject_seq_id":{"type":"string","title":"Subject Seq Id"},"pident":{"type":"number","title":"Pident"},"length":{"type":"integer","title":"Length"},"mismatch":{"type":"integer","title":"Mismatch"},"gapopen":{"type":"integer","title":"Gapopen"},"qstart":{"type":"integer","title":"Qstart"},"qend":{"type":"integer","title":"Qend"},"sstart":{"type":"integer","title":"Sstart"},"send":{"type":"integer","title":"Send"},"evalue":{"type":"number","title":"Evalue"},"bitscore":{"type":"number","title":"Bitscore"},"plasticdb_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plasticdb Id"},"protein_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Protein Name"},"entity_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Type"},"entity_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entity Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"detail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail Url"},"variant_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant Type"}},"type":"object","required":["query_seq_id","subject_seq_id","pident","length","mismatch","gapopen","qstart","qend","sstart","send","evalue","bitscore"],"title":"SequenceSearchResult","description":"Single DIAMOND hit from a synchronous sequence search."},"SequenceValidationRequest":{"properties":{"sequence":{"type":"string","maxLength":100000,"minLength":1,"title":"Sequence"}},"type":"object","required":["sequence"],"title":"SequenceValidationRequest"},"SequenceValidationResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"is_amino_acid":{"type":"boolean","title":"Is Amino Acid","default":false},"is_nucleotide":{"type":"boolean","title":"Is Nucleotide","default":false},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["valid"],"title":"SequenceValidationResponse"},"SettingFieldOut":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"type":{"type":"string","title":"Type"},"help":{"type":"string","title":"Help"},"placeholder":{"type":"string","title":"Placeholder"},"secret":{"type":"boolean","title":"Secret"},"overridden":{"type":"boolean","title":"Overridden"},"value":{"anyOf":[{},{"type":"null"}],"title":"Value"},"is_set":{"type":"boolean","title":"Is Set"},"masked":{"type":"string","title":"Masked","default":""}},"type":"object","required":["key","label","type","help","placeholder","secret","overridden","is_set"],"title":"SettingFieldOut"},"SettingGroupOut":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"icon":{"type":"string","title":"Icon"},"description":{"type":"string","title":"Description"},"fields":{"items":{"$ref":"#/components/schemas/SettingFieldOut"},"type":"array","title":"Fields"}},"type":"object","required":["key","label","icon","description","fields"],"title":"SettingGroupOut"},"SettingsResponse":{"properties":{"groups":{"items":{"$ref":"#/components/schemas/SettingGroupOut"},"type":"array","title":"Groups"},"test":{"anyOf":[{"$ref":"#/components/schemas/TestResult"},{"type":"null"}]}},"type":"object","required":["groups"],"title":"SettingsResponse"},"SettingsUpdate":{"properties":{"values":{"type":"object","title":"Values"}},"type":"object","required":["values"],"title":"SettingsUpdate"},"SnapshotLatestResponse":{"properties":{"release_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Release Label"},"figshare_doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Figshare Doi"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"entity_counts":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Entity Counts"}},"type":"object","required":["release_label","figshare_doi","published_at","entity_counts"],"title":"SnapshotLatestResponse"},"SnapshotListItem":{"properties":{"id":{"type":"integer","title":"Id"},"release_label":{"type":"string","title":"Release Label"},"status":{"type":"string","title":"Status"},"entity_counts":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Entity Counts"},"figshare_doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Figshare Doi"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"}},"type":"object","required":["id","release_label","status","entity_counts","figshare_doi","created_at","published_at"],"title":"SnapshotListItem"},"SnapshotRead":{"properties":{"id":{"type":"integer","title":"Id"},"release_label":{"type":"string","title":"Release Label"},"status":{"type":"string","title":"Status"},"entity_counts":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Entity Counts"},"file_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"File Size"},"checksum":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checksum"},"figshare_doi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Figshare Doi"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"}},"type":"object","required":["id","release_label","status","entity_counts","file_size","checksum","figshare_doi","created_at","published_at"],"title":"SnapshotRead"},"SoleCarbonSource":{"type":"string","enum":["yes","no","not_stated"],"title":"SoleCarbonSource","description":"Was the plastic the sole carbon source in the assay? ``not_stated`` is\nthe paper saying nothing (stored NULL)."},"StrainOccurrenceRead":{"properties":{"strain_designation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Strain Designation"},"genome_assembly_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genome Assembly Accession"},"culture_collection_ids":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Culture Collection Ids"},"sample_source":{"anyOf":[{"$ref":"#/components/schemas/SampleSourceRead"},{"type":"null"}]},"genetic_background":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genetic Background"},"id":{"type":"integer","title":"Id"},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"counts_for_species":{"type":"boolean","title":"Counts For Species","description":"False for an expression host, knockout or engineered strain: its\nassay is not evidence that the species itself degrades the plastic.","readOnly":true}},"type":"object","required":["id","counts_for_species"],"title":"StrainOccurrenceRead","description":"A microorganism's occurrence in a specific paper (for the organism page)."},"StrainOccurrenceRef":{"properties":{"strain_designation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Strain Designation"},"genome_assembly_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genome Assembly Accession"},"culture_collection_ids":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Culture Collection Ids"},"sample_source":{"anyOf":[{"$ref":"#/components/schemas/SampleSourceRead"},{"type":"null"}]},"genetic_background":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genetic Background"},"counts_for_species":{"type":"boolean","title":"Counts For Species","description":"False for an expression host, knockout or engineered strain: its\nassay is not evidence that the species itself degrades the plastic.","readOnly":true}},"type":"object","required":["counts_for_species"],"title":"StrainOccurrenceRef","description":"Strain-/isolate-level facts for a microorganism as reported in one study."},"SubmissionMatchSummary":{"properties":{"submission_id":{"type":"integer","title":"Submission Id"},"protein_results":{"items":{"$ref":"#/components/schemas/ProteinSubmissionResult"},"type":"array","title":"Protein Results","default":[]},"all_complete":{"type":"boolean","title":"All Complete","default":false}},"type":"object","required":["submission_id"],"title":"SubmissionMatchSummary"},"SubmissionTypeEnum":{"type":"string","enum":["Add data","Remove data","Change data","Other"],"title":"SubmissionTypeEnum"},"SubmissionUpdateAdmin":{"properties":{"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"admin_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Admin Notes"},"content":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"title":"Content"},"data_json":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Data Json"}},"type":"object","title":"SubmissionUpdateAdmin"},"SubstrateForm":{"type":"string","enum":["model_substrate","amorphous_film","crystalline_film","film","powder","emulsion","granule","particle","whole_polymer"],"title":"SubstrateForm"},"TaxIdLookupResponse":{"properties":{"tax_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"},"scientific_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scientific Name"},"lineage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lineage"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"phylum":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phylum"},"class_":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Class "},"order":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Order"},"family":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family"},"genus":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genus"},"found":{"type":"boolean","title":"Found","default":false},"name_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name Class"},"synonym_of":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Synonym Of"},"other_names":{"items":{"type":"string"},"type":"array","title":"Other Names"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","title":"TaxIdLookupResponse","description":"One organism name resolved against NCBI Taxonomy.\n\n``name_class`` / ``synonym_of`` are how a *silent* rename is made visible.\nNCBI reclassifies organisms, and a faithful extraction of a name that was\ncorrect when the paper was published (``Pseudomonas stutzeri``) resolves to a\nnode NCBI now calls something else (``Stutzerimonas stutzeri``, taxon 316).\nPromotion stores the current name, which is right — but a curator approving\nthe record has to be able to see that the name they are looking at is not the\nname that will be stored. ``name_class`` is set **only** when NCBI itself\nlists the queried string as a synonym of the node (see\n``external_api._read_other_names``), never inferred from the two names\ndiffering.\n\n``other_names`` is every alternative name NCBI lists for the resolved node.\nIt is carried so the stored record can be found by the name the paper used\nas well as by the name NCBI uses now."},"TaxonomyAction":{"type":"string","enum":["accept_unresolved","use_tax_id","rename"],"title":"TaxonomyAction","description":"What a curator decided to do about an organism name NCBI could not settle."},"TaxonomyCause":{"type":"string","enum":["absent_from_ncbi","obsolete_name","misspelling","not_validly_published","other"],"title":"TaxonomyCause","description":"Why a name did not resolve — four situations, one former error message.\n\nThe remedy differs by cause, which is the whole reason this is recorded\nrather than inferred: ``absent_from_ncbi`` is a correct name waiting for NCBI\nto catch up (NCBI Taxonomy indexes sequence data, not nomenclature — LPSN and\nIndex Fungorum hold names it does not); ``obsolete_name`` and ``misspelling``\nare names that want correcting; ``not_validly_published`` never resolves at\nall, and is the only one that stops the retry job."},"TaxonomyDecision":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"action":{"$ref":"#/components/schemas/TaxonomyAction"},"tax_id":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Tax Id"},"new_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"New Name"},"cause":{"anyOf":[{"$ref":"#/components/schemas/TaxonomyCause"},{"type":"null"}]},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"}},"type":"object","required":["name","action"],"title":"TaxonomyDecision","description":"One curator ruling on one organism name, sent with the approve that uses it.\n\nIt travels **with the approval** rather than being stored first and applied\nlater, so a decision cannot outlive the payload it was made about: the\ncurator saw this name, in this extraction, and said what to do. The set is\nrecorded on the ingestion afterwards as the audit trail."},"TaxonomyRunStart":{"properties":{"scope":{"type":"string","enum":["all","missing","unresolved","single"],"title":"Scope","default":"missing"},"microorganism_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Microorganism Id"}},"type":"object","title":"TaxonomyRunStart","description":"Body for ``POST /api/v1/admin/taxonomy/runs``.\n\n``scope`` is validated against a literal rather than a free string because it\nselects how many NCBI requests the run will make — 1, ~25, or ~1300 — and a\ntypo that silently fell through to the widest one would spend the shared\ninstitutional IP's allowance without anyone asking for it."},"TempClass":{"type":"string","enum":["psychrophile","mesophile","thermophile"],"title":"TempClass","description":"Growth-temperature class, bucketed from the organism's recorded optimum\ngrowth temperature (``growth_temp_opt``) — not from any assay temperature.\n\nAn Enum so an unknown value is a 422: ``temp_class=thermophilic`` used to be\nsilently ignored and return the whole list (R11-2)."},"TestResult":{"properties":{"ok":{"type":"boolean","title":"Ok"},"detail":{"type":"string","title":"Detail"}},"type":"object","required":["ok","detail"],"title":"TestResult"},"Token":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"}},"type":"object","required":["access_token"],"title":"Token"},"TreeBuildRequest":{"properties":{"microorganism_ids":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Microorganism Ids"},"q":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"plastic":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plastic"},"include_subtypes":{"type":"boolean","title":"Include Subtypes","default":false},"plastic_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Plastic Id"},"tax_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tax Id"},"year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Year"},"min_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Year"},"max_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Year"},"temp_class":{"anyOf":[{"type":"string","enum":["psychrophile","mesophile","thermophile"]},{"type":"null"}],"title":"Temp Class"},"environment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"lineage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lineage"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"kingdom":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kingdom"},"phylum":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phylum"},"class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Class"},"order":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Order"},"family":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family"},"genus":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genus"},"evidence_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evidence Method"},"substrate_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Substrate Form"},"sole_carbon_source":{"anyOf":[{"type":"string","enum":["yes","no","not_stated"]},{"type":"null"}],"title":"Sole Carbon Source"},"aerobicity":{"anyOf":[{"type":"string","enum":["aerobic","anaerobic","microaerophilic","not_reported"]},{"type":"null"}],"title":"Aerobicity"},"include_negative":{"type":"boolean","title":"Include Negative","default":false},"polarity":{"anyOf":[{"$ref":"#/components/schemas/TreePolarityEnum"},{"type":"null"}]},"evidence_scope":{"$ref":"#/components/schemas/TreeEvidenceScopeEnum","default":"organism_or_enzyme"}},"type":"object","title":"TreeBuildRequest","description":"What to build a phylogeny of — **a filter, or an explicit id list** (#308).\n\nThe filter block is deliberately the *whole* microorganism browse filter set,\nfield for field, because the browse page's \"View as Tree\" button now sends\nthe filter it is showing instead of the ids it happens to have loaded. It had\nto send ids, and that is how the 500-organism truncation survived the fix\nthat removed the cap from :func:`app.api.v1.tree._resolve_ids`: the page\nfetched ``/api/v1/microorganisms?limit=500`` — 500 being that endpoint's\ndocumented maximum, a deliberate cap on materialising a table (B2) — and\nPOSTed those 500 ids, so ``_resolve_ids`` never ran at all.\n\nA short filter list would have re-created the problem in a quieter form. The\npage can filter by polarity, evidence scope, plastic name, year, temperature\nclass, environment and location; a request that could not carry those would\nforce the page back to resolving ids itself, which is the defect. So the\ncontract is: **anything the list can be filtered by, the tree can be built\nfrom**, and :func:`app.api.v1.tree._resolve_ids` answers it with the very\nsame :func:`app.services.query.microorganism_list_filters` the list uses.\n\n``microorganism_ids`` stays, and is not deprecated. It is the only way to ask\nfor a set that no organism filter describes — the proteins page builds a tree\nof the organisms its matched *proteins* came from, and ``/tools/build-tree``\naccepts an explicit ``?ids=`` deep link. When it is present it wins and no\nfilter is resolved."},"TreeEvidenceScopeEnum":{"type":"string","enum":["organism_or_enzyme","whole_organism","enzyme_only"],"title":"TreeEvidenceScopeEnum","description":"``app.services.query``'s ``SCOPE_*`` constants, restated — see above.\n\nAn unknown scope must be a 422 rather than a silent fallback:\n``microorganism_list_filters`` reads anything it does not recognise as the\ninclusive default, so a typo would build a *different* tree from the list the\nuser is looking at and say nothing. That is the exact class of quiet\ndisagreement this request model exists to remove."},"TreePolarityEnum":{"type":"string","enum":["positive","negative","inconclusive"],"title":"TreePolarityEnum","description":"The values of :class:`app.schemas.ingestions.ResultEnum`, restated.\n\nRestated rather than imported: ``app.schemas.ingestions`` reaches\n``app.services`` at import time, and ``app.services.__init__`` imports\n``app.schemas.schemas``, which imports *this* module — a cycle. The values\nare pinned to the canonical enum by\n``tests/test_tree_build_from_filters.py::test_the_tree_request_vocabularies_match_the_list_endpoints``,\nso the duplication cannot drift silently."},"UserCreateRecaptcha":{"properties":{"recaptcha_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recaptcha Token"},"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","minLength":8,"title":"Password"},"full_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Full Name"}},"type":"object","required":["email","password"],"title":"UserCreateRecaptcha"},"UserPublicProfile":{"properties":{"id":{"type":"string","title":"Id"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"orcid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Orcid"},"orcid_verified":{"type":"boolean","title":"Orcid Verified","default":false},"gravatar_url":{"type":"string","title":"Gravatar Url","default":""},"total_annotations":{"type":"integer","title":"Total Annotations","default":0},"total_suggestions_accepted":{"type":"integer","title":"Total Suggestions Accepted","default":0},"total_evidence":{"type":"integer","title":"Total Evidence","default":0},"total_submissions":{"type":"integer","title":"Total Submissions","default":0}},"type":"object","required":["id","full_name","orcid"],"title":"UserPublicProfile"},"UserRead":{"properties":{"id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"is_active":{"type":"boolean","title":"Is Active"},"is_superuser":{"type":"boolean","title":"Is Superuser"},"is_curator":{"type":"boolean","title":"Is Curator","default":false},"email_verified":{"type":"boolean","title":"Email Verified","default":false},"has_api_key":{"type":"boolean","title":"Has Api Key","default":false},"orcid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Orcid"},"orcid_verified":{"type":"boolean","title":"Orcid Verified","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"gravatar_url":{"type":"string","title":"Gravatar Url","default":""}},"type":"object","required":["id","email","full_name","is_active","is_superuser","created_at"],"title":"UserRead"},"UserUpdate":{"properties":{"full_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Full Name"},"password":{"anyOf":[{"type":"string","minLength":8},{"type":"null"}],"title":"Password"},"orcid":{"anyOf":[{"type":"string","maxLength":19},{"type":"null"}],"title":"Orcid"}},"type":"object","title":"UserUpdate"},"UserUpdateAdmin":{"properties":{"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"is_superuser":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Superuser"},"is_curator":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Curator"}},"type":"object","title":"UserUpdateAdmin"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VariantDetail":{"properties":{"id":{"type":"integer","title":"Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"variant_name":{"type":"string","title":"Variant Name"},"variant_type":{"type":"string","title":"Variant Type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"sequence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sequence"},"engineering_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Engineering Method"},"performance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Performance"},"numbering_scheme":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Numbering Scheme"},"numbering_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Numbering Offset"},"structures":{"items":{"$ref":"#/components/schemas/ProteinStructureRead"},"type":"array","title":"Structures","default":[]},"primary_structure":{"anyOf":[{"$ref":"#/components/schemas/ProteinStructureRead"},{"type":"null"}]},"structure_file":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Structure File"},"has_signal_peptide":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Signal Peptide"},"signal_peptide_cleavage_site":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Signal Peptide Cleavage Site"},"parent_protein":{"anyOf":[{"$ref":"#/components/schemas/VariantParentRef"},{"type":"null"}]},"paper":{"anyOf":[{"$ref":"#/components/schemas/PaperRead"},{"type":"null"}]},"mutations":{"items":{"$ref":"#/components/schemas/MutationRead"},"type":"array","title":"Mutations","default":[]},"kinetics":{"items":{"$ref":"#/components/schemas/EnzymeKineticsRead"},"type":"array","title":"Kinetics","default":[]},"properties":{"items":{"$ref":"#/components/schemas/EnzymePropertiesRead"},"type":"array","title":"Properties","default":[]},"plastics":{"items":{"$ref":"#/components/schemas/PlasticRead"},"type":"array","title":"Plastics","default":[]},"interactions":{"items":{"$ref":"#/components/schemas/InteractionRead"},"type":"array","title":"Interactions","default":[]},"degradation_links":{"items":{"$ref":"#/components/schemas/DegradationLink"},"type":"array","title":"Degradation Links","default":[]}},"type":"object","required":["id","variant_name","variant_type"],"title":"VariantDetail","description":"Full detail for one engineered protein variant, for its own page."},"VariantParentRef":{"properties":{"id":{"type":"integer","title":"Id"},"accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accession"},"name":{"type":"string","title":"Name"},"genbank_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Genbank Id"},"uniprot_accession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uniprot Accession"}},"type":"object","required":["id","name"],"title":"VariantParentRef","description":"Minimal parent-protein context shown on a variant page."},"app__schemas__compounds__PlasticRef":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"abbreviation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abbreviation"}},"type":"object","required":["id","name"],"title":"PlasticRef","description":"Minimal plastic reference for compound detail — avoids circular import."},"app__schemas__entities__PlasticRef":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"abbreviation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abbreviation"}},"type":"object","required":["id","name"],"title":"PlasticRef","description":"Minimal plastic reference for embedding in interaction responses."}},"securitySchemes":{"OAuth2PasswordBearer":{"type":"oauth2","flows":{"password":{"scopes":{},"tokenUrl":"/api/v1/auth/login"}}},"HTTPBearer":{"type":"http","scheme":"bearer"},"APIKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"}}}}