{
  "openapi": "3.0.3",
  "info": {
    "title": "StocksSG API",
    "description": "Programmatic access to Singapore-listed company data, board intelligence, financial analytics, and charity information. Covers SGX-listed issuers, directors, fair value estimates, dividend safety scores, accounting quality indicators, and more.",
    "version": "1.0.0",
    "contact": {
      "name": "StocksSG API Support",
      "url": "https://stocks.com.sg/developers",
      "email": "api@stocks.com.sg"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://stocks.com.sg/terms"
    }
  },
  "servers": [
    {
      "url": "https://stocks.com.sg",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Companies",
      "description": "SGX-listed company data including profiles, officers, and financial details"
    },
    {
      "name": "Directors",
      "description": "Board director search and company board listings"
    },
    {
      "name": "Analytics",
      "description": "Quantitative models — fair value, dividend safety, accounting quality, and financial distress"
    },
    {
      "name": "Screener",
      "description": "Multi-factor stock screener with filtering and sorting"
    },
    {
      "name": "Charities",
      "description": "Singapore registered charity data, financials, and ratings"
    },
    {
      "name": "Research",
      "description": "AI-powered deep research reports (SSE streaming)"
    }
  ],
  "paths": {
    "/api/v1/companies": {
      "get": {
        "tags": ["Companies"],
        "summary": "List companies",
        "description": "Returns all SGX-listed companies, optionally filtered by search query or sector.",
        "operationId": "listCompanies",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Search query (matches company name or ticker)",
            "schema": { "type": "string" },
            "example": "DBS"
          },
          {
            "name": "sector",
            "in": "query",
            "description": "Filter by GICS sector",
            "schema": { "type": "string" },
            "example": "Financials"
          }
        ],
        "responses": {
          "200": {
            "description": "List of companies",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Company" }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "count": { "type": "integer" }
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "ticker": "D05",
                      "company_name": "DBS Group Holdings Ltd",
                      "gics_sector": "Financials",
                      "gics_industry_group": "Banks",
                      "market_cap_sgd": 112000000000
                    }
                  ],
                  "meta": { "count": 1 }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/companies/{ticker}": {
      "get": {
        "tags": ["Companies"],
        "summary": "Company detail",
        "description": "Returns detailed profile for a single SGX-listed company by ticker.",
        "operationId": "getCompany",
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "description": "SGX ticker symbol",
            "schema": { "type": "string" },
            "example": "D05"
          }
        ],
        "responses": {
          "200": {
            "description": "Company detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/CompanyDetail" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/directors": {
      "get": {
        "tags": ["Directors"],
        "summary": "Search directors",
        "description": "Search for directors by name, or list board members for a specific company by ticker. One of `q` or `ticker` is required.",
        "operationId": "listDirectors",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Search director name (case-insensitive partial match)",
            "schema": { "type": "string" },
            "example": "Piyush Gupta"
          },
          {
            "name": "ticker",
            "in": "query",
            "description": "List current board members for this ticker",
            "schema": { "type": "string" },
            "example": "D05"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum results (default 50, max 200)",
            "schema": { "type": "integer", "default": 50, "maximum": 200 }
          }
        ],
        "responses": {
          "200": {
            "description": "List of directors",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Director" }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing required parameter",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" },
                "example": { "error": "Provide ?q=name or ?ticker=DBS" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/officers/{ticker}": {
      "get": {
        "tags": ["Companies"],
        "summary": "Company officers",
        "description": "Returns all board members and executives for a company, including current and former officers with appointment dates.",
        "operationId": "getOfficers",
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "description": "SGX ticker symbol",
            "schema": { "type": "string" },
            "example": "D05"
          },
          {
            "name": "type",
            "in": "query",
            "description": "Filter by officer type",
            "schema": { "type": "string", "enum": ["board", "executive"] }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by current/former status",
            "schema": { "type": "string", "enum": ["current", "former"] }
          },
          {
            "name": "from",
            "in": "query",
            "description": "Filter appointments from this date (YYYY-MM-DD)",
            "schema": { "type": "string", "format": "date" }
          },
          {
            "name": "to",
            "in": "query",
            "description": "Filter appointments up to this date (YYYY-MM-DD)",
            "schema": { "type": "string", "format": "date" }
          }
        ],
        "responses": {
          "200": {
            "description": "Officers list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "ticker": { "type": "string" },
                        "company_name": { "type": "string" },
                        "officers": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/Officer" }
                        },
                        "total_count": { "type": "integer" },
                        "current_count": { "type": "integer" }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "ticker": "D05",
                    "company_name": "DBS Group Holdings Ltd",
                    "officers": [
                      {
                        "name": "Piyush Gupta",
                        "type": "executive",
                        "role": "Chief Executive Officer",
                        "is_current": true,
                        "appointed_date": "2009-11-09",
                        "departed_date": null,
                        "is_independent": null,
                        "permanent_id": null
                      }
                    ],
                    "total_count": 25,
                    "current_count": 18
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/screener": {
      "get": {
        "tags": ["Screener"],
        "summary": "Stock screener",
        "description": "Multi-factor stock screener. Returns all SGX-listed companies with fundamental, governance, and market data columns. Supports filtering by sector, index membership, and market cap range.",
        "operationId": "screener",
        "parameters": [
          {
            "name": "sector",
            "in": "query",
            "description": "Filter by GICS sector",
            "schema": { "type": "string" },
            "example": "Financials"
          },
          {
            "name": "index",
            "in": "query",
            "description": "Filter by index membership",
            "schema": { "type": "string", "enum": ["STI", "FTSE_ST_MID", "FTSE_ST_SMALL"] }
          },
          {
            "name": "min_mcap",
            "in": "query",
            "description": "Minimum market cap in SGD",
            "schema": { "type": "integer" },
            "example": 1000000000
          },
          {
            "name": "max_mcap",
            "in": "query",
            "description": "Maximum market cap in SGD",
            "schema": { "type": "integer" }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Column to sort by (default: market_cap_sgd)",
            "schema": { "type": "string", "default": "market_cap_sgd" }
          },
          {
            "name": "dir",
            "in": "query",
            "description": "Sort direction",
            "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" }
          }
        ],
        "responses": {
          "200": {
            "description": "Screener results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/ScreenerRow" }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "count": { "type": "integer" },
                        "columns": {
                          "type": "array",
                          "items": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/fair-value/{ticker}": {
      "get": {
        "tags": ["Analytics"],
        "summary": "Fair value estimate",
        "description": "Three-model valuation estimate (DCF, DDM, EV/EBITDA relative) for an SGX-listed company. Not financial advice.",
        "operationId": "getFairValue",
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "description": "SGX ticker symbol",
            "schema": { "type": "string" },
            "example": "D05"
          }
        ],
        "responses": {
          "200": {
            "description": "Fair value estimates",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/FairValue" }
                  }
                },
                "example": {
                  "data": {
                    "ticker": "D05",
                    "company_name": "DBS Group Holdings Ltd",
                    "current_price": 38.50,
                    "composite_fair_value": 42.10,
                    "upside_pct": 9.35,
                    "verdict": "Slightly Undervalued",
                    "models": {
                      "dcf": { "value": 44.20, "confidence": "medium" },
                      "ddm": { "value": 40.50, "confidence": "high" },
                      "ev_ebitda": { "value": 41.60, "confidence": "medium" }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/dividend-safety/{ticker}": {
      "get": {
        "tags": ["Analytics"],
        "summary": "Dividend safety score",
        "description": "Multi-factor dividend safety assessment including yield, payout ratio, streak, and coverage analysis.",
        "operationId": "getDividendSafety",
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "description": "SGX ticker symbol",
            "schema": { "type": "string" },
            "example": "O39"
          }
        ],
        "responses": {
          "200": {
            "description": "Dividend safety analysis",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/DividendSafety" }
                  }
                },
                "example": {
                  "data": {
                    "ticker": "O39",
                    "company_name": "OCBC Bank",
                    "score": 82,
                    "grade": "A",
                    "is_reit": false,
                    "dividend_yield_pct": 5.2,
                    "dps_sgd": 0.72,
                    "payout_ratio_pct": 48.5,
                    "streak_years": 10,
                    "components": {}
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/accounting-quality/{ticker}": {
      "get": {
        "tags": ["Analytics"],
        "summary": "Accounting quality (Beneish M-Score)",
        "description": "Forensic accounting indicators including Beneish M-Score, Sloan Accruals Ratio, and composite quality score. Requires at least one year of financial data.",
        "operationId": "getAccountingQuality",
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "description": "SGX ticker symbol",
            "schema": { "type": "string" },
            "example": "Z74"
          }
        ],
        "responses": {
          "200": {
            "description": "Accounting quality analysis",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/AccountingQuality" },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "methodology": { "type": "string" },
                        "disclaimer": { "type": "string" }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/financial-distress/{ticker}": {
      "get": {
        "tags": ["Analytics"],
        "summary": "Financial distress (Altman Z-Score)",
        "description": "Financial distress indicators including Altman Z-Score (original and adjusted) and Piotroski F-Score. REITs are excluded from Z-Score calculations due to structural leverage.",
        "operationId": "getFinancialDistress",
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "description": "SGX ticker symbol",
            "schema": { "type": "string" },
            "example": "U11"
          }
        ],
        "responses": {
          "200": {
            "description": "Financial distress analysis",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/FinancialDistress" },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "models": {
                          "type": "array",
                          "items": { "type": "string" }
                        },
                        "disclaimer": { "type": "string" }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/charities": {
      "get": {
        "tags": ["Charities"],
        "summary": "List charities",
        "description": "Search Singapore registered charities by name, or filter by state. Returns aggregate stats when called without filters.",
        "operationId": "listCharities",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Search charity name",
            "schema": { "type": "string" },
            "example": "community"
          },
          {
            "name": "state",
            "in": "query",
            "description": "Filter by registration state",
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "List of charities or stats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "oneOf": [
                        {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/Charity" }
                        },
                        { "$ref": "#/components/schemas/CharityStats" }
                      ]
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "count": { "type": "integer" },
                        "hint": { "type": "string" }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/charities/{slug}": {
      "get": {
        "tags": ["Charities"],
        "summary": "Charity detail",
        "description": "Returns full charity profile including financials, officers, and rating.",
        "operationId": "getCharity",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Charity URL slug",
            "schema": { "type": "string" },
            "example": "singapore-red-cross"
          }
        ],
        "responses": {
          "200": {
            "description": "Charity detail with financials and officers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/CharityDetail" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/degrees-of-separation": {
      "get": {
        "tags": ["Directors"],
        "summary": "Board network — degrees of separation",
        "description": "Finds the shortest connection path between two directors through shared board memberships. Uses BFS with a maximum depth of 6 degrees.",
        "operationId": "getDegreesOfSeparation",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "Source director ID (UUID)",
            "schema": { "type": "string", "format": "uuid" }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "Target director ID (UUID)",
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "responses": {
          "200": {
            "description": "Connection path between directors",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/DegreesOfSeparation" }
                  }
                },
                "example": {
                  "data": {
                    "from": "abc-123",
                    "to": "def-456",
                    "connected": true,
                    "degrees": 2,
                    "path": [
                      { "person_id": "abc-123", "person_name": "John Tan", "company_ticker": null, "company_name": null },
                      { "person_id": "ghi-789", "person_name": "Jane Lim", "company_ticker": "D05", "company_name": "DBS Group Holdings Ltd" },
                      { "person_id": "def-456", "person_name": "Peter Wong", "company_ticker": "O39", "company_name": "OCBC Bank" }
                    ],
                    "shared_companies": []
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid parameters",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/deep-research/{ticker}": {
      "get": {
        "tags": ["Research"],
        "summary": "AI deep research report",
        "description": "Generates a comprehensive AI-powered research report for an SGX-listed company. Returns Server-Sent Events (SSE) stream with progressive content. Requires Pro tier or above.",
        "operationId": "deepResearch",
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "required": true,
            "description": "SGX ticker symbol",
            "schema": { "type": "string" },
            "example": "D05"
          }
        ],
        "responses": {
          "200": {
            "description": "SSE stream of research report chunks",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Server-Sent Events stream. Each event contains a `data` field with a JSON object containing `type` (section/content/done) and `content` (markdown text)."
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key for authentication. Requests without an API key are treated as free tier (10 requests/minute). Pass your key via the `x-api-key` header."
      }
    },
    "schemas": {
      "Company": {
        "type": "object",
        "properties": {
          "ticker": { "type": "string", "example": "D05" },
          "company_name": { "type": "string", "example": "DBS Group Holdings Ltd" },
          "gics_sector": { "type": "string", "example": "Financials" },
          "gics_industry_group": { "type": "string", "example": "Banks" },
          "market_cap_sgd": { "type": "number", "example": 112000000000 }
        }
      },
      "CompanyDetail": {
        "type": "object",
        "properties": {
          "ticker": { "type": "string" },
          "company_name": { "type": "string" },
          "gics_sector": { "type": "string" },
          "gics_industry_group": { "type": "string" },
          "market_cap_sgd": { "type": "number" },
          "website": { "type": "string" },
          "description": { "type": "string" },
          "uen": { "type": "string", "description": "Unique Entity Number (Singapore business identifier)" },
          "index_membership": {
            "type": "array",
            "items": { "type": "string" }
          },
          "listing_date": { "type": "string", "format": "date" }
        }
      },
      "Director": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "full_name": { "type": "string", "example": "Piyush Gupta" },
          "gender": { "type": "string", "enum": ["M", "F"] },
          "nationality": { "type": "string" },
          "birth_year": { "type": "integer" }
        }
      },
      "Officer": {
        "type": "object",
        "properties": {
          "name": { "type": "string", "example": "Piyush Gupta" },
          "type": { "type": "string", "enum": ["board", "executive"] },
          "role": { "type": "string", "example": "Chief Executive Officer" },
          "is_current": { "type": "boolean" },
          "appointed_date": { "type": "string", "format": "date", "nullable": true },
          "departed_date": { "type": "string", "format": "date", "nullable": true },
          "is_independent": { "type": "boolean", "nullable": true },
          "permanent_id": { "type": "string", "nullable": true }
        }
      },
      "ScreenerRow": {
        "type": "object",
        "description": "Row from the screener view. Contains many columns — key ones listed here.",
        "properties": {
          "ticker": { "type": "string" },
          "company_name": { "type": "string" },
          "gics_sector": { "type": "string" },
          "gics_industry_group": { "type": "string" },
          "market_cap_sgd": { "type": "number" },
          "pe_ratio": { "type": "number", "nullable": true },
          "dividend_yield_pct": { "type": "number", "nullable": true },
          "roe_pct": { "type": "number", "nullable": true },
          "debt_to_equity": { "type": "number", "nullable": true }
        }
      },
      "FairValue": {
        "type": "object",
        "properties": {
          "ticker": { "type": "string" },
          "company_name": { "type": "string" },
          "current_price": { "type": "number" },
          "composite_fair_value": { "type": "number" },
          "upside_pct": { "type": "number" },
          "verdict": { "type": "string", "example": "Slightly Undervalued" },
          "models": {
            "type": "object",
            "properties": {
              "dcf": { "$ref": "#/components/schemas/ValuationModel" },
              "ddm": { "$ref": "#/components/schemas/ValuationModel" },
              "ev_ebitda": { "$ref": "#/components/schemas/ValuationModel" }
            }
          }
        }
      },
      "ValuationModel": {
        "type": "object",
        "properties": {
          "value": { "type": "number" },
          "confidence": { "type": "string", "enum": ["low", "medium", "high"] }
        }
      },
      "DividendSafety": {
        "type": "object",
        "properties": {
          "ticker": { "type": "string" },
          "company_name": { "type": "string" },
          "score": { "type": "integer", "description": "0-100 safety score" },
          "grade": { "type": "string", "enum": ["A+", "A", "B+", "B", "C+", "C", "D", "F"] },
          "is_reit": { "type": "boolean" },
          "dividend_yield_pct": { "type": "number" },
          "dps_sgd": { "type": "number", "description": "Dividends per share in SGD" },
          "payout_ratio_pct": { "type": "number" },
          "streak_years": { "type": "integer", "description": "Consecutive years of dividends" },
          "components": { "type": "object", "description": "Individual scoring component breakdown" }
        }
      },
      "AccountingQuality": {
        "type": "object",
        "properties": {
          "ticker": { "type": "string" },
          "company_name": { "type": "string" },
          "m_score": { "type": "number", "description": "Beneish M-Score (< -1.78 = low manipulation risk)" },
          "manipulation_risk": { "type": "string", "enum": ["low", "moderate", "high"] },
          "accruals_ratio": { "type": "number" },
          "quality_score": { "type": "number", "description": "Composite quality score 0-100" },
          "components": { "type": "object" }
        }
      },
      "FinancialDistress": {
        "type": "object",
        "properties": {
          "ticker": { "type": "string" },
          "company_name": { "type": "string" },
          "altman_z": { "type": "number", "description": "Altman Z-Score (> 2.99 = safe, < 1.81 = distress)" },
          "altman_z_adjusted": { "type": "number", "description": "Adjusted Z-Score for non-manufacturing firms" },
          "piotroski_f": { "type": "integer", "description": "Piotroski F-Score (0-9, higher = stronger)" },
          "zone": { "type": "string", "enum": ["safe", "grey", "distress"] },
          "is_reit": { "type": "boolean" }
        }
      },
      "Charity": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "slug": { "type": "string" },
          "uen": { "type": "string" },
          "registration_status": { "type": "string" },
          "sector": { "type": "string" }
        }
      },
      "CharityStats": {
        "type": "object",
        "properties": {
          "total_charities": { "type": "integer" },
          "active_charities": { "type": "integer" },
          "total_revenue": { "type": "number" }
        }
      },
      "CharityDetail": {
        "type": "object",
        "properties": {
          "charity": { "$ref": "#/components/schemas/Charity" },
          "financials": { "type": "array", "items": { "type": "object" } },
          "officers": { "type": "array", "items": { "type": "object" } },
          "rating": { "type": "object", "nullable": true }
        }
      },
      "DegreesOfSeparation": {
        "type": "object",
        "properties": {
          "from": { "type": "string" },
          "to": { "type": "string" },
          "connected": { "type": "boolean" },
          "degrees": { "type": "integer", "nullable": true },
          "path": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "person_id": { "type": "string" },
                "person_name": { "type": "string" },
                "company_ticker": { "type": "string", "nullable": true },
                "company_name": { "type": "string", "nullable": true }
              }
            }
          },
          "shared_companies": {
            "type": "array",
            "items": { "type": "string" }
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string" }
        },
        "required": ["error"]
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Invalid or inactive API key",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": { "error": "Invalid API key" }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": { "error": "Company D05 not found" }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": { "error": "Rate limit exceeded. Upgrade your plan for higher limits." }
          }
        }
      }
    }
  }
}
