{
  "openapi": "3.1.1",
  "info": {
    "title": "Electric \u0026 Magnetic Field Line Plotter API",
    "version": "1.0.0",
    "summary": "Field lines and equipotentials of point charges and current-carrying wires, with probe values.",
    "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://prooflinefieldlines.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Field lines and equipotentials of point charges and current-carrying wires, with probe values.",
        "description": "Place point charges (in nC) and long straight wires (in A) in a plane and get a drawing of the electric field lines from positive to negative charges, the magnetic field loops around the wires and the equipotential lines, traced numerically from Coulomb’s law and the Biot–Savart law. The number of lines per charge follows Gauss’s law; probe points give the exact field strength, direction, potential and magnetic flux density. Part of the Proofline math notebook.\n\nMethodology:\n- Electric field of point charges: E = Σ k·qᵢ·(r − rᵢ)/|r − rᵢ|³ with k = 1/(4πε₀) = 8.9875517923 × 10⁹ N·m²/C²; potential V = Σ k·qᵢ/|r − rᵢ|. Magnetic field of a long straight wire: |B| = μ₀·I/(2π·r), circling the wire anticlockwise for current out of the page (μ₀ = 1.25663706212 × 10⁻⁶ N/A²). Fields superpose.\n- Field lines start on a small circle around each positive charge, evenly spaced in angle, in a number proportional to the charge, and follow the unit field direction with fixed RK4 steps until they reach a negative charge or leave the view. Negative charges also send lines backwards; those that reach a positive charge are dropped as duplicates. Magnetic lines start at radii of equal flux steps and close on themselves.\n- Equipotentials are contour lines (marching squares) of V on a 161 × 121 grid at the potentials of a lone charge at fixed fractions of the view size, both signs, and V = 0.\n- Verified: E = kq/r² of a single charge (1 nC at 1 cm: 89 875.5 V/m), E = 2kq/(d/2)² midway in a dipole, B = μ₀I/(2πr) (1 A at 1 cm: 20 µT), radial lines of a single charge, and line counts in proportion to the charges (Gauss’s law).\n\nAn idealised 2-D picture: point charges in vacuum and infinitely long wires. The line density shows the field strength only qualitatively in a plane drawing of a 3-D field.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "proofline_field_lines",
        "x-owner-app": "proofline",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProoflineFieldLinesInput"
              },
              "examples": {
                "example1": {
                  "summary": "Electric dipole with probes on the axis and the bisector",
                  "value": {
                    "sources": "charge 1 -2 0\ncharge -1 2 0",
                    "probes": "0 0.0001\n0 3\n6 0"
                  }
                },
                "example2": {
                  "summary": "Two equal positive charges",
                  "value": {
                    "sources": "charge 1 -2 0\ncharge 1 2 0"
                  }
                },
                "example3": {
                  "summary": "Unequal charges: +2 nC and −1 nC",
                  "value": {
                    "sources": "charge 2 -2 0\ncharge -1 2 0"
                  }
                },
                "example4": {
                  "summary": "Two antiparallel currents (a transmission line)",
                  "value": {
                    "sources": "wire 5 -2 0\nwire -5 2 0",
                    "probes": "0 0\n0 4"
                  }
                },
                "example5": {
                  "summary": "A charged quadrupole",
                  "value": {
                    "sources": "charge 1 -2 -2\ncharge -1 2 -2\ncharge 1 2 2\ncharge -1 -2 2"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProoflineFieldLinesResult"
                }
              }
            }
          },
          "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"
                }
              }
            }
          }
        }
      },
      "ProoflineFieldLinesInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "sources": {
            "title": "Charges and wires (one per line)",
            "description": "“charge q x y” is a point charge q in nC at (x, y) in cm; “wire I x y” is a long straight wire carrying I amperes out of the page (negative: into the page). At most 16 lines; # starts a comment.",
            "type": "string",
            "maxLength": 2000
          },
          "linesPerUnit": {
            "title": "Field lines per nC (or per 2 A)",
            "type": "number",
            "minimum": 1,
            "maximum": 40,
            "default": 8
          },
          "equipotentials": {
            "title": "Draw equipotential lines",
            "type": "boolean",
            "default": true
          },
          "extent": {
            "title": "View half-height (cm)",
            "description": "Empty: fit the view around the sources.",
            "type": "number",
            "minimum": 0
          },
          "probes": {
            "title": "Probe points (optional)",
            "description": "One point per line: x and y in cm. The table lists E, the potential and B there (at most 20).",
            "type": "string",
            "maxLength": 1000,
            "default": ""
          }
        },
        "required": [
          "sources"
        ]
      },
      "ProoflineFieldLinesResult": {
        "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": [
              "sources",
              "view",
              "netCharge",
              "netCurrent",
              "lines",
              "lineCounts",
              "probes",
              "equipotentialLevels"
            ],
            "properties": {
              "sources": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "kind",
                    "value",
                    "x",
                    "y",
                    "label"
                  ],
                  "properties": {
                    "kind": {
                      "type": "string",
                      "enum": [
                        "charge",
                        "wire"
                      ]
                    },
                    "value": {
                      "type": "number"
                    },
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    },
                    "label": {
                      "type": "string"
                    }
                  }
                }
              },
              "view": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "x0",
                  "x1",
                  "y0",
                  "y1"
                ],
                "properties": {
                  "x0": {
                    "type": "number"
                  },
                  "x1": {
                    "type": "number"
                  },
                  "y0": {
                    "type": "number"
                  },
                  "y1": {
                    "type": "number"
                  }
                }
              },
              "netCharge": {
                "type": "number"
              },
              "netCurrent": {
                "type": "number"
              },
              "lines": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "field",
                    "from",
                    "to",
                    "closed",
                    "length",
                    "points"
                  ],
                  "properties": {
                    "field": {
                      "type": "string",
                      "enum": [
                        "E",
                        "B"
                      ]
                    },
                    "from": {
                      "type": "string"
                    },
                    "to": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "closed": {
                      "type": "boolean"
                    },
                    "length": {
                      "type": "number"
                    },
                    "points": {
                      "type": "integer"
                    }
                  }
                }
              },
              "lineCounts": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "source",
                    "leaving",
                    "arriving"
                  ],
                  "properties": {
                    "source": {
                      "type": "string"
                    },
                    "leaving": {
                      "type": "integer"
                    },
                    "arriving": {
                      "type": "integer"
                    }
                  }
                }
              },
              "probes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "x",
                    "y",
                    "Ex",
                    "Ey",
                    "E",
                    "V",
                    "Bx",
                    "By",
                    "B"
                  ],
                  "properties": {
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    },
                    "Ex": {
                      "type": "number"
                    },
                    "Ey": {
                      "type": "number"
                    },
                    "E": {
                      "type": "number"
                    },
                    "V": {
                      "type": "number"
                    },
                    "Bx": {
                      "type": "number"
                    },
                    "By": {
                      "type": "number"
                    },
                    "B": {
                      "type": "number"
                    }
                  }
                }
              },
              "equipotentialLevels": {
                "type": "array",
                "items": {
                  "type": "number"
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      }
    }
  }
}