{
  "openapi": "3.1.0",
  "info": {
    "title": "Peptide Calculator API",
    "version": "1.0.0",
    "description": "Programmatic reconstitution and dosage arithmetic for laboratory research. Calculates concentration, required draw volume, and insulin syringe unit markings from vial contents, diluent volume, and target dose.",
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    },
    "contact": {
      "name": "Peptide Calculator Support",
      "url": "https://peptidecalculator.live/about"
    }
  },
  "servers": [
    {
      "url": "https://peptidecalculator.live",
      "description": "Production server"
    }
  ],
  "paths": {
    "/api/reconstitute": {
      "post": {
        "summary": "Calculate reconstitution arithmetic",
        "description": "Computes solution concentration (mg/mL and mcg/mL), draw volume (mL), and insulin syringe units (U-100 and U-40) for a target peptide dose.",
        "operationId": "calculateReconstitution",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReconstitutionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation result",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Quota of requests per 60-second window (100)"
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Remaining requests in current window"
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current rate limit window resets (60)"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReconstitutionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input parameter or out-of-range value",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying request (60)"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "Calculate reconstitution via query parameters",
        "description": "Computes reconstitution parameters using URL query parameters for fast agent and script lookups without a request body.",
        "operationId": "getReconstitutionCalculation",
        "parameters": [
          {
            "name": "vialAmount",
            "in": "query",
            "required": true,
            "description": "Mass of peptide contained in the lyophilized vial",
            "schema": {
              "type": "number",
              "minimum": 0.001,
              "example": 5
            }
          },
          {
            "name": "vialUnit",
            "in": "query",
            "required": false,
            "description": "Unit of the vial mass (mg or mcg, default: mg)",
            "schema": {
              "type": "string",
              "enum": [
                "mg",
                "mcg"
              ],
              "default": "mg"
            }
          },
          {
            "name": "diluentMl",
            "in": "query",
            "required": true,
            "description": "Volume of bacteriostatic water added in millilitres",
            "schema": {
              "type": "number",
              "minimum": 0.01,
              "maximum": 100,
              "example": 2
            }
          },
          {
            "name": "doseAmount",
            "in": "query",
            "required": true,
            "description": "Target dose amount to draw per administration",
            "schema": {
              "type": "number",
              "minimum": 0.001,
              "example": 250
            }
          },
          {
            "name": "doseUnit",
            "in": "query",
            "required": false,
            "description": "Unit of target dose (mcg or mg, default: mcg)",
            "schema": {
              "type": "string",
              "enum": [
                "mcg",
                "mg"
              ],
              "default": "mcg"
            }
          },
          {
            "name": "syringe",
            "in": "query",
            "required": false,
            "description": "Insulin syringe calibration scale (u100 or u40, default: u100)",
            "schema": {
              "type": "string",
              "enum": [
                "u100",
                "u40"
              ],
              "default": "u100"
            }
          },
          {
            "name": "vialCost",
            "in": "query",
            "required": false,
            "description": "Optional monetary price of the vial to compute cost per dose",
            "schema": {
              "type": "number",
              "minimum": 0.01,
              "example": 40
            }
          },
          {
            "name": "dosesPerWeek",
            "in": "query",
            "required": false,
            "description": "Optional injection frequency in doses per week",
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 21,
              "example": 2
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReconstitutionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input parameter or out-of-range value",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "summary": "API health check and capability metadata",
        "description": "Returns service status, version, and links to documentation.",
        "operationId": "getApiHealth",
        "responses": {
          "200": {
            "description": "API is healthy and operational",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ReconstitutionRequest": {
        "type": "object",
        "required": [
          "vialAmount",
          "diluentMl",
          "doseAmount"
        ],
        "properties": {
          "vialAmount": {
            "type": "number",
            "description": "Amount of peptide in the vial (e.g. 5 for 5 mg)",
            "example": 5
          },
          "vialUnit": {
            "type": "string",
            "enum": [
              "mg",
              "mcg"
            ],
            "default": "mg",
            "description": "Mass unit of the vial contents",
            "example": "mg"
          },
          "diluentMl": {
            "type": "number",
            "description": "Volume of bacteriostatic water added in millilitres",
            "example": 2
          },
          "doseAmount": {
            "type": "number",
            "description": "Target dose per administration",
            "example": 250
          },
          "doseUnit": {
            "type": "string",
            "enum": [
              "mcg",
              "mg"
            ],
            "default": "mcg",
            "description": "Unit of target dose",
            "example": "mcg"
          },
          "syringe": {
            "type": "string",
            "enum": [
              "u100",
              "u40"
            ],
            "default": "u100",
            "description": "Insulin syringe scale type",
            "example": "u100"
          },
          "vialCost": {
            "type": "number",
            "description": "Optional total price of vial in currency units",
            "example": 50
          },
          "dosesPerWeek": {
            "type": "number",
            "description": "Optional planned dosing frequency per week",
            "example": 1
          }
        }
      },
      "ReconstitutionResponse": {
        "type": "object",
        "required": [
          "concentrationMgPerMl",
          "concentrationMcgPerMl",
          "drawVolumeMl",
          "syringeUnits",
          "syringeUnitsRounded",
          "dosesPerVial"
        ],
        "properties": {
          "concentrationMgPerMl": {
            "type": "number",
            "description": "Calculated concentration in milligrams per millilitre",
            "example": 2.5
          },
          "concentrationMcgPerMl": {
            "type": "number",
            "description": "Calculated concentration in micrograms per millilitre",
            "example": 2500
          },
          "mcgPerUnit": {
            "type": "number",
            "description": "Micrograms delivered per single syringe unit mark",
            "example": 25
          },
          "drawVolumeMl": {
            "type": "number",
            "description": "Required liquid volume to draw in millilitres",
            "example": 0.1
          },
          "syringeUnits": {
            "type": "number",
            "description": "Exact syringe unit mark corresponding to draw volume",
            "example": 10
          },
          "syringeUnitsRounded": {
            "type": "number",
            "description": "Syringe unit mark rounded to nearest half-unit",
            "example": 10
          },
          "deliveredMcgAtRounded": {
            "type": "number",
            "description": "Actual microgram dose delivered at rounded mark",
            "example": 250
          },
          "dosesPerVial": {
            "type": "integer",
            "description": "Number of full doses available in the vial",
            "example": 20
          },
          "remainderMcg": {
            "type": "number",
            "description": "Leftover peptide mass after all full doses are drawn",
            "example": 0
          },
          "costPerDose": {
            "type": "number",
            "description": "Cost per dose if vialCost was provided"
          },
          "daysPerVial": {
            "type": "number",
            "description": "Estimated day supply if dosesPerWeek was provided"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Safety warnings (e.g. units-rounded, draw-very-small, concentration-very-high)"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "resolution"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable error identifier",
                "example": "INVALID_INPUT"
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation of what went wrong",
                "example": "diluentMl must be a positive number."
              },
              "resolution": {
                "type": "string",
                "description": "Direct actionable guidance for agents or callers to resolve the issue",
                "example": "Provide a valid diluentMl between 0.01 and 100 mL."
              }
            }
          }
        }
      },
      "HealthResponse": {
        "type": "object",
        "required": [
          "status",
          "service",
          "version"
        ],
        "properties": {
          "status": {
            "type": "string",
            "example": "pass"
          },
          "service": {
            "type": "string",
            "example": "Peptide Calculator API"
          },
          "version": {
            "type": "string",
            "example": "1.0.0"
          },
          "openapi": {
            "type": "string",
            "example": "/openapi.json"
          },
          "documentation": {
            "type": "string",
            "example": "https://peptidecalculator.live/about#agents"
          }
        }
      }
    }
  }
}