{
  "openapi": "3.1.1",
  "info": {
    "title": "Chemical Equation Balancer & Stoichiometry API",
    "version": "1.0.0",
    "summary": "Balance any reaction or redox equation exactly, then find the limiting reagent and yields.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://prooflinereactionbalancer.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Balance any reaction or redox equation exactly, then find the limiting reagent and yields.",
        "description": "Type a reaction such as C3H8 + O2 -> CO2 + H2O or an ionic redox equation such as MnO4- + Fe+2 + H+ -> Mn+2 + Fe+3 + H2O and get the smallest whole-number coefficients, computed exactly from the null space of the composition matrix. The tool tells you when a reaction cannot be balanced, when a species does not take part and when the species allow several independent reactions. Add starting masses or amounts to get the limiting reagent, the theoretical yield of every product, the leftovers and your percentage yield. Part of the Proofline math notebook.\n\nMethodology:\n- Each species becomes a column of the composition matrix A: its atom count per element (isotopes as separate elements) and its charge, positive for reactants and negative for products. Balanced coefficients ν satisfy A·ν = 0.\n- The null space of A is computed exactly: rational Gaussian elimination with arbitrary-precision fractions to the reduced row echelon form, one basis vector per free column, scaled to the smallest whole numbers (no floating point, so large redox equations stay exact).\n- Nullity 1 with all coefficients positive is a unique balanced equation. Nullity 0 means no balance exists; a zero entry means a species cannot take part; mixed signs mean a species belongs on the other side. Nullity above 1 means several independent reactions: the basis is listed, and the positive combination with the smallest coefficients (small integer multiples of the basis) is shown as one possibility.\n- Stoichiometry: amounts n = m / M; the extent ξ = min(nᵢ / νᵢ) over the reactants given, which identifies the limiting reagent; every species reacts or forms νᵢ·ξ, leftovers are nᵢ − νᵢ·ξ, and the percentage yield is actual ÷ theoretical × 100.\n\nBalancing conserves atoms and charge; it does not tell whether a reaction actually happens, how fast, or what else forms. Real yields depend on equilibrium, side reactions and losses. Nothing here is advice on handling chemicals safely.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "proofline_reaction_balancer",
        "x-owner-app": "proofline",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProoflineReactionBalancerInput"
              },
              "examples": {
                "example1": {
                  "summary": "Combustion of propane",
                  "value": {
                    "equation": "C3H8 + O2 -> CO2 + H2O"
                  }
                },
                "example2": {
                  "summary": "Permanganate oxidises iron(II) in acid (redox, ionic)",
                  "value": {
                    "equation": "MnO4- + Fe+2 + H+ -> Mn+2 + Fe+3 + H2O"
                  }
                },
                "example3": {
                  "summary": "Potassium permanganate and hydrochloric acid",
                  "value": {
                    "equation": "KMnO4 + HCl = KCl + MnCl2 + H2O + Cl2"
                  }
                },
                "example4": {
                  "summary": "Dichromate half-reaction with electrons",
                  "value": {
                    "equation": "Cr2O7^2- + H+ + e- -> Cr^3+ + H2O"
                  }
                },
                "example5": {
                  "summary": "Blast furnace: limiting reagent and percentage yield",
                  "value": {
                    "equation": "Fe2O3 + CO -> Fe + CO2",
                    "amounts": "Fe2O3 = 100 g, CO = 50 g",
                    "actualYield": "Fe = 60 g"
                  }
                },
                "example6": {
                  "summary": "Copper and nitric acid: two independent reactions",
                  "value": {
                    "equation": "Cu + HNO3 -> Cu(NO3)2 + NO + NO2 + H2O"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProoflineReactionBalancerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ProoflineReactionBalancerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "equation": {
            "title": "Reaction",
            "description": "Reactants, an arrow (-> = → or <=>), then products, separated by “ + ”. Write charges at the end of ions (Fe+2, MnO4-, SO4^2-) and electrons as e-. Element symbols with counts (H2O), brackets ( ) and [ ] that may nest (K4[Fe(CN)6]), hydrates with · or * or a dot (CuSO4·5H2O), charges at the end (SO4^2-, Fe+3, NH4+), isotopes (^13C, D, T) and state symbols such as (aq), which are ignored. Coefficients you type are checked and replaced by the balanced ones.",
            "type": "string",
            "maxLength": 2000
          },
          "amounts": {
            "title": "Starting amounts of reactants (optional)",
            "description": "Each reactant with a mass (g, mg, kg) or an amount (mol, mmol). Reactants left out are assumed to be in excess.",
            "type": "string",
            "maxLength": 2000,
            "default": ""
          },
          "actualYield": {
            "title": "Actual yield (optional)",
            "description": "The amount of a product you obtained, to calculate the percentage yield.",
            "type": "string",
            "maxLength": 1000,
            "default": ""
          }
        },
        "required": [
          "equation"
        ]
      },
      "ProoflineReactionBalancerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "status",
              "coefficients",
              "species",
              "equation",
              "equationPretty",
              "elements",
              "matrix",
              "rank",
              "nullity",
              "independentReactions",
              "givenBalanced",
              "check",
              "message",
              "stoichiometry"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "balanced",
                  "multiple",
                  "impossible",
                  "zero-coefficient",
                  "wrong-side"
                ]
              },
              "coefficients": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "type": "integer"
                }
              },
              "species": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "formula",
                    "pretty",
                    "side",
                    "coefficient",
                    "givenCoefficient",
                    "molarMass"
                  ],
                  "properties": {
                    "formula": {
                      "type": "string"
                    },
                    "pretty": {
                      "type": "string"
                    },
                    "side": {
                      "type": "string",
                      "enum": [
                        "reactant",
                        "product"
                      ]
                    },
                    "coefficient": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "givenCoefficient": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "molarMass": {
                      "type": "number"
                    }
                  }
                }
              },
              "equation": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "equationPretty": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "elements": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "matrix": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "integer"
                  }
                },
                "description": "Composition matrix: one row per element (and charge), one column per species; reactants positive, products negative."
              },
              "rank": {
                "type": "integer"
              },
              "nullity": {
                "type": "integer",
                "description": "Number of independent reactions (dimension of the null space)."
              },
              "independentReactions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "coefficients",
                    "equation"
                  ],
                  "properties": {
                    "coefficients": {
                      "type": "array",
                      "items": {
                        "type": "integer"
                      }
                    },
                    "equation": {
                      "type": "string"
                    }
                  }
                }
              },
              "givenBalanced": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "check": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "key",
                    "label",
                    "reactants",
                    "products"
                  ],
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "label": {
                      "type": "string"
                    },
                    "reactants": {
                      "type": "number"
                    },
                    "products": {
                      "type": "number"
                    }
                  }
                }
              },
              "message": {
                "type": "string"
              },
              "stoichiometry": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "extent",
                  "limiting",
                  "rows"
                ],
                "properties": {
                  "extent": {
                    "type": "number"
                  },
                  "limiting": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "rows": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "formula",
                        "side",
                        "coefficient",
                        "molarMass",
                        "givenMol",
                        "givenG",
                        "reactingMol",
                        "reactingG",
                        "remainingMol",
                        "remainingG",
                        "limiting",
                        "actualG",
                        "percentYield"
                      ],
                      "properties": {
                        "formula": {
                          "type": "string"
                        },
                        "side": {
                          "type": "string",
                          "enum": [
                            "reactant",
                            "product"
                          ]
                        },
                        "coefficient": {
                          "type": "integer"
                        },
                        "molarMass": {
                          "type": "number"
                        },
                        "givenMol": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "givenG": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "reactingMol": {
                          "type": "number"
                        },
                        "reactingG": {
                          "type": "number"
                        },
                        "remainingMol": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "remainingG": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "limiting": {
                          "type": "boolean"
                        },
                        "actualG": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "percentYield": {
                          "type": [
                            "number",
                            "null"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}