{
  "openapi": "3.1.0",
  "info": {
    "title": "Medical Bill Checker API",
    "version": "1.0.0",
    "description": "Free educational bill review. No API key is required. Use the v1 paths for new integrations; original /api/config/ and /api/analyze/ remain compatible aliases. Compatible fields may be added within v1; breaking changes use a new major path. Planned retirements will be announced on the developer page and through Deprecation and Sunset headers at least 90 days ahead. No retirement date is currently scheduled. Analysis receives medical-bill text: obtain informed user permission, omit unnecessary identifiers, and never log or publicly cache payloads. Prefer the visible checker for personal bills. Estimates are amounts to investigate, not balances or guaranteed savings. Public MCP guides and fictional examples are documented separately."
  },
  "servers": [
    {
      "url": "https://medical-bill-checker-five.vercel.app"
    }
  ],
  "externalDocs": {
    "description": "Developer, MCP and browser WebMCP documentation",
    "url": "https://medical-bill-checker-five.vercel.app/developers/"
  },
  "security": [],
  "paths": {
    "/api/v1/config/": {
      "get": {
        "operationId": "getCheckerConfiguration",
        "summary": "Read current processing availability and text limits",
        "description": "120 requests per client IP per minute, per server instance. Shares its rate counter with the unversioned /api/config/ alias. Read RateLimit and RateLimit-Policy; honor Retry-After on a 429 response.",
        "responses": {
          "200": {
            "description": "Current configuration; no-store response.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              },
              "RateLimit": {
                "description": "Current rate quota using structured fields. Per client IP and server instance.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Rate policy using structured fields. Configuration: 120 per 60 seconds; analysis: 30 per 600 seconds. Aliases share counters.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppConfig"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait for Retry-After before trying again.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              },
              "RateLimit": {
                "description": "Current rate quota using structured fields. Per client IP and server instance.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Rate policy using structured fields. Configuration: 120 per 60 seconds; analysis: 30 per 600 seconds. Aliases share counters.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/analyze/": {
      "post": {
        "operationId": "analyzeReviewedMedicalBill",
        "summary": "Review user-approved itemized bill text",
        "description": "Processes in request memory and returns a full structured report. This response may contain health information. A consent boolean is a caller assertion, not evidence of human review. Optional AI must be explicitly requested by the person after provider disclosure. Default basic checks still process text on this server. Body limit 128 KB; 30 requests per client per ten minutes; up to three concurrent analyses per server instance. Origin headers, when supplied, must be accepted by the service. No general cross-origin browser API.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnalyzeRequest"
              },
              "example": {
                "bill_text": "SYNTHETIC EXAMPLE\n2026-08-14 | 99213 | Office visit | 1 | $180.00\nTotal charges: $180.00",
                "use_ai": false,
                "consent": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Full report. Cache-Control: no-store, private. Retain warnings and estimate_ready when displaying results.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              },
              "RateLimit": {
                "description": "Current rate quota using structured fields. Per client IP and server instance.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Rate policy using structured fields. Configuration: 120 per 60 seconds; analysis: 30 per 600 seconds. Aliases share counters.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisReport"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, JSON or missing AI consent.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Origin not accepted.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 128 KB.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Content-Type must be application/json.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Bill text cannot be analyzed.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait for Retry-After before trying again.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              },
              "RateLimit": {
                "description": "Current rate quota using structured fields. Per client IP and server instance.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Rate policy using structured fields. Configuration: 120 per 60 seconds; analysis: 30 per 600 seconds. Aliases share counters.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Analysis failed.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AI unavailable or server busy.",
            "headers": {
              "X-BillCheck-API-Version": {
                "description": "API major version.",
                "schema": {
                  "type": "string",
                  "const": "1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "AppConfig": {
        "type": "object",
        "required": [
          "provider",
          "ai_available",
          "extraction_provider",
          "max_text_length",
          "max_line_items"
        ],
        "properties": {
          "provider": {
            "type": "string",
            "enum": [
              "local",
              "openai",
              "typesafe"
            ]
          },
          "ai_available": {
            "type": "boolean"
          },
          "extraction_provider": {
            "type": "string",
            "enum": [
              "local",
              "openai"
            ]
          },
          "max_text_length": {
            "type": "integer"
          },
          "max_line_items": {
            "type": "integer"
          }
        }
      },
      "AnalyzeRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "bill_text"
        ],
        "properties": {
          "bill_text": {
            "type": "string",
            "minLength": 5,
            "maxLength": 20000
          },
          "eob_text": {
            "type": "string",
            "maxLength": 20000
          },
          "use_ai": {
            "type": "boolean",
            "default": false
          },
          "consent": {
            "type": "boolean",
            "default": false,
            "description": "Required true with use_ai. Set only after the person has explicitly agreed to the disclosed AI provider processing."
          }
        }
      },
      "LineItem": {
        "type": "object",
        "required": [
          "code",
          "description",
          "units",
          "amount_usd",
          "date_of_service"
        ],
        "properties": {
          "code": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": "string"
          },
          "units": {
            "type": "number"
          },
          "amount_usd": {
            "type": "number",
            "description": "Amount in U.S. dollars. Computed by code using integer cents."
          },
          "date_of_service": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          }
        }
      },
      "BillState": {
        "type": "object",
        "required": [
          "bill",
          "eob",
          "reference"
        ],
        "properties": {
          "bill": {
            "type": "object",
            "required": [
              "line_items",
              "total_usd"
            ],
            "properties": {
              "line_items": {
                "type": "array",
                "maxItems": 40,
                "items": {
                  "$ref": "#/components/schemas/LineItem"
                }
              },
              "total_usd": {
                "type": "number",
                "description": "Amount in U.S. dollars. Computed by code using integer cents."
              }
            }
          },
          "eob": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "required": [
                  "allowed_amount_usd",
                  "patient_responsibility_usd"
                ],
                "properties": {
                  "allowed_amount_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Amount in U.S. dollars. Computed by code using integer cents."
                  },
                  "patient_responsibility_usd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Amount in U.S. dollars. Computed by code using integer cents."
                  }
                }
              }
            ]
          },
          "reference": {
            "type": "object",
            "properties": {
              "bundled_codes": {
                "type": "object",
                "additionalProperties": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      },
      "Answer": {
        "type": "object",
        "required": [
          "value",
          "confidence"
        ],
        "properties": {
          "value": {
            "type": [
              "boolean",
              "number"
            ]
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          }
        }
      },
      "Finding": {
        "type": "object",
        "required": [
          "id",
          "kind",
          "title",
          "explanation",
          "line_indices",
          "confidence",
          "label",
          "severity",
          "dollar_impact_usd",
          "included_in_estimate_usd",
          "question"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "duplicate_line_item",
              "unbundling_detected",
              "quantity_looks_wrong",
              "description_code_mismatch",
              "exceeds_allowed_amount",
              "math_error"
            ]
          },
          "title": {
            "type": "string"
          },
          "explanation": {
            "type": "string"
          },
          "line_indices": {
            "type": "array",
            "description": "Zero-based indices in state.bill.line_items.",
            "items": {
              "type": "integer",
              "minimum": 0
            }
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "label": {
            "type": "string",
            "enum": [
              "likely",
              "possible"
            ]
          },
          "severity": {
            "type": "integer",
            "enum": [
              0,
              1,
              2
            ]
          },
          "dollar_impact_usd": {
            "type": [
              "number",
              "null"
            ],
            "description": "Amount in U.S. dollars. Computed by code using integer cents."
          },
          "included_in_estimate_usd": {
            "type": "number",
            "description": "Amount in U.S. dollars. Computed by code using integer cents."
          },
          "question": {
            "type": "string"
          }
        }
      },
      "AnalysisReport": {
        "type": "object",
        "required": [
          "state",
          "findings",
          "estimated_overcharge_usd",
          "estimate_ready",
          "estimate",
          "warnings",
          "provider",
          "extraction_method",
          "total_source",
          "checks_run",
          "answers"
        ],
        "properties": {
          "state": {
            "$ref": "#/components/schemas/BillState"
          },
          "findings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Finding"
            }
          },
          "estimated_overcharge_usd": {
            "type": "number",
            "description": "Amount in U.S. dollars. Computed by code using integer cents."
          },
          "estimate_ready": {
            "type": "boolean",
            "description": "If false, the amount must not be presented as a usable estimate."
          },
          "estimate": {
            "type": "object",
            "required": [
              "duplicate_usd",
              "unbundled_usd",
              "above_allowed_usd",
              "overlap_removed_usd",
              "explanation"
            ],
            "properties": {
              "duplicate_usd": {
                "type": "number",
                "description": "Amount in U.S. dollars. Computed by code using integer cents."
              },
              "unbundled_usd": {
                "type": "number",
                "description": "Amount in U.S. dollars. Computed by code using integer cents."
              },
              "above_allowed_usd": {
                "type": "number",
                "description": "Amount in U.S. dollars. Computed by code using integer cents."
              },
              "overlap_removed_usd": {
                "type": "number",
                "description": "Amount in U.S. dollars. Computed by code using integer cents."
              },
              "explanation": {
                "type": "string"
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "provider": {
            "type": "string",
            "enum": [
              "local",
              "openai",
              "typesafe"
            ]
          },
          "extraction_method": {
            "type": "string",
            "enum": [
              "local",
              "openai"
            ]
          },
          "total_source": {
            "type": "string",
            "enum": [
              "stated",
              "calculated"
            ]
          },
          "checks_run": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "answers": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/Answer"
            }
          }
        }
      }
    }
  }
}
