{
  "openapi": "3.1.0",
  "info": {
    "title": "Quantum Orbitals API",
    "version": "16.5.1",
    "summary": "Molecular geometry, localized orbital, peptide conversion, nomenclature and rendering API.",
    "description": "API for the Quantum Orbitals web application. RDKit builds the molecular graph and one deterministic conformer; the qo_chem orbital layer (Coulson σ hybrids from the real bond angles, σ/π lone-pair typing, Hückel π with p axes taken from the geometry, Slater orbitals in a Löwdin basis) adds charges, bond orders, molecular orbitals and pKa descriptors. /api/model returns the 3D model with that layer in `chemistry`; /api/pi-model returns the compact π payload the browser turns into density, interference, charge-shift, potential and orbital maps. Real-space fields are never computed on the server. The protected SVG renderer requires a bearer token. The IUPAC/systematic-name endpoint is an optional capability (py2opsin + Java). /api/site (16.4) takes a protein structure (PDB, mmCIF, BinaryCIF, or a GL1X MolNFT record), finds a PROSITE motif or a metal site, cuts out a capped, protonated fragment, and returns its orbital layer in the protein's own frame, including the ligands' donor pairs and zinc's empty 4s/4p acceptor orbitals.",
    "license": {
      "name": "Project-specific / see repository"
    }
  },
  "servers": [
    {
      "url": "/",
      "description": "Current host"
    }
  ],
  "tags": [
    {
      "name": "Core",
      "description": "Core molecular model and rendering."
    },
    {
      "name": "Peptides",
      "description": "Standard peptide sequence/SMILES conversion."
    },
    {
      "name": "Nomenclature",
      "description": "Optional systematic-name parsing."
    },
    {
      "name": "Health",
      "description": "Deployment and capability diagnostics."
    }
  ],
  "paths": {
    "/api/model": {
      "post": {
        "tags": [
          "Core"
        ],
        "summary": "Build a 3D molecular/local-orbital model from SMILES",
        "description": "Parses SMILES with RDKit, adds hydrogens, generates one deterministic ETKDG conformer, optimizes with MMFF/UFF when available, and returns atoms, bonds and a compact local s/p orbital model.",
        "operationId": "buildMoleculeModel",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SmilesRequest"
              },
              "example": {
                "smiles": "CCO"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Molecular model",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MoleculeModel"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or model-generation failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/pi-model": {
      "post": {
        "tags": [
          "Core"
        ],
        "summary": "π layer and acid/base pairs for any SMILES",
        "description": "Builds the same conformer as /api/model, runs the qo_chem orbital layer, finds ionisable sites and, for each, builds the acid and base form on the same geometry (only the proton moves). Returns compact π payloads (axes, Slater exponents, Löwdin matrix, Hückel coefficients) that pi-field-engine.js turns into maps, plus three pKa descriptors and a calibrated π forecast with its leave-one-out error. The `speciation` block titrates every site together (≤ 6 sites, all protonation microstates): site pKa (parent value + substituent term, others neutral), its held-out error on IUPAC data, the site–site charge terms W (pKa units) and the macroscopic deprotonation steps.",
        "operationId": "buildPiModel",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PiModelRequest"
              },
              "example": {
                "smiles": "Oc1ccc(cc1)[N+](=O)[O-]",
                "ph": 7.4
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "π model",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PiModelResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or model-generation failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/render-svg": {
      "post": {
        "tags": [
          "Core"
        ],
        "summary": "Render a standalone molecular/orbital SVG",
        "description": "Bearer-protected page-independent SVG renderer. This endpoint currently uses the server-side schematic/local-orbital renderer; it is not identical to the browser's harmonic 3Dmol surface renderer.",
        "operationId": "renderMoleculeSvg",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenderSvgRequest"
              },
              "example": {
                "smiles": "N[C@@H](CS)C(=O)O",
                "render": {
                  "width": 1200,
                  "height": 820
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Standalone SVG",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or incorrect bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Bearer token not configured on server",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/sequence-to-smiles": {
      "post": {
        "tags": [
          "Peptides"
        ],
        "summary": "Convert a standard one-letter peptide sequence to SMILES",
        "description": "Supports the 20 standard amino acids and RDKit's standard linear-peptide construction.",
        "operationId": "sequenceToSmiles",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SequenceRequest"
              },
              "example": {
                "sequence": "ACDEFGHIK"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Peptide structure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SequenceToSmilesResult"
                }
              }
            }
          },
          "400": {
            "description": "Unsupported or invalid sequence",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/smiles-to-sequence": {
      "post": {
        "tags": [
          "Peptides"
        ],
        "summary": "Conservatively recover a standard linear peptide sequence from SMILES",
        "description": "Only returns a sequence when the graph can be segmented into one connected linear peptide composed of standard residues. Modified, cyclic, branched or ambiguous peptides are rejected.",
        "operationId": "smilesToSequence",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SmilesRequest"
              },
              "example": {
                "smiles": "N[C@@H](CS)C(=O)O"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recognized sequence",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmilesToSequenceResult"
                }
              }
            }
          },
          "400": {
            "description": "Not safely convertible to a standard linear peptide sequence",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/iupac-to-smiles": {
      "post": {
        "tags": [
          "Nomenclature"
        ],
        "summary": "Parse a systematic chemical name to SMILES with optional local OPSIN",
        "description": "Optional capability. The server calls py2opsin/OPSIN if installed and then validates/canonicalizes the result with RDKit. Local OPSIN requires a Java runtime. Absence of OPSIN must not affect the core molecular API.",
        "operationId": "iupacToSmiles",
        "x-optional-capability": "opsin-local",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IupacRequest"
              },
              "example": {
                "name": "2,4-dimethylbenzaldehyde"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parsed and RDKit-validated structure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IupacResult"
                }
              }
            }
          },
          "400": {
            "description": "Parsing failure or optional OPSIN capability unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "Core service health",
        "operationId": "api_health",
        "responses": {
          "200": {
            "description": "Health/capability report",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/api/catalogue-health": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "Functional-group catalogue and RDKit.js asset health",
        "operationId": "api_catalogue_health",
        "responses": {
          "200": {
            "description": "Health/capability report",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/api/viewer-health": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "3Dmol viewer asset health",
        "operationId": "api_viewer_health",
        "responses": {
          "200": {
            "description": "Health/capability report",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/api/pi-density-health": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "π-density module asset/data health",
        "operationId": "api_pi_density_health",
        "responses": {
          "200": {
            "description": "Health/capability report",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        },
        "description": "Static assets of /pka-density, the 20-case dataset, the qo_chem version, a benzene self-test and the pKa calibration in use."
      }
    },
    "/api/site": {
      "post": {
        "tags": [
          "Core"
        ],
        "summary": "Orbitals of a protein site (motif, metal or ligand), in the protein's frame",
        "description": "Reads the structure, lists every occurrence of the motif (never across a chain break) and every metal site, builds the selected site as a capped, protonated fragment with its metal (placed by least squares when the file has none), runs the orbital layer on it and returns an /api/model-shaped payload. At most 1500 atoms with hydrogens (server option --max-site-atoms) and two concurrent computations. Ligand mode (16.5): send `ligand`; the answer adds `ligand` and `free_molecule`. Extra error codes: ligand_not_found, ligand_not_molecular.",
        "operationId": "buildSite",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SiteRequest"
              },
              "example": {
                "example": "5a7u",
                "motif": "C-x(2,4)-C-x(12)-H-x(3,5)-H"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Site",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input (code: no_occurrence, invalid_motif, motif_too_general, site_too_large, gl1x, busy, ligand_not_found, ligand_not_molecular, bad_request)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected failure while reading or building",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/site-health": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "Protein-site deployment check",
        "operationId": "siteHealth",
        "description": "Whether zinc's radial functions are installed, the fragment size limit, whether the server fetches structures from GL1X (gl1x_fetch) and ligand definitions from data.rcsb.org (ccd_fetch), whether OPSIN reads ligand names (name_to_smiles), the examples and the formats it reads.",
        "responses": {
          "200": {
            "description": "Status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "opaque token",
        "description": "Token configured server-side with QUANTUM_ORBITALS_API_TOKEN."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "hint": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "SmilesRequest": {
        "type": "object",
        "required": [
          "smiles"
        ],
        "properties": {
          "smiles": {
            "type": "string",
            "examples": [
              "CCO",
              "N[C@@H](CS)C(=O)O"
            ]
          }
        },
        "additionalProperties": false
      },
      "RadialModel": {
        "type": [
          "object",
          "null"
        ],
        "description": "Valence radial functions of the element: free-atom Hartree–Fock ns/np fitted by 1–6 Slater terms (qo_chem/radial.py). The same functions are used for π overlaps, π densities and the 3D surfaces.",
        "properties": {
          "model": {
            "type": "string",
            "examples": [
              "hartree_fock_fit",
              "slater_rules"
            ]
          },
          "units": {
            "type": "string",
            "examples": [
              "bohr"
            ]
          },
          "n": {
            "type": "integer"
          },
          "s": {
            "type": "array",
            "description": "Slater terms [N, zeta (1/bohr), c] of R(r) = sum c (2 zeta)^(N+1/2)/sqrt((2N)!) r^(N-1) exp(-zeta r)",
            "items": {
              "type": "array",
              "items": {
                "type": "number"
              },
              "minItems": 3,
              "maxItems": 3
            }
          },
          "p": {
            "type": "array",
            "description": "Slater terms [N, zeta (1/bohr), c] of R(r) = sum c (2 zeta)^(N+1/2)/sqrt((2N)!) r^(N-1) exp(-zeta r)",
            "items": {
              "type": "array",
              "items": {
                "type": "number"
              },
              "minItems": 3,
              "maxItems": 3
            }
          },
          "extent_angstrom": {
            "type": "number",
            "description": "radius enclosing 99 % of the valence radial probability"
          },
          "overlap_with_hartree_fock": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "radial_phase_convention": {
            "type": "string",
            "examples": [
              "outermost_lobe_positive"
            ]
          },
          "z_eff": {
            "type": "number",
            "description": "Slater's Z_eff, kept for viewers older than 16.1"
          }
        },
        "additionalProperties": true
      },
      "Atom": {
        "type": "object",
        "required": [
          "id",
          "element",
          "atomic_number",
          "position",
          "formal_charge"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "element": {
            "type": "string",
            "examples": [
              "C"
            ]
          },
          "atomic_number": {
            "type": "integer"
          },
          "position": {
            "type": "array",
            "minItems": 3,
            "maxItems": 3,
            "items": {
              "type": "number"
            },
            "description": "3D Cartesian coordinates in Å."
          },
          "formal_charge": {
            "type": "integer"
          },
          "partial_charge": {
            "type": "number",
            "description": "Heuristic Gasteiger charge where available."
          },
          "partial_charge_model": {
            "type": "string"
          },
          "radial_charge_proxy": {
            "type": "number",
            "description": "Display-oriented charge proxy used by the optional radial extent heuristic."
          },
          "radial_charge_proxy_model": {
            "type": "string"
          },
          "hybridization": {
            "type": "string"
          },
          "valence_electrons": {
            "type": "integer"
          },
          "color": {
            "type": "string"
          },
          "valence_shell": {
            "type": [
              "integer",
              "null"
            ]
          },
          "valence_basis": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "radial_model": {
            "$ref": "#/components/schemas/RadialModel"
          }
        },
        "additionalProperties": true
      },
      "Bond": {
        "type": "object",
        "required": [
          "a",
          "b",
          "order",
          "aromatic",
          "type"
        ],
        "properties": {
          "a": {
            "type": "integer"
          },
          "b": {
            "type": "integer"
          },
          "order": {
            "type": "number"
          },
          "aromatic": {
            "type": "boolean"
          },
          "type": {
            "type": "string"
          }
        }
      },
      "LocalOrbital": {
        "type": "object",
        "required": [
          "kind",
          "occupancy",
          "direction",
          "coefficients_s_px_py_pz",
          "atom"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Examples include sigma_direction, lone_pair, residual_sigma_space, pi_basis, s_basis."
          },
          "bond_to": {
            "type": [
              "integer",
              "null"
            ]
          },
          "occupancy": {
            "type": "number"
          },
          "direction": {
            "type": "array",
            "minItems": 3,
            "maxItems": 3,
            "items": {
              "type": "number"
            }
          },
          "coefficients_s_px_py_pz": {
            "type": "array",
            "minItems": 4,
            "maxItems": 4,
            "items": {
              "type": "number"
            }
          },
          "s_character": {
            "type": "number"
          },
          "p_character": {
            "type": "number"
          },
          "atom": {
            "type": "integer"
          }
        },
        "additionalProperties": true
      },
      "PiOverlap": {
        "type": "object",
        "properties": {
          "a": {
            "type": "integer"
          },
          "b": {
            "type": "integer"
          },
          "components": {
            "type": "integer"
          },
          "aromatic": {
            "type": "boolean"
          }
        },
        "additionalProperties": true
      },
      "MoleculeSummary": {
        "type": "object",
        "properties": {
          "atoms_with_hydrogen": {
            "type": "integer"
          },
          "heavy_atoms": {
            "type": "integer"
          },
          "bonds": {
            "type": "integer"
          },
          "local_orbitals": {
            "type": "integer"
          },
          "pi_connections": {
            "type": "integer"
          }
        }
      },
      "MoleculeModel": {
        "type": "object",
        "required": [
          "smiles",
          "canonical_smiles",
          "formula",
          "molblock",
          "atoms",
          "bonds",
          "orbitals",
          "summary"
        ],
        "properties": {
          "smiles": {
            "type": "string"
          },
          "canonical_smiles": {
            "type": "string"
          },
          "formula": {
            "type": "string"
          },
          "molblock": {
            "type": "string",
            "description": "RDKit MolBlock of the conformer, in the same centred coordinates as atoms[].position."
          },
          "atoms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Atom"
            }
          },
          "bonds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Bond"
            }
          },
          "orbitals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LocalOrbital"
            }
          },
          "pi_overlaps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PiOverlap"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "summary": {
            "$ref": "#/components/schemas/MoleculeSummary"
          },
          "model_notes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "chemistry": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "qo-chem/16.1 orbital layer: badges, normalization, atoms (role, σ/π lone pairs, pi_charge, description), hybrids (Coulson labels sp^n, deviation_deg, lone_pair_sets incl. rotation_pair), pi_components (x, C, occ, charges, bond_orders, HOMO/LUMO), acceptors (sn2, pi_star), hammett, ions, radial (Hartree–Fock fit summary per element), sanity_checks, pka (descriptors per ionisable site), warnings, provenance."
          },
          "orbital_model": {
            "type": "string",
            "example": "qo-chem/16.1: Coulson hybrids + σ/π lone pairs + Hückel π + Hartree–Fock radial fits"
          },
          "pi_field": {
            "description": "The molecule's π layer in the PiForm payload, same conformer and centred frame as atoms[].position; the 3D viewer draws π density, interference, orbitals and potential from it. Null when the orbital layer is unavailable.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/PiForm"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "additionalProperties": true
      },
      "RenderSvgRequest": {
        "type": "object",
        "required": [
          "smiles"
        ],
        "properties": {
          "smiles": {
            "type": "string",
            "examples": [
              "N[C@@H](CS)C(=O)O"
            ]
          },
          "render": {
            "type": "object",
            "properties": {
              "width": {
                "type": "integer",
                "minimum": 320,
                "maximum": 2400,
                "default": 1200
              },
              "height": {
                "type": "integer",
                "minimum": 240,
                "maximum": 1800,
                "default": 820
              },
              "orbital_scale": {
                "type": "number",
                "minimum": 0.2,
                "maximum": 3.0,
                "default": 1.2
              },
              "atom_scale": {
                "type": "number",
                "minimum": 0.35,
                "maximum": 2.0,
                "default": 0.95
              },
              "show_hydrogens": {
                "type": "boolean",
                "default": true
              },
              "show_sigma": {
                "type": "boolean",
                "default": true
              },
              "show_lone_pairs": {
                "type": "boolean",
                "default": true
              },
              "show_pi": {
                "type": "boolean",
                "default": true
              },
              "show_labels": {
                "type": "boolean",
                "default": true
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "SequenceRequest": {
        "type": "object",
        "required": [
          "sequence"
        ],
        "properties": {
          "sequence": {
            "type": "string",
            "examples": [
              "ACDEFGHIK"
            ]
          }
        },
        "additionalProperties": false
      },
      "SequenceToSmilesResult": {
        "type": "object",
        "properties": {
          "sequence": {
            "type": "string"
          },
          "length": {
            "type": "integer"
          },
          "three_letter": {
            "type": "string"
          },
          "smiles": {
            "type": "string"
          },
          "formula": {
            "type": "string"
          },
          "molblock": {
            "type": "string"
          },
          "interpretation": {
            "type": "string"
          },
          "limitations": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": true
      },
      "SmilesToSequenceResult": {
        "type": "object",
        "properties": {
          "smiles": {
            "type": "string"
          },
          "sequence": {
            "type": "string"
          },
          "length": {
            "type": "integer"
          },
          "three_letter": {
            "type": "string"
          },
          "formula": {
            "type": "string"
          },
          "residues": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "stereochemistry": {
            "type": "string"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "interpretation": {
            "type": "string"
          },
          "limitations": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": true
      },
      "IupacRequest": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 1200,
            "examples": [
              "2,4-dimethylbenzaldehyde"
            ]
          }
        },
        "additionalProperties": false
      },
      "IupacResult": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "smiles": {
            "type": "string"
          },
          "opsin_smiles": {
            "type": "string"
          },
          "formula": {
            "type": "string"
          },
          "heavy_atoms": {
            "type": "integer"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "parser": {
            "type": "string"
          },
          "depiction_backend": {
            "type": [
              "string",
              "null"
            ]
          },
          "svg": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "additionalProperties": true
      },
      "Health": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "additionalProperties": true
      },
      "PiModelRequest": {
        "type": "object",
        "required": [
          "smiles"
        ],
        "properties": {
          "smiles": {
            "type": "string",
            "example": "Oc1ccc(cc1)[N+](=O)[O-]"
          },
          "ph": {
            "type": "number",
            "minimum": 0,
            "maximum": 14,
            "description": "Optional: adds per-site protonation states at this pH."
          }
        }
      },
      "PiOrbital": {
        "type": "object",
        "properties": {
          "atom": {
            "type": "integer"
          },
          "axis": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "minItems": 3,
            "maxItems": 3
          },
          "type": {
            "type": "string",
            "description": "Streitwieser type: C, O=, O:, N=, N:, N+, S:, Cl …"
          }
        }
      },
      "PiComponent": {
        "type": "object",
        "description": "One conjugated π system. C[r][k]: coefficient of orbital r in MO k (Löwdin basis). E_k = α + x_k β.",
        "properties": {
          "atoms": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "orbitals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PiOrbital"
            }
          },
          "basis": {
            "type": "object",
            "properties": {
              "positions": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                }
              },
              "M": {
                "type": "array",
                "description": "S^-1/2 (Löwdin)",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                }
              },
              "radial": {
                "type": "array",
                "description": "per π orbital: its Slater terms [N, zeta, c]",
                "items": {
                  "type": "array",
                  "description": "Slater terms [N, zeta (1/bohr), c] of R(r) = sum c (2 zeta)^(N+1/2)/sqrt((2N)!) r^(N-1) exp(-zeta r)",
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    },
                    "minItems": 3,
                    "maxItems": 3
                  }
                }
              }
            }
          },
          "x": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "C": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number"
              }
            }
          },
          "occ": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "homo": {
            "type": [
              "integer",
              "null"
            ]
          },
          "lumo": {
            "type": [
              "integer",
              "null"
            ]
          },
          "n_electrons": {
            "type": "number"
          },
          "bond_orders": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "PiForm": {
        "type": "object",
        "description": "Everything the browser needs to draw one form of the molecule.",
        "properties": {
          "atoms": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "el": {
                  "type": "string"
                },
                "x": {
                  "type": "number"
                },
                "y": {
                  "type": "number"
                },
                "z": {
                  "type": "number"
                },
                "Q": {
                  "type": "number",
                  "description": "net charge (π + formal)"
                },
                "formal": {
                  "type": "integer"
                },
                "pi": {
                  "type": "boolean"
                },
                "label": {
                  "type": "string"
                }
              }
            }
          },
          "bonds": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "integer"
              }
            }
          },
          "components": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PiComponent"
            }
          },
          "site": {
            "type": [
              "integer",
              "null"
            ]
          },
          "probe": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "number"
            }
          },
          "E_pi": {
            "type": "number"
          }
        }
      },
      "PkaSite": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "example": "phenol"
          },
          "type": {
            "type": "string",
            "enum": [
              "acid",
              "base"
            ]
          },
          "group_pka": {
            "oneOf": [
              {
                "type": "number"
              },
              {
                "type": "array",
                "items": {
                  "type": "number"
                }
              }
            ]
          },
          "family": {
            "type": [
              "string",
              "null"
            ]
          },
          "descriptors": {
            "type": "object",
            "properties": {
              "Q_site": {
                "type": "number"
              },
              "V_probe": {
                "type": "number"
              },
              "dE_deloc": {
                "type": "number"
              }
            }
          },
          "pi_forecast": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "pka": {
                "type": "number"
              },
              "plus_minus": {
                "type": "number"
              },
              "descriptor": {
                "type": "string"
              },
              "calibration": {
                "type": "string"
              }
            }
          },
          "outside_pi_model": {
            "type": "boolean"
          },
          "forms": {
            "type": "object",
            "properties": {
              "acid": {
                "$ref": "#/components/schemas/PiForm"
              },
              "base": {
                "$ref": "#/components/schemas/PiForm"
              }
            }
          }
        }
      },
      "PiModelResult": {
        "type": "object",
        "properties": {
          "smiles": {
            "type": "string"
          },
          "canonical_smiles": {
            "type": "string"
          },
          "inchikey": {
            "type": [
              "string",
              "null"
            ]
          },
          "formula": {
            "type": "string"
          },
          "model": {
            "type": "string",
            "example": "qo-chem/16"
          },
          "molecule": {
            "$ref": "#/components/schemas/PiForm"
          },
          "sites": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PkaSite"
            }
          },
          "calibration": {
            "type": "object"
          },
          "protonation": {
            "type": [
              "object",
              "null"
            ]
          },
          "tautomers": {
            "type": "object"
          },
          "badges": {
            "type": "object"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "provenance": {
            "type": [
              "object",
              "null"
            ]
          },
          "summary": {
            "type": "object"
          },
          "speciation": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Speciation"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Speciation": {
        "type": "object",
        "description": "Coupled titration of all ionisable sites (qo_chem.speciation). Same order as `sites`. Weights: log10 w(h) = Σ h_i (pKa_i − pH) − Σ_{i<j} W_ij q_i q_j.",
        "properties": {
          "model": {
            "type": "string"
          },
          "kinds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pka": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "description": "site pKa with every other site neutral"
          },
          "plus_minus": {
            "type": "array",
            "items": {
              "type": [
                "number",
                "null"
              ]
            },
            "description": "held-out RMSE of the site kind on IUPAC data"
          },
          "type": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "acid",
                "base"
              ]
            }
          },
          "W": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "number"
              }
            },
            "description": "pair charge term, pKa units"
          },
          "distance_bonds": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          },
          "interaction": {
            "type": "object"
          },
          "macro_pka": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "description": "macroscopic steps, ascending"
          },
          "steps": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "pka": {
                  "type": "number"
                },
                "share": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                }
              }
            }
          },
          "source": {
            "type": [
              "string",
              "null"
            ]
          },
          "attribution": {
            "type": [
              "string",
              "null"
            ]
          },
          "accuracy": {
            "type": [
              "object",
              "null"
            ]
          },
          "error": {
            "type": "string",
            "description": "present only if the model could not be built"
          }
        }
      },
      "SiteRequest": {
        "type": "object",
        "description": "One source (structure, structure_b64, gl1x or example) plus what to cut out: a motif occurrence, a metal site, or a ligand (16.5).",
        "properties": {
          "structure": {
            "type": "string",
            "description": "PDB or PDBx/mmCIF text (≤ 20 MB)."
          },
          "structure_b64": {
            "type": "string",
            "description": "Base64 bytes: BinaryCIF and/or gzip-compressed files."
          },
          "gl1x": {
            "type": "string",
            "description": "MolNFT record as <contract>/<token> or a gl1x.com record link. Alone, the server fetches the file from gl1x.com; with structure(_b64) it only labels the source.",
            "example": "0xbf7491af3407816dfa88a5ea4c82e8a2b1d721ed/1"
          },
          "example": {
            "type": "string",
            "enum": [
              "5a7u",
              "7ddo",
              "1hvr",
              "1a28",
              "19hc"
            ]
          },
          "name": {
            "type": "string"
          },
          "motif": {
            "type": "string",
            "description": "PROSITE pattern: x, x(n), x(n,m), [ST], {P}, <, >; or a bare sequence.",
            "example": "C-x(2,4)-C-x(12)-H-x(3,5)-H"
          },
          "chain": {
            "type": "string"
          },
          "occurrence": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "metal_site": {
            "type": "integer",
            "minimum": 0,
            "description": "Used when no motif is given."
          },
          "scope": {
            "type": "string",
            "enum": [
              "segment",
              "ligands"
            ],
            "default": "segment"
          },
          "metal": {
            "type": "string",
            "enum": [
              "auto",
              "refit",
              "zn",
              "none"
            ],
            "default": "auto"
          },
          "ph": {
            "type": "number",
            "minimum": 0,
            "maximum": 14,
            "default": 7.4
          },
          "list_only": {
            "type": "boolean",
            "default": false
          },
          "return_structure": {
            "type": "boolean",
            "default": false,
            "description": "Add the whole first model as PDB (or mmCIF) text under `display`."
          },
          "ligand": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "integer",
                "minimum": 0
              }
            ],
            "description": "A ligand instead of a motif: 'HEM:A:301', 'HEM A 301', 'A:301', 'HEM' (the first) or an index into `ligands`.",
            "example": "XK2:A:263"
          },
          "smiles": {
            "type": "string",
            "maxLength": 4000,
            "description": "Template SMILES for the ligand, matched onto its atoms; the page sends the CCD's."
          },
          "smiles_source": {
            "type": "string",
            "enum": [
              "ccd",
              "user",
              "name"
            ],
            "default": "ccd"
          },
          "ccd_name": {
            "type": "string"
          },
          "ccd_formula": {
            "type": "string"
          },
          "ccd": {
            "type": "boolean",
            "default": true,
            "description": "Without `smiles`, let the server fetch the CCD entry from data.rcsb.org (unless started with --no-ccd-fetch). It waits at most 5 s and, after failing to reach the RCSB, does not try again for 10 minutes."
          },
          "name_to_smiles": {
            "oneOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string",
                "enum": [
                  "always"
                ]
              }
            ],
            "default": true,
            "description": "Read the component's name with OPSIN, when the server has it: by default only when no dictionary fits the atoms (each new name starts Java); 'always' reads it as a check; false never."
          },
          "pocket": {
            "type": "boolean",
            "default": true,
            "description": "Ligand mode: add the side chains within 4.5 Å and a zinc the ligand binds."
          }
        }
      },
      "SiteResult": {
        "type": "object",
        "required": [
          "schema",
          "source",
          "structure",
          "occurrences",
          "metal_sites"
        ],
        "properties": {
          "schema": {
            "type": "string",
            "const": "qo-site/1"
          },
          "source": {
            "type": "object",
            "description": "kind (upload, gl1x, example), sha256, bytes; for GL1X the record and structure-file URLs and the collection."
          },
          "structure": {
            "type": "object",
            "description": "id, title, method, resolution, format, predicted_model, atoms, chains, metals."
          },
          "motif": {
            "type": "object"
          },
          "occurrences": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "metal_sites": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "selected": {
            "type": "object"
          },
          "site": {
            "type": "object",
            "description": "Report: residues, protonation, confidence (B-factor or pLDDT), metal with ligands, distances against Harding's targets, angles, refit or placement fit, warnings, notes."
          },
          "model": {
            "type": "object",
            "description": "Shaped like /api/model (atoms with radial_model, orbitals, bonds, pi_field, molblock, summary) plus metal_bonds: donor hybrids, angles to the metal, donor–acceptor overlaps, acceptor and open-site orbitals."
          },
          "fragment_pdb": {
            "type": "string"
          },
          "display": {
            "type": "object"
          },
          "timing_ms": {
            "type": "object"
          },
          "ligands": {
            "type": "array",
            "description": "Every non-polymer residue but water (first 400).",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "index": {
                  "type": "integer"
                },
                "comp": {
                  "type": "string"
                },
                "chain": {
                  "type": "string"
                },
                "resseq": {
                  "type": "integer"
                },
                "icode": {
                  "type": "string"
                },
                "class": {
                  "type": "string",
                  "enum": [
                    "ligand",
                    "sugar",
                    "additive",
                    "ion",
                    "metal",
                    "modified residue"
                  ]
                },
                "heavy_atoms": {
                  "type": "integer"
                },
                "name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "formula_file": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "dictionary": {
                  "type": "boolean",
                  "description": "the file carries this component's bond table"
                },
                "center": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                }
              }
            }
          },
          "ligands_total": {
            "type": "integer"
          },
          "ligand": {
            "type": "object",
            "description": "Ligand mode: which molecule it is. `routes` (file, ccd, name, user, geometry) each with smiles, same_graph, same_molecule, differences, stereo and leaving_atoms; `chosen` (route, smiles, smiles_bound, smiles_free, formulas); links, metal_contacts, pocket, polar_contacts, notes, warnings."
          },
          "free_molecule": {
            "type": "object",
            "properties": {
              "smiles": {
                "type": "string"
              },
              "source": {
                "type": "string"
              },
              "smiles_bound": {
                "type": "string"
              },
              "pages": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                },
                "description": "links to /molviewer, /molecule, /pka-density, /catalogue and /name-to-smiles"
              }
            }
          }
        }
      }
    }
  }
}