{
  "openapi": "3.0.3",
  "info": {
    "title": "BiopharmaWatch API",
    "version": "2.0.0",
    "description": "Build with the BiopharmaWatch API. Access the entire BiopharmaWatch data platform directly from your code, and power your quant models, trading systems, and research dashboards with institutional-grade biotech data.\n\nAuthentication: pass your API key as the `apiKey` query parameter on every request.\n\nBiopharmaWatch API Basic includes the complete FDA calendar with upcoming clinical readouts and PDUFA dates, Probability of Approval (PoA) summaries and deep scorecards, 5+ years of PDUFA decisions with outcomes, historical catalyst data with price movements, the auto-updated clinical-pipeline database, SEC financial-health signals (runway, burn, dilution, distress), unusual-volume alerts, the company universe, holders and gainers/losers.\n\nBiopharmaWatch API Elite Plus adds the full proprietary signal layer: company and pipeline scoring with risk-adjusted NPV (rNPV), M&A target scores, deal tracker and acquirer leaderboard, pipeline-health grades and competitive landscape intelligence, Smart Money hedge-fund positioning and insider activity, conviction-weighted hedge-fund sentiment, proprietary machine-learning clinical-trial results and risk signals, FDA designations, approvals and adverse-event signals, options flow and put-call analytics, and analyst ratings with price targets.\n\nRate limits: 100 requests/min on Basic and 1,000 requests/min on Elite Plus, plus the per-endpoint per-minute limits noted on each operation."
  },
  "servers": [
    {
      "url": "https://api.biopharmawatch.com"
    }
  ],
  "tags": [
    {
      "name": "API Basic",
      "description": "Included in BiopharmaWatch API Basic and Elite Plus."
    },
    {
      "name": "Elite Plus",
      "description": "BiopharmaWatch API Elite Plus only."
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "query",
        "name": "apiKey"
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/api/v2/pdufa/historical": {
      "get": {
        "summary": "Historical PDUFA decisions: rows from the HISTORICAL_PDUFA collection whose 'PDUFA Date' is on or before today, joined to the company name from tblcompanies.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 300s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 300
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number. Page size is fixed at 50 (skip = (page-1)*50, applied inside the $facet). Defaults to 1."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on the Ticker field."
          },
          {
            "name": "drug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on the Drug field."
          },
          {
            "name": "company",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on the joined company name (pdufaCompanies.name from the tblcompanies $lookup)."
          },
          {
            "name": "indication",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on the Indication field."
          },
          {
            "name": "pdufadate",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on 'PDUFA Date' (string, YYYY-MM-DD form as stored). Added in addition to the always-applied <= today constraint."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "string",
                            "description": "Mongo document id. NOT excluded in the $project (no _id:0), so it is returned."
                          },
                          "Ticker": {
                            "type": "string",
                            "description": "Stock ticker symbol."
                          },
                          "Drug": {
                            "type": "string",
                            "description": "Drug name."
                          },
                          "Indication": {
                            "type": "string",
                            "description": "Indication / condition treated."
                          },
                          "PDUFA Date": {
                            "type": "string",
                            "description": "PDUFA decision date (string field; results always filtered to <= today and sorted descending)."
                          },
                          "Decision": {
                            "type": "string",
                            "description": "FDA decision outcome for the PDUFA."
                          },
                          "name": {
                            "type": "string",
                            "description": "Company name from the tblcompanies join (mapped from pdufaCompanies.name)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/pdufa/upcoming": {
      "get": {
        "summary": "Upcoming FDA filing/decision catalysts (catalyst in BLA Filing, NDA Filing, PDUFA Date) from the FDA_CALENDAR collection dated today or later.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 300s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 300
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; pageSize is 50 (from getPagination). Echoed in the pagination object. NOTE: this endpoint applies NO $skip/$limit/$facet stage, so the FULL filtered set is returned and pagination.total = returned array length, regardless of page."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on ticker."
          },
          {
            "name": "drug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on drugname."
          },
          {
            "name": "treatment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on treatment."
          },
          {
            "name": "catalyst",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on catalyst, AND-ed with the base constraint catalyst in [BLA Filing, NDA Filing, PDUFA Date] (so it can only narrow within that set)."
          },
          {
            "name": "pdufadate",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on catdate."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Stock ticker symbol."
                          },
                          "drugname": {
                            "type": "string",
                            "description": "Drug name."
                          },
                          "catdate": {
                            "type": "string",
                            "description": "Catalyst date (display string)."
                          },
                          "catalyst": {
                            "type": "string",
                            "description": "Catalyst type; base $match constrains to 'BLA Filing', 'NDA Filing', or 'PDUFA Date'."
                          },
                          "stage": {
                            "type": "string",
                            "description": "Clinical / regulatory stage."
                          },
                          "decision": {
                            "type": "string",
                            "description": "Decision field (if present on the document)."
                          },
                          "treatment": {
                            "type": "string",
                            "description": "Treatment / indication."
                          },
                          "description": {
                            "type": "string",
                            "description": "Catalyst description text."
                          },
                          "probabiity_of_approval": {
                            "type": "object",
                            "description": "Probability-of-approval object, returned whole (field name spelled 'probabiity_of_approval' as stored in the DB)."
                          },
                          "drugType": {
                            "type": "string",
                            "description": "Drug type / modality classification."
                          },
                          "therapeuticArea": {
                            "type": "string",
                            "description": "Therapeutic area."
                          },
                          "predicted_iv": {
                            "type": "number",
                            "description": "Predicted implied volatility for the catalyst."
                          },
                          "formattedDate": {
                            "type": "string",
                            "description": "Normalized catalyst date (YYYY-MM-DD); filtered to >= today and sorted descending."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/catalystsync": {
      "get": {
        "summary": "Clinical-trial catalyst sync: trials from the Clinical Trials collection, sorted ascending by a parsed CompletionDate.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; page size fixed at 50 (skip = (page-1)*50, applied inside the $facet). Defaults to 1."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on ticker."
          },
          {
            "name": "phase",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on Phase."
          },
          {
            "name": "condition",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex match on Condition (new RegExp(value, 'i'))."
          },
          {
            "name": "interventionName",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex match on InterventionName ($regex with $options: 'i')."
          },
          {
            "name": "completionDate",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on the CompletionDate string field (matched against the raw string, not the parsed date)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "LeadSponsorName": {
                            "type": "string",
                            "description": "Lead sponsor (company) of the trial."
                          },
                          "CompletionDate": {
                            "type": "string",
                            "description": "Trial completion date (raw string as stored)."
                          },
                          "Condition": {
                            "type": "string",
                            "description": "Condition / indication studied."
                          },
                          "InterventionName": {
                            "type": "string",
                            "description": "Intervention / drug name."
                          },
                          "BriefTitle": {
                            "type": "string",
                            "description": "Brief title of the trial."
                          },
                          "nctId": {
                            "type": "string",
                            "description": "ClinicalTrials.gov NCT identifier."
                          },
                          "Phase": {
                            "type": "string",
                            "description": "Trial phase."
                          },
                          "ticker": {
                            "type": "string",
                            "description": "Mapped stock ticker."
                          },
                          "primaryOutcomes": {
                            "type": "string",
                            "description": "Primary outcome measure(s)."
                          },
                          "secondaryOutcomes": {
                            "type": "string",
                            "description": "Secondary outcome measure(s)."
                          },
                          "updatedAt": {
                            "type": "string",
                            "description": "Last-updated timestamp of the trial record."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/fdacalendar": {
      "get": {
        "summary": "Upcoming FDA catalyst calendar (catalysts dated today or later) from FDA_CALENDAR, enriched with company financial/insider fields from tblcompanies.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 120s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 120
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; page size fixed at 50 (skip = (page-1)*50, applied inside the $facet). Defaults to 1."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on ticker."
          },
          {
            "name": "drug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex match on drugname ($regex with $options: 'i')."
          },
          {
            "name": "phase",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on stage."
          },
          {
            "name": "catalyst",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on catalyst."
          },
          {
            "name": "treatment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex match on treatment ($regex with $options: 'i')."
          },
          {
            "name": "catdate",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on catdate."
          },
          {
            "name": "catdateFrom",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Lower bound on formattedDate. Accepts YYYY, YYYY-MM, or YYYY-MM-DD (normalized to period start). Returns HTTP 400 'Invalid catdateFrom' if it cannot be parsed."
          },
          {
            "name": "catdateTo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Upper bound on formattedDate. Accepts YYYY, YYYY-MM, or YYYY-MM-DD (normalized to period end). Returns HTTP 400 'Invalid catdateTo' if it cannot be parsed."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Point-in-time. Returns the calendar as recorded on or before this date (YYYY-MM-DD): catalysts whose createdDate is on or before as_of. createdDate is organic from ~February 2025, so point-in-time is meaningful from then forward; rows with no createdDate are excluded. Use the same as_of on /fdacalendar and /fdacalendar/historical to reconstruct the forward calendar as it stood on that date."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Stock ticker symbol."
                          },
                          "name": {
                            "type": "string",
                            "description": "Company name from the tblcompanies join (mapped from combinedData.name; scalar because of the $unwind)."
                          },
                          "drugname": {
                            "type": "string",
                            "description": "Drug name."
                          },
                          "catdate": {
                            "type": "string",
                            "description": "Catalyst date (display string)."
                          },
                          "stage": {
                            "type": "string",
                            "description": "Clinical / regulatory stage."
                          },
                          "treatment": {
                            "type": "string",
                            "description": "Treatment / indication."
                          },
                          "description": {
                            "type": "string",
                            "description": "Catalyst description text."
                          },
                          "catalyst": {
                            "type": "string",
                            "description": "Catalyst type."
                          },
                          "poa": {
                            "type": "number",
                            "description": "Probability of approval percent (mapped from probabiity_of_approval.poa_%)."
                          },
                          "poa_summary": {
                            "type": "string",
                            "description": "Probability-of-approval summary (mapped from probabiity_of_approval.poa_summary)."
                          },
                          "market_analysis": {
                            "type": "string",
                            "description": "Market analysis content for the catalyst."
                          },
                          "regulatory_designations": {
                            "type": "string",
                            "description": "Regulatory designations (e.g. ODD, Fast Track, Breakthrough)."
                          },
                          "regulatory_designations_active": {
                            "type": "string",
                            "description": "Currently active regulatory designations."
                          },
                          "key_risks": {
                            "type": "string",
                            "description": "Key risks for the catalyst."
                          },
                          "upcoming_catalysts": {
                            "type": "string",
                            "description": "Related upcoming catalysts."
                          },
                          "therapeuticArea": {
                            "type": "string",
                            "description": "Therapeutic area."
                          },
                          "drugType": {
                            "type": "string",
                            "description": "Drug type / modality."
                          },
                          "createdDate": {
                            "type": "string",
                            "description": "Date the catalyst record was created."
                          },
                          "avgInsiderTransactions": {
                            "type": "number",
                            "description": "Average insider transactions (mapped from combinedData.avgInsiderTransactions)."
                          },
                          "Industry": {
                            "type": "string",
                            "description": "Industry classification (mapped from combinedData.Industry)."
                          },
                          "Monthly_Burn_Rate": {
                            "type": "number",
                            "description": "Monthly cash burn (mapped from combinedData.Monthly_Burn_Rate)."
                          },
                          "Cash_and_Cash_Equivalents": {
                            "type": "number",
                            "description": "Cash and equivalents (mapped from combinedData.Cash_and_Cash_Equivalents)."
                          },
                          "Short_percent_of_Float": {
                            "type": "number",
                            "description": "Short interest as percent of float (mapped from combinedData.Short_percent_of_Float)."
                          },
                          "formattedDate": {
                            "type": "string",
                            "description": "Normalized catalyst date (YYYY-MM-DD); base-filtered to >= today and sorted descending."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/fdacalendar/historical": {
      "get": {
        "summary": "Historical FDA catalyst calendar from HISTORICAL_FDA_CALENDAR, with a realized percent move (created-day vs catalyst-day price) computed per catalyst.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; page size fixed at 50 (skip = (page-1)*50, applied inside the $facet). Defaults to 1."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on ticker."
          },
          {
            "name": "drug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex match on drugname ($regex with $options: 'i')."
          },
          {
            "name": "phase",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on stage."
          },
          {
            "name": "catalyst",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on catalyst."
          },
          {
            "name": "treatment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex match on treatment ($regex with $options: 'i')."
          },
          {
            "name": "catdate",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Exact match on catdate."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Point-in-time. Returns the calendar as recorded on or before this date (YYYY-MM-DD): catalysts whose createdDate is on or before as_of. createdDate is organic from ~February 2025, so point-in-time is meaningful from then forward; rows with no createdDate are excluded. Use the same as_of on /fdacalendar and /fdacalendar/historical to reconstruct the forward calendar as it stood on that date."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "string",
                            "description": "Mongo document id. NOT excluded in the $project (no _id:0), so it is returned."
                          },
                          "ticker": {
                            "type": "string",
                            "description": "Stock ticker symbol."
                          },
                          "name": {
                            "type": "array",
                            "description": "Company name(s) from the tblcompanies join. The $lookup is done WITHOUT a $unwind, so combinedData is an array and name (= combinedData.name) resolves to an array of names (typically a single element, or empty if no company matched)."
                          },
                          "catalyst": {
                            "type": "string",
                            "description": "Catalyst type."
                          },
                          "drugname": {
                            "type": "string",
                            "description": "Drug name."
                          },
                          "catdate": {
                            "type": "string",
                            "description": "Catalyst date (display string)."
                          },
                          "createdDayPrice": {
                            "type": "number",
                            "description": "Stock price on the catalyst record's created date (mapped from createdDatePrice)."
                          },
                          "catalystDayPrice": {
                            "type": "number",
                            "description": "Stock price on the catalyst day."
                          },
                          "percentageChange": {
                            "type": "number",
                            "description": "Realized percent move = (catalystDayPrice - createdDatePrice)/createdDatePrice * 100; null if either price is null (computed in $addFields)."
                          },
                          "poa": {
                            "type": "number",
                            "description": "Probability of approval percent (mapped from probabiity_of_approval.poa_%)."
                          },
                          "poa_summary": {
                            "type": "string",
                            "description": "Probability-of-approval summary (mapped from probabiity_of_approval.poa_summary)."
                          },
                          "market_analysis": {
                            "type": "string",
                            "description": "Market analysis content for the catalyst."
                          },
                          "regulatory_designations": {
                            "type": "string",
                            "description": "Regulatory designations."
                          },
                          "regulatory_designations_active": {
                            "type": "string",
                            "description": "Currently active regulatory designations."
                          },
                          "key_risks": {
                            "type": "string",
                            "description": "Key risks for the catalyst."
                          },
                          "upcoming_catalysts": {
                            "type": "string",
                            "description": "Related upcoming catalysts."
                          },
                          "therapeuticArea": {
                            "type": "string",
                            "description": "Therapeutic area."
                          },
                          "drugType": {
                            "type": "string",
                            "description": "Drug type / modality."
                          },
                          "stage": {
                            "type": "string",
                            "description": "Clinical / regulatory stage."
                          },
                          "treatment": {
                            "type": "string",
                            "description": "Treatment / indication."
                          },
                          "description": {
                            "type": "string",
                            "description": "Catalyst description text."
                          },
                          "createdDate": {
                            "type": "string",
                            "description": "Date we first recorded this catalyst (YYYY/MM/DD). The point-in-time anchor used by as_of."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/fda/designations": {
      "get": {
        "summary": "FDA special designations (Orphan Drug, Breakthrough Therapy, Fast Track, RMAT, Priority Review, etc.) granted to drug candidates, enriched with the company name from tblcompanies (ticker -> symbol) and sorted newest-designation-first.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number for pagination, parsed via parseInt(query.page) || 1, so missing or non-numeric values default to 1. Page size is fixed at 50 records server-side (getPagination hardcodes pageSize=50); it is not client-tunable. Paging is implemented in the Mongo $facet as { $skip: (page-1)*50, $limit: 50 }."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single company ticker symbol. Upper-cased server-side (req.query.ticker.toUpperCase()), then matched for exact equality against the 'ticker' field. Optional; the endpoint returns all designations across companies when omitted."
          },
          {
            "name": "designation_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex (substring) filter on the designation_type field, e.g. 'orphan', 'breakthrough', 'fast track'. Applied as { $regex: value, $options: 'i' }."
          },
          {
            "name": "drug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex (substring) filter on the drug_name field. Applied as { $regex: value, $options: 'i' }."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Company ticker symbol associated with the designation (projected from the source document's ticker field)."
                          },
                          "company_name": {
                            "type": "string",
                            "description": "Company name, looked up from tblcompanies by ticker -> symbol ($lookup + $unwind with preserveNullAndEmptyArrays). Projected as $company.name; null/absent when no matching company is found."
                          },
                          "drug_name": {
                            "type": "string",
                            "description": "Name of the drug candidate that received the designation."
                          },
                          "designation_type": {
                            "type": "string",
                            "description": "Type of FDA designation (e.g. Orphan Drug, Breakthrough Therapy, Fast Track, RMAT, Priority Review)."
                          },
                          "designation_date": {
                            "type": "string",
                            "description": "Date the designation was granted. Results are sorted by this field descending (newest first)."
                          },
                          "indication": {
                            "type": "string",
                            "description": "Disease/condition the designated drug targets."
                          },
                          "nctId": {
                            "type": "string",
                            "description": "ClinicalTrials.gov NCT identifier linked to the designated drug, when available."
                          },
                          "status": {
                            "type": "string",
                            "description": "Current status of the designation record."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/fda/approvals": {
      "get": {
        "summary": "Historical FDA approval records (approved NDAs/BLAs) for drugs, enriched with the company name from tblcompanies (ticker -> symbol) and sorted newest-approval-first.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number for pagination, parsed via parseInt(query.page) || 1 (missing/non-numeric defaults to 1). Page size is fixed at 50 records server-side; not client-tunable. Paging via $facet { $skip: (page-1)*50, $limit: 50 }."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single company ticker symbol. Upper-cased server-side, then matched for exact equality against the 'ticker' field."
          },
          {
            "name": "drug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex (substring) filter on the drug_name field. Applied as { $regex: value, $options: 'i' }."
          },
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to approvals in a given year. Applied as an anchored regex { approval_date: { $regex: `^<year>` } } against the approval_date string, selecting records whose approval_date begins with the given prefix (e.g. '2024'). It is a string-prefix match, not a numeric range; pass a 4-digit year string."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Company ticker symbol associated with the approval."
                          },
                          "company_name": {
                            "type": "string",
                            "description": "Company name, looked up from tblcompanies by ticker -> symbol ($lookup + $unwind preserveNullAndEmptyArrays). Projected as $company.name; null/absent when no matching company is found."
                          },
                          "drug_name": {
                            "type": "string",
                            "description": "Name of the approved drug."
                          },
                          "approval_date": {
                            "type": "string",
                            "description": "Date the FDA approval was granted. Results are sorted by this field descending (newest first); also the field the 'year' filter matches against."
                          },
                          "indication": {
                            "type": "string",
                            "description": "Approved indication / condition the drug treats."
                          },
                          "application_type": {
                            "type": "string",
                            "description": "FDA application type for the approval (e.g. NDA, BLA)."
                          },
                          "submission_type": {
                            "type": "string",
                            "description": "Submission type/classification of the application."
                          },
                          "review_designation": {
                            "type": "string",
                            "description": "Review designation/pathway (e.g. Priority Review, Standard)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/fda/adverse-events": {
      "get": {
        "summary": "FDA adverse event reports linked to drugs/companies, enriched with the company name from tblcompanies (ticker -> symbol) and sorted newest-event-first.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number for pagination, parsed via parseInt(query.page) || 1 (missing/non-numeric defaults to 1). Page size is fixed at 50 records server-side; not client-tunable. Paging via $facet { $skip: (page-1)*50, $limit: 50 }."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single company ticker symbol. Upper-cased server-side, then matched for exact equality against the 'ticker' field."
          },
          {
            "name": "drug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex (substring) filter on the drug_name field. Applied as { $regex: value, $options: 'i' }."
          },
          {
            "name": "severity",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex (substring) filter on the severity field, e.g. 'serious', 'severe'. Applied as { $regex: value, $options: 'i' }."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Company ticker symbol associated with the adverse event report."
                          },
                          "company_name": {
                            "type": "string",
                            "description": "Company name, looked up from tblcompanies by ticker -> symbol ($lookup + $unwind preserveNullAndEmptyArrays). Projected as $company.name; null/absent when no matching company is found."
                          },
                          "drug_name": {
                            "type": "string",
                            "description": "Name of the drug the adverse event was reported against."
                          },
                          "event_date": {
                            "type": "string",
                            "description": "Date of the adverse event report. Results are sorted by this field descending (newest first)."
                          },
                          "adverse_event": {
                            "type": "string",
                            "description": "Description of the reported adverse event / reaction."
                          },
                          "severity": {
                            "type": "string",
                            "description": "Reported severity of the event."
                          },
                          "outcome": {
                            "type": "string",
                            "description": "Reported outcome of the event (e.g. hospitalization, recovery, death)."
                          },
                          "report_type": {
                            "type": "string",
                            "description": "Type/source classification of the adverse event report."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/clinical-trials/results": {
      "get": {
        "summary": "Clinical trial result and readout announcements mapped to tickers (Clinical Trial Results dataset): drug, phase, indications, a bulleted results summary, date and source link.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single stock ticker. Upper-cased server-side (toUpperCase), exact match on the 'ticker' field."
          },
          {
            "name": "phase",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by trial phase. Case-insensitive regex (substring, $options:'i') match on the 'phase' field (e.g. 'Phase 3')."
          },
          {
            "name": "condition",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by condition/indication. Case-insensitive regex (substring, $options:'i') match on the 'condition' field."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number for pagination (getPagination). Page size is fixed at 50 records ($skip/$limit). Defaults to 1 if absent or non-numeric (parseInt(query.page) || 1)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Stock ticker."
                          },
                          "drug_name": {
                            "type": "string",
                            "description": "Drug or program name(s) covered by the announcement."
                          },
                          "trial_title": {
                            "type": "string",
                            "description": "Title of the result or readout announcement."
                          },
                          "phase": {
                            "type": "string",
                            "description": "Clinical trial phase (e.g. Phase 1/2, Phase 2, Phase 3)."
                          },
                          "indications": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Indications or conditions addressed."
                          },
                          "results_summary": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Bulleted summary of the reported results."
                          },
                          "date": {
                            "type": "string",
                            "description": "Announcement / readout date (YYYY-MM-DD)."
                          },
                          "link": {
                            "type": "string",
                            "description": "Source URL for the announcement."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/sec/company-health": {
      "get": {
        "summary": "SEC-derived financial health scorecard per biotech ticker (runway, burn, liquidity, dilution risk, risk level).",
        "description": "Returns a paginated list of company financial-health records derived from SEC filings (collection sec_company_health), $lookup-joined to tblcompanies (on ticker = symbol) for company_name and basic market cap. Each record carries a categorical risk_level (CRITICAL/DISTRESSED/CAUTIOUS/HEALTHY/PROFITABLE), adjusted cash runway, burn rate, total liquidity, dilution risk, cash position, and the source filing date. Sorted ascending by adjusted_runway.adjusted_runway_months (shortest runway first). Optionally filter by ticker (uppercased) and/or risk_level (uppercased, validated). Faceted pagination 50 rows per page via the page param. Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single ticker; uppercased before matching the record's ticker field."
          },
          {
            "name": "risk_level",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by risk level; uppercased and validated against CRITICAL, DISTRESSED, CAUTIOUS, HEALTHY, PROFITABLE. An invalid value returns HTTP 400."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number for pagination (page size fixed at 50 by getPagination). Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Stock ticker symbol of the company."
                          },
                          "company_name": {
                            "type": "string",
                            "description": "Company name, joined from tblcompanies.name (mapped from $company.name)."
                          },
                          "risk_level": {
                            "type": "string",
                            "description": "Categorical financial-health risk level (CRITICAL/DISTRESSED/CAUTIOUS/HEALTHY/PROFITABLE)."
                          },
                          "adjusted_runway": {
                            "type": "object",
                            "description": "Adjusted cash-runway object, passed through verbatim from the stored document; results are sorted by its adjusted_runway_months subfield (ascending).",
                            "properties": {
                              "adjusted_runway_months": {
                                "type": "number",
                                "description": "Estimated months of cash runway after adjustments; the sort key for this endpoint (ascending)."
                              }
                            }
                          },
                          "burn_rate": {
                            "type": "object",
                            "description": "Monthly cash burn-rate object, passed through verbatim from the stored document."
                          },
                          "total_liquidity": {
                            "type": "number",
                            "description": "Total liquidity available to the company, passed through from the stored document."
                          },
                          "dilution_risk": {
                            "type": "object",
                            "description": "Dilution-risk assessment object, passed through verbatim from the stored document."
                          },
                          "filing_date": {
                            "type": "string",
                            "description": "Date of the SEC filing the health metrics were derived from."
                          },
                          "cash_position": {
                            "type": "number",
                            "description": "Cash and equivalents position, passed through from the stored document."
                          },
                          "market_cap": {
                            "type": "number",
                            "description": "Basic market cap, joined from tblcompanies.market_cap_basic (mapped from $company.market_cap_basic)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/sec/company-health/distressed": {
      "get": {
        "summary": "Most financially distressed biotechs (risk_level CRITICAL or DISTRESSED) ranked by shortest cash runway, with live price.",
        "description": "Returns companies whose risk_level is CRITICAL or DISTRESSED (pre-filtered in the pipeline $match), $lookup-joined to tblcompanies (ticker = symbol) for company_name, basic market cap, last close, and daily change. Sorted ascending by adjusted_runway.adjusted_runway_months (shortest runway first) and capped by the limit param (default 50). This is a flat-array (non-faceted) response: the page param is read only for the response envelope, while row count is governed by limit (validated as a positive integer). Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Maximum number of distressed companies to return. If provided it must parse to a positive integer (>= 1), else HTTP 400. Defaults to 50."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Read by getPagination for the response envelope only; defaults to 1. Row count is controlled by limit, not page (no $skip is applied)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Stock ticker symbol."
                          },
                          "company_name": {
                            "type": "string",
                            "description": "Company name, joined from tblcompanies.name (mapped from $company.name)."
                          },
                          "risk_level": {
                            "type": "string",
                            "description": "Risk level, constrained to CRITICAL or DISTRESSED for this endpoint."
                          },
                          "adjusted_runway": {
                            "type": "object",
                            "description": "Adjusted cash-runway object, passed through verbatim; sorted ascending by its adjusted_runway_months subfield.",
                            "properties": {
                              "adjusted_runway_months": {
                                "type": "number",
                                "description": "Estimated months of cash runway; the sort key (ascending)."
                              }
                            }
                          },
                          "burn_rate": {
                            "type": "object",
                            "description": "Monthly cash burn-rate object, passed through verbatim."
                          },
                          "total_liquidity": {
                            "type": "number",
                            "description": "Total liquidity available, passed through from the stored document."
                          },
                          "dilution_risk": {
                            "type": "object",
                            "description": "Dilution-risk assessment object, passed through verbatim."
                          },
                          "filing_date": {
                            "type": "string",
                            "description": "Date of the source SEC filing."
                          },
                          "market_cap": {
                            "type": "number",
                            "description": "Basic market cap, joined from tblcompanies.market_cap_basic (mapped from $company.market_cap_basic)."
                          },
                          "close": {
                            "type": "number",
                            "description": "Last close price, joined from tblcompanies.close (mapped from $company.close)."
                          },
                          "change": {
                            "type": "number",
                            "description": "Daily price change, joined from tblcompanies.change (mapped from $company.change)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/sec/financials": {
      "get": {
        "summary": "Quarterly 10-Q financial statement data for a single ticker (most recent quarters first).",
        "description": "Returns the most recent 10-Q quarterly financial records for the required ticker (uppercased), sorted descending by period_end_date and capped by the limit param (default 8 quarters). The controller does a plain find().project({ _id: 0 }) with no field allow-list, so each record is the complete stored sec_10q_financials document minus _id. ticker is required (HTTP 400 if missing). Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticker to fetch quarterly financials for; uppercased before matching the ticker field. Required (returns HTTP 400 if missing)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Number of most-recent quarters to return. parseInt(req.query.limit) || 8, so defaults to 8 (and a non-numeric or 0 value falls back to 8)."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Read by getPagination for the response envelope only; defaults to 1. Row count is governed by limit, not page (no skip is applied)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Ticker the financial record belongs to (the filter key; uppercased)."
                          },
                          "period_end_date": {
                            "type": "string",
                            "description": "Fiscal period-end date of the 10-Q quarter; the descending sort key."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/sec/offerings": {
      "get": {
        "summary": "SEC securities-offering filings (S-1, S-3, 424B etc.) with offer amount, price, and shares offered.",
        "description": "Returns a paginated list of SEC offering filings (collection sec_offerings), sorted descending by filingDate (newest first). Optionally filter by ticker (uppercased, matched against the symbol field) and/or form_type via a case-insensitive regex on the type param. Each record exposes form type, filing date, offer amount, share price, shares offered, and a free-text description. Faceted pagination 50 per page via the page param. Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by ticker; uppercased and matched against the record's symbol field (not a field literally named ticker)."
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by form type via a case-insensitive ($options:'i') regex against form_type (e.g. S-1, S-3, 424B)."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number (page size fixed at 50). Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "symbol": {
                            "type": "string",
                            "description": "Ticker symbol of the filing company."
                          },
                          "form_type": {
                            "type": "string",
                            "description": "SEC form type of the offering (e.g. S-1, S-3, 424B)."
                          },
                          "filingDate": {
                            "type": "string",
                            "description": "Date the offering was filed; the descending sort key."
                          },
                          "offer_amount": {
                            "type": "number",
                            "description": "Total dollar amount of the offering."
                          },
                          "share_price": {
                            "type": "number",
                            "description": "Offer price per share."
                          },
                          "shares_offered": {
                            "type": "number",
                            "description": "Number of shares offered."
                          },
                          "description": {
                            "type": "string",
                            "description": "Free-text description of the offering."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/sec/ownership": {
      "get": {
        "summary": "SEC beneficial-ownership filings (SC 13D / 13G) per ticker: owner, ownership type, shares held, percent owned.",
        "description": "Returns a paginated list of SEC ownership / beneficial-ownership filings (collection sec_ownership; e.g. 13D/13G), sorted descending by filingDate (newest first). Optionally filter by ticker (uppercased, matched against the symbol field). Each record exposes the owner name, ownership type, shares held, percent ownership, and form type. Faceted pagination 50 per page via the page param. Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by ticker; uppercased and matched against the record's symbol field (not a field literally named ticker)."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number (page size fixed at 50). Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "symbol": {
                            "type": "string",
                            "description": "Ticker symbol the ownership filing relates to."
                          },
                          "filingDate": {
                            "type": "string",
                            "description": "Date the ownership filing was filed; the descending sort key."
                          },
                          "owner_name": {
                            "type": "string",
                            "description": "Name of the beneficial owner / filer."
                          },
                          "ownership_type": {
                            "type": "string",
                            "description": "Type of ownership disclosed (e.g. active 13D vs passive 13G)."
                          },
                          "shares_held": {
                            "type": "number",
                            "description": "Number of shares beneficially held."
                          },
                          "percent_ownership": {
                            "type": "number",
                            "description": "Percent of outstanding shares owned."
                          },
                          "form_type": {
                            "type": "string",
                            "description": "SEC form type of the filing (e.g. SC 13D, SC 13G)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/sec/proxy": {
      "get": {
        "summary": "SEC proxy-statement (DEF 14A) data for a single ticker, primarily executive compensation; latest 5 filings.",
        "description": "Returns the 5 most recent SEC proxy-statement records for the required ticker (uppercased, matched against the symbol field), sorted descending by filingDate. The controller does a plain find().project({ _id: 0 }) with no field allow-list, so each record is the complete stored sec_proxy document minus _id (executive compensation and related proxy data). The 5-record cap is hard-coded (.limit(5)); ticker is required (HTTP 400 if missing). Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticker to fetch proxy data for; uppercased and matched against the symbol field. Required (returns HTTP 400 if missing)."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Read by getPagination for the response envelope only; defaults to 1. Result is hard-capped at the 5 most recent filings regardless of page (no skip is applied)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "symbol": {
                            "type": "string",
                            "description": "Ticker symbol the proxy filing belongs to (the filter key; uppercased)."
                          },
                          "filingDate": {
                            "type": "string",
                            "description": "Date the proxy statement was filed; the descending sort key."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/hedge-fund/holdings": {
      "get": {
        "summary": "13F hedge-fund holdings per ticker/fund/quarter, with quarter-over-quarter share change.",
        "description": "Returns individual hedge-fund position rows (one row per fund per ticker per quarter) from the hedge-fund holdings collection. Each row carries the symbol, fund name, the quarter label and its numeric order, the current share count, market value, percent of the fund's portfolio, and the QoQ share change. Sorted by quarter_order (descending, most recent first) then symbol ascending, paginated in pages of 50 via the page query param (the page slice is applied inside a $facet). Optional filters narrow by ticker (uppercased, exact on symbol), fund name (case-insensitive regex on hedgeFundName), and an exact quarter string. Envelope: { result: [...], pagination: { page, pageSize, total } } via buildResponse; demo keys also receive a Note. Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single symbol; uppercased server-side and matched exactly on the 'symbol' field."
          },
          {
            "name": "fund_name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by hedge fund name (case-insensitive regex match on 'hedgeFundName')."
          },
          {
            "name": "quarter",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to an exact quarter string (matched on the 'quarter' field, e.g. 'Q1 2026')."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; pageSize is fixed at 50. Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "symbol": {
                            "type": "string",
                            "description": "Ticker symbol of the held company."
                          },
                          "hedgeFundName": {
                            "type": "string",
                            "description": "Name of the hedge fund holding the position."
                          },
                          "quarter": {
                            "type": "string",
                            "description": "Reporting quarter label (e.g. 'Q1 2026')."
                          },
                          "quarter_order": {
                            "type": "number",
                            "description": "Numeric ordinal of the quarter used for sorting (descending = most recent first)."
                          },
                          "current_shares": {
                            "type": "number",
                            "description": "Shares held by the fund as of this quarter's 13F."
                          },
                          "current_mv": {
                            "type": "number",
                            "description": "Current market value of the position."
                          },
                          "current_percent_of_portfolio": {
                            "type": "number",
                            "description": "Position as a percent of the fund's total reported portfolio."
                          },
                          "QoQ_chg": {
                            "type": "number",
                            "description": "Quarter-over-quarter change in shares held."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/hedge-fund/screener": {
      "get": {
        "summary": "Fund-level 13F screener: one row per hedge fund with portfolio size, total value, top holdings, and the top company's logo.",
        "description": "Returns aggregated per-fund rows from the hedge-fund screener collection, enriched via a $lookup against tblcompanies on the fund's largest single position (symbolWithMaxOwnership) to expose that company's logoid. Each row gives the fund name, quarter, the count of distinct holdings (symbolLength), total portfolio market value, the symbol of max ownership and its market value, a top_holdings array, and the matched company logoid. Sorted by total_mv descending and paginated in pages of 50 inside a $facet. Optional filters narrow by fund name (case-insensitive regex on hedgeFundName) and a minimum holding count (min_shares, parsed as int, matched as symbolLength >= value). Envelope via buildResponse with pagination { page, pageSize, total }; demo keys receive a Note. Plan: BiopharmaWatch API Elite Plus. Rate limit: 30 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 30,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "fund_name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by hedge fund name (case-insensitive regex on 'hedgeFundName')."
          },
          {
            "name": "min_shares",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Minimum number of distinct holdings; parsed with parseInt and matched as 'symbolLength' >= value. Despite the param name, this filters holding count, not share count."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; pageSize is fixed at 50. Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "hedgeFundName": {
                            "type": "string",
                            "description": "Name of the hedge fund."
                          },
                          "quarter": {
                            "type": "string",
                            "description": "Reporting quarter label."
                          },
                          "symbolLength": {
                            "type": "number",
                            "description": "Count of distinct symbols (holdings) in the fund's portfolio."
                          },
                          "total_mv": {
                            "type": "number",
                            "description": "Total market value of the fund's reported portfolio (sort key, descending)."
                          },
                          "symbolWithMaxOwnership": {
                            "type": "string",
                            "description": "Ticker of the fund's single largest position by ownership."
                          },
                          "maxOwnershipSymbolMV": {
                            "type": "number",
                            "description": "Market value of that largest position."
                          },
                          "top_holdings": {
                            "type": "array",
                            "description": "The fund's top holdings, as stored on the screener document."
                          },
                          "logoid": {
                            "type": "string",
                            "description": "Logo identifier of the max-ownership company, joined from tblcompanies.logoid via $lookup (null/absent when no company match, since preserveNullAndEmptyArrays is true)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/hedge-fund/sentiment": {
      "get": {
        "summary": "Composite hedge-fund sentiment score for a single ticker, diffing the latest 13F quarter against the prior one.",
        "description": "Computes a single composite hedge-fund sentiment object for the required ticker by comparing the latest reported quarter (by quarter_order) against the previous one. The score is computed in application code (not a Mongo $project) and blends a fund-count signal (60% weight, driven by new positions vs exits), a share-magnitude signal (25% weight, average per-fund share change), and a conviction signal (15% weight, average percent-of-portfolio change), each clamped to [0,1]. It produces a compositeScore rounded to 2 decimals and a POSITIVE/NEUTRAL/NEGATIVE label (>=0.6 POSITIVE, <=0.4 NEGATIVE, else NEUTRAL), plus a breakdown of the three sub-scores and an activity object (buyers, sellers, new positions, exits). When no hedge-fund data exists for the ticker it returns a { message } object (still wrapped by buildResponse). Demo keys receive a Note. Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticker to score; uppercased server-side. Returns HTTP 400 { error: 'ticker parameter is required' } if omitted."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Read by getPagination and echoed into the response envelope; the result is a single object so paging does not slice data. Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "The (uppercased) ticker that was scored."
                          },
                          "quarter": {
                            "type": "string",
                            "description": "Label of the latest reported quarter used as the 'current' period (from the top-ranked doc by quarter_order)."
                          },
                          "totalFunds": {
                            "type": "number",
                            "description": "Number of funds reporting a position in the current quarter (currentData.length)."
                          },
                          "compositeScore": {
                            "type": "number",
                            "description": "Blended sentiment score in [0,1], rounded to 2 decimals: 0.6*fundCountScore + 0.25*shareMagnitudeScore + 0.15*convictionScore."
                          },
                          "sentimentLabel": {
                            "type": "string",
                            "description": "POSITIVE if compositeScore >= 0.6, NEGATIVE if <= 0.4, else NEUTRAL."
                          },
                          "breakdown": {
                            "type": "object",
                            "properties": {
                              "fundCountScore": {
                                "type": "number",
                                "description": "Fund-count signal in [0,1] (60% weight) = clamp(0.5 + ((newPositions*1.5 - exits*1.5)/max(previousFunds,1))/2), rounded to 2 decimals."
                              },
                              "shareMagnitudeScore": {
                                "type": "number",
                                "description": "Average per-fund share-change signal in [0,1] (25% weight) = clamp(0.5 + avgShareChange/2), rounded to 2 decimals."
                              },
                              "convictionScore": {
                                "type": "number",
                                "description": "Percent-of-portfolio change signal in [0,1] (15% weight) = clamp(0.5 + avgConviction*10), rounded to 2 decimals."
                              }
                            }
                          },
                          "activity": {
                            "type": "object",
                            "properties": {
                              "buyers": {
                                "type": "number",
                                "description": "Funds with no prior-quarter position OR a higher current share count vs the prior quarter."
                              },
                              "sellers": {
                                "type": "number",
                                "description": "Funds with a prior-quarter position whose current share count is lower than the prior quarter."
                              },
                              "newPositions": {
                                "type": "number",
                                "description": "Funds present this quarter but absent the prior quarter."
                              },
                              "exits": {
                                "type": "number",
                                "description": "Funds present the prior quarter but absent this quarter."
                              }
                            }
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/insider-trades": {
      "get": {
        "summary": "Form-4 insider buy/sell transactions, enriched with company name and live price, restricted to active companies.",
        "description": "Returns individual insider transaction rows from the inside-trades collection, joined via $lookup to tblcompanies for company name and current close/change. Holdings-only rows (transactionCode 'H') and zero-share-change rows (change == 0) are always excluded, and after the join results are restricted to companies whose company_status is 'active' or whose company_status field is absent. Sorted by transactionDate descending and paginated in pages of 50 inside a $facet. Optional filters narrow by ticker (uppercased, exact on symbol), buy/sell side (exact on buy_sell), and a transaction-date range; dateFrom/dateTo accept YYYY, YYYY-MM, or YYYY-MM-DD and return HTTP 400 on an unparseable value. Envelope via buildResponse with pagination { page, pageSize, total }; demo keys receive a Note. Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single symbol; uppercased server-side and matched exactly on 'symbol'."
          },
          {
            "name": "buy_sell",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by transaction side; matched exactly on the 'buy_sell' field (e.g. 'Buy' / 'Sale')."
          },
          {
            "name": "dateFrom",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Inclusive lower bound on transactionDate. Accepts YYYY, YYYY-MM, or YYYY-MM-DD (normalized to start of period). Returns HTTP 400 with an 'Invalid dateFrom' error if unparseable."
          },
          {
            "name": "dateTo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Inclusive upper bound on transactionDate. Accepts YYYY, YYYY-MM, or YYYY-MM-DD (normalized to end of period). Returns HTTP 400 with an 'Invalid dateTo' error if unparseable."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; pageSize is fixed at 50. Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "symbol": {
                            "type": "string",
                            "description": "Ticker symbol of the company."
                          },
                          "company_name": {
                            "type": "string",
                            "description": "Company name, joined from tblcompanies.name (mapped from $company.name)."
                          },
                          "insiderName": {
                            "type": "string",
                            "description": "Name of the insider (mapped from the source field 'name')."
                          },
                          "insiderPosition": {
                            "type": "string",
                            "description": "Insider's role/relationship to the company (mapped from the source field 'relationship')."
                          },
                          "buy_sell": {
                            "type": "string",
                            "description": "Transaction side, e.g. 'Buy' or 'Sale'."
                          },
                          "shares": {
                            "type": "number",
                            "description": "Number of shares transacted (mapped from the source field 'change'; never 0, as zero-change rows are filtered out)."
                          },
                          "tradePrice": {
                            "type": "number",
                            "description": "Per-share transaction price (mapped from the source field 'transactionPrice')."
                          },
                          "traded_value": {
                            "type": "number",
                            "description": "Total dollar value of the transaction."
                          },
                          "transactionDate": {
                            "type": "string",
                            "description": "Date of the transaction (sort key, descending)."
                          },
                          "close": {
                            "type": "number",
                            "description": "Company's current/last close price, joined from tblcompanies.close (mapped from $company.close)."
                          },
                          "change": {
                            "type": "number",
                            "description": "Company's current daily price change, joined from tblcompanies.change (mapped from $company.change; this is the company's live daily change, NOT the insider's share change)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/insider-trades/sentiment": {
      "get": {
        "summary": "Monthly insider buy-vs-sell aggregation (most recent 12 months) with a per-month sentiment label.",
        "description": "Aggregates insider transactions into monthly buckets and returns the most recent 12 months (sorted descending) with buy/sell dollar value and counts per month, a net value, and a POSITIVE/NEUTRAL/NEGATIVE sentiment label. Holdings-only rows (transactionCode 'H') and zero-share-change rows (change == 0) are excluded, and rows whose transactionDate cannot be parsed by $dateFromString are dropped. An optional ticker filter scopes the aggregation to one symbol; with no ticker it aggregates across all symbols. The 12-month cap is applied server-side via $limit (not via the page param). Result is a flat array (no $facet), wrapped by buildResponse with a pagination object; demo keys receive a Note. Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Scope the monthly aggregation to a single symbol; uppercased server-side and matched exactly on 'symbol'. If omitted, aggregates across all tickers."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Read by getPagination and echoed into the envelope's pagination object; the result is hard-capped to 12 months server-side ($limit:12), so page does not paginate beyond that. Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "month": {
                            "type": "string",
                            "description": "Calendar month bucket in 'YYYY-MM' format (mapped from the $group _id; sorted descending, max 12 rows)."
                          },
                          "buyValue": {
                            "type": "number",
                            "description": "Sum of traded_value for Buy transactions in the month."
                          },
                          "sellValue": {
                            "type": "number",
                            "description": "Sum of traded_value for Sale transactions in the month."
                          },
                          "buyCount": {
                            "type": "number",
                            "description": "Number of Buy transactions in the month."
                          },
                          "sellCount": {
                            "type": "number",
                            "description": "Number of Sale transactions in the month."
                          },
                          "netValue": {
                            "type": "number",
                            "description": "buyValue minus sellValue for the month ($subtract)."
                          },
                          "sentiment": {
                            "type": "string",
                            "description": "POSITIVE if buyValue > sellValue, NEGATIVE if buyValue < sellValue, else NEUTRAL."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/alerts/unusual-volume": {
      "get": {
        "summary": "Unusual-volume alerts: biotech tickers whose current trading volume exceeds their average by an unusualness ratio (> 0), joined to live company name/price/change from tblcompanies.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 120s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 120
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to one symbol (uppercased server-side)."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number (parseInt(page) || 1); pageSize fixed at 50 via $facet $skip/$limit."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Stock symbol."
                          },
                          "company_name": {
                            "type": "string",
                            "description": "Company name ($company.name from tblcompanies lookup; null if unmatched)."
                          },
                          "current_volume": {
                            "type": "number",
                            "description": "Current trading volume (source field 'Current Volume')."
                          },
                          "average_volume": {
                            "type": "number",
                            "description": "Average trading volume (source field 'Average Volume')."
                          },
                          "unusualness_ratio": {
                            "type": "number",
                            "description": "Unusualness ratio (source field 'Unusualness Ratio'); pre-filtered to > 0 and sorted descending."
                          },
                          "close": {
                            "type": "number",
                            "description": "Latest close price ($company.close)."
                          },
                          "change": {
                            "type": "number",
                            "description": "Latest daily change ($company.change)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/ipos": {
      "get": {
        "summary": "Upcoming / pending IPOs (ipo_status in pending,new,rumor,direct_listing_process by default) with proposed pricing and offer-size detail. Optional status and sector filters.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 120s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 120
        },
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated ipo_status values; defaults to 'pending,new,rumor,direct_listing_process'. Split on comma, each value trimmed, matched with $in."
          },
          {
            "name": "sector",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex match on sector."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; pageSize fixed at 50 via $facet."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Proposed ticker."
                          },
                          "issuer_name": {
                            "type": "string",
                            "description": "Issuing company name."
                          },
                          "ipo_status": {
                            "type": "string",
                            "description": "IPO status (pending / new / rumor / direct_listing_process / etc.)."
                          },
                          "listing_date": {
                            "type": "string",
                            "description": "Expected listing date; results sorted by this field descending."
                          },
                          "proposed_offer_price": {
                            "type": "number",
                            "description": "Proposed offer price."
                          },
                          "min_price": {
                            "type": "number",
                            "description": "Bottom of the proposed price range."
                          },
                          "max_price": {
                            "type": "number",
                            "description": "Top of the proposed price range."
                          },
                          "total_offer_size": {
                            "type": "number",
                            "description": "Total offering size."
                          },
                          "sector": {
                            "type": "string",
                            "description": "Sector."
                          },
                          "industry": {
                            "type": "string",
                            "description": "Industry."
                          },
                          "description": {
                            "type": "string",
                            "description": "Issuer description."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/ipos/historical": {
      "get": {
        "summary": "Historical (completed) IPOs (ipo_status = 'history') with a computed return_percentage from final issue price to the current close (joined from tblcompanies).",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 120s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 120
        },
        "parameters": [
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a listing year; matched as a regex anchored to the start of listing_date (e.g. '^2024')."
          },
          {
            "name": "sector",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex match on sector."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; pageSize fixed at 50 via $facet."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Ticker."
                          },
                          "issuer_name": {
                            "type": "string",
                            "description": "Issuing company name."
                          },
                          "listing_date": {
                            "type": "string",
                            "description": "Listing date; results sorted by this field descending."
                          },
                          "final_issue_price": {
                            "type": "number",
                            "description": "Final IPO issue price."
                          },
                          "current_price": {
                            "type": "number",
                            "description": "Current close price ($addFields = $company.close from tblcompanies lookup)."
                          },
                          "return_percentage": {
                            "type": "number",
                            "description": "Percent return = (company.close - final_issue_price)/final_issue_price * 100; null unless both final_issue_price > 0 and company.close > 0."
                          },
                          "total_offer_size": {
                            "type": "number",
                            "description": "Total offering size."
                          },
                          "sector": {
                            "type": "string",
                            "description": "Sector."
                          },
                          "industry": {
                            "type": "string",
                            "description": "Industry."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/earnings-calendar": {
      "get": {
        "summary": "Biotech earnings calendar for a given month/year (defaults to current month/year). Unwinds matchedStocks, filters by parsed earnings date, one row per matched stock with company price and fundamentals.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 120s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 120
        },
        "parameters": [
          {
            "name": "month",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Calendar month 1-12; defaults to current month. Non-integer or out-of-range returns 400."
          },
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "4-digit year 1990-2100; defaults to current year. Invalid values return 400."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to one matchedStocks.symbol (uppercased); injected as a $match spliced into the pipeline at index 3."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; pageSize fixed at 50 via $facet."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "symbol": {
                            "type": "string",
                            "description": "Stock symbol ($matchedStocks.symbol)."
                          },
                          "earnings_date": {
                            "type": "string",
                            "description": "Earnings date ($matchedStocks.date); results sorted ascending by this field."
                          },
                          "company_name": {
                            "type": "string",
                            "description": "Company name ($company.name)."
                          },
                          "market_cap": {
                            "type": "number",
                            "description": "Basic market cap ($company.market_cap_basic)."
                          },
                          "close": {
                            "type": "number",
                            "description": "Latest close price ($company.close)."
                          },
                          "change": {
                            "type": "number",
                            "description": "Latest daily change ($company.change)."
                          },
                          "eps": {
                            "type": "number",
                            "description": "Earnings per share ($company.earnings_per_share)."
                          },
                          "Industry": {
                            "type": "string",
                            "description": "Industry ($company.Industry)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/options/chain": {
      "get": {
        "summary": "Options chain for one underlying ticker: per strike price, the call and put contract market data plus greeks. Ticker required; returns the full chain as a flat array.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 30 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 30,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Underlying ticker (matched as underlying_ticker, uppercased). Returns 400 if missing."
          },
          {
            "name": "expiration_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single expiration; parsed with new Date() and matched against expiration_date."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Read by getPagination for the response envelope (page/pageSize), but NO $skip/$limit is applied, so the full chain is returned."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "strike_price": {
                            "type": "number",
                            "description": "Strike price (group _id); results sorted ascending by strike."
                          },
                          "call": {
                            "type": "object",
                            "properties": {
                              "last_price": {
                                "type": "number",
                                "description": "Call last/close price ($market_data.close)."
                              },
                              "open": {
                                "type": "number",
                                "description": "Call open price."
                              },
                              "high": {
                                "type": "number",
                                "description": "Call high price."
                              },
                              "low": {
                                "type": "number",
                                "description": "Call low price."
                              },
                              "volume": {
                                "type": "number",
                                "description": "Call volume."
                              },
                              "open_interest": {
                                "type": "number",
                                "description": "Call open interest."
                              },
                              "implied_volatility": {
                                "type": "number",
                                "description": "Call implied volatility."
                              },
                              "delta": {
                                "type": "number",
                                "description": "Call delta ($market_data.greeks.delta)."
                              },
                              "gamma": {
                                "type": "number",
                                "description": "Call gamma ($market_data.greeks.gamma)."
                              },
                              "theta": {
                                "type": "number",
                                "description": "Call theta ($market_data.greeks.theta)."
                              },
                              "vega": {
                                "type": "number",
                                "description": "Call vega ($market_data.greeks.vega)."
                              }
                            }
                          },
                          "put": {
                            "type": "object",
                            "properties": {
                              "last_price": {
                                "type": "number",
                                "description": "Put last/close price ($market_data.close)."
                              },
                              "open": {
                                "type": "number",
                                "description": "Put open price."
                              },
                              "high": {
                                "type": "number",
                                "description": "Put high price."
                              },
                              "low": {
                                "type": "number",
                                "description": "Put low price."
                              },
                              "volume": {
                                "type": "number",
                                "description": "Put volume."
                              },
                              "open_interest": {
                                "type": "number",
                                "description": "Put open interest."
                              },
                              "implied_volatility": {
                                "type": "number",
                                "description": "Put implied volatility."
                              },
                              "delta": {
                                "type": "number",
                                "description": "Put delta ($market_data.greeks.delta)."
                              },
                              "gamma": {
                                "type": "number",
                                "description": "Put gamma."
                              },
                              "theta": {
                                "type": "number",
                                "description": "Put theta."
                              },
                              "vega": {
                                "type": "number",
                                "description": "Put vega."
                              }
                            }
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/options/summary": {
      "get": {
        "summary": "Aggregate options metrics for one underlying ticker: total/call/put open interest and volume with put/call ratios. Ticker required; returns a single aggregate object.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Underlying ticker (matched as underlying_ticker, uppercased). Returns 400 if missing."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Read by getPagination but unused: this endpoint returns a single aggregate object (result[0] || {}) with no pagination."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "totalOpenInterest": {
                            "type": "number",
                            "description": "callOpenInterest + putOpenInterest."
                          },
                          "callOpenInterest": {
                            "type": "number",
                            "description": "Summed open_interest across call contracts."
                          },
                          "putOpenInterest": {
                            "type": "number",
                            "description": "Summed open_interest across put contracts."
                          },
                          "openInterestPutCallRatio": {
                            "type": "number",
                            "description": "putOpenInterest / callOpenInterest; null when callOpenInterest is not > 0."
                          },
                          "totalVolume": {
                            "type": "number",
                            "description": "callVolume + putVolume."
                          },
                          "callVolume": {
                            "type": "number",
                            "description": "Summed volume across call contracts."
                          },
                          "putVolume": {
                            "type": "number",
                            "description": "Summed volume across put contracts."
                          },
                          "volumePutCallRatio": {
                            "type": "number",
                            "description": "putVolume / callVolume; null when callVolume is not > 0."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/conferences": {
      "get": {
        "summary": "Biotech/pharma conference calendar for a given month/year (defaults to current), matching conferences whose coerced Start Date or End Date falls in the requested period.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 120s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 120
        },
        "parameters": [
          {
            "name": "month",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Calendar month 1-12; defaults to current month. Non-integer or out-of-range returns 400."
          },
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "4-digit year 1990-2100; defaults to current year. Invalid values return 400."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Read by getPagination for the envelope (page/pageSize), but NO $skip/$limit is applied, so the full matching month is returned."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "conference_name": {
                            "type": "string",
                            "description": "Conference name (source field 'Conference Name')."
                          },
                          "start_date": {
                            "type": "string",
                            "description": "Start date (source 'Start Date'); results sorted ascending by this field."
                          },
                          "end_date": {
                            "type": "string",
                            "description": "End date (source 'End Date')."
                          },
                          "location": {
                            "type": "string",
                            "description": "Location (source 'Location')."
                          },
                          "description": {
                            "type": "string",
                            "description": "Description (source 'Description')."
                          },
                          "website": {
                            "type": "string",
                            "description": "Conference website (source 'Website')."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/news": {
      "get": {
        "summary": "Curated biotech news feed with AI-generated summary and sentiment, joined to live company name/price/change. Optional ticker and category filters.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 120s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 120
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to one symbol (uppercased)."
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex match against subCategory."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number; pageSize fixed at 50 via $facet."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Associated stock symbol."
                          },
                          "title": {
                            "type": "string",
                            "description": "Article title ($original_title)."
                          },
                          "published": {
                            "type": "string",
                            "description": "Publication timestamp; results sorted descending by this field."
                          },
                          "summary": {
                            "type": "string",
                            "description": "AI-generated summary ($ai_generated_content.summary)."
                          },
                          "sentiment_score": {
                            "type": "number",
                            "description": "AI sentiment score ($ai_generated_content.sentiment_analysis.score)."
                          },
                          "category": {
                            "type": "string",
                            "description": "News category."
                          },
                          "subCategory": {
                            "type": "string",
                            "description": "News sub-category (also the field the category filter regex-matches)."
                          },
                          "source_url": {
                            "type": "string",
                            "description": "Original source URL."
                          },
                          "company_name": {
                            "type": "string",
                            "description": "Company name ($company.name)."
                          },
                          "close": {
                            "type": "number",
                            "description": "Latest close price ($company.close)."
                          },
                          "change": {
                            "type": "number",
                            "description": "Latest daily change ($company.change)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/companies": {
      "get": {
        "summary": "List biotech/pharma companies with profile, price, market-cap, and financial-health fields. Filterable by ticker, sector, industry, and market-cap range; paginated 50 per page and sorted alphabetically by symbol.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 30 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 30,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single company by exact symbol (upper-cased server-side; matched against `symbol`)."
          },
          {
            "name": "sector",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex filter on `sector`."
          },
          {
            "name": "industry",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex filter on `Industry`."
          },
          {
            "name": "market_cap_min",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Minimum basic market cap ($gte filter on `market_cap_basic`). Must be a non-negative number or returns 400."
          },
          {
            "name": "market_cap_max",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Maximum basic market cap ($lte filter on `market_cap_basic`). Must be a non-negative number or returns 400."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number. Page size is fixed at 50. Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "symbol": {
                            "type": "string",
                            "description": "Ticker symbol."
                          },
                          "name": {
                            "type": "string",
                            "description": "Company name."
                          },
                          "sector": {
                            "type": "string",
                            "description": "Sector classification."
                          },
                          "Industry": {
                            "type": "string",
                            "description": "Industry classification."
                          },
                          "close": {
                            "type": "number",
                            "description": "Latest close price."
                          },
                          "change": {
                            "type": "number",
                            "description": "Daily price change percent."
                          },
                          "volume": {
                            "type": "number",
                            "description": "Trading volume."
                          },
                          "market_cap_basic": {
                            "type": "number",
                            "description": "Basic market capitalization (shares outstanding x price)."
                          },
                          "earnings_per_share": {
                            "type": "number",
                            "description": "Earnings per share."
                          },
                          "company_status": {
                            "type": "string",
                            "description": "Company status (e.g. active); may be absent on some docs."
                          },
                          "cik": {
                            "type": "string",
                            "description": "SEC CIK identifier."
                          },
                          "list_date": {
                            "type": "string",
                            "description": "Exchange listing date."
                          },
                          "Short_percent_of_Float": {
                            "type": "number",
                            "description": "Short interest as a percent of float."
                          },
                          "Monthly_Burn_Rate": {
                            "type": "number",
                            "description": "Monthly cash burn rate."
                          },
                          "Cash_and_Cash_Equivalents": {
                            "type": "number",
                            "description": "Cash and cash equivalents from the latest filing."
                          },
                          "Runway_(Months)": {
                            "type": "number",
                            "description": "Estimated cash runway in months (cash / monthly burn)."
                          },
                          "drugtypes": {
                            "type": "array",
                            "description": "Drug-type / modality classifications for the company's pipeline."
                          },
                          "therapeuticAreas": {
                            "type": "array",
                            "description": "Therapeutic-area classifications for the company's pipeline."
                          },
                          "financialStage": {
                            "type": "string",
                            "description": "Financial / clinical stage classification."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/companies/{ticker}": {
      "get": {
        "summary": "Full profile for a single company by ticker, including description, address, exchange, share counts, financial-health fields, and an aggregated insider-activity metric. Returns 404 if the ticker is not found.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 30 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 30,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Company ticker symbol (req.params.ticker, upper-cased server-side; matched against `symbol`)."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Parsed for the response envelope (the single-object result is not actually paginated). Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "symbol": {
                            "type": "string",
                            "description": "Ticker symbol."
                          },
                          "name": {
                            "type": "string",
                            "description": "Company name."
                          },
                          "sector": {
                            "type": "string",
                            "description": "Sector classification."
                          },
                          "Industry": {
                            "type": "string",
                            "description": "Industry classification."
                          },
                          "close": {
                            "type": "number",
                            "description": "Latest close price."
                          },
                          "change": {
                            "type": "number",
                            "description": "Daily price change percent."
                          },
                          "volume": {
                            "type": "number",
                            "description": "Trading volume."
                          },
                          "market_cap_basic": {
                            "type": "number",
                            "description": "Basic market capitalization."
                          },
                          "earnings_per_share": {
                            "type": "number",
                            "description": "Earnings per share."
                          },
                          "company_status": {
                            "type": "string",
                            "description": "Company status (e.g. active)."
                          },
                          "cik": {
                            "type": "string",
                            "description": "SEC CIK identifier."
                          },
                          "list_date": {
                            "type": "string",
                            "description": "Exchange listing date."
                          },
                          "primary_exchange_mic": {
                            "type": "string",
                            "description": "Primary exchange MIC code."
                          },
                          "homepageUrl": {
                            "type": "string",
                            "description": "Company homepage URL."
                          },
                          "massive_description": {
                            "type": "string",
                            "description": "Long-form company description."
                          },
                          "massive_address": {
                            "type": "string",
                            "description": "Company mailing / headquarters address."
                          },
                          "sic_code": {
                            "type": "string",
                            "description": "SIC industry code."
                          },
                          "Short_percent_of_Float": {
                            "type": "number",
                            "description": "Short interest as a percent of float."
                          },
                          "Total_Shares": {
                            "type": "number",
                            "description": "Total shares outstanding."
                          },
                          "Float_Shares": {
                            "type": "number",
                            "description": "Freely tradable float shares."
                          },
                          "Monthly_Burn_Rate": {
                            "type": "number",
                            "description": "Monthly cash burn rate."
                          },
                          "Cash_and_Cash_Equivalents": {
                            "type": "number",
                            "description": "Cash and cash equivalents from the latest filing."
                          },
                          "Runway_(Months)": {
                            "type": "number",
                            "description": "Estimated cash runway in months."
                          },
                          "drugtypes": {
                            "type": "array",
                            "description": "Drug-type / modality classifications."
                          },
                          "therapeuticAreas": {
                            "type": "array",
                            "description": "Therapeutic-area classifications."
                          },
                          "Specific_Diseases": {
                            "type": "array",
                            "description": "Specific diseases / indications the company targets."
                          },
                          "financialStage": {
                            "type": "string",
                            "description": "Financial / clinical stage classification."
                          },
                          "avgInsiderTransactions": {
                            "type": "number",
                            "description": "Aggregated average insider (Form 4) transaction metric."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/analyst-ratings": {
      "get": {
        "summary": "Analyst price targets, rating actions, and consensus changes, enriched with company name and latest close price via a $lookup join to tblcompanies. Filterable by ticker, firm, and rating; sorted newest-first and paginated 50 per page.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 120s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 120
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by exact symbol (upper-cased; matched against `Symbol`)."
          },
          {
            "name": "firm",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex filter on the analyst `Firm`."
          },
          {
            "name": "rating",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex filter on the `Rating` value."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number. Page size is fixed at 50. Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "Symbol": {
                            "type": "string",
                            "description": "Ticker symbol of the rated company."
                          },
                          "company_name": {
                            "type": "string",
                            "description": "Company name (joined from tblcompanies.name via $company.name)."
                          },
                          "PriceTarget": {
                            "type": "number",
                            "description": "Analyst's new price target."
                          },
                          "Firm": {
                            "type": "string",
                            "description": "Analyst firm / research house."
                          },
                          "FromPrice": {
                            "type": "number",
                            "description": "Prior price target the rating moved from."
                          },
                          "PercentChange": {
                            "type": "number",
                            "description": "Percent change in the price target."
                          },
                          "Action": {
                            "type": "string",
                            "description": "Rating action (e.g. initiated, raised, lowered, maintained)."
                          },
                          "Rating": {
                            "type": "string",
                            "description": "Analyst rating (e.g. Buy, Hold, Overweight)."
                          },
                          "date": {
                            "type": "string",
                            "description": "Date of the rating / price-target action (sort key, descending)."
                          },
                          "close": {
                            "type": "number",
                            "description": "Latest close price of the company (joined from tblcompanies.close via $company.close)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/gainers-losers": {
      "get": {
        "summary": "Daily biotech top gainers or losers, sorted by percent change. Returns a precomputed leaderboard of up to `limit` rows (default 25) with logo id, name, symbol, close, and change.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 120s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 120
        },
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Either 'gainers' or 'losers'. Defaults to 'gainers'. Any other value returns 400. Controls both the filter ({ type }) and sort direction (gainers = change descending, losers = ascending)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Max number of rows to return. Must be a positive integer (>= 1) or returns 400. Defaults to 25."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Parsed for the response envelope; results are limit-capped via .limit(), not page-sliced. Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "logoid": {
                            "type": "string",
                            "description": "Logo identifier for the company."
                          },
                          "name": {
                            "type": "string",
                            "description": "Company name."
                          },
                          "symbol": {
                            "type": "string",
                            "description": "Ticker symbol."
                          },
                          "close": {
                            "type": "number",
                            "description": "Latest close price."
                          },
                          "change": {
                            "type": "number",
                            "description": "Daily price change percent (sort key)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/holders": {
      "get": {
        "summary": "Institutional / major holders for a single ticker. Returns the full holder documents for the requested company (every stored field except the Mongo _id). The ticker query parameter is required (400 if omitted).",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 60 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticker symbol to fetch holders for (upper-cased server-side; matched against `ticker`). Returns 400 if omitted."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Parsed for the response envelope; the query is not page-sliced (returns all matching holder docs). Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "(all document fields except _id)": {
                            "type": "object",
                            "description": "No allow-list $project: the query uses .project({ _id: 0 }) (exclusion-only), so every field stored on the matched holder document(s) is returned and the exact shape follows the holders-collection schema rather than a fixed projection. Only _id is stripped."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/pipeline/leaderboard": {
      "get": {
        "summary": "Ranked pipeline-score leaderboard (screener) across all covered tickers, with grade / valuation-signal / peer-tier / minScore filters and sortable, paginated results.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 30 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 30,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number (fixed page size of 50). Defaults to 1."
          },
          {
            "name": "grade",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated pipeline-grade filter; each value trimmed and upper-cased, matched against pipelineGrade (e.g. 'A,B')."
          },
          {
            "name": "valuation",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated valuation-signal filter; each value trimmed and upper-cased, matched against valuation_signal."
          },
          {
            "name": "tier",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated peer-tier filter; each value trimmed (case preserved, NOT upper-cased), matched against peerTier."
          },
          {
            "name": "minScore",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Minimum pipelineScore (>=). Parsed with parseFloat; a non-numeric value returns HTTP 400."
          },
          {
            "name": "sortKey",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Sort field. Allowed: pipelineScore, totalPipelineRNPV_B, rNPV_to_mktcap_ratio, marketCapB, percentileRank. Any other value falls back to pipelineScore. Defaults to pipelineScore."
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Sort direction. '1' = ascending; any other value = descending. Defaults to descending."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Stock ticker symbol."
                          },
                          "companyName": {
                            "type": "string",
                            "description": "Company name."
                          },
                          "pipelineScore": {
                            "type": "number",
                            "description": "Composite pipeline score."
                          },
                          "pipelineGrade": {
                            "type": "string",
                            "description": "Letter grade derived from the pipeline score."
                          },
                          "valuation_signal": {
                            "type": "string",
                            "description": "Valuation signal (e.g. undervalued / fair / overvalued)."
                          },
                          "totalPipelineRNPV_B": {
                            "type": "number",
                            "description": "Total risk-adjusted NPV of the pipeline, in $B."
                          },
                          "marketCapB": {
                            "type": "number",
                            "description": "Market capitalization, in $B."
                          },
                          "rNPV_to_mktcap_ratio": {
                            "type": "number",
                            "description": "Ratio of total pipeline rNPV to market cap."
                          },
                          "assetCount": {
                            "type": "number",
                            "description": "Total number of pipeline assets."
                          },
                          "activeAssetCount": {
                            "type": "number",
                            "description": "Number of active pipeline assets."
                          },
                          "percentileRank": {
                            "type": "number",
                            "description": "Percentile rank of the pipeline score across the universe."
                          },
                          "peerTier": {
                            "type": "string",
                            "description": "Peer-tier classification."
                          },
                          "headline": {
                            "type": "string",
                            "description": "Human-readable headline summarizing the pipeline."
                          },
                          "components": {
                            "type": "object",
                            "properties": {
                              "riskAdjustedValue": {
                                "type": "object",
                                "properties": {
                                  "bestAsset": {
                                    "type": "object",
                                    "properties": {
                                      "drugName": {
                                        "type": "string",
                                        "description": "Best asset's drug name (from the risk-adjusted-value component)."
                                      },
                                      "indication": {
                                        "type": "string",
                                        "description": "Best asset's indication."
                                      },
                                      "currentPhase": {
                                        "type": "string",
                                        "description": "Best asset's current clinical phase."
                                      },
                                      "rNPV_B": {
                                        "type": "number",
                                        "description": "Best asset's risk-adjusted NPV, in $B."
                                      }
                                    }
                                  }
                                }
                              },
                              "financialRunway": {
                                "type": "object",
                                "properties": {
                                  "riskLevel": {
                                    "type": "string",
                                    "description": "Financial-runway risk level (from the financial-runway component)."
                                  },
                                  "runwayMonths": {
                                    "type": "number",
                                    "description": "Estimated cash runway, in months."
                                  }
                                }
                              }
                            }
                          },
                          "computedAt": {
                            "type": "string",
                            "description": "Timestamp the score was last computed."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/pipeline/score/{ticker}": {
      "get": {
        "summary": "Full pipeline score card for a single ticker: composite score, grade, valuation signal, rNPV-to-mktcap, asset/trial counts, peer ranking and percentiles, phase distribution, top assets, scoring components, and commercial-reality block.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticker symbol (upper-cased server-side). Required; an empty value returns 400."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Read by getPagination (page size fixed at 50) but the response is a single object, so no pagination block is emitted. Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Stock ticker symbol."
                          },
                          "companyName": {
                            "type": "string",
                            "description": "Company name."
                          },
                          "pipelineScore": {
                            "type": "number",
                            "description": "Composite pipeline score."
                          },
                          "pipelineGrade": {
                            "type": "string",
                            "description": "Letter grade derived from the pipeline score."
                          },
                          "valuation_signal": {
                            "type": "string",
                            "description": "Valuation signal."
                          },
                          "rNPV_to_mktcap_ratio": {
                            "type": "number",
                            "description": "Ratio of total pipeline rNPV to market cap."
                          },
                          "marketCapB": {
                            "type": "number",
                            "description": "Market capitalization, in $B."
                          },
                          "totalPipelineRNPV_B": {
                            "type": "number",
                            "description": "Total risk-adjusted NPV of the pipeline, in $B."
                          },
                          "totalTAM_B": {
                            "type": "number",
                            "description": "Total addressable market across the pipeline, in $B."
                          },
                          "assetCount": {
                            "type": "number",
                            "description": "Total number of pipeline assets."
                          },
                          "activeAssetCount": {
                            "type": "number",
                            "description": "Number of active pipeline assets."
                          },
                          "totalTrialCount": {
                            "type": "number",
                            "description": "Total number of clinical trials across the pipeline."
                          },
                          "percentileRank": {
                            "type": "number",
                            "description": "Percentile rank of the pipeline score across the universe."
                          },
                          "rNPVPercentile": {
                            "type": "number",
                            "description": "Percentile rank of the total pipeline rNPV."
                          },
                          "peerTier": {
                            "type": "string",
                            "description": "Peer-tier classification."
                          },
                          "rankOutOf": {
                            "type": "number",
                            "description": "Size of the ranked universe the percentile is computed against."
                          },
                          "headline": {
                            "type": "string",
                            "description": "Human-readable headline summarizing the pipeline."
                          },
                          "phaseDistribution": {
                            "type": "object",
                            "description": "Distribution of assets across clinical phases."
                          },
                          "topAssets": {
                            "type": "array",
                            "description": "Top pipeline assets (highlighted subset)."
                          },
                          "components": {
                            "type": "object",
                            "description": "Full scoring-component breakdown (riskAdjustedValue, financialRunway, etc.)."
                          },
                          "commercialReality": {
                            "type": "object",
                            "description": "Commercial-reality assessment block."
                          },
                          "computedAt": {
                            "type": "string",
                            "description": "Timestamp the score was last computed."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/pipeline/assets/{ticker}": {
      "get": {
        "summary": "Per-drug asset detail for a ticker: risk-adjusted NPV (rNPV), PTRS / LOA probabilities, modality, revenue and market sizing, competitors, FDA designations, modifiers, and trial NCT IDs.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticker symbol (upper-cased server-side). Required; an empty value returns 400."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Passed to buildResponse for the pagination block (page size fixed at 50). The query itself is not skip/limited. Defaults to 1."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Stock ticker symbol."
                          },
                          "drugName": {
                            "type": "string",
                            "description": "Drug/asset name."
                          },
                          "indication": {
                            "type": "string",
                            "description": "Indication the asset is being developed for."
                          },
                          "currentPhase": {
                            "type": "string",
                            "description": "Current clinical phase of the asset."
                          },
                          "modality": {
                            "type": "string",
                            "description": "Drug modality (small molecule, mAb, ADC, gene therapy, etc.)."
                          },
                          "assetType": {
                            "type": "string",
                            "description": "Asset type classification."
                          },
                          "ptrs": {
                            "type": "number",
                            "description": "Probability of Technical and Regulatory Success."
                          },
                          "loa": {
                            "type": "number",
                            "description": "Likelihood of Approval (base)."
                          },
                          "adjustedLOA": {
                            "type": "number",
                            "description": "LOA after modifier adjustments."
                          },
                          "combinedLOA": {
                            "type": "number",
                            "description": "Combined likelihood of approval."
                          },
                          "conditionalPTRS": {
                            "type": "number",
                            "description": "Conditional PTRS."
                          },
                          "rNPV_B": {
                            "type": "number",
                            "description": "Risk-adjusted NPV of the asset, in $B."
                          },
                          "revenueBasis_B": {
                            "type": "number",
                            "description": "Revenue basis used in the rNPV calc, in $B."
                          },
                          "totalMarket_B": {
                            "type": "number",
                            "description": "Total addressable market for the asset, in $B."
                          },
                          "revenueSource": {
                            "type": "string",
                            "description": "Source/basis of the revenue estimate."
                          },
                          "competitors": {
                            "type": "array",
                            "description": "Competing assets/companies for the indication."
                          },
                          "fdaDesignations": {
                            "type": "array",
                            "description": "FDA designations (ODD, Breakthrough, Fast Track, etc.)."
                          },
                          "modifiersApplied": {
                            "type": "array",
                            "description": "List of modifiers applied to the LOA/PTRS."
                          },
                          "nctIds": {
                            "type": "array",
                            "description": "ClinicalTrials.gov NCT identifiers associated with the asset."
                          },
                          "timeDiscount": {
                            "type": "number",
                            "description": "Time-discount factor applied in the rNPV model."
                          },
                          "totalIndications": {
                            "type": "number",
                            "description": "Total number of indications for the asset."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/pipeline/intelligence/{ticker}": {
      "get": {
        "summary": "Unified pipeline-intelligence dossier for a ticker: the company pipeline score, the full set of scored assets enriched with trial detail / risk signals / recent changes, and a 90-day changelog severity summary.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 30 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 30,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticker symbol (upper-cased server-side). Required; an empty value returns 400."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "companyScore": {
                            "type": "object",
                            "description": "Company pipeline score document, or null if the company has no score but has assets. When present, same field set as /pipeline/score/{ticker}: ticker, companyName, pipelineScore, pipelineGrade, valuation_signal, rNPV_to_mktcap_ratio, marketCapB, totalPipelineRNPV_B, totalTAM_B, assetCount, activeAssetCount, totalTrialCount, percentileRank, rNPVPercentile, peerTier, rankOutOf, headline, phaseDistribution, topAssets, components, commercialReality, computedAt."
                          },
                          "assets": {
                            "type": "array",
                            "description": "Array of enriched pipeline assets (each element is an object with the assets[].* fields below). The assets are hand-assembled in code (NOT a Mongo $project): only the listed fields are emitted, with defaults applied as noted."
                          },
                          "assets[]": {
                            "type": "object",
                            "properties": {
                              "drugName": {
                                "type": "string",
                                "description": "Drug/asset name."
                              },
                              "indication": {
                                "type": "string",
                                "description": "Asset indication."
                              },
                              "therapeuticArea": {
                                "type": "string",
                                "description": "Therapeutic area of the asset."
                              },
                              "modality": {
                                "type": "string",
                                "description": "Drug modality."
                              },
                              "currentPhase": {
                                "type": "string",
                                "description": "Current clinical phase."
                              },
                              "baseLOA": {
                                "type": "number",
                                "description": "Base likelihood of approval (sourced from the asset's baseLOA field, not loa)."
                              },
                              "adjustedLOA": {
                                "type": "number",
                                "description": "LOA after modifier adjustments."
                              },
                              "combinedLOA": {
                                "type": "number",
                                "description": "Combined likelihood of approval (also the primary sort key for the assets list)."
                              },
                              "conditionalPTRS": {
                                "type": "number",
                                "description": "Conditional PTRS."
                              },
                              "fdaDesignations": {
                                "type": "array",
                                "description": "FDA designations (defaults to empty array if absent)."
                              },
                              "modifiersApplied": {
                                "type": "array",
                                "description": "Modifiers applied to the LOA/PTRS (defaults to empty array if absent)."
                              },
                              "rNPV_B": {
                                "type": "number",
                                "description": "Risk-adjusted NPV of the asset, in $B (null if absent)."
                              },
                              "revenueBasis_B": {
                                "type": "number",
                                "description": "Revenue basis used in the rNPV calc, in $B (null if absent)."
                              },
                              "totalMarket_B": {
                                "type": "number",
                                "description": "Total addressable market, in $B (null if absent)."
                              },
                              "competitors": {
                                "type": "array",
                                "description": "Competing assets/companies (null if absent)."
                              },
                              "totalTrials": {
                                "type": "number",
                                "description": "Total trial count for the asset (from the asset's totalTrials field)."
                              },
                              "activeTrials": {
                                "type": "number",
                                "description": "Active trial count for the asset (from the asset's activeTrials field)."
                              },
                              "nctIds": {
                                "type": "array",
                                "description": "NCT identifiers for the asset (defaults to empty array if absent)."
                              },
                              "trials": {
                                "type": "array",
                                "description": "Per-trial detail joined from clinical trials 2.0 for this asset's NCT IDs (trials with no match are dropped); each entry carries the trial projection fields plus riskSignals and recentChanges."
                              },
                              "trials[]": {
                                "type": "object",
                                "properties": {
                                  "nctId": {
                                    "type": "string",
                                    "description": "ClinicalTrials.gov NCT identifier."
                                  },
                                  "briefTitle": {
                                    "type": "string",
                                    "description": "Trial brief title."
                                  },
                                  "phase": {
                                    "type": "string",
                                    "description": "Trial phase."
                                  },
                                  "completionDate": {
                                    "type": "string",
                                    "description": "Trial completion date."
                                  },
                                  "overallStatus": {
                                    "type": "string",
                                    "description": "Trial overall status (Recruiting, Completed, etc.)."
                                  },
                                  "enrollmentCount": {
                                    "type": "number",
                                    "description": "Planned/actual enrollment count."
                                  },
                                  "conditions": {
                                    "type": "array",
                                    "description": "Conditions/diseases studied."
                                  },
                                  "interventionNames": {
                                    "type": "array",
                                    "description": "Intervention names."
                                  },
                                  "primaryOutcomes": {
                                    "type": "array",
                                    "description": "Primary outcome measures."
                                  },
                                  "secondaryOutcomes": {
                                    "type": "array",
                                    "description": "Secondary outcome measures."
                                  },
                                  "therapeuticArea": {
                                    "type": "string",
                                    "description": "Trial therapeutic area."
                                  },
                                  "designAllocation": {
                                    "type": "string",
                                    "description": "Study design allocation (e.g. randomized)."
                                  },
                                  "designMasking": {
                                    "type": "string",
                                    "description": "Study design masking/blinding."
                                  },
                                  "numberOfArms": {
                                    "type": "number",
                                    "description": "Number of trial arms."
                                  },
                                  "locationCount": {
                                    "type": "number",
                                    "description": "Number of trial sites/locations."
                                  },
                                  "startDate": {
                                    "type": "string",
                                    "description": "Trial start date."
                                  },
                                  "lastUpdatePostDate": {
                                    "type": "string",
                                    "description": "Date the trial record was last updated on CT.gov."
                                  },
                                  "leadSponsorName": {
                                    "type": "string",
                                    "description": "Lead sponsor name."
                                  },
                                  "riskSignals": {
                                    "type": "object",
                                    "description": "Per-trial risk signals, or null if none. Fields: nctId, enrollmentVelocity, durationRisk, designQuality."
                                  },
                                  "recentChanges": {
                                    "type": "array",
                                    "description": "Up to 5 most recent changelog entries for the trial; each entry has nctId, changeDate, severity, changes, briefTitle, phase."
                                  }
                                }
                              }
                            }
                          },
                          "changelogSummary": {
                            "type": "object",
                            "description": "90-day changelog severity rollup for the ticker.",
                            "properties": {
                              "CRITICAL": {
                                "type": "number",
                                "description": "Count of CRITICAL-severity changes in the last 90 days."
                              },
                              "HIGH": {
                                "type": "number",
                                "description": "Count of HIGH-severity changes."
                              },
                              "MEDIUM": {
                                "type": "number",
                                "description": "Count of MEDIUM-severity changes."
                              },
                              "LOW": {
                                "type": "number",
                                "description": "Count of LOW-severity changes."
                              },
                              "POSITIVE": {
                                "type": "number",
                                "description": "Count of POSITIVE-severity changes."
                              },
                              "totalChanges": {
                                "type": "number",
                                "description": "Total changelog entries in the last 90 days (capped at 100 by the underlying query)."
                              },
                              "trialsAffected": {
                                "type": "number",
                                "description": "Distinct trials (NCT IDs) touched by changes in the window."
                              }
                            }
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/clinical-trials/risk-signals": {
      "get": {
        "summary": "Per-trial clinical-trial risk signals: enrollment velocity vs phase/condition benchmarks, trial-duration overrun risk, a research-backed 6-category design-quality score (0-100), and AACT-derived competitive density. Computed by the pharma-service risk-signals pipeline over active industry-sponsored trials in Clinical Trials 2.0.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number (parseInt(query.page) || 1). pageSize is fixed at 50 internally; skip = (page-1)*50. pageSize is NOT a caller-settable query param."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to one company ticker. Upper-cased before matching the doc's ticker field."
          },
          {
            "name": "nctId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to one trial by ClinicalTrials.gov NCT id. Upper-cased before matching nctId."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "nctId": {
                            "type": "string",
                            "description": "ClinicalTrials.gov identifier of the trial."
                          },
                          "ticker": {
                            "type": "string",
                            "description": "Company stock ticker the trial is mapped to."
                          },
                          "phase": {
                            "type": "string",
                            "description": "Trial phase (e.g. PHASE2, PHASE3) from Clinical Trials 2.0."
                          },
                          "overallStatus": {
                            "type": "string",
                            "description": "Trial recruitment/overall status (RECRUITING, ACTIVE_NOT_RECRUITING, etc.)."
                          },
                          "conditions": {
                            "type": "string",
                            "description": "Conditions/indications the trial targets."
                          },
                          "briefTitle": {
                            "type": "string",
                            "description": "Brief title of the trial."
                          },
                          "enrollmentVelocity": {
                            "type": "object",
                            "properties": {
                              "enrollmentCount": {
                                "type": "number",
                                "description": "Enrollment count used for the velocity calc."
                              },
                              "enrollmentType": {
                                "type": "string",
                                "description": "ACTUAL | ESTIMATED | UNKNOWN."
                              },
                              "monthsElapsed": {
                                "type": "number",
                                "description": "Months elapsed from start to now, rounded to 0.1."
                              },
                              "velocity": {
                                "type": "number",
                                "description": "Patients enrolled per month (enrollmentCount / months), rounded to 0.1."
                              },
                              "benchmarkMedian": {
                                "type": "string",
                                "description": "Median peer velocity for the phase/condition benchmark; null when no benchmark."
                              },
                              "percentile": {
                                "type": "number",
                                "description": "Velocity percentile vs peers (defaults 50 when no benchmark)."
                              },
                              "rating": {
                                "type": "string",
                                "description": "VERY_FAST | FAST | AVERAGE | SLOW | STALLED."
                              },
                              "isStalled": {
                                "type": "boolean",
                                "description": "True if RECRUITING and lastUpdatePostDate is >90 days old."
                              },
                              "daysSinceUpdate": {
                                "type": "number",
                                "description": "Days since lastUpdatePostDate (0 when not applicable)."
                              },
                              "stalledSeverity": {
                                "type": "string",
                                "description": "CRITICAL (>180d) | WARNING (>90d) | null."
                              },
                              "benchmarkSampleSize": {
                                "type": "number",
                                "description": "Number of peer trials behind the benchmark (0 when none)."
                              }
                            }
                          },
                          "durationRisk": {
                            "type": "object",
                            "properties": {
                              "expectedDurationMonths": {
                                "type": "number",
                                "description": "Benchmark median duration (months), rounded to 0.1."
                              },
                              "actualElapsedMonths": {
                                "type": "number",
                                "description": "Actual months elapsed since start, rounded to 0.1."
                              },
                              "durationRatio": {
                                "type": "number",
                                "description": "actualElapsed / expected, rounded to 0.01."
                              },
                              "riskLevel": {
                                "type": "string",
                                "description": "CRITICAL (>2x) | HIGH (>1.5x) | MODERATE (>1x) | LOW."
                              },
                              "benchmarkSampleSize": {
                                "type": "number",
                                "description": "Peer sample size behind the benchmark."
                              }
                            }
                          },
                          "designQuality": {
                            "type": "object",
                            "description": "Research-backed 6-category trial-design quality score (always present).",
                            "properties": {
                              "score": {
                                "type": "number",
                                "description": "Composite design-quality score, clamped 0-100 (sum of the 6 component scores)."
                              },
                              "grade": {
                                "type": "string",
                                "description": "Letter grade derived from score via toGrade()."
                              },
                              "components": {
                                "type": "object",
                                "description": "Per-category breakdown with these six keys: studyArchitecture, blindingRigor, patientSelection, scalePower, regulatoryStrength, operationalQuality (each an object with score plus category-specific sub-fields)."
                              },
                              "scoringVersion": {
                                "type": "number",
                                "description": "Scoring algorithm version (2 = 6-category system)."
                              }
                            }
                          },
                          "competitiveDensity": {
                            "type": "object",
                            "properties": {
                              "condition": {
                                "type": "string",
                                "description": "Primary condition analyzed."
                              },
                              "competitorCount": {
                                "type": "number",
                                "description": "Distinct competing sponsors for the condition."
                              },
                              "densityLevel": {
                                "type": "string",
                                "description": "VERY_HIGH (>15) | HIGH (>8) | MODERATE (>3) | LOW."
                              },
                              "isFirstInClass": {
                                "type": "boolean",
                                "description": "True when competitorCount === 0."
                              },
                              "topCompetitors": {
                                "type": "string",
                                "description": "Up to 5 { sponsor, trialCount } competitors sorted by trial count desc."
                              }
                            }
                          },
                          "isBiomarkerSelected": {
                            "type": "boolean",
                            "description": "Whether enrollment is biomarker-selected (coerced to boolean)."
                          },
                          "hasDataMonitoringCommittee": {
                            "type": "boolean",
                            "description": "Whether the trial has a Data Monitoring Committee (coerced to boolean)."
                          },
                          "numberOfArms": {
                            "type": "number",
                            "description": "Number of trial arms (0 if unknown)."
                          },
                          "controlType": {
                            "type": "string",
                            "description": "Control type (e.g. PLACEBO, ACTIVE; UNKNOWN if absent)."
                          },
                          "computedAt": {
                            "type": "string",
                            "description": "When this signal doc was last computed."
                          },
                          "version": {
                            "type": "number",
                            "description": "Risk-signal doc schema version (2)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/clinical-trials/pipeline-health/{ticker}": {
      "get": {
        "summary": "Per-company clinical pipeline health grade: a weighted composite of five components (cash runway 0.25, enrollment momentum 0.25, insider conviction 0.15, pipeline diversification 0.15, trial-design quality 0.20) plus early-warning signals and a per-phase trial breakdown. Returns a single company document.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Company stock ticker (upper-cased). 400 if empty; 404 if no pipeline-health doc exists."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Parsed by getPagination but NOT applied; the single-doc response is not paginated and carries no pagination object."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Company stock ticker."
                          },
                          "companyName": {
                            "type": "string",
                            "description": "Company name from the companies collection (falls back to ticker)."
                          },
                          "pipelineScore": {
                            "type": "number",
                            "description": "Weighted composite pipeline health score (rounded; 0-100)."
                          },
                          "pipelineGrade": {
                            "type": "string",
                            "description": "Letter grade derived from pipelineScore via toGrade()."
                          },
                          "components": {
                            "type": "object",
                            "description": "Five weighted scoring components: cashRunway, enrollmentMomentum, insiderConviction, pipelineDiversification, trialDesignQuality.",
                            "properties": {
                              "cashRunway": {
                                "type": "object",
                                "description": "{ score, weight (0.25), riskLevel, runwayMonths, burnTrend } from sec_company_health; UNKNOWN/null fields when no health doc."
                              },
                              "enrollmentMomentum": {
                                "type": "object",
                                "description": "{ score, weight (0.25), avgVelocityPercentile, activeTrialCount, stalledTrialCount }."
                              },
                              "insiderConviction": {
                                "type": "object",
                                "description": "{ score, weight (0.15), buys180d, sells180d, totalTrades180d, netRatio, buyValue, sellValue } from insider trades (no-data branch omits totalTrades180d)."
                              },
                              "pipelineDiversification": {
                                "type": "object",
                                "description": "{ score, weight (0.15), distinctConditions, phases } across the company's active trials (phases = map of phase -> count)."
                              },
                              "trialDesignQuality": {
                                "type": "object",
                                "description": "{ score, weight (0.20), avgDesignScore } averaged over the company's trial design-quality scores."
                              }
                            }
                          },
                          "earlyWarnings": {
                            "type": "string",
                            "description": "Early-warning signals: each { type, severity, message, detectedAt }; STALLED_ENROLLMENT and CASH_CRUNCH rows also carry nctId. Types: STALLED_ENROLLMENT, CASH_CRUNCH, INSIDER_SELLING_SPIKE, DILUTION_WARNING, ADVERSE_EVENT_SURGE. Severities: CRITICAL | WARNING."
                          },
                          "activeTrialCount": {
                            "type": "number",
                            "description": "Number of active trials scored for this company."
                          },
                          "trialsByPhase": {
                            "type": "object",
                            "description": "Map of phase -> count of active trials in that phase (UNKNOWN bucket for missing phase)."
                          },
                          "computedAt": {
                            "type": "string",
                            "description": "When this company health doc was last computed."
                          },
                          "version": {
                            "type": "number",
                            "description": "Pipeline-health doc schema version (1)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/clinical-trials/changelog": {
      "get": {
        "summary": "Bitemporal trial change log (\"git diff for clinical trials\"): day-over-day changes to tracked trial fields, classified by changeType and rolled up to a per-trial severity, plus synthetic NEW_TRIAL and TRIAL_REMOVED rows. Filterable by ticker, severity, phase, and a recency window.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number (parseInt(query.page) || 1). pageSize is fixed at 50 internally and is not a caller-settable param."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of tickers; each trimmed and upper-cased, matched with $in."
          },
          {
            "name": "severity",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated severities; each trimmed and upper-cased (CRITICAL, HIGH, MEDIUM, LOW, POSITIVE), matched with $in."
          },
          {
            "name": "phase",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated phases; each trimmed (case preserved), matched with $in on the phase field."
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Lookback window in days; must be a positive integer (else 400). Filters changeDate >= now - days."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "nctId": {
                            "type": "string",
                            "description": "ClinicalTrials.gov identifier of the changed trial."
                          },
                          "ticker": {
                            "type": "string",
                            "description": "Company stock ticker the trial maps to."
                          },
                          "briefTitle": {
                            "type": "string",
                            "description": "Brief title of the trial."
                          },
                          "leadSponsorName": {
                            "type": "string",
                            "description": "Lead sponsor name."
                          },
                          "phase": {
                            "type": "string",
                            "description": "Trial phase at the time of the change. Present on field-diff rows; absent on synthetic NEW_TRIAL and TRIAL_REMOVED rows."
                          },
                          "changeDate": {
                            "type": "string",
                            "description": "Timestamp when the change was detected (diff run time)."
                          },
                          "changes": {
                            "type": "string",
                            "description": "List of detected field changes, each { field, old, new, changeType }. Synthetic rows use field NEW_TRIAL (changeType new_trial_detected or trial_first_observed, also carrying studyFirstPostDate and, for backfill artifacts, reason) or TRIAL_REMOVED (changeType trial_no_longer_active)."
                          },
                          "severity": {
                            "type": "string",
                            "description": "Roll-up severity: CRITICAL | HIGH | MEDIUM | LOW | POSITIVE; null on suppressed backfill-artifact rows."
                          },
                          "changeCount": {
                            "type": "number",
                            "description": "Number of changed fields in this entry. Present on field-diff rows; absent on synthetic NEW_TRIAL/TRIAL_REMOVED rows."
                          },
                          "isNewTrial": {
                            "type": "boolean",
                            "description": "True only when the entry represents a genuinely new trial registration (NEW_TRIAL with severity LOW)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/drug-pipeline/{ticker}": {
      "get": {
        "summary": "Canonical drug-pipeline reference for a company: the authoritative, deduplicated list of distinct drug assets the company is actively developing, with modality, per-indication phases, most-advanced phase, and active trial counts. One row per canonical drug, sorted by active trial count desc.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Company stock ticker (upper-cased). 400 if empty."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Parsed by getPagination and echoed in the pagination block, but the underlying query is NOT page-sliced (all matching rows returned, demo-capped at 5)."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Company stock ticker."
                          },
                          "canonicalKey": {
                            "type": "string",
                            "description": "Canonical dedup key for the drug (drugMatchKey; compound-id + brand-to-generic normalized)."
                          },
                          "displayName": {
                            "type": "string",
                            "description": "Human-readable drug name."
                          },
                          "allNames": {
                            "type": "string",
                            "description": "All observed name variants for this drug across its trials."
                          },
                          "modality": {
                            "type": "string",
                            "description": "Drug modality/class (e.g. small molecule, mAb, ADC) from detectModality."
                          },
                          "interventionType": {
                            "type": "string",
                            "description": "Intervention type (typically DRUG)."
                          },
                          "indications": {
                            "type": "string",
                            "description": "Per-indication entries, each { condition, phase, trialCount } where phase is the most-advanced phase observed for that condition."
                          },
                          "bestPhase": {
                            "type": "string",
                            "description": "Most advanced phase across the drug's active trials."
                          },
                          "activeTrialCount": {
                            "type": "number",
                            "description": "Count of active trials contributing to this drug (default sort key, desc)."
                          },
                          "nctIds": {
                            "type": "string",
                            "description": "Distinct NCT ids of the active trials for this drug."
                          },
                          "updatedAt": {
                            "type": "string",
                            "description": "When this reference row was last rebuilt."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/competitive-landscape/company/{ticker}": {
      "get": {
        "summary": "All indications where a given company competes, with its rank and the top competing companies in each indication.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Company ticker to look up; upper-cased server-side (req.params.ticker). Matched against competitors.ticker inside each landscape doc. Returns 400 if empty, 404 if the ticker appears in no landscape."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "The requested ticker (upper-cased)."
                          },
                          "companyName": {
                            "type": "string",
                            "description": "Company name of the ticker, taken from the first matching competitor entry that carries one; null if none did."
                          },
                          "totalIndications": {
                            "type": "number",
                            "description": "Count of indications in which this ticker competes (length of indications[])."
                          },
                          "indications": {
                            "type": "array",
                            "description": "One entry per indication where the ticker appears, sorted by totalTrials descending."
                          },
                          "indications[]": {
                            "type": "object",
                            "properties": {
                              "indication": {
                                "type": "string",
                                "description": "Indication name (doc.indication)."
                              },
                              "totalTrials": {
                                "type": "number",
                                "description": "Total trials across the whole competitive field for this indication (doc.totalTrials)."
                              },
                              "totalCompetitors": {
                                "type": "number",
                                "description": "Total competitor companies in this indication (doc.totalCompetitors)."
                              },
                              "marketData": {
                                "type": "string",
                                "description": "Market data block for the indication (doc.marketData), or null if absent."
                              },
                              "rank": {
                                "type": "number",
                                "description": "This company's 1-based rank within the indication when competitors are sorted by competitiveStrength descending (idx + 1)."
                              },
                              "thisCompany": {
                                "type": "object",
                                "description": "This company's own competitor entry for the indication, with the heavy nested trials[] array stripped (stripTrials). The remaining stored competitor fields pass through verbatim; ticker, companyName, and competitiveStrength are the ones the code references explicitly."
                              },
                              "topCompetitors": {
                                "type": "array",
                                "description": "Up to 10 other competitor entries (excluding this ticker) sorted by competitiveStrength descending, each with trials[] stripped (same competitor object shape as thisCompany)."
                              }
                            }
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/competitive-landscape/indication/{indication}": {
      "get": {
        "summary": "Full competitive field (all competing companies) for a single indication, ranked by competitive strength.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "indication",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Indication name; decodeURIComponent'd and trimmed (req.params.indication). Looked up first by exact match, then by case-insensitive anchored regex (^...$). Returns 400 if empty, 404 if no landscape exists for it."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "indication": {
                            "type": "string",
                            "description": "Indication name as stored on the matched doc (doc.indication), not necessarily the raw param."
                          },
                          "totalTrials": {
                            "type": "number",
                            "description": "Total trials across the competitive field for this indication (doc.totalTrials)."
                          },
                          "totalCompetitors": {
                            "type": "number",
                            "description": "Total competitor companies in this indication (doc.totalCompetitors)."
                          },
                          "marketData": {
                            "type": "string",
                            "description": "Market data block for the indication (doc.marketData), or null if absent."
                          },
                          "competitors": {
                            "type": "array",
                            "description": "All competitor entries for the indication, sorted by competitiveStrength descending, each with the nested trials[] array stripped (stripTrials). Each entry's stored fields pass through verbatim; ticker, companyName, and competitiveStrength are referenced explicitly in code."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/ma/target-scores": {
      "get": {
        "summary": "Acquisition-likelihood scores for biotech targets (a 10-signal composite), listable and filterable, ranked by total score.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 30 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 30,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number (parseInt(query.page) || 1; defaults to 1). Fixed page size of 50 rows (getPagination)."
          },
          {
            "name": "ticker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single ticker (upper-cased server-side); matches the stored ticker exactly."
          },
          {
            "name": "tier",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of tier values; each split value is trimmed and upper-cased, matched with $in against the doc's tier."
          },
          {
            "name": "minScore",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Minimum totalScore (parseFloat, matched with $gte). Returns 400 if not a number."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Target company ticker."
                          },
                          "companyName": {
                            "type": "string",
                            "description": "Target company name."
                          },
                          "totalScore": {
                            "type": "number",
                            "description": "Composite acquisition-likelihood score; result is sorted by this descending."
                          },
                          "tier": {
                            "type": "string",
                            "description": "Score tier classification for the target."
                          },
                          "marketCap": {
                            "type": "number",
                            "description": "Target market capitalization."
                          },
                          "cashRunway_months": {
                            "type": "number",
                            "description": "Estimated cash runway in months."
                          },
                          "signals": {
                            "type": "object",
                            "description": "Breakdown of the individual signals that make up the composite score (passed through whole)."
                          },
                          "potentialAcquirers": {
                            "type": "array",
                            "description": "Candidate acquirers identified for this target (passed through whole)."
                          },
                          "computedAt": {
                            "type": "string",
                            "description": "When the score was computed."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/ma/target-scores/{ticker}": {
      "get": {
        "summary": "Single company's M&A target score document plus its related deal history.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 60 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 60,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Target ticker (upper-cased server-side, req.params.ticker). Returns 400 if empty, 404 if no target score exists for it."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "(target document fields)": {
                            "type": "object",
                            "description": "The full MA_TARGET_SCORES document for the ticker with projection { _id: 0, _meta: 0 } (exclude-only, so EVERY other stored field is returned, not a whitelist). Includes at least the fields the list endpoint projects: ticker, companyName, totalScore, tier, marketCap, cashRunway_months, signals, potentialAcquirers, computedAt, plus any other stored fields. relatedDeals is appended as a sibling key on this same object."
                          },
                          "relatedDeals": {
                            "type": "array",
                            "description": "Deals from maDealsCol (MA_TRACKER_DEALS) where target.ticker matches, sorted by announcementDate descending. Each element is projected to the exact whitelist below (_id:0)."
                          },
                          "relatedDeals[]": {
                            "type": "object",
                            "properties": {
                              "dealId": {
                                "type": "string",
                                "description": "Deal identifier."
                              },
                              "acquirer": {
                                "type": "object",
                                "properties": {
                                  "ticker": {
                                    "type": "string",
                                    "description": "Acquirer ticker."
                                  },
                                  "name": {
                                    "type": "string",
                                    "description": "Acquirer name."
                                  }
                                }
                              },
                              "dealType": {
                                "type": "string",
                                "description": "Type of deal (e.g. acquisition / merger / licensing)."
                              },
                              "dealValue": {
                                "type": "object",
                                "properties": {
                                  "amountM": {
                                    "type": "number",
                                    "description": "Deal value in millions USD."
                                  },
                                  "premiumPct": {
                                    "type": "number",
                                    "description": "Acquisition premium percentage."
                                  }
                                }
                              },
                              "status": {
                                "type": "string",
                                "description": "Deal status."
                              },
                              "announcementDate": {
                                "type": "string",
                                "description": "Date the deal was announced."
                              }
                            }
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/ma/deals": {
      "get": {
        "summary": "Curated biotech M&A deal history (2019 onward), filterable by acquirer, target, deal type, status, and therapeutic area.",
        "description": " Plan: BiopharmaWatch API Basic. Rate limit: 30 requests / 60s.",
        "tags": [
          "API Basic"
        ],
        "x-tier": "basic",
        "x-rate-limit": {
          "limit": 30,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number (defaults to 1). Fixed page size of 50 rows (getPagination)."
          },
          {
            "name": "acquirerTicker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by acquirer.ticker (upper-cased server-side)."
          },
          {
            "name": "targetTicker",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by target.ticker (upper-cased server-side)."
          },
          {
            "name": "dealType",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of deal types (each split value trimmed, NOT case-changed); matched with $in against dealType."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of statuses (each split value trimmed, NOT case-changed); matched with $in against status."
          },
          {
            "name": "therapeuticArea",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive regex (escapeRe + 'i' flag) substring match against the deal's therapeuticAreas field."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "(full deal document)": {
                            "type": "object",
                            "description": "Each row is the full MA_TRACKER_DEALS document with projection { _id: 0, _meta: 0 } (exclude-only, NO field whitelist) so every other stored field is returned. Fields the codebase references explicitly: dealId (string), acquirer.ticker (string), acquirer.name (string), target.ticker (string), dealType (string), dealValue.amountM (number, USD millions), dealValue.premiumPct (number), status (string), announcementDate (date), therapeuticAreas (string or array, used by the regex filter)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    },
    "/api/v2/ma/acquirers": {
      "get": {
        "summary": "Acquirer leaderboard aggregated from the deal history: deal count, total spend, average premium, last deal date, and deal types per acquirer.",
        "description": " Plan: BiopharmaWatch API Elite Plus. Rate limit: 30 requests / 60s.",
        "tags": [
          "Elite Plus"
        ],
        "x-tier": "elite",
        "x-rate-limit": {
          "limit": 30,
          "window_seconds": 60
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "1-based page number (defaults to 1). Fixed page size of 50 rows (getPagination). No other query params are read by this endpoint."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "result": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ticker": {
                            "type": "string",
                            "description": "Acquirer ticker (the $group _id on acquirer.ticker, renamed to ticker in $project)."
                          },
                          "name": {
                            "type": "string",
                            "description": "Acquirer name ($first acquirer.name seen in the group)."
                          },
                          "dealCount": {
                            "type": "number",
                            "description": "Number of deals by this acquirer ($sum: 1); result sorted by this descending, then totalSpendM descending."
                          },
                          "totalSpendM": {
                            "type": "number",
                            "description": "Sum of dealValue.amountM across the acquirer's deals ($ifNull nulls -> 0), rounded to 2 decimals."
                          },
                          "avgPremium": {
                            "type": "number",
                            "description": "Average dealValue.premiumPct across the acquirer's deals ($avg), rounded to 2 decimals."
                          },
                          "lastDealDate": {
                            "type": "string",
                            "description": "Most recent announcementDate among the acquirer's deals ($max)."
                          },
                          "dealTypes": {
                            "type": "array",
                            "description": "Distinct set of dealType values for this acquirer ($addToSet)."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    },
                    "Note": {
                      "type": "string",
                      "description": "Present on demo keys only."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key"
          },
          "403": {
            "description": "Tier or bundle not permitted, access paused/expired"
          },
          "429": {
            "description": "Rate limit exceeded (per-minute limit)"
          }
        }
      }
    }
  }
}
