{"openapi":"3.1.0","info":{"title":"Halal Terminal API","description":"The **Halal Terminal API** is the most comprehensive Islamic finance data\nplatform available — 58+ REST endpoints, 22 MCP tools, and 7 AI resources\nacross 15 categories covering Shariah screening, market data, portfolio\ncompliance, ETF analysis, news, SEC filings, dividends, zakat calculators,\nand more. Connect via REST API or MCP (Model Context Protocol) for AI-native access.\n\n---\n\n## Quick start\n\n**1. Get a free API key** — no credit card required:\n\n```bash\ncurl -X POST https://api.halalterminal.com/api/keys/generate \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\": \"you@example.com\"}'\n```\n\n**2. Screen your first stock:**\n\n```bash\ncurl https://api.halalterminal.com/api/screen?symbol=AAPL \\\n  -H \"X-API-Key: YOUR_KEY\"\n```\n\n**3. Parse the response:**\n\n```json\n{\n  \"symbol\": \"AAPL\",\n  \"is_compliant\": true,\n  \"compliance_status\": \"COMPLIANT\",\n  \"revenue_breakdown\": { ... },\n  \"financial_ratios\": { ... }\n}\n```\n\nThat's it — you're screening.\n\n---\n\n## Authentication\n\nEvery `/api/*` request must include your key in the `X-API-Key` header.\n\n**Exempt endpoints** (no key required): `GET /api/health`,\n`POST /api/keys/*`, `POST /api/billing/*`.\n\n### Code examples\n\n**Python**\n```python\nimport requests\n\nheaders = {\"X-API-Key\": \"YOUR_KEY\"}\nr = requests.get(\n    \"https://api.halalterminal.com/api/screen\",\n    params={\"symbol\": \"AAPL\"},\n    headers=headers,\n)\nprint(r.json())\n```\n\n**JavaScript (fetch)**\n```javascript\nconst res = await fetch(\n  \"https://api.halalterminal.com/api/screen?symbol=AAPL\",\n  { headers: { \"X-API-Key\": \"YOUR_KEY\" } }\n);\nconst data = await res.json();\n```\n\n---\n\n## Plans & token-based pricing\n\n| Plan | Tokens / month | Price | Overage |\n|------|---------------:|------:|---------|\n| **Free** | 50 | $0 | Hard block |\n| **Starter** | 2,500 | $19/mo | $0.01/token |\n| **Pro** | 15,000 | $49/mo | $0.008/token |\n| **Enterprise** | Unlimited | $199/mo | N/A |\n\nEach API request costs a certain number of **tokens** depending on the\nendpoint. Lightweight reads (database search, news) cost **1 token**,\nstandard reads (quotes, OHLC) cost **2 tokens**, screening and heavy\noperations cost **5–50 tokens**. Free endpoints (health, education,\napi-keys, billing) cost **0 tokens**.\n\nSee the full cost table at [`GET /api/keys/token-costs`](/api/keys/token-costs).\n\n**Overage**: Free plan hard-blocks at the limit. Paid plans continue\nat the per-token overage rate — you're never locked out. Token usage\nresets monthly.\n\nUpgrade anytime via the [billing endpoint](/api/billing/checkout).\n\n---\n\n## Common recipes\n\n| Use case | Endpoint | Method |\n|----------|----------|--------|\n| Screen a single stock | `/api/screen?symbol=AAPL` | GET |\n| Bulk-screen an index | `/api/screen-bulk` | POST |\n| Get real-time quote | `/api/quote/{symbol}` | GET |\n| Check portfolio compliance | `/api/portfolio/scan` | POST |\n| Screen an ETF's holdings | `/api/etf/{symbol}/screening` | GET |\n| Calculate zakat | `/api/zakat/calculate` | POST |\n| Calculate dividend purification | `/api/dividends/{symbol}/purification` | GET |\n| Search the stock database | `/api/database/search?q=apple` | GET |\n| Get market news | `/api/news/market` | GET |\n| Fetch SEC filings | `/api/filings/{symbol}` | GET |\n\n---\n\n## Error handling\n\nAll errors return a consistent JSON envelope:\n\n```json\n{\n  \"code\": \"ERROR_CODE\",\n  \"message\": \"Human-readable explanation\",\n  \"detail\": null\n}\n```\n\n| Status | Code | Meaning |\n|--------|------|---------|\n| 400 | `HTTP_400` | Bad request — check parameters |\n| 401 | `API_KEY_REQUIRED` | Missing `X-API-Key` header |\n| 401 | `INVALID_API_KEY` | Key does not exist |\n| 403 | `API_KEY_DEACTIVATED` | Key has been disabled |\n| 404 | `HTTP_404` | Resource not found |\n| 429 | `QUOTA_EXCEEDED` | Monthly quota exhausted — upgrade plan |\n| 500 | `INTERNAL_ERROR` | Server error — retry or contact support |\n\n---\n\n## Rate limits & headers\n\nEvery authenticated response includes:\n\n| Header | Description |\n|--------|-------------|\n| `X-Request-ID` | Unique request identifier for debugging |\n| `X-Tokens-Charged` | Number of tokens deducted for this request |\n| `X-Tokens-Remaining` | Tokens remaining in the current billing period (-1 = unlimited) |\n| `X-Tokens-Overage` | Present and set to `true` when the request exceeded the plan allowance |\n\nWhen you hit your quota the `429` response includes your current\n`plan`, `tokens_limit`, and `tokens_used` in the `detail` field.\n\n---\n","version":"1.0.0"},"paths":{"/api/health":{"get":{"tags":["health"],"summary":"Health Check","description":"Check API health status.\n\nReturns a simple status message confirming the API is running.\nThis endpoint requires no authentication and is suitable for\nuptime monitors and load-balancer health probes.\n\n**curl example**:\n```bash\ncurl https://api.halalterminal.com/api/health\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.get(\"https://api.halalterminal.com/api/health\")\nprint(resp.json()[\"message\"])\n```","operationId":"health_check_api_health_get","responses":{"200":{"description":"API health status message","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}},"security":[]}},"/api/screen-bulk/indices":{"get":{"tags":["screening"],"summary":"List Indices","description":"List available stock indices for bulk screening.\n\nReturns every index supported by the bulk-screening engine, along with\nan estimated ticker count and a short description.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/screen-bulk/indices\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/screen-bulk/indices\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"list_indices_api_screen_bulk_indices_get","responses":{"200":{"description":"List of available stock indices with metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndicesResponse"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"}}}},"/api/screen-bulk/status":{"get":{"tags":["screening"],"summary":"Bulk Status","description":"Get the status of a bulk screening run.\n\nReturns real-time progress for the active run (or a specific run if\n`run_id` is provided), including completion percentage, current symbol\nbeing processed, and estimated time remaining.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/screen-bulk/status?run_id=abc123\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/screen-bulk/status\",\n    params={\"run_id\": \"abc123\"},\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"bulk_status_api_screen_bulk_status_get","parameters":[{"name":"run_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id"}}],"responses":{"200":{"description":"Current status of the active or most recent bulk screening run","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkStatusResponse"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screen-bulk/runs":{"get":{"tags":["screening"],"summary":"List Runs","description":"List historical bulk screening runs.\n\nReturns a paginated history of screening runs, optionally filtered by\nindex name (e.g. \"SP500\") or status (e.g. \"completed\", \"running\").\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/screen-bulk/runs?index_name=SP500&page=1&page_size=10\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/screen-bulk/runs\",\n    params={\"index_name\": \"SP500\", \"page\": 1, \"page_size\": 10},\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"list_runs_api_screen_bulk_runs_get","parameters":[{"name":"index_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Index Name"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Paginated list of past and current screening runs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunHistoryResponse"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screen-bulk/compare":{"get":{"tags":["screening"],"summary":"Compare Runs","description":"Compare the results of two bulk screening runs.\n\nIdentifies symbols whose compliance status changed between run A and\nrun B, including newly compliant, newly non-compliant, added, and\nremoved symbols.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/screen-bulk/compare?run_a=abc123&run_b=def456\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/screen-bulk/compare\",\n    params={\"run_a\": \"abc123\", \"run_b\": \"def456\"},\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"compare_runs_api_screen_bulk_compare_get","parameters":[{"name":"run_a","in":"query","required":true,"schema":{"type":"string","title":"Run A"}},{"name":"run_b","in":"query","required":true,"schema":{"type":"string","title":"Run B"}}],"responses":{"200":{"description":"Side-by-side comparison of two screening runs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/backend__schemas__screening__CompareResponse"}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Resource or symbol not found"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screen-bulk":{"post":{"tags":["screening"],"summary":"Screen Bulk","description":"Trigger a new bulk Shariah screening run.\n\nStarts asynchronous screening of all tickers in the specified index\n(e.g. \"SP500\", \"DJIA\"). Returns immediately with a run ID that can be\nused to poll status, fetch results, or cancel the run.\n\n**curl example:**\n```bash\ncurl -X POST \"https://api.example.com/api/screen-bulk\" \\\n     -H \"Authorization: Bearer <API_KEY>\" \\\n     -H \"Content-Type: application/json\" \\\n     -d '{\"index_name\": \"SP500\", \"limit\": 50, \"force_refresh\": false}'\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.example.com/api/screen-bulk\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n    json={\"index_name\": \"SP500\", \"limit\": 50, \"force_refresh\": False},\n)\nprint(resp.json())\n```","operationId":"screen_bulk_api_screen_bulk_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkScreenRequest"}}},"required":true},"responses":{"202":{"description":"Bulk screening run accepted and queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkScreenResponse"}}}},"400":{"description":"Invalid request parameters"},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"500":{"description":"Internal server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screen-bulk/{run_id}/cancel":{"post":{"tags":["screening"],"summary":"Cancel Run","description":"Cancel a running bulk screening job.\n\nStops the specified run gracefully. Results already collected are\npreserved and can still be queried. Returns the run status at the time\nof cancellation.\n\n**curl example:**\n```bash\ncurl -X POST \"https://api.example.com/api/screen-bulk/abc123/cancel\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.example.com/api/screen-bulk/abc123/cancel\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"cancel_run_api_screen_bulk__run_id__cancel_post","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Confirmation that the run has been cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelResponse"}}}},"400":{"description":"Invalid request parameters"},"401":{"description":"API key required or invalid"},"404":{"description":"Resource or symbol not found"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screen-bulk/{run_id}/results":{"get":{"tags":["screening"],"summary":"Get Run Results","description":"Retrieve filtered, paginated results for a bulk screening run.\n\nReturns individual symbol screening results for the given run. Supports\nfiltering by compliance status, methodology (e.g. \"aaoifi\", \"djim\"),\nsector, and error state, plus sorting and pagination.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/screen-bulk/abc123/results?compliant=true&methodology=aaoifi&page=1&page_size=20\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/screen-bulk/abc123/results\",\n    params={\"compliant\": True, \"methodology\": \"aaoifi\", \"page\": 1},\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"get_run_results_api_screen_bulk__run_id__results_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"compliant","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Compliant"}},{"name":"methodology","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Methodology"}},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"}},{"name":"has_error","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Error"}},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort By"}},{"name":"sort_order","in":"query","required":false,"schema":{"type":"string","default":"asc","title":"Sort Order"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Page Size"}}],"responses":{"200":{"description":"Paginated screening results for the specified run","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunResultsResponse"}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Resource or symbol not found"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screen-bulk/{run_id}/summary":{"get":{"tags":["screening"],"summary":"Get Run Summary","description":"Get an aggregated summary of a bulk screening run.\n\nReturns compliance statistics broken down by methodology and sector,\noverall compliance rate, and a list of the top compliant stocks.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/screen-bulk/abc123/summary\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/screen-bulk/abc123/summary\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"get_run_summary_api_screen_bulk__run_id__summary_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Aggregated compliance summary for the screening run","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunSummaryResponse"}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Resource or symbol not found"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screen-bulk/{run_id}/export/csv":{"get":{"tags":["screening"],"summary":"Export Csv","description":"Export screening results as a CSV file.\n\nReturns a downloadable CSV containing every screened symbol, its\ncompliance status, financial ratios, and methodology-level verdicts.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/screen-bulk/abc123/export/csv\" \\\n     -H \"Authorization: Bearer <API_KEY>\" \\\n     -o screening_results.csv\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/screen-bulk/abc123/export/csv\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nwith open(\"screening_results.csv\", \"w\") as f:\n    f.write(resp.text)\n```","operationId":"export_csv_api_screen_bulk__run_id__export_csv_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"CSV file download of all screening results","content":{"application/json":{"schema":{}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Resource or symbol not found"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screen-bulk/{run_id}/export/json":{"get":{"tags":["screening"],"summary":"Export Json","description":"Export screening results as JSON.\n\nReturns the complete screening dataset for a run in JSON format,\nsuitable for programmatic consumption or archiving.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/screen-bulk/abc123/export/json\" \\\n     -H \"Authorization: Bearer <API_KEY>\" \\\n     -o screening_results.json\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/screen-bulk/abc123/export/json\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\ndata = resp.json()\n```","operationId":"export_json_api_screen_bulk__run_id__export_json_get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"JSON export of all screening results","content":{"application/json":{"schema":{}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Resource or symbol not found"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screen-bulk/{run_id}":{"delete":{"tags":["screening"],"summary":"Delete Run","description":"Delete a bulk screening run and its results.\n\nPermanently removes a completed or cancelled run and all associated\nscreening results from the database. This action cannot be undone.\n\n**curl example:**\n```bash\ncurl -X DELETE \"https://api.example.com/api/screen-bulk/abc123\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.delete(\n    \"https://api.example.com/api/screen-bulk/abc123\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"delete_run_api_screen_bulk__run_id__delete","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Confirmation that the run was deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteRunResponse"}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Resource or symbol not found"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/results/updates":{"get":{"tags":["screening"],"summary":"Get Results Updates","description":"Get screening results updated since a given timestamp.\n\nReturns only the results that have been created or modified after the\n`since` ISO-8601 timestamp. Useful for incremental polling by\nfront-end dashboards.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/results/updates?since=2025-01-15T00:00:00Z\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/results/updates\",\n    params={\"since\": \"2025-01-15T00:00:00Z\"},\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"get_results_updates_api_results_updates_get","parameters":[{"name":"since","in":"query","required":true,"schema":{"type":"string","title":"Since"}},{"name":"run_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id"}}],"responses":{"200":{"description":"List of screening results updated since the given timestamp","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScreeningResultResponse"},"title":"Response Get Results Updates Api Results Updates Get"}}}},"400":{"description":"Invalid request parameters"},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/results":{"get":{"tags":["screening"],"summary":"Get Results","description":"Get all cached screening results.\n\nReturns every screening result currently stored in the database,\nregardless of when the screening was performed.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/results\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/results\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nresults = resp.json()\n```","operationId":"get_results_api_results_get","responses":{"200":{"description":"List of all cached screening results","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ScreeningResultResponse"},"type":"array","title":"Response Get Results Api Results Get"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"}}}},"/api/result/{symbol}":{"get":{"tags":["screening"],"summary":"Get Result","description":"Get the cached screening result for a single symbol.\n\nReturns the most recent Shariah compliance screening result for the\ngiven ticker symbol. Returns 404 if the symbol has not been screened.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.example.com/api/result/AAPL\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.example.com/api/result/AAPL\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"get_result_api_result__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Shariah compliance screening result for the requested symbol","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreeningResultResponse"}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Resource or symbol not found"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screen/{symbol}":{"get":{"tags":["screening"],"summary":"Screen Symbol","description":"Screen a single symbol for Shariah compliance.\n\nPerforms a full Shariah compliance analysis on the given ticker,\nincluding business activity screening and financial ratio checks\nagainst AAOIFI, DJIM, FTSE, MSCI, and S&P methodologies.\n\nBoth ``GET`` and ``POST`` are accepted; ``POST`` is canonical and\nappears in all examples, while ``GET`` is provided as a forgiveness\nalias so clients that intuitively reach for ``GET`` (a common\nmistake) succeed instead of receiving 405. There is no request body\non either method; the only input is the path parameter.\n\nPass ``?force_refresh=true`` to bypass the engine's in-memory cache\nand re-run the full screen — useful after a methodology code change\nor upstream financial-data correction. Defaults to ``false`` so\nnormal traffic remains served from cache.\n\n**curl example:**\n```bash\ncurl -X POST \"https://api.example.com/api/screen/AAPL\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.example.com/api/screen/AAPL\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"screen_symbol_api_screen__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"force_refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force Refresh"}}],"responses":{"200":{"description":"Freshly computed Shariah compliance screening result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreeningResultResponse"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"500":{"description":"Internal server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["screening"],"summary":"Screen Symbol","description":"Screen a single symbol for Shariah compliance.\n\nPerforms a full Shariah compliance analysis on the given ticker,\nincluding business activity screening and financial ratio checks\nagainst AAOIFI, DJIM, FTSE, MSCI, and S&P methodologies.\n\nBoth ``GET`` and ``POST`` are accepted; ``POST`` is canonical and\nappears in all examples, while ``GET`` is provided as a forgiveness\nalias so clients that intuitively reach for ``GET`` (a common\nmistake) succeed instead of receiving 405. There is no request body\non either method; the only input is the path parameter.\n\nPass ``?force_refresh=true`` to bypass the engine's in-memory cache\nand re-run the full screen — useful after a methodology code change\nor upstream financial-data correction. Defaults to ``false`` so\nnormal traffic remains served from cache.\n\n**curl example:**\n```bash\ncurl -X POST \"https://api.example.com/api/screen/AAPL\" \\\n     -H \"Authorization: Bearer <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.example.com/api/screen/AAPL\",\n    headers={\"Authorization\": \"Bearer <API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"screen_symbol_api_screen__symbol__post","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"force_refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force Refresh"}}],"responses":{"200":{"description":"Freshly computed Shariah compliance screening result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreeningResultResponse"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"500":{"description":"Internal server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sukuk/search":{"get":{"tags":["sukuk"],"summary":"Search Sukuk","operationId":"search_sukuk_api_sukuk_search_get","parameters":[{"name":"issuer","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Issuer"}},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"}},{"name":"structure","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Structure"}},{"name":"documentation_basis","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Documentation Basis"}},{"name":"currency","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"}},{"name":"maturity_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Maturity From"}},{"name":"maturity_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Maturity To"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Search Sukuk Api Sukuk Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sukuk/issuer/{lei}":{"get":{"tags":["sukuk"],"summary":"Get Issuer Sukuk","operationId":"get_issuer_sukuk_api_sukuk_issuer__lei__get","parameters":[{"name":"lei","in":"path","required":true,"schema":{"type":"string","title":"Lei"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Issuer Sukuk Api Sukuk Issuer  Lei  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sukuk/portfolio-impact":{"post":{"tags":["sukuk"],"summary":"Portfolio Impact","operationId":"portfolio_impact_api_sukuk_portfolio_impact_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioImpactBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Portfolio Impact Api Sukuk Portfolio Impact Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sukuk/{isin}":{"get":{"tags":["sukuk"],"summary":"Get Sukuk","operationId":"get_sukuk_api_sukuk__isin__get","parameters":[{"name":"isin","in":"path","required":true,"schema":{"type":"string","title":"Isin"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Sukuk Api Sukuk  Isin  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/suggest":{"get":{"tags":["database"],"summary":"Suggest Symbol","description":"Auto-complete symbol suggestions for a search query.\n\nReturns a ranked list of symbol suggestions that match the provided\nquery prefix, useful for type-ahead search interfaces.\n\n**curl example**:\n```bash\ncurl -X GET \"http://localhost:8000/api/suggest?q=AAP\"\n```\n\n**Python requests example**:\n```python\nimport requests\nresp = requests.get(\n    \"http://localhost:8000/api/suggest\",\n    params={\"q\": \"AAP\"},\n)\nsuggestions = resp.json()\n```","operationId":"suggest_symbol_api_suggest_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}}],"responses":{"200":{"description":"List of symbol suggestions matching the query","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SuggestionResponse"},"title":"Response Suggest Symbol Api Suggest Get"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/database/search":{"get":{"tags":["database"],"summary":"Search Database","description":"Search the local database of assets with filtering and pagination.\n\nReturns a paginated list of assets matching the query string and optional\nfilters for asset type, sector, country, and exchange.\n\n**curl example**:\n```bash\ncurl -X GET \"http://localhost:8000/api/database/search?q=Apple&asset_type=equities&limit=10\"\n```\n\n**Python requests example**:\n```python\nimport requests\nresp = requests.get(\n    \"http://localhost:8000/api/database/search\",\n    params={\"q\": \"Apple\", \"asset_type\": \"equities\", \"limit\": 10},\n)\nresults = resp.json()\n```","operationId":"search_database_api_database_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}},{"name":"asset_type","in":"query","required":false,"schema":{"type":"string","default":"equities","title":"Asset Type"}},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"}},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"}},{"name":"exchange","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Paginated search results with total count","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseSearchResponse"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/database/stock/{symbol}":{"get":{"tags":["database"],"summary":"Get Stock From Database","description":"Retrieve the database record for a single stock by symbol.\n\nReturns the stored reference data for the given symbol including name,\nsector, exchange, and country.\n\n**curl example**:\n```bash\ncurl -X GET \"http://localhost:8000/api/database/stock/AAPL\"\n```\n\n**Python requests example**:\n```python\nimport requests\nresp = requests.get(\"http://localhost:8000/api/database/stock/AAPL\")\nstock = resp.json()\n```","operationId":"get_stock_from_database_api_database_stock__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Full database record for the requested symbol","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseStockResponse"}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Symbol not found in database"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/database/stats":{"get":{"tags":["database"],"summary":"Get Database Stats","description":"Get aggregate statistics about the database contents.\n\nReturns counts of equities, ETFs, funds, indices, and screening results,\nalong with the number of distinct sectors and countries for equities.\n\n**curl example**:\n```bash\ncurl -X GET \"http://localhost:8000/api/database/stats\"\n```\n\n**Python requests example**:\n```python\nimport requests\nresp = requests.get(\"http://localhost:8000/api/database/stats\")\nstats = resp.json()\n```","operationId":"get_database_stats_api_database_stats_get","responses":{"200":{"description":"Aggregate statistics across all asset categories","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseStatsResponse"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"}}}},"/api/ohlc/{symbol}":{"get":{"tags":["market"],"summary":"Get Ohlc","description":"Retrieve OHLC candlestick data for a given symbol.\n\nReturns a time-series list of Open, High, Low, Close, and Volume data\npoints for the requested symbol, period, and interval.\n\n**curl example**:\n```bash\ncurl -X GET \"http://localhost:8000/api/ohlc/AAPL?period=1y&interval=1d\"\n```\n\n**Python requests example**:\n```python\nimport requests\nresp = requests.get(\n    \"http://localhost:8000/api/ohlc/AAPL\",\n    params={\"period\": \"1y\", \"interval\": \"1d\"},\n)\ncandles = resp.json()\n```","operationId":"get_ohlc_api_ohlc__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"period","in":"query","required":false,"schema":{"type":"string","default":"1y","title":"Period"}},{"name":"interval","in":"query","required":false,"schema":{"type":"string","default":"1d","title":"Interval"}}],"responses":{"200":{"description":"List of OHLC candlestick data points","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OHLCPointResponse"},"title":"Response Get Ohlc Api Ohlc  Symbol  Get"}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Symbol not found in database"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/quote/{symbol}":{"get":{"tags":["market"],"summary":"Get Quote","description":"Get a real-time quote for a single symbol.\n\nReturns the latest price, change, volume, and key metrics for the\nrequested ticker symbol.\n\n**curl example**:\n```bash\ncurl -X GET \"http://localhost:8000/api/quote/AAPL\"\n```\n\n**Python requests example**:\n```python\nimport requests\nresp = requests.get(\"http://localhost:8000/api/quote/AAPL\")\nquote = resp.json()\n```","operationId":"get_quote_api_quote__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Real-time quote for the requested symbol","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteResponse"}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Symbol not found in database"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/quotes/batch":{"post":{"tags":["market"],"summary":"Get Quotes Batch","description":"Fetch quotes for multiple symbols in a single request.\n\nReturns a dictionary keyed by symbol, where each value is either the\nquote object or null if the symbol could not be resolved.\n\n**curl example**:\n```bash\ncurl -X POST \"http://localhost:8000/api/quotes/batch\"          -H \"Content-Type: application/json\"          -d '{\"symbols\": [\"AAPL\", \"MSFT\", \"GOOGL\"]}'\n```\n\n**Python requests example**:\n```python\nimport requests\nresp = requests.post(\n    \"http://localhost:8000/api/quotes/batch\",\n    json={\"symbols\": [\"AAPL\", \"MSFT\", \"GOOGL\"]},\n)\nquotes = resp.json()\n```","operationId":"get_quotes_batch_api_quotes_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchQuoteRequest"}}},"required":true},"responses":{"200":{"description":"Mapping of each requested symbol to its quote (or null if unavailable)","content":{"application/json":{"schema":{"additionalProperties":{"anyOf":[{"$ref":"#/components/schemas/QuoteResponse"},{"type":"null"}]},"type":"object","title":"Response Get Quotes Batch Api Quotes Batch Post"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/asset/{symbol}/full":{"get":{"tags":["market"],"summary":"Get Asset Full","description":"Get a comprehensive view of an asset combining multiple data sources.\n\nReturns a unified response containing the live quote, Shariah screening\nresult, and static database record for the given symbol.\n\n**curl example**:\n```bash\ncurl -X GET \"http://localhost:8000/api/asset/AAPL/full\"\n```\n\n**Python requests example**:\n```python\nimport requests\nresp = requests.get(\"http://localhost:8000/api/asset/AAPL/full\")\nasset = resp.json()\n```","operationId":"get_asset_full_api_asset__symbol__full_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Aggregated asset view with quote, screening, and database data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetFullResponse"}}}},"401":{"description":"API key required or invalid"},"404":{"description":"Symbol not found in database"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/trending":{"get":{"tags":["market"],"summary":"Get Trending","description":"List currently trending assets.\n\nReturns an ordered list of assets that are currently trending by\ntrading activity or price movement.\n\n**curl example**:\n```bash\ncurl -X GET \"http://localhost:8000/api/trending\"\n```\n\n**Python requests example**:\n```python\nimport requests\nresp = requests.get(\"http://localhost:8000/api/trending\")\ntrending = resp.json()\n```","operationId":"get_trending_api_trending_get","responses":{"200":{"description":"List of currently trending assets","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/TrendingItemResponse"},"type":"array","title":"Response Get Trending Api Trending Get"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"}}}},"/api/portfolio/scan":{"post":{"tags":["portfolio"],"summary":"Portfolio Scan","description":"Scan a portfolio of stocks for Shariah compliance.\n\nSet `force_refresh=true` to bypass cached screening data — available\nonly for enterprise and internal plans. For other plans the flag is\nsilently treated as False.","operationId":"portfolio_scan_api_portfolio_scan_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioScanRequest"}}},"required":true},"responses":{"200":{"description":"Per-symbol screening results and aggregate portfolio compliance summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioScanResponse"}}}},"429":{"description":"Rate limit exceeded. Try again later."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/watchlists":{"get":{"tags":["watchlists"],"summary":"List Watchlists","description":"List all watchlists.\n\nReturns every watchlist owned by the authenticated user, ordered by\ncreation date.\n\n**curl example**:\n```bash\ncurl https://api.halalterminal.com/api/watchlists \\\n  -H \"X-API-Key: sk_live_abc123def456\"\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/watchlists\",\n    headers={\"X-API-Key\": \"sk_live_abc123def456\"},\n)\nwatchlists = resp.json()\n```","operationId":"list_watchlists_api_watchlists_get","responses":{"200":{"description":"All watchlists for the authenticated user","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/WatchlistResponse"},"type":"array","title":"Response List Watchlists Api Watchlists Get"}}}},"401":{"description":"Missing or invalid API key"},"429":{"description":"Rate limit exceeded"}}},"post":{"tags":["watchlists"],"summary":"Create Watchlist","description":"Create a new watchlist.\n\nCreates a named watchlist with an optional initial set of symbols.\nReturns the full watchlist object including its generated ID.\n\n**curl example**:\n```bash\ncurl -X POST https://api.halalterminal.com/api/watchlists \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-Key: sk_live_abc123def456\" \\\n  -d '{\"name\": \"Halal Tech\", \"symbols\": [\"AAPL\", \"MSFT\", \"GOOGL\"]}'\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.halalterminal.com/api/watchlists\",\n    headers={\"X-API-Key\": \"sk_live_abc123def456\"},\n    json={\"name\": \"Halal Tech\", \"symbols\": [\"AAPL\", \"MSFT\", \"GOOGL\"]},\n)\nwatchlist = resp.json()\n```","operationId":"create_watchlist_api_watchlists_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistCreateRequest"}}},"required":true},"responses":{"200":{"description":"The newly created watchlist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistResponse"}}}},"401":{"description":"Missing or invalid API key"},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/watchlists/{watchlist_id}":{"get":{"tags":["watchlists"],"summary":"Get Watchlist","description":"Get a single watchlist by ID.\n\nReturns the full watchlist object including all symbols. Raises 404\nif the watchlist does not exist.\n\n**curl example**:\n```bash\ncurl https://api.halalterminal.com/api/watchlists/wl_abc123 \\\n  -H \"X-API-Key: sk_live_abc123def456\"\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/watchlists/wl_abc123\",\n    headers={\"X-API-Key\": \"sk_live_abc123def456\"},\n)\nwatchlist = resp.json()\n```","operationId":"get_watchlist_api_watchlists__watchlist_id__get","parameters":[{"name":"watchlist_id","in":"path","required":true,"schema":{"type":"string","title":"Watchlist Id"}}],"responses":{"200":{"description":"The requested watchlist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistResponse"}}}},"401":{"description":"Missing or invalid API key"},"404":{"description":"Watchlist not found"},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["watchlists"],"summary":"Delete Watchlist","description":"Delete a watchlist.\n\nPermanently removes the watchlist and all its symbol associations.\nReturns a confirmation object. Raises 404 if the watchlist does not\nexist.\n\n**curl example**:\n```bash\ncurl -X DELETE https://api.halalterminal.com/api/watchlists/wl_abc123 \\\n  -H \"X-API-Key: sk_live_abc123def456\"\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.delete(\n    \"https://api.halalterminal.com/api/watchlists/wl_abc123\",\n    headers={\"X-API-Key\": \"sk_live_abc123def456\"},\n)\nassert resp.json()[\"deleted\"] is True\n```","operationId":"delete_watchlist_api_watchlists__watchlist_id__delete","parameters":[{"name":"watchlist_id","in":"path","required":true,"schema":{"type":"string","title":"Watchlist Id"}}],"responses":{"200":{"description":"Confirmation that the watchlist was deleted","content":{"application/json":{"schema":{}}}},"401":{"description":"Missing or invalid API key"},"404":{"description":"Watchlist not found"},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/watchlists/{watchlist_id}/symbols":{"post":{"tags":["watchlists"],"summary":"Add Symbol To Watchlist","description":"Add a symbol to an existing watchlist.\n\nAppends a single ticker symbol to the watchlist. Returns the updated\nwatchlist. Raises 404 if the watchlist does not exist.\n\n**curl example**:\n```bash\ncurl -X POST https://api.halalterminal.com/api/watchlists/wl_abc123/symbols \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-Key: sk_live_abc123def456\" \\\n  -d '{\"symbol\": \"AMZN\"}'\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.halalterminal.com/api/watchlists/wl_abc123/symbols\",\n    headers={\"X-API-Key\": \"sk_live_abc123def456\"},\n    json={\"symbol\": \"AMZN\"},\n)\nupdated = resp.json()\n```","operationId":"add_symbol_to_watchlist_api_watchlists__watchlist_id__symbols_post","parameters":[{"name":"watchlist_id","in":"path","required":true,"schema":{"type":"string","title":"Watchlist Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistSymbolRequest"}}}},"responses":{"200":{"description":"The updated watchlist with the new symbol added","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistResponse"}}}},"401":{"description":"Missing or invalid API key"},"404":{"description":"Watchlist not found"},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/watchlists/{watchlist_id}/symbols/{symbol}":{"delete":{"tags":["watchlists"],"summary":"Remove Symbol From Watchlist","description":"Remove a symbol from a watchlist.\n\nRemoves the specified ticker symbol from the watchlist. Returns the\nupdated watchlist. Raises 404 if the watchlist does not exist.\n\n**curl example**:\n```bash\ncurl -X DELETE https://api.halalterminal.com/api/watchlists/wl_abc123/symbols/AMZN \\\n  -H \"X-API-Key: sk_live_abc123def456\"\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.delete(\n    \"https://api.halalterminal.com/api/watchlists/wl_abc123/symbols/AMZN\",\n    headers={\"X-API-Key\": \"sk_live_abc123def456\"},\n)\nupdated = resp.json()\n```","operationId":"remove_symbol_from_watchlist_api_watchlists__watchlist_id__symbols__symbol__delete","parameters":[{"name":"watchlist_id","in":"path","required":true,"schema":{"type":"string","title":"Watchlist Id"}},{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"The updated watchlist with the symbol removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchlistResponse"}}}},"401":{"description":"Missing or invalid API key"},"404":{"description":"Watchlist not found"},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/compare":{"post":{"tags":["comparison"],"summary":"Compare Symbols","description":"Compare Shariah compliance across multiple symbols.\n\nAccepts 2-5 ticker symbols and returns screening results, market\nquotes, and stored database data for each symbol side by side.\n\n**curl example**:\n```bash\ncurl -X POST https://api.halalterminal.com/api/compare \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-Key: sk_live_abc123def456\" \\\n  -d '{\"symbols\": [\"AAPL\", \"MSFT\"]}'\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.halalterminal.com/api/compare\",\n    headers={\"X-API-Key\": \"sk_live_abc123def456\"},\n    json={\"symbols\": [\"AAPL\", \"MSFT\"]},\n)\ncomparison = resp.json()\nfor item in comparison[\"items\"]:\n    print(item[\"symbol\"], item[\"screening\"][\"status\"])\n```","operationId":"compare_symbols_api_compare_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareRequest"}}},"required":true},"responses":{"200":{"description":"Side-by-side compliance comparison for the requested symbols","content":{"application/json":{"schema":{"$ref":"#/components/schemas/backend__schemas__comparison__CompareResponse"}}}},"400":{"description":"Fewer than 2 or more than 5 symbols provided"},"401":{"description":"Missing or invalid API key"},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/education/glossary":{"get":{"tags":["education"],"summary":"Get Glossary","description":"Retrieve the Islamic finance glossary, optionally filtered by search query.\n\nReturns a list of key Islamic finance terms (e.g. Riba, Gharar, Murabaha,\nSukuk) with their Arabic script, definitions, categories, and scholarly\nreferences. Use the optional query parameter to search for specific terms.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/education/glossary?q=riba\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"http://localhost:8000/api/education/glossary\",\n    params={\"q\": \"riba\"},\n)\nfor term in resp.json()[\"terms\"]:\n    print(f\"{term['term']} ({term['arabic']}): {term['definition']}\")\n```","operationId":"get_glossary_api_education_glossary_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}}],"responses":{"200":{"description":"List of Islamic finance glossary terms","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GlossaryResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"Methodology 'unknown' not found"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/education/methodologies":{"get":{"tags":["education"],"summary":"Get Methodologies","description":"List all supported Shariah screening methodologies.\n\nReturns summary information for every screening methodology available in\nthe system, such as AAOIFI, SEC Malaysia, DJIM, MSCI, and FTSE. Each\nentry includes identification, thresholds, and distinguishing features.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/education/methodologies\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\"http://localhost:8000/api/education/methodologies\")\nfor m in resp.json()[\"methodologies\"]:\n    print(f\"{m['name']}: {m.get('full_name', 'N/A')}\")\n```","operationId":"get_methodologies_api_education_methodologies_get","responses":{"200":{"description":"List of all available Shariah screening methodologies","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MethodologiesResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"Methodology 'unknown' not found"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}}}}},"/api/education/methodologies/{name}":{"get":{"tags":["education"],"summary":"Get Methodology","description":"Retrieve detailed information about a specific Shariah screening methodology.\n\nReturns comprehensive details for the requested methodology, including its\nscreening process, financial ratio thresholds, Shariah board information,\nand scholarly references. Use the methodology name or ID as returned by\nthe ``/methodologies`` endpoint (e.g. ``aaoifi``, ``sec``, ``djim``).\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/education/methodologies/aaoifi\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\"http://localhost:8000/api/education/methodologies/aaoifi\")\ndata = resp.json()\nprint(f\"{data['full_name']} (est. {data['established']})\")\nprint(\"Thresholds:\", data[\"thresholds\"])\n```","operationId":"get_methodology_api_education_methodologies__name__get","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Detailed information for the requested methodology","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MethodologyDetailResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"Methodology 'unknown' not found"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/education/screening-criteria":{"get":{"tags":["education"],"summary":"Get Screening Criteria","description":"Retrieve the Shariah compliance screening criteria.\n\nReturns the business activity screening rules (prohibited sectors and\nrevenue thresholds) and financial ratio screening thresholds (debt,\ninterest income, liquid assets) used to determine whether a stock\nis Shariah-compliant.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/education/screening-criteria\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\"http://localhost:8000/api/education/screening-criteria\")\ncriteria = resp.json()\nprint(\"Prohibited sectors:\", criteria[\"business_screening\"].get(\"prohibited_sectors\"))\nprint(\"Max debt ratio:\", criteria[\"financial_screening\"].get(\"max_debt_to_total_assets\"))\n```","operationId":"get_screening_criteria_api_education_screening_criteria_get","responses":{"200":{"description":"Business and financial screening criteria for Shariah compliance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreeningCriteriaResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"Methodology 'unknown' not found"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}}}}},"/api/education/purification":{"get":{"tags":["education"],"summary":"Get Purification Guide","description":"Retrieve the dividend purification and zakat guide.\n\nReturns educational content on how to purify investment returns that may\ncontain a haram (impermissible) component. Includes the purification\nformula, guidance on capital gains purification, zakat calculation for\ninvestments, and scholarly references.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/education/purification\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\"http://localhost:8000/api/education/purification\")\nguide = resp.json()\nprint(\"Formula:\", guide[\"purification_formula\"].get(\"formula\"))\nprint(\"Zakat rate:\", guide[\"zakat_on_investments\"].get(\"rate\"))\n```","operationId":"get_purification_guide_api_education_purification_get","responses":{"200":{"description":"Guide for purifying investment income","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurificationGuideResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"Methodology 'unknown' not found"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}}}}},"/api/news":{"get":{"tags":["news"],"summary":"Get News","description":"Retrieve a paginated list of Islamic finance and market news articles.\n\nReturns news articles from all configured sources, optionally filtered by\nsource, category, or free-text search query. Results are sorted by\npublication date (most recent first) and include sentiment scores.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/news?category=islamic_finance&page=1&page_size=10\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"http://localhost:8000/api/news\",\n    params={\"category\": \"islamic_finance\", \"page\": 1, \"page_size\": 10},\n)\ndata = resp.json()\nfor article in data[\"articles\"]:\n    print(article[\"title\"], article[\"sentiment\"])\n```","operationId":"get_news_api_news_get","parameters":[{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Paginated list of news articles matching the filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsListResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"No news articles found"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/news/sources":{"get":{"tags":["news"],"summary":"Get Sources","description":"List all configured news sources.\n\nReturns every news feed source available in the system, including its\ncategory, URL, and whether it is currently enabled.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/news/sources\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\"http://localhost:8000/api/news/sources\")\nfor src in resp.json()[\"sources\"]:\n    print(src[\"name\"], src[\"category\"], src[\"enabled\"])\n```","operationId":"get_sources_api_news_sources_get","responses":{"200":{"description":"List of all configured news feed sources","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsSourcesResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"No news articles found"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}}}}},"/api/news/{symbol}":{"get":{"tags":["news"],"summary":"Get News For Symbol","description":"Retrieve recent news articles for a specific stock symbol.\n\nEach article is tagged with `compliance_relevance` (high/medium/low) and\n`compliance_categories` (debt_issuance, m_and_a, dividend_change,\nequity_action, distress) so callers can prioritize events that may shift\nthe stock's screening verdict.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/news/AAPL?limit=10&compliance_relevance=high\"\n```","operationId":"get_news_for_symbol_api_news__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"compliance_relevance","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(high|medium|low)$"},{"type":"null"}],"description":"Filter to only articles at or above this compliance-event relevance bar. 'high' surfaces debt issuances, M&A, dividend policy changes, distress events — the corporate actions that actually move a Shariah verdict. Omit to get all articles.","title":"Compliance Relevance"},"description":"Filter to only articles at or above this compliance-event relevance bar. 'high' surfaces debt issuances, M&A, dividend policy changes, distress events — the corporate actions that actually move a Shariah verdict. Omit to get all articles."}],"responses":{"200":{"description":"News articles related to the given ticker symbol","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsListResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"No news articles found"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/filings/{symbol}":{"get":{"tags":["filings"],"summary":"Get Filings","description":"Retrieve SEC EDGAR filings for a company by ticker symbol.\n\nReturns a list of filings (10-K, 10-Q, 8-K, etc.) sourced from the SEC\nEDGAR database. Results can be filtered by filing type and are returned\nin reverse chronological order.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/filings/AAPL?filing_type=10-K&limit=5\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"http://localhost:8000/api/filings/AAPL\",\n    params={\"filing_type\": \"10-K\", \"limit\": 5},\n)\ndata = resp.json()\nprint(f\"{data['company_name']} (CIK {data['cik']}): {data['count']} filings\")\nfor f in data[\"filings\"]:\n    print(f\"  {f['filing_type']}  {f['filing_date']}  {f['filing_url']}\")\n```","operationId":"get_filings_api_filings__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"filing_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filing Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"List of SEC filings for the requested company","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilingsListResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Company or filing not found","content":{"application/json":{"example":{"detail":"No filings found for symbol 'XYZ'"}}}},"429":{"description":"Rate limit exceeded — SEC EDGAR enforces strict rate limits","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/filings/{symbol}/facts":{"get":{"tags":["filings"],"summary":"Get Facts","description":"Retrieve XBRL company facts for a ticker symbol.\n\nReturns structured financial data extracted from the company's SEC filings\nvia the EDGAR XBRL API. Facts are organized by taxonomy (e.g. us-gaap)\nand concept (e.g. Revenue, Assets). This data is used internally for\nfinancial-ratio-based Shariah compliance screening.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/filings/MSFT/facts\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\"http://localhost:8000/api/filings/MSFT/facts\")\nfacts = resp.json()[\"facts\"]\n# Access US-GAAP revenue data\nrevenue = facts.get(\"us-gaap\", {}).get(\"Revenue\", {})\nprint(revenue)\n```","operationId":"get_facts_api_filings__symbol__facts_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"XBRL company facts from SEC EDGAR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyFactsResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Company or filing not found","content":{"application/json":{"example":{"detail":"No filings found for symbol 'XYZ'"}}}},"429":{"description":"Rate limit exceeded — SEC EDGAR enforces strict rate limits","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/filings/{symbol}/events":{"get":{"tags":["filings"],"summary":"Get Events","description":"Retrieve the parsed 8-K event feed for a company by ticker symbol.\n\nEach 8-K (current report) filed by the company is parsed into structured\nevents: SEC item codes resolved to human-readable labels, each flagged for\nwhether it can move a Shariah-compliance verdict. Pass\n`compliance_relevant=true` for the compliance-watch feed — debt raises,\nacquisitions, bankruptcies, restatements and the like.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/filings/AAPL/events?compliance_relevant=true&limit=10\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"http://localhost:8000/api/filings/AAPL/events\",\n    params={\"compliance_relevant\": True, \"limit\": 10},\n)\nfor event in resp.json()[\"events\"]:\n    codes = \", \".join(i[\"code\"] for i in event[\"items\"])\n    print(f\"{event['filing_date']}  8-K  items {codes}\")\n```","operationId":"get_events_api_filings__symbol__events_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"compliance_relevant","in":"query","required":false,"schema":{"type":"boolean","description":"Return only events with at least one item that can move a Shariah-compliance verdict.","default":false,"title":"Compliance Relevant"},"description":"Return only events with at least one item that can move a Shariah-compliance verdict."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Parsed 8-K event feed for the requested company","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EightKEventsResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Company or filing not found","content":{"application/json":{"example":{"detail":"No filings found for symbol 'XYZ'"}}}},"429":{"description":"Rate limit exceeded — SEC EDGAR enforces strict rate limits","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dividends/{symbol}":{"get":{"tags":["dividends"],"summary":"Get Dividend History","description":"Retrieve the dividend payment history for a stock.\n\nReturns every recorded dividend payment for the given symbol, including\nthe payment date and per-share amount in USD, ordered chronologically.\n\n**curl example:**\n\n    curl -X GET \"http://localhost:8000/api/dividends/MSFT\"\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.get(\"http://localhost:8000/api/dividends/MSFT\")\ndata = resp.json()\nprint(f\"{data['symbol']}: {data['count']} dividends\")\nfor d in data[\"dividends\"][-4:]:\n    print(f\"  {d['date']}: ${d['amount']:.4f}\")\n```","operationId":"get_dividend_history_api_dividends__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Chronological list of historical dividend payments.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DividendHistoryResponse"}}}},"404":{"description":"Symbol not found or has no dividend history."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dividends/{symbol}/purification":{"get":{"tags":["dividends"],"summary":"Get Dividend Purification","description":"Calculate dividend purification amounts for a stock.\n\nApplies the company's Shariah purification rate to each historical\ndividend payment and returns per-dividend purification amounts, the\nhalal portion, and aggregate totals.\n\nKey fields in the response:\n- `purification_rate`: the company-level rate (e.g. 0.031 = 3.1%)\n- `total_dividends`: sum of all dividends\n- `total_purification`: total amount to donate\n- `total_halal`: total amount that is halal to keep\n\n**curl example:**\n\n    curl -X GET \"http://localhost:8000/api/dividends/MSFT/purification\"\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.get(\"http://localhost:8000/api/dividends/MSFT/purification\")\ndata = resp.json()\nprint(f\"Purification rate: {data['purification_rate']:.1%}\")\nprint(f\"Total to purify: ${data['total_purification']:.2f}\")\n```","operationId":"get_dividend_purification_api_dividends__symbol__purification_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Dividend purification breakdown with per-payment and total amounts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DividendPurificationResponse"}}}},"404":{"description":"Symbol not found or has no dividend/screening data."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/zakat/calculate":{"post":{"tags":["zakat"],"summary":"Calculate Zakat","description":"Calculate zakat owed on a portfolio of stock holdings.\n\nDetermines whether the total market value of the provided holdings exceeds\nthe nisab threshold (85 grams of gold at the given price per gram). If\nabove nisab, calculates 2.5% zakat on each holding. Returns per-holding\nzakat amounts and aggregate totals.\n\nKey response fields:\n- `nisab_threshold`: 85 * gold_price_per_gram\n- `is_above_nisab`: whether zakat is due\n- `total_zakat`: total amount to pay (0 if below nisab)\n\n**curl example:**\n\n    curl -X POST \"http://localhost:8000/api/zakat/calculate\" \\\n         -H \"Content-Type: application/json\" \\\n         -d '{\"holdings\": [{\"symbol\": \"AAPL\", \"market_value\": 25000}, {\"symbol\": \"MSFT\", \"market_value\": 18000}], \"gold_price_per_gram\": 65.0}'\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.post(\n    \"http://localhost:8000/api/zakat/calculate\",\n    json={\n        \"holdings\": [\n            {\"symbol\": \"AAPL\", \"market_value\": 25000},\n            {\"symbol\": \"MSFT\", \"market_value\": 18000},\n        ],\n        \"gold_price_per_gram\": 65.0,\n    },\n)\ndata = resp.json()\nif data[\"is_above_nisab\"]:\n    print(f\"Zakat due: ${data['total_zakat']:.2f}\")\nelse:\n    print(\"Below nisab — no zakat due\")\n```","operationId":"calculate_zakat_api_zakat_calculate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZakatCalculateRequest"}}},"required":true},"responses":{"200":{"description":"Zakat calculation with nisab check and per-holding breakdown.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZakatCalculateResponse"}}}},"401":{"description":"Authentication required (if auth is enabled)."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/purification/calculate":{"post":{"tags":["zakat"],"summary":"Calculate Purification","description":"Calculate dividend purification amounts for multiple holdings at once.\n\nFor each holding, looks up its Shariah purification rate and applies it to\nthe provided dividend income to determine how much should be donated. Also\nreturns the halal amount and whether each holding is compliant.\n\nKey response fields:\n- `total_purification`: total dollar amount to donate across all holdings\n- `total_halal`: total halal dividend amount to keep\n- Each holding includes `purification_rate`, `purification_amount`, and\n  `is_compliant`\n\n**curl example:**\n\n    curl -X POST \"http://localhost:8000/api/purification/calculate\" \\\n         -H \"Content-Type: application/json\" \\\n         -d '{\"holdings\": [{\"symbol\": \"MSFT\", \"dividend_income\": 320}, {\"symbol\": \"AAPL\", \"dividend_income\": 150}]}'\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.post(\n    \"http://localhost:8000/api/purification/calculate\",\n    json={\n        \"holdings\": [\n            {\"symbol\": \"MSFT\", \"dividend_income\": 320},\n            {\"symbol\": \"AAPL\", \"dividend_income\": 150},\n        ],\n    },\n)\ndata = resp.json()\nprint(f\"Total to purify: ${data['total_purification']:.2f}\")\nprint(f\"Halal to keep:   ${data['total_halal']:.2f}\")\n```","operationId":"calculate_purification_api_purification_calculate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurificationCalculateRequest"}}},"required":true},"responses":{"200":{"description":"Purification amounts per holding with halal/non-halal split.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurificationCalculateResponse"}}}},"401":{"description":"Authentication required (if auth is enabled)."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reports/screening/{symbol}":{"get":{"tags":["reports"],"summary":"Get Screening Report","description":"Generate a Shariah compliance screening report for a single stock.\n\nReturns a comprehensive report including business activity screening,\nfinancial ratio analysis, and an overall compliance determination for\nthe given ticker symbol. The report uses the configured screening\nmethodology (e.g. AAOIFI thresholds).\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/reports/screening/AAPL\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\"http://localhost:8000/api/reports/screening/AAPL\")\nreport = resp.json()\nprint(f\"Symbol: {report['symbol']}\")\nprint(f\"Compliant: {report['screening']['is_compliant']}\")\nprint(f\"Generated: {report['report_generated_at']}\")\n```","operationId":"get_screening_report_api_reports_screening__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Full Shariah compliance screening report for the symbol","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreeningReportResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"No screening data found for symbol 'XYZ'"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reports/portfolio":{"post":{"tags":["reports"],"summary":"Get Portfolio Report","description":"Generate a Shariah compliance report for a portfolio of stocks.\n\nAccepts a list of ticker symbols and returns an aggregated report with\nper-holding compliance results, overall compliance percentage, and\nsummary counts. Useful for screening an entire portfolio at once.\n\n**curl example:**\n```bash\ncurl -X POST \"http://localhost:8000/api/reports/portfolio\" \\\n     -H \"Content-Type: application/json\" \\\n     -d '{\"symbols\": [\"AAPL\", \"MSFT\", \"AMZN\"]}'\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.post(\n    \"http://localhost:8000/api/reports/portfolio\",\n    json={\"symbols\": [\"AAPL\", \"MSFT\", \"AMZN\"]},\n)\nreport = resp.json()\nprint(f\"Compliance: {report['compliance_percentage']}%\")\nprint(f\"Compliant: {report['compliant']}/{report['total']}\")\n```","operationId":"get_portfolio_report_api_reports_portfolio_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioReportRequest"}}},"required":true},"responses":{"200":{"description":"Aggregated Shariah compliance report for the portfolio","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioReportResponse"}}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"No screening data found for symbol 'XYZ'"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}},"400":{"description":"Invalid request — at least one symbol is required","content":{"application/json":{"example":{"detail":"At least 1 symbol required"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reports/export/csv":{"get":{"tags":["reports"],"summary":"Export Csv","description":"Export all cached screening results as a downloadable CSV file.\n\nReturns a CSV file containing the most recent screening results for all\npreviously screened stocks. The file is served as a streaming download\nwith the filename ``screening_results.csv``.\n\n**curl example:**\n```bash\ncurl -X GET \"http://localhost:8000/api/reports/export/csv\" -o screening_results.csv\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\"http://localhost:8000/api/reports/export/csv\")\nwith open(\"screening_results.csv\", \"w\") as f:\n    f.write(resp.text)\n```","operationId":"export_csv_api_reports_export_csv_get","responses":{"200":{"description":"CSV file with screening results","content":{"application/json":{"schema":{}},"text/csv":{"example":"symbol,is_compliant,methodology,debt_ratio,interest_ratio\nAAPL,True,aaoifi,0.25,0.01\nMSFT,True,aaoifi,0.18,0.02\n"}}},"401":{"description":"Authentication required","content":{"application/json":{"example":{"detail":"Not authenticated"}}}},"404":{"description":"Resource not found","content":{"application/json":{"example":{"detail":"No screening data found for symbol 'XYZ'"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"example":{"detail":"Rate limit exceeded. Try again in 60 seconds."}}}}}}},"/api/etf/{symbol}/holdings":{"get":{"tags":["etf"],"summary":"Get Etf Holdings","description":"Retrieve the full list of holdings for an ETF.\n\nReturns every underlying position with its ticker, name, portfolio weight,\nshare count, market value, and Shariah compliance status (if previously\nscreened).\n\n**curl example:**\n\n    curl -X GET \"http://localhost:8000/api/etf/VTI/holdings\"\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.get(\"http://localhost:8000/api/etf/VTI/holdings\")\ndata = resp.json()\nprint(data[\"holdings_count\"], \"holdings\")\n```","operationId":"get_etf_holdings_api_etf__symbol__holdings_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"ETF holdings list with weights and compliance statuses.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFHoldingsResponse"}}}},"404":{"description":"ETF symbol not found or has no holdings data."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/etf/{symbol}/info":{"get":{"tags":["etf"],"summary":"Get Etf Info","description":"Retrieve general fund information for an ETF.\n\nReturns metadata such as the fund name, description, inception date,\nexpense ratio, NAV, total assets, category, sector weightings, and\ncountry weightings.\n\n**curl example:**\n\n    curl -X GET \"http://localhost:8000/api/etf/SPY/info\"\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.get(\"http://localhost:8000/api/etf/SPY/info\")\ninfo = resp.json()\nprint(info[\"name\"], \"- expense ratio:\", info[\"expense_ratio\"])\n```","operationId":"get_etf_info_api_etf__symbol__info_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Fund-level metadata including expense ratio, AUM, sector weightings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFFundInfoResponse"}}}},"404":{"description":"ETF symbol not found."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/etf/{symbol}/screen":{"post":{"tags":["etf"],"summary":"Screen Etf","description":"Run a Shariah compliance screening on an ETF.\n\nScreens every holding in the ETF against Shariah compliance criteria and\nreturns an overall compliance status, a weighted-average purification rate,\na compliance summary (counts and weights), and per-holding screening\nresults. Pass `force_refresh=true` to bypass cached results — available\nonly for enterprise and internal plans; for other plans the flag is\nsilently treated as False.\n\n**curl example:**\n\n    curl -X POST \"http://localhost:8000/api/etf/VTI/screen?force_refresh=false\"\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.post(\"http://localhost:8000/api/etf/VTI/screen\", params={\"force_refresh\": False})\nresult = resp.json()\nprint(result[\"compliance_status\"], \"- compliant weight:\", result[\"summary\"][\"compliant_weight\"])\n```","operationId":"screen_etf_api_etf__symbol__screen_post","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"force_refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force Refresh"}}],"responses":{"200":{"description":"Full Shariah screening result with per-holding compliance details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFScreeningResponse"}}}},"404":{"description":"ETF symbol not found or has no holdings data."},"429":{"description":"Rate limit exceeded. Try again later."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/etf/{symbol}/screening":{"get":{"tags":["etf"],"summary":"Get Etf Screening","description":"Retrieve a previously cached Shariah screening result for an ETF.\n\nUnlike the POST `/screen` endpoint, this does **not** trigger a new\nscreening run. It returns the most recent cached result, or 404 if no\nscreening has been performed yet.\n\n**curl example:**\n\n    curl -X GET \"http://localhost:8000/api/etf/VTI/screening\"\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.get(\"http://localhost:8000/api/etf/VTI/screening\")\nif resp.status_code == 200:\n    print(resp.json()[\"compliance_status\"])\nelse:\n    print(\"No cached screening available\")\n```","operationId":"get_etf_screening_api_etf__symbol__screening_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Cached Shariah screening result, if available.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFScreeningResponse"}}}},"404":{"description":"No cached screening found for this ETF symbol."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/etf/{symbol}/purification":{"post":{"tags":["etf"],"summary":"Calculate Etf Purification","description":"Calculate the purification amount for an ETF investment.\n\nGiven an investment amount and optional dividend income, computes how much\nmoney should be donated to purify returns based on each holding's\npurification rate. Returns both aggregate amounts and a per-holding\nbreakdown.\n\n**curl example:**\n\n    curl -X POST \"http://localhost:8000/api/etf/VTI/purification\" \\\n         -H \"Content-Type: application/json\" \\\n         -d '{\"investment_amount\": 50000, \"dividend_income\": 1200}'\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.post(\n    \"http://localhost:8000/api/etf/VTI/purification\",\n    json={\"investment_amount\": 50000, \"dividend_income\": 1200},\n)\ndata = resp.json()\nprint(f\"Total to purify: ${data['total_purification_amount']:.2f}\")\n```","operationId":"calculate_etf_purification_api_etf__symbol__purification_post","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFPurificationRequest"}}}},"responses":{"200":{"description":"Purification amounts for the investment and optional dividend income.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFPurificationResponse"}}}},"404":{"description":"ETF symbol not found or has no screening data."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/etf/compare":{"post":{"tags":["etf"],"summary":"Compare Etfs","description":"Compare two to five ETFs side by side.\n\nReturns per-ETF summary data (holdings count, expense ratio, compliance\nstatus, compliant/non-compliant weights) and identifies holdings that\noverlap across multiple ETFs with their respective weights.\n\n**curl example:**\n\n    curl -X POST \"http://localhost:8000/api/etf/compare\" \\\n         -H \"Content-Type: application/json\" \\\n         -d '{\"symbols\": [\"VTI\", \"SPY\", \"SCHB\"]}'\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.post(\n    \"http://localhost:8000/api/etf/compare\",\n    json={\"symbols\": [\"VTI\", \"SPY\"]},\n)\ndata = resp.json()\nprint(f\"Overlap: {data['overlap_count']} holdings\")\n```","operationId":"compare_etfs_api_etf_compare_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFCompareRequest"}}},"required":true},"responses":{"200":{"description":"Side-by-side ETF comparison with overlap analysis.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFCompareResponse"}}}},"404":{"description":"One or more ETF symbols not found."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/etf/screen-bulk":{"post":{"tags":["etf"],"summary":"Screen Bulk","description":"Screen multiple ETFs for Shariah compliance in a single request.\n\nAccepts up to 100 ETF symbols and returns each ETF's compliance status,\ncompliant/non-compliant weights, and purification rate. Also includes a\nsummary with total/compliant/non-compliant/error counts. Pass\n`force_refresh=true` to bypass cached results — available only for\nenterprise and internal plans; for other plans the flag is silently\ntreated as False.\n\n**curl example:**\n\n    curl -X POST \"http://localhost:8000/api/etf/screen-bulk\" \\\n         -H \"Content-Type: application/json\" \\\n         -d '{\"symbols\": [\"VTI\", \"SPY\", \"SCHB\"], \"force_refresh\": false}'\n\n**Python requests example:**\n\n```python\nimport requests\nresp = requests.post(\n    \"http://localhost:8000/api/etf/screen-bulk\",\n    json={\"symbols\": [\"VTI\", \"SPY\", \"SCHB\"], \"force_refresh\": False},\n)\ndata = resp.json()\nprint(f\"Compliant: {data['summary']['compliant']}/{data['summary']['total']}\")\n```","operationId":"screen_bulk_api_etf_screen_bulk_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFBulkScreenRequest"}}},"required":true},"responses":{"200":{"description":"Bulk screening results with per-ETF statuses and aggregate summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ETFBulkScreenResponse"}}}},"429":{"description":"Rate limit exceeded. Try again later."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keys/generate":{"post":{"tags":["api-keys"],"summary":"Generate Key","description":"Generate a free-trial API key.\n\nCreates a new API key with 500 free tokens for the given email\naddress. If a key already exists for this email, behavior depends\non backend configuration.\n\n**curl example**:\n```bash\ncurl -X POST https://api.halalterminal.com/api/keys/generate \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\": \"dev@example.com\"}'\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.halalterminal.com/api/keys/generate\",\n    json={\"email\": \"dev@example.com\"},\n)\nkey_data = resp.json()\nprint(\"Your API key:\", key_data[\"api_key\"])\n```","operationId":"generate_key_api_keys_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateKeyRequest"}}},"required":true},"responses":{"200":{"description":"The newly generated API key with plan details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateKeyResponse"}}}},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/api/keys/revoke":{"post":{"tags":["api-keys"],"summary":"Revoke Key","description":"Deactivate a key by its public prefix. Internal-plan callers only.\n\nUsed by the admin dashboard to revoke a customer key without ever\nhandling the raw key value (which is bcrypt-hashed at rest and not\nrecoverable after creation).","operationId":"revoke_key_api_keys_revoke_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeKeyRequest"}}},"required":true},"responses":{"200":{"description":"Revoked status","content":{"application/json":{"schema":{}}}},"403":{"description":"Internal-only endpoint"},"404":{"description":"Key not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keys/token-costs":{"get":{"tags":["api-keys"],"summary":"Get Token Costs","description":"Return the full token cost table.\n\nLists every endpoint pattern and how many tokens each request costs.\nUse this to estimate usage before making API calls. No authentication\nrequired.\n\n**curl example**:\n```bash\ncurl https://api.halalterminal.com/api/keys/token-costs\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.get(\"https://api.halalterminal.com/api/keys/token-costs\")\nfor cost in resp.json()[\"costs\"]:\n    print(f\"{cost['pattern']} ({cost['method']}): {cost['tokens']} tokens\")\n```","operationId":"get_token_costs_api_keys_token_costs_get","responses":{"200":{"description":"Token cost table for all endpoint categories","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenCostsResponse"}}}}},"security":[]}},"/api/keys/{api_key}/usage":{"get":{"tags":["api-keys"],"summary":"Get Usage","description":"**Deprecated** — use `GET /api/auth/me` instead.\n\nThe path-parameter form leaks the key into Caddy/proxy access logs.\nThe replacement reads from the `X-API-Key` header only.\n\nRequires authentication via X-API-Key header. You can only view\nusage for your own key.","operationId":"get_usage_api_keys__api_key__usage_get","parameters":[{"name":"api_key","in":"path","required":true,"schema":{"type":"string","title":"Api Key"}}],"responses":{"200":{"description":"Usage statistics for the API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyUsageResponse"}}}},"403":{"description":"Caller does not own this API key"},"404":{"description":"API key not found"},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keys/{api_key}/usage/daily":{"get":{"tags":["api-keys"],"summary":"Get Daily Usage","description":"**Deprecated** — use `GET /api/auth/me/usage/daily` instead.\n\nThe path-parameter form leaks the key into Caddy/proxy access logs.\nThe replacement reads from the `X-API-Key` header only.","operationId":"get_daily_usage_api_keys__api_key__usage_daily_get","parameters":[{"name":"api_key","in":"path","required":true,"schema":{"type":"string","title":"Api Key"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Per-day request and token counts for the specified period","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyUsageResponse"}}}},"403":{"description":"Caller does not own this API key"},"404":{"description":"API key not found"},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keys/{api_key}/usage/recent":{"get":{"tags":["api-keys"],"summary":"Get Recent Requests","description":"**Deprecated** — use `GET /api/auth/me/usage/recent` instead.\n\nThe path-parameter form leaks the key into Caddy/proxy access logs.\nThe replacement reads from the `X-API-Key` header only.","operationId":"get_recent_requests_api_keys__api_key__usage_recent_get","parameters":[{"name":"api_key","in":"path","required":true,"schema":{"type":"string","title":"Api Key"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Most recent individual API requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecentRequestsResponse"}}}},"403":{"description":"Caller does not own this API key"},"404":{"description":"API key not found"},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keys/{api_key}/regenerate":{"post":{"tags":["api-keys"],"summary":"Regenerate Key","description":"**Deprecated** — use `POST /api/auth/me/regenerate` instead.\n\nThe path-parameter form leaks the key into Caddy/proxy access logs.\nThe replacement reads from the `X-API-Key` header only.","operationId":"regenerate_key_api_keys__api_key__regenerate_post","parameters":[{"name":"api_key","in":"path","required":true,"schema":{"type":"string","title":"Api Key"}}],"responses":{"200":{"description":"The old (deactivated) key and the new replacement key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegenerateKeyResponse"}}}},"401":{"description":"Missing or invalid API key"},"403":{"description":"Caller does not own this key"},"404":{"description":"API key not found or already inactive"},"429":{"description":"Rate limit exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keys/plans":{"get":{"tags":["api-keys"],"summary":"List Plans","description":"List all available API plans with pricing.\n\nReturns every plan tier including name, monthly price, token\nlimits, overage rates, and included features. No authentication required.\n\n**curl example**:\n```bash\ncurl https://api.halalterminal.com/api/keys/plans\n```\n\n**Python example**:\n```python\nimport requests\n\nresp = requests.get(\"https://api.halalterminal.com/api/keys/plans\")\nfor plan in resp.json()[\"plans\"]:\n    print(f\"{plan['display_name']}: ${plan['price_monthly']}/mo — {plan['tokens_limit']} tokens\")\n```","operationId":"list_plans_api_keys_plans_get","responses":{"200":{"description":"All available API subscription plans","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlansResponse"}}}},"429":{"description":"Rate limit exceeded"}},"security":[]}},"/api/auth/me":{"get":{"tags":["auth"],"summary":"Me","description":"Return plan, quota, and identity for the calling API key.\n\nRequires the X-API-Key header. Calling this endpoint does not consume\ntokens — it's safe to poll for live quota state.\n\n**curl example**:\n```bash\ncurl -H \"X-API-Key: ht_abc123\" https://api.halalterminal.com/api/auth/me\n```","operationId":"me_api_auth_me_get","responses":{"200":{"description":"Plan, quota, and identity for the calling API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyUsageResponse"}}}},"401":{"description":"Missing or invalid API key"}}}},"/api/auth/me/usage/daily":{"get":{"tags":["auth"],"summary":"Me Usage Daily","description":"Return per-day usage for the *calling* API key (header-only).\n\nPath-clean replacement for `/api/keys/{api_key}/usage/daily`. The key\nis read from the `X-API-Key` header — never the URL — so it does not\nend up in proxy access logs.\n\n**curl example**:\n```bash\ncurl -H \"X-API-Key: ht_abc123\"       \"https://api.halalterminal.com/api/auth/me/usage/daily?days=7\"\n```","operationId":"me_usage_daily_api_auth_me_usage_daily_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Per-day request and token counts for the calling key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyUsageResponse"}}}},"401":{"description":"Missing or invalid API key"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/me/usage/recent":{"get":{"tags":["auth"],"summary":"Me Usage Recent","description":"Return the most recent individual requests for the *calling* API key.\n\nPath-clean replacement for `/api/keys/{api_key}/usage/recent`.\n\n**curl example**:\n```bash\ncurl -H \"X-API-Key: ht_abc123\"       \"https://api.halalterminal.com/api/auth/me/usage/recent?limit=10\"\n```","operationId":"me_usage_recent_api_auth_me_usage_recent_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Most recent individual requests for the calling key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecentRequestsResponse"}}}},"401":{"description":"Missing or invalid API key"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/me/regenerate":{"post":{"tags":["auth"],"summary":"Me Regenerate","description":"Deactivate the *calling* API key and issue a replacement.\n\nPath-clean replacement for `/api/keys/{api_key}/regenerate`. The\nrequest must carry the old key in the `X-API-Key` header; after\nsuccess the old key is permanently deactivated and the response\ncarries the `new_key` to use for subsequent requests.\n\n**curl example**:\n```bash\ncurl -X POST -H \"X-API-Key: ht_abc123\"       https://api.halalterminal.com/api/auth/me/regenerate\n```","operationId":"me_regenerate_api_auth_me_regenerate_post","responses":{"200":{"description":"The old (deactivated) key and the new replacement key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegenerateKeyResponse"}}}},"401":{"description":"Missing or invalid API key"},"404":{"description":"API key not found or already inactive"}}}},"/api/billing/checkout":{"post":{"tags":["billing"],"summary":"Create Checkout","description":"Create a Stripe Checkout session for a plan upgrade.\n\nRequires the `X-API-Key` header — the calling key is the one that\nwill be upgraded. The returned URL should be opened in the user's\nbrowser to complete payment.\n\n**curl example**:\n```bash\ncurl -X POST https://api.halalterminal.com/api/billing/checkout \\\n  -H \"X-API-Key: ht_abc123def456\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"plan\": \"starter\"}'\n```","operationId":"create_checkout_api_billing_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Stripe checkout session URL and ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"400":{"description":"No Stripe price configured for the requested plan"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Body api_key does not match X-API-Key header"},"404":{"description":"API key not found"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Stripe is not configured or SDK not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/webhook":{"post":{"tags":["billing"],"summary":"Stripe Webhook","description":"Handle Stripe webhook events for subscription lifecycle.\n\nProcesses ``checkout.session.completed`` (plan upgrade),\n``customer.subscription.deleted`` (downgrade to free, sub-canceled email),\n``invoice.paid`` (receipt email + overage settlement), and\n``invoice.payment_failed`` (action-required email) events sent by Stripe.\nThis endpoint verifies the webhook signature before processing.\n\n**curl example**:\n```bash\n# Typically called by Stripe, but for local testing with the Stripe CLI:\nstripe listen --forward-to localhost:8000/api/billing/webhook\n```\n\n**Python example**:\n```python\n# Webhook endpoints are called by Stripe, not by your application.\n# Use the Stripe CLI or Dashboard to inspect delivered events.\n```","operationId":"stripe_webhook_api_billing_webhook_post","responses":{"200":{"description":"Acknowledgement that the webhook event was received","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid webhook signature"},"503":{"description":"Webhook secret not configured"}},"security":[]}},"/api/billing/portal":{"post":{"tags":["billing"],"summary":"Create Portal Session","description":"Create a Stripe Customer Portal session for the calling key.\n\nRequires the `X-API-Key` header — the calling key's subscription is\nthe one that will be managed. The portal lets the user update their\npayment method, view invoices, and cancel their subscription.\nRequires the key to have an associated Stripe customer (i.e. has\npaid at least once).","operationId":"create_portal_session_api_billing_portal_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalRequest"}}},"required":true},"responses":{"200":{"description":"Stripe Customer Portal session URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalResponse"}}}},"400":{"description":"Key has no active paid subscription"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Body api_key does not match X-API-Key header"},"404":{"description":"API key not found"},"503":{"description":"Stripe not configured or Customer Portal not enabled"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/unsubscribe/{token}":{"get":{"tags":["unsubscribe"],"summary":"Unsubscribe Get","operationId":"unsubscribe_get_api_unsubscribe__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]},"post":{"tags":["unsubscribe"],"summary":"Unsubscribe Post","description":"RFC 8058 one-click unsubscribe (called automatically by Gmail/Outlook).","operationId":"unsubscribe_post_api_unsubscribe__token__post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/api/webhooks/resend":{"post":{"tags":["webhooks"],"summary":"Resend Webhook","description":"Receive Resend delivery events. Verifies Svix signature, then logs\nthe event and updates the suppression list when applicable.","operationId":"resend_webhook_api_webhooks_resend_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[]}},"/api/webhooks/resend/inbound":{"post":{"tags":["webhooks"],"summary":"Resend Inbound","description":"Receive parsed inbound emails from Resend Inbound.\n\nResend Inbound delivers each received message as a webhook event of\ntype ``email.received`` whose ``data`` carries the parsed envelope\nplus body. We thread it onto an existing conversation when possible\n(``In-Reply-To`` → our outbound ``message_id``), else attach it to a\nthread keyed on ``(contact_email, normalized_subject)``.","operationId":"resend_inbound_api_webhooks_resend_inbound_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[]}},"/api/insights/{symbol}/alternatives":{"get":{"tags":["insights"],"summary":"Halal alternatives for a non-compliant ticker","description":"For any non-compliant or unscreened ticker, surface up to N\nShariah-compliant alternatives in the same sector ranked by how\nclose their market cap sits to the source on a log scale.\n\nReturns the source's status and chosen sector so the caller can\nexplain WHY these alternatives showed up.\n\n**Example:** `GET /api/insights/JPM/alternatives?limit=3` returns\ncompliant Financial-Services-or-adjacent siblings (typically\ninsurance, asset managers screened compliant).","operationId":"get_alternatives_api_insights__symbol__alternatives_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"Max alternatives to return.","default":5,"title":"Limit"},"description":"Max alternatives to return."}],"responses":{"200":{"description":"Compliant siblings in the same sector ranked by market-cap proximity","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Alternatives Api Insights  Symbol  Alternatives Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/insights/{symbol}/staleness":{"get":{"tags":["insights"],"summary":"Detect screening staleness from recent SEC filings","description":"Cross-reference the symbol's last screening timestamp with its\nSEC filing history. Returns a `screening_stale_reason` when a\nmaterial 8-K (debt issuance, M&A, dividend policy change,\nbusiness combination) was filed after the last screening — the\nvery events that move the Shariah verdict.\n\nEmpty `screening_stale_reason` means the cached verdict is still\naligned with the latest material disclosures.","operationId":"get_staleness_api_insights__symbol__staleness_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}}],"responses":{"200":{"description":"Whether material 8-Ks since last screening recommend a re-screen","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Staleness Api Insights  Symbol  Staleness Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/insights/{symbol}/trajectory":{"get":{"tags":["insights"],"summary":"Compliance ratio trajectory from XBRL facts","description":"Build a time series of the four ratios that drive Shariah\ncompliance — debt/assets, cash/assets, liquidity/assets,\ninterest/revenue — from the SEC XBRL company-facts cache (already\npopulated by /api/filings/{symbol}/facts).\n\nLets users see whether a stock is trending toward or away from\ncompliance, e.g. AAPL has held debt/assets ~22% for 8 quarters\nwhile TSLA jumped from 8% to 28% last quarter.","operationId":"get_trajectory_api_insights__symbol__trajectory_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","title":"Symbol"}},{"name":"quarters","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":2,"description":"Number of trailing quarters to return.","default":8,"title":"Quarters"},"description":"Number of trailing quarters to return."}],"responses":{"200":{"description":"Quarter-by-quarter debt/MC, cash/MC, interest/revenue series","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Trajectory Api Insights  Symbol  Trajectory Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/disclaimers":{"get":{"tags":["disclaimers"],"summary":"Canonical disclaimer registry","operationId":"get_disclaimers_api_disclaimers_get","responses":{"200":{"description":"Every disclaimer the API may attach to a response, keyed by stable ID. Use this to render long-form text or translate disclaimers client-side.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisclaimersResponse"}}}}},"security":[]}},"/api/disclaimers/{disclaimer_id}":{"get":{"tags":["disclaimers"],"summary":"Lookup a single disclaimer by ID","operationId":"get_disclaimer_api_disclaimers__disclaimer_id__get","parameters":[{"name":"disclaimer_id","in":"path","required":true,"schema":{"type":"string","title":"Disclaimer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Disclaimer"}}}},"404":{"description":"Unknown disclaimer ID."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}}},"components":{"schemas":{"AssetFullResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol"},"quote":{"anyOf":[{"$ref":"#/components/schemas/QuoteResponse"},{"type":"null"}],"description":"Live quote data from the market data provider"},"screening":{"anyOf":[{"$ref":"#/components/schemas/ScreeningResultResponse"},{"type":"null"}],"description":"Shariah screening result, if available"},"database":{"anyOf":[{"$ref":"#/components/schemas/DatabaseStockResponse"},{"type":"null"}],"description":"Static reference data from the local database"},"disclaimers":{"anyOf":[{"items":{"$ref":"#/components/schemas/Disclaimer"},"type":"array"},{"type":"null"}],"title":"Disclaimers","description":"Attached by middleware; see /api/disclaimers."}},"type":"object","required":["symbol"],"title":"AssetFullResponse","example":{"database":{"country":"United States","exchange":"NMS","name":"Apple Inc.","sector":"Technology","symbol":"AAPL","type":"equities"},"quote":{"beta":1.28,"change":1.32,"changePercent":0.71,"dividendYield":0.0055,"high":188.5,"low":185.73,"marketCap":2890000000000,"name":"Apple Inc.","open":186.12,"peRatio":29.5,"previousClose":186.12,"price":187.44,"symbol":"AAPL","volume":54638921},"symbol":"AAPL"}},"BatchQuoteRequest":{"properties":{"symbols":{"items":{"type":"string"},"type":"array","title":"Symbols","description":"List of ticker symbols to fetch quotes for"}},"type":"object","required":["symbols"],"title":"BatchQuoteRequest"},"BulkScreenRequest":{"properties":{"index_name":{"type":"string","title":"Index Name","description":"Name of the stock index to screen, e.g. 'SP500', 'DJIA'"},"limit":{"anyOf":[{"type":"integer","maximum":500.0},{"type":"null"}],"title":"Limit","description":"Maximum number of tickers to screen (None = all)"},"force_refresh":{"type":"boolean","title":"Force Refresh","description":"Re-screen symbols even if cached results exist","default":false}},"type":"object","required":["index_name"],"title":"BulkScreenRequest","example":{"force_refresh":false,"index_name":"SP500","limit":50}},"BulkScreenResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"index_name":{"type":"string","title":"Index Name","description":"Name of the index being screened, e.g. 'SP500'"},"total":{"type":"integer","title":"Total","description":"Total number of tickers queued for screening"},"tickers":{"items":{"type":"string"},"type":"array","title":"Tickers","description":"List of ticker symbols included in this run"},"status":{"type":"string","title":"Status","default":"triggered"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Count"},"queue_job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Queue Job Id"}},"type":"object","required":["run_id","index_name","total","tickers"],"title":"BulkScreenResponse","example":{"count":503,"created_at":"2025-01-15T08:00:00Z","index_name":"SP500","message":"Bulk screening triggered for SP500","run_id":"run_2025-01-15_sp500","status":"triggered","tickers":["AAPL","MSFT","GOOGL","AMZN","..."],"total":503}},"BulkStatusResponse":{"properties":{"run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id"},"running":{"type":"boolean","title":"Running"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"Run lifecycle status: pending, running, completed, cancelled, failed"},"index_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Index Name"},"total":{"type":"integer","title":"Total","default":0},"done":{"type":"integer","title":"Done","default":0},"failed_count":{"type":"integer","title":"Failed Count","description":"Number of symbols that failed during screening","default":0},"current_symbol":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Symbol","description":"Ticker currently being processed"},"progress_pct":{"type":"number","title":"Progress Pct","description":"Completion percentage (0.0 to 100.0)","default":0.0},"estimated_remaining_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Remaining Seconds"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"},"finished_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finished At"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error","description":"Most recent error message, if any"}},"additionalProperties":false,"type":"object","required":["running"],"title":"BulkStatusResponse","example":{"created_at":"2025-01-15T08:00:00Z","current_symbol":"MSFT","done":247,"estimated_remaining_seconds":312,"failed_count":3,"index_name":"SP500","progress_pct":49.1,"run_id":"run_2025-01-15_sp500","running":true,"started_at":"2025-01-15T08:00:01Z","status":"running","total":503,"updated_at":"2025-01-15T08:05:23Z"}},"CancelResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"status":{"type":"string","title":"Status"},"done":{"type":"integer","title":"Done","description":"Number of symbols that were screened before cancellation"},"total":{"type":"integer","title":"Total","description":"Total number of symbols that were queued"}},"type":"object","required":["run_id","status","done","total"],"title":"CancelResponse","example":{"done":247,"run_id":"run_2025-01-15_sp500","status":"cancelled","total":503}},"CheckoutRequest":{"properties":{"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key","description":"Deprecated — set the `X-API-Key` header instead. If provided here it must match the header value."},"plan":{"type":"string","title":"Plan","description":"Target plan name (starter, pro, or enterprise)"}},"type":"object","required":["plan"],"title":"CheckoutRequest","description":"Request body for creating a Stripe checkout session.\n\nAuthentication is via the `X-API-Key` header. The `api_key` body\nfield is retained for backwards compat with older clients; if\nprovided it must match the header value, otherwise the request is\nrejected. New clients should send the key in the header only.","example":{"plan":"starter"}},"CheckoutResponse":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url","description":"Stripe-hosted checkout page URL"},"session_id":{"type":"string","title":"Session Id","description":"Stripe checkout session identifier"}},"type":"object","required":["checkout_url","session_id"],"title":"CheckoutResponse","description":"Response containing the Stripe checkout session URL.","example":{"checkout_url":"https://checkout.stripe.com/c/pay/cs_test_abc123","session_id":"cs_test_abc123"}},"CompanyFactsResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol of the company"},"cik":{"type":"string","title":"Cik","description":"SEC Central Index Key (CIK) number for the company"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name","description":"Official company name as registered with the SEC"},"facts":{"additionalProperties":true,"type":"object","title":"Facts","description":"XBRL facts organized by taxonomy (e.g. 'us-gaap', 'dei') and concept"},"fundamentals":{"anyOf":[{"$ref":"#/components/schemas/CompanyFundamentals"},{"type":"null"}],"description":"Canonical Shariah-screening fundamentals normalized from the raw XBRL facts — the figures the screen consumes, each with its source concept and filing for citeable provenance."}},"type":"object","required":["symbol","cik","facts"],"title":"CompanyFactsResponse","description":"XBRL company facts from SEC EDGAR.","example":{"cik":"0000320193","company_name":"Apple Inc.","facts":{"us-gaap":{"Revenue":{"label":"Revenue","units":{"USD":[{"fy":2023,"val":383285000000}]}}}},"symbol":"AAPL"}},"CompanyFundamentals":{"properties":{"total_debt":{"anyOf":[{"$ref":"#/components/schemas/NormalizedFactModel"},{"type":"null"}]},"cash_and_investments":{"anyOf":[{"$ref":"#/components/schemas/NormalizedFactModel"},{"type":"null"}]},"total_assets":{"anyOf":[{"$ref":"#/components/schemas/NormalizedFactModel"},{"type":"null"}]},"total_revenue":{"anyOf":[{"$ref":"#/components/schemas/NormalizedFactModel"},{"type":"null"}]},"net_income":{"anyOf":[{"$ref":"#/components/schemas/NormalizedFactModel"},{"type":"null"}]},"stockholders_equity":{"anyOf":[{"$ref":"#/components/schemas/NormalizedFactModel"},{"type":"null"}]},"accounts_receivable":{"anyOf":[{"$ref":"#/components/schemas/NormalizedFactModel"},{"type":"null"}]},"interest_income":{"anyOf":[{"$ref":"#/components/schemas/NormalizedFactModel"},{"type":"null"}]}},"type":"object","title":"CompanyFundamentals","description":"Canonical Shariah-screening fundamentals normalized from XBRL facts.\n\nEach metric is null when the issuer tags no usable us-gaap concept for it.\n`total_debt` includes finance and operating lease liabilities."},"CompareChange":{"properties":{"symbol":{"type":"string","title":"Symbol"},"change":{"type":"string","title":"Change","description":"Type of change: became_compliant, became_non_compliant, added, or removed"},"run_a_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Run A Compliant"},"run_b_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Run B Compliant"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Human-readable explanation for the compliance change"}},"type":"object","required":["symbol","change"],"title":"CompareChange"},"CompareItemResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol for this comparison item"},"screening":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Screening","description":"Shariah screening result including compliance status"},"quote":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Quote","description":"Latest market quote data"},"database":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Database","description":"Stored company data from the database"}},"additionalProperties":false,"type":"object","required":["symbol"],"title":"CompareItemResponse","description":"Compliance and quote data for a single symbol in a comparison.","example":{"database":{"sector":"Technology"},"quote":{"currency":"USD","price":198.5},"screening":{"revenue_breakdown":{"doubtful":5.0,"halal":95.0},"status":"COMPLIANT"},"symbol":"AAPL"}},"CompareRequest":{"properties":{"symbols":{"items":{"type":"string"},"type":"array","title":"Symbols","description":"List of 2-5 stock ticker symbols to compare"}},"type":"object","required":["symbols"],"title":"CompareRequest","description":"Request body for comparing Shariah compliance across multiple symbols.","example":{"symbols":["AAPL","MSFT"]}},"CompareSummary":{"properties":{"newly_compliant":{"type":"integer","title":"Newly Compliant","description":"Symbols that became compliant in run B"},"newly_non_compliant":{"type":"integer","title":"Newly Non Compliant","description":"Symbols that became non-compliant in run B"},"unchanged_compliant":{"type":"integer","title":"Unchanged Compliant"},"unchanged_non_compliant":{"type":"integer","title":"Unchanged Non Compliant"},"added_symbols":{"type":"integer","title":"Added Symbols","description":"Symbols present in run B but not in run A"},"removed_symbols":{"type":"integer","title":"Removed Symbols","description":"Symbols present in run A but not in run B"}},"type":"object","required":["newly_compliant","newly_non_compliant","unchanged_compliant","unchanged_non_compliant","added_symbols","removed_symbols"],"title":"CompareSummary"},"CountStatsResponse":{"properties":{"count":{"type":"integer","title":"Count","description":"Total count of items in this category","default":0}},"type":"object","title":"CountStatsResponse"},"DailyUsageEntry":{"properties":{"date":{"type":"string","title":"Date","description":"Calendar date in YYYY-MM-DD format"},"count":{"type":"integer","title":"Count","description":"Number of API requests made on this date"},"tokens":{"type":"integer","title":"Tokens","description":"Total tokens charged on this date","default":0}},"type":"object","required":["date","count"],"title":"DailyUsageEntry","description":"Request count and token usage for a single day.","example":{"count":12,"date":"2025-06-15","tokens":48}},"DailyUsageResponse":{"properties":{"api_key":{"type":"string","title":"Api Key","description":"The API key these stats belong to"},"days":{"type":"integer","title":"Days","description":"Number of days included in the breakdown"},"daily":{"items":{"$ref":"#/components/schemas/DailyUsageEntry"},"type":"array","title":"Daily","description":"Per-day request and token counts"}},"type":"object","required":["api_key","days","daily"],"title":"DailyUsageResponse","description":"Per-day usage breakdown for an API key.","example":{"api_key":"ht_abc123def456","daily":[{"count":12,"date":"2025-06-15","tokens":48},{"count":8,"date":"2025-06-14","tokens":32}],"days":30}},"DataQualityInfo":{"properties":{"missing_fields":{"items":{"type":"string"},"type":"array","title":"Missing Fields","description":"Field names absent from the upstream financials (e.g. 'total_debt', 'market_cap')."},"methodologies_insufficient":{"items":{"type":"string"},"type":"array","title":"Methodologies Insufficient","description":"Methodologies that could not be scored. When this set contains every methodology, the aggregate `is_compliant` is null and `shariah_compliance_status` is `insufficient_data`."}},"type":"object","title":"DataQualityInfo","description":"Diagnostic block reporting which raw fields were missing and which\nmethodologies abstained as a result. Useful for surfacing 'we don't\nknow yet' instead of conflating it with non-compliance."},"DatabaseSearchItemResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Company or asset name"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type","description":"Asset type, e.g. equities, etfs, funds"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector","description":"Sector classification"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry","description":"Industry classification"},"exchange":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange","description":"Exchange where the asset is listed"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country","description":"Country of incorporation or domicile"},"market_cap":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Market Cap","description":"Market capitalization bucket (e.g. Large, Mid, Small)"}},"additionalProperties":false,"type":"object","required":["symbol"],"title":"DatabaseSearchItemResponse","example":{"country":"United States","exchange":"NMS","industry":"Consumer Electronics","market_cap":"Large","name":"Apple Inc.","sector":"Technology","symbol":"AAPL","type":"equities"}},"DatabaseSearchResponse":{"properties":{"total":{"type":"integer","title":"Total","description":"Total number of results matching the query"},"limit":{"type":"integer","title":"Limit","description":"Maximum number of results returned per page"},"offset":{"type":"integer","title":"Offset","description":"Offset into the full result set"},"results":{"items":{"$ref":"#/components/schemas/DatabaseSearchItemResponse"},"type":"array","title":"Results","description":"Page of matching search results"}},"type":"object","required":["total","limit","offset","results"],"title":"DatabaseSearchResponse","example":{"limit":100,"offset":0,"results":[{"country":"United States","exchange":"NMS","industry":"Consumer Electronics","market_cap":"Large","name":"Apple Inc.","sector":"Technology","symbol":"AAPL","type":"equities"}],"total":1}},"DatabaseStatsResponse":{"properties":{"equities":{"$ref":"#/components/schemas/EquitiesStatsResponse","description":"Aggregate statistics for equities"},"etfs":{"$ref":"#/components/schemas/CountStatsResponse","description":"Aggregate statistics for ETFs"},"funds":{"$ref":"#/components/schemas/CountStatsResponse","description":"Aggregate statistics for mutual funds"},"indices":{"$ref":"#/components/schemas/CountStatsResponse","description":"Aggregate statistics for indices"},"screening_results":{"$ref":"#/components/schemas/CountStatsResponse","description":"Count of available Shariah screening results"}},"type":"object","required":["equities","etfs","funds","indices","screening_results"],"title":"DatabaseStatsResponse","example":{"equities":{"count":12450,"countries":78,"sectors":11},"etfs":{"count":3200},"funds":{"count":1540},"indices":{"count":85},"screening_results":{"count":4200}}},"DatabaseStockResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type","description":"Asset type, e.g. equities, etfs, funds"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Company or asset name"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector","description":"Sector classification"},"exchange":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange","description":"Exchange where the asset is listed"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country","description":"Country of incorporation or domicile"}},"additionalProperties":false,"type":"object","required":["symbol"],"title":"DatabaseStockResponse","example":{"country":"United States","exchange":"NMS","name":"Apple Inc.","sector":"Technology","symbol":"AAPL","type":"equities"}},"DeleteRunResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"deleted":{"type":"boolean","title":"Deleted","description":"Whether the run was successfully deleted"}},"type":"object","required":["run_id","deleted"],"title":"DeleteRunResponse","example":{"deleted":true,"run_id":"run_2025-01-15_sp500"}},"Disclaimer":{"properties":{"id":{"type":"string","title":"Id","description":"Stable category identifier — safe for clients to dedupe and cache on."},"version":{"type":"string","title":"Version","description":"ISO-8601 date of the most recent edit to `text`. Advances whenever the wording changes, even for typo fixes."},"lang":{"type":"string","title":"Lang","description":"BCP-47 language tag for `text`. Today always 'en'; reserved for future i18n.","default":"en"},"severity":{"type":"string","title":"Severity","description":"Grouping hint for UIs. 'religious' for fatwa/scholar caveats; 'data' for data-freshness, sourcing, or coverage caveats."},"text":{"type":"string","title":"Text","description":"Short inline disclaimer text."},"url":{"type":"string","title":"Url","description":"Canonical legal page URL (deep-linked to the relevant section)."}},"type":"object","required":["id","version","severity","text","url"],"title":"Disclaimer","description":"Inline disclaimer object attached to relevant API responses.\n\nThe full registry is available at `GET /api/disclaimers`. Clients\nshould dedupe on `id`; `text` and `url` may be updated without an\nID change. When `version` advances, treat the text as edited.","example":{"id":"screening","lang":"en","severity":"religious","text":"Compliance verdict derived from automated screening of public financial filings — not a fatwa or scholarly attestation. Cached verdicts may go stale as issuers refile; consult a qualified scholar for personal religious decisions.","url":"https://halalterminal.com/legal/disclaimer#no-shariah-certification","version":"2026-05-12"}},"DisclaimersResponse":{"properties":{"disclaimers":{"items":{"$ref":"#/components/schemas/Disclaimer"},"type":"array","title":"Disclaimers"},"total":{"type":"integer","title":"Total","description":"Number of disclaimers in the registry."}},"type":"object","required":["disclaimers","total"],"title":"DisclaimersResponse","example":{"disclaimers":[{"id":"screening","lang":"en","severity":"religious","text":"Compliance verdict derived from automated screening of public financial filings — not a fatwa or scholarly attestation. Cached verdicts may go stale as issuers refile; consult a qualified scholar for personal religious decisions.","url":"https://halalterminal.com/legal/disclaimer#no-shariah-certification","version":"2026-05-12"}],"total":6}},"DividendHistoryResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol (e.g. 'MSFT')."},"count":{"type":"integer","title":"Count","description":"Total number of dividend payments returned."},"dividends":{"items":{"$ref":"#/components/schemas/DividendPayment"},"type":"array","title":"Dividends","description":"Chronological list of dividend payments."}},"type":"object","required":["symbol","count","dividends"],"title":"DividendHistoryResponse","description":"Historical dividend payments for a stock.","example":{"count":4,"dividends":[{"amount":0.75,"date":"2025-03-13"},{"amount":0.75,"date":"2025-06-12"},{"amount":0.75,"date":"2025-09-11"},{"amount":0.83,"date":"2025-12-11"}],"symbol":"MSFT"}},"DividendPayment":{"properties":{"date":{"type":"string","title":"Date","description":"Payment date in YYYY-MM-DD format."},"amount":{"type":"number","title":"Amount","description":"Dividend amount per share in USD."}},"type":"object","required":["date","amount"],"title":"DividendPayment","description":"A single dividend payment event.","example":{"amount":0.75,"date":"2025-12-15"}},"DividendPurificationResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol (e.g. 'MSFT')."},"purification_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Purification Rate","description":"Company-level purification rate (e.g. 0.031 = 3.1%)."},"count":{"type":"integer","title":"Count","description":"Total number of dividend payments included."},"dividends":{"items":{"$ref":"#/components/schemas/PurifiedDividend"},"type":"array","title":"Dividends","description":"List of dividends with purification amounts."},"total_dividends":{"type":"number","title":"Total Dividends","description":"Sum of all dividend amounts in USD."},"total_purification":{"type":"number","title":"Total Purification","description":"Total amount to purify across all dividends in USD."},"total_halal":{"type":"number","title":"Total Halal","description":"Total halal amount after purification in USD."}},"type":"object","required":["symbol","count","dividends","total_dividends","total_purification","total_halal"],"title":"DividendPurificationResponse","description":"Dividend purification breakdown for a stock over its full history.","example":{"count":4,"dividends":[{"amount":0.75,"date":"2025-03-13","halal_amount":0.727,"purification_amount":0.023,"purification_rate":0.031},{"amount":0.75,"date":"2025-06-12","halal_amount":0.727,"purification_amount":0.023,"purification_rate":0.031}],"purification_rate":0.031,"symbol":"MSFT","total_dividends":3.08,"total_halal":2.985,"total_purification":0.095}},"ETFBulkScreenItemResult":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"ETF ticker symbol."},"is_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Compliant","description":"Whether the ETF is Shariah-compliant."},"compliance_status":{"type":"string","title":"Compliance Status","description":"Overall compliance status.","default":"unscreened"},"compliant_weight":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Compliant Weight","description":"Sum of weights of compliant holdings."},"non_compliant_weight":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Non Compliant Weight","description":"Sum of weights of non-compliant holdings."},"purification_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Purification Rate","description":"Weighted-average purification rate."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Error message if screening failed for this ETF."}},"type":"object","required":["symbol"],"title":"ETFBulkScreenItemResult","description":"Screening result for one ETF in a bulk screening run.","example":{"compliance_status":"non_compliant","compliant_weight":0.78,"is_compliant":false,"non_compliant_weight":0.19,"purification_rate":0.032,"symbol":"VTI"}},"ETFBulkScreenRequest":{"properties":{"symbols":{"items":{"type":"string"},"type":"array","maxItems":100,"minItems":1,"title":"Symbols","description":"List of 1-100 ETF ticker symbols to screen."},"force_refresh":{"type":"boolean","title":"Force Refresh","description":"When true, bypass cached screening results and re-screen from scratch.","default":false}},"type":"object","required":["symbols"],"title":"ETFBulkScreenRequest","description":"Request to screen multiple ETFs in one call.","example":{"force_refresh":false,"symbols":["VTI","SPY","SCHB"]}},"ETFBulkScreenResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/ETFBulkScreenItemResult"},"type":"array","title":"Results","description":"Per-ETF screening results.","default":[]},"summary":{"$ref":"#/components/schemas/ETFBulkScreenSummary","description":"Aggregate screening statistics.","default":{"total":0,"compliant":0,"non_compliant":0,"errors":0}}},"type":"object","title":"ETFBulkScreenResponse","description":"Response for a bulk ETF screening operation.","example":{"results":[{"compliance_status":"non_compliant","compliant_weight":0.78,"is_compliant":false,"non_compliant_weight":0.19,"purification_rate":0.032,"symbol":"VTI"}],"summary":{"compliant":0,"errors":0,"non_compliant":3,"total":3}}},"ETFBulkScreenSummary":{"properties":{"total":{"type":"integer","title":"Total","description":"Total number of ETFs screened.","default":0},"compliant":{"type":"integer","title":"Compliant","description":"Number of compliant ETFs.","default":0},"non_compliant":{"type":"integer","title":"Non Compliant","description":"Number of non-compliant ETFs.","default":0},"errors":{"type":"integer","title":"Errors","description":"Number of ETFs that failed to screen.","default":0}},"type":"object","title":"ETFBulkScreenSummary","description":"Aggregate statistics across all ETFs in a bulk screening run.","example":{"compliant":0,"errors":0,"non_compliant":3,"total":3}},"ETFCompareItem":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"ETF ticker symbol."},"name":{"type":"string","title":"Name","description":"ETF fund name.","default":""},"holdings_count":{"type":"integer","title":"Holdings Count","description":"Number of holdings.","default":0},"total_assets":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Assets","description":"Total assets under management in USD."},"expense_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Expense Ratio","description":"Annual expense ratio as a decimal."},"compliance_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compliance Status","description":"Overall Shariah compliance status."},"compliant_weight":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Compliant Weight","description":"Sum of weights of compliant holdings."},"non_compliant_weight":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Non Compliant Weight","description":"Sum of weights of non-compliant holdings."}},"type":"object","required":["symbol"],"title":"ETFCompareItem","description":"Summary comparison data for a single ETF.","example":{"compliance_status":"non_compliant","compliant_weight":0.76,"expense_ratio":0.0945,"holdings_count":503,"name":"SPDR S&P 500 ETF Trust","non_compliant_weight":0.21,"symbol":"SPY","total_assets":500000000000.0}},"ETFCompareRequest":{"properties":{"symbols":{"items":{"type":"string"},"type":"array","maxItems":5,"minItems":2,"title":"Symbols","description":"List of 2-5 ETF ticker symbols to compare."}},"type":"object","required":["symbols"],"title":"ETFCompareRequest","description":"Request body to compare two to five ETFs side by side.","example":{"symbols":["VTI","SPY","SCHB"]}},"ETFCompareResponse":{"properties":{"etfs":{"items":{"$ref":"#/components/schemas/ETFCompareItem"},"type":"array","title":"Etfs","description":"Per-ETF comparison summaries.","default":[]},"overlap_holdings":{"items":{"$ref":"#/components/schemas/ETFOverlapHolding"},"type":"array","title":"Overlap Holdings","description":"Holdings that appear in multiple ETFs.","default":[]},"overlap_count":{"type":"integer","title":"Overlap Count","description":"Total number of overlapping holdings.","default":0}},"type":"object","title":"ETFCompareResponse","description":"Side-by-side comparison of multiple ETFs with overlap analysis.","example":{"etfs":[{"compliance_status":"non_compliant","compliant_weight":0.78,"holdings_count":3500,"name":"Vanguard Total Stock Market ETF","non_compliant_weight":0.19,"symbol":"VTI"},{"compliance_status":"non_compliant","compliant_weight":0.76,"holdings_count":503,"name":"SPDR S&P 500 ETF Trust","non_compliant_weight":0.21,"symbol":"SPY"}],"overlap_count":480,"overlap_holdings":[]}},"ETFComplianceSummary":{"properties":{"total_holdings":{"type":"integer","title":"Total Holdings","description":"Total number of holdings analysed.","default":0},"screened_count":{"type":"integer","title":"Screened Count","description":"Number of holdings that were actually screened.","default":0},"compliant_count":{"type":"integer","title":"Compliant Count","description":"Number of holdings deemed Shariah-compliant.","default":0},"non_compliant_count":{"type":"integer","title":"Non Compliant Count","description":"Number of holdings deemed non-compliant.","default":0},"unscreened_count":{"type":"integer","title":"Unscreened Count","description":"Number of holdings with no screening data.","default":0},"compliant_weight":{"type":"number","title":"Compliant Weight","description":"Sum of weights of compliant holdings (0.0 – 1.0).","default":0.0},"non_compliant_weight":{"type":"number","title":"Non Compliant Weight","description":"Sum of weights of non-compliant holdings (0.0 – 1.0).","default":0.0},"unscreened_weight":{"type":"number","title":"Unscreened Weight","description":"Sum of weights of unscreened holdings (0.0 – 1.0).","default":0.0}},"type":"object","title":"ETFComplianceSummary","description":"Aggregate compliance statistics for an ETF screening run.","example":{"compliant_count":380,"compliant_weight":0.78,"non_compliant_count":105,"non_compliant_weight":0.19,"screened_count":485,"total_holdings":500,"unscreened_count":15,"unscreened_weight":0.03}},"ETFFundInfoResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"ETF ticker symbol."},"name":{"type":"string","title":"Name","description":"ETF fund name.","default":""},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Brief fund description."},"inception_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inception Date","description":"Fund inception date (YYYY-MM-DD)."},"expense_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Expense Ratio","description":"Annual expense ratio as a decimal (0.0003 = 0.03%)."},"nav":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Nav","description":"Net asset value per share in USD."},"total_assets":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Assets","description":"Total assets under management in USD."},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","description":"Morningstar or provider category."},"family":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family","description":"Fund family name (e.g. 'Vanguard')."},"exchange":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exchange","description":"Exchange where the ETF is listed (e.g. 'NYSE Arca')."},"sector_weightings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Sector Weightings","description":"Mapping of sector names to portfolio weight percentages."},"asset_classes":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Asset Classes","description":"Mapping of asset class labels (equity, bond, etc.) to weight percentages."},"country_weightings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Country Weightings","description":"Mapping of country codes/names to portfolio weight percentages."},"turnover":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Turnover","description":"Annual portfolio turnover rate as a decimal."}},"type":"object","required":["symbol"],"title":"ETFFundInfoResponse","description":"General fund-level metadata for an ETF.","example":{"category":"Large Blend","description":"Tracks the S&P 500 index.","exchange":"NYSE Arca","expense_ratio":0.0945,"family":"SPDR State Street Global Advisors","inception_date":"1993-01-22","name":"SPDR S&P 500 ETF Trust","nav":510.25,"sector_weightings":{"healthcare":0.13,"technology":0.3},"symbol":"SPY","total_assets":500000000000.0,"turnover":0.02}},"ETFHoldingPurificationDetail":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol of the holding."},"name":{"type":"string","title":"Name","description":"Company or security name.","default":""},"weight":{"type":"number","title":"Weight","description":"Portfolio weight as a decimal.","default":0.0},"compliance_status":{"type":"string","title":"Compliance Status","description":"Shariah compliance status.","default":"unscreened"},"purification_rate":{"type":"number","title":"Purification Rate","description":"Purification rate for this holding (e.g. 0.03 = 3%).","default":0.0},"purification_amount":{"type":"number","title":"Purification Amount","description":"Dollar amount to purify for this holding.","default":0.0}},"type":"object","required":["symbol"],"title":"ETFHoldingPurificationDetail","description":"Purification breakdown for a single holding.","example":{"compliance_status":"compliant","name":"Apple Inc.","purification_amount":81.25,"purification_rate":0.025,"symbol":"AAPL","weight":0.065}},"ETFHoldingResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol of the underlying holding (e.g. 'AAPL')."},"name":{"type":"string","title":"Name","description":"Company or security name.","default":""},"weight":{"type":"number","title":"Weight","description":"Portfolio weight as a decimal (0.05 = 5%).","default":0.0},"shares":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Shares","description":"Number of shares held by the ETF."},"market_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Market Value","description":"Current market value of the position in USD."},"isin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Isin","description":"ISIN identifier, if available."},"cusip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cusip","description":"CUSIP identifier, if available."},"compliance_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compliance Status","description":"Shariah compliance status: 'compliant', 'non_compliant', or 'unscreened'."}},"type":"object","required":["symbol"],"title":"ETFHoldingResponse","description":"A single holding within an ETF.","example":{"compliance_status":"compliant","cusip":"037833100","isin":"US0378331005","market_value":32436000.0,"name":"Apple Inc.","shares":180200,"symbol":"AAPL","weight":0.065}},"ETFHoldingScreeningResult":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol of the holding."},"name":{"type":"string","title":"Name","description":"Company or security name.","default":""},"weight":{"type":"number","title":"Weight","description":"Portfolio weight as a decimal.","default":0.0},"compliance_status":{"type":"string","title":"Compliance Status","description":"Shariah compliance status: 'compliant', 'non_compliant', or 'unscreened'.","default":"unscreened"},"purification_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Purification Rate","description":"Percentage of income requiring purification (e.g. 0.03 = 3%)."}},"type":"object","required":["symbol"],"title":"ETFHoldingScreeningResult","description":"Screening result for a single holding within an ETF.","example":{"compliance_status":"compliant","name":"Apple Inc.","purification_rate":0.025,"symbol":"AAPL","weight":0.065}},"ETFHoldingsResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"ETF ticker symbol."},"name":{"type":"string","title":"Name","description":"ETF fund name.","default":""},"holdings_count":{"type":"integer","title":"Holdings Count","description":"Total number of holdings in the ETF.","default":0},"holdings":{"items":{"$ref":"#/components/schemas/ETFHoldingResponse"},"type":"array","title":"Holdings","description":"List of individual holdings.","default":[]},"data_source":{"type":"string","title":"Data Source","description":"Provider that supplied the holdings data (e.g. 'yfinance').","default":""},"disclaimers":{"anyOf":[{"items":{"$ref":"#/components/schemas/Disclaimer"},"type":"array"},{"type":"null"}],"title":"Disclaimers","description":"Attached by middleware; see /api/disclaimers."}},"type":"object","required":["symbol"],"title":"ETFHoldingsResponse","description":"Complete holdings list for an ETF.","example":{"data_source":"yfinance","holdings":[{"compliance_status":"compliant","market_value":32436000.0,"name":"Apple Inc.","shares":180200,"symbol":"AAPL","weight":0.065},{"compliance_status":"compliant","market_value":28920000.0,"name":"Microsoft Corp.","shares":120500,"symbol":"MSFT","weight":0.058}],"holdings_count":2,"name":"Vanguard Total Stock Market ETF","symbol":"VTI"}},"ETFOverlapHolding":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol of the overlapping holding."},"name":{"type":"string","title":"Name","description":"Company or security name.","default":""},"etfs":{"items":{"type":"string"},"type":"array","title":"Etfs","description":"ETF symbols containing this holding.","default":[]},"weights":{"additionalProperties":{"type":"number"},"type":"object","title":"Weights","description":"Mapping of ETF symbol to weight for this holding.","default":{}}},"type":"object","required":["symbol"],"title":"ETFOverlapHolding","description":"A holding that appears in more than one of the compared ETFs.","example":{"etfs":["VTI","SPY"],"name":"Apple Inc.","symbol":"AAPL","weights":{"SPY":0.072,"VTI":0.065}}},"ETFPurificationRequest":{"properties":{"investment_amount":{"type":"number","exclusiveMinimum":0.0,"title":"Investment Amount","description":"Total investment amount in USD."},"dividend_income":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Dividend Income","description":"Dividend income received from the ETF in USD."}},"type":"object","required":["investment_amount"],"title":"ETFPurificationRequest","description":"Request body for calculating purification amounts on an ETF investment.","example":{"dividend_income":1200.0,"investment_amount":50000.0}},"ETFPurificationResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"ETF ticker symbol."},"investment_amount":{"type":"number","title":"Investment Amount","description":"Original investment amount in USD.","default":0.0},"dividend_income":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dividend Income","description":"Dividend income in USD, if provided."},"etf_purification_rate":{"type":"number","title":"Etf Purification Rate","description":"Weighted-average purification rate for the ETF.","default":0.0},"investment_purification_amount":{"type":"number","title":"Investment Purification Amount","description":"Amount to purify from investment gains.","default":0.0},"dividend_purification_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dividend Purification Amount","description":"Amount to purify from dividends."},"total_purification_amount":{"type":"number","title":"Total Purification Amount","description":"Total purification amount (investment + dividends).","default":0.0},"holdings":{"items":{"$ref":"#/components/schemas/ETFHoldingPurificationDetail"},"type":"array","title":"Holdings","description":"Per-holding purification breakdown.","default":[]},"disclaimers":{"anyOf":[{"items":{"$ref":"#/components/schemas/Disclaimer"},"type":"array"},{"type":"null"}],"title":"Disclaimers","description":"Attached by middleware; see /api/disclaimers."}},"type":"object","required":["symbol"],"title":"ETFPurificationResponse","description":"Purification calculation result for an ETF investment.","example":{"dividend_income":1200.0,"dividend_purification_amount":38.4,"etf_purification_rate":0.032,"holdings":[],"investment_amount":50000.0,"investment_purification_amount":1600.0,"symbol":"VTI","total_purification_amount":1638.4}},"ETFScreeningResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"ETF ticker symbol."},"name":{"type":"string","title":"Name","description":"ETF fund name.","default":""},"is_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Compliant","description":"Always null for ETFs (v2 spec §10.3). Use `disposition` or compute from `summary.non_compliant_weight` instead."},"compliance_status":{"type":"string","title":"Compliance Status","description":"Holdings-based bucket label kept for backwards compatibility: 'compliant', 'non_compliant', 'insufficient_data', 'unscreened'. For the verdict-shaped client signal, read `disposition` instead.","default":"unscreened"},"disposition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disposition","description":"Non-verdict summary derived from scholar attestations + holdings analysis: 'scholar_certified', 'data_quality_flag', 'contested', 'unrated'. See spec §11."},"scholar_attestations":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Scholar Attestations","description":"List of scholar-board attestations carrying methodology, position, verified_on, and source_url. Empty when no attestation is on file."},"non_compliant_threshold":{"type":"number","title":"Non Compliant Threshold","description":"Maximum non-compliant weight allowed (default 5%).","default":0.05},"purification_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Purification Rate","description":"Weighted-average purification rate for the ETF."},"summary":{"anyOf":[{"$ref":"#/components/schemas/ETFComplianceSummary"},{"type":"null"}],"description":"Aggregate compliance statistics."},"holdings":{"items":{"$ref":"#/components/schemas/ETFHoldingScreeningResult"},"type":"array","title":"Holdings","description":"Per-holding screening results.","default":[]},"fund_info":{"anyOf":[{"$ref":"#/components/schemas/ETFFundInfoResponse"},{"type":"null"}],"description":"Fund metadata, if available."},"data_source":{"type":"string","title":"Data Source","description":"Data provider used for screening.","default":""},"disclaimers":{"anyOf":[{"items":{"$ref":"#/components/schemas/Disclaimer"},"type":"array"},{"type":"null"}],"title":"Disclaimers","description":"Attached by middleware; see /api/disclaimers."}},"type":"object","required":["symbol"],"title":"ETFScreeningResponse","description":"Full Shariah screening result for an ETF.\n\nPer the v2 cert spec (docs/superpowers/specs/2026-05-08-shariah-methodology-\nheadline-design.md §10–11), ETFs never carry a binary `is_compliant`\nverdict. Scholars publish verdicts; we publish data. The response carries:\n\n  - `is_compliant: null`  (always, by design)\n  - `disposition`: scholar_certified | data_quality_flag | contested | unrated\n  - `scholar_attestations`: list of board attestations (multi-board friendly)\n  - `holdings_analysis` data via `summary` + `holdings` (unchanged)\n\nClients should switch on `disposition` (or compute their own threshold from\n`summary.non_compliant_weight`) instead of `is_compliant`.","example":{"compliance_status":"non_compliant","data_source":"issuer","disposition":"scholar_certified","holdings":[],"name":"Wahed FTSE USA Shariah ETF","non_compliant_threshold":0.05,"purification_rate":0.0,"scholar_attestations":[{"authority":"Yasaar Research Inc.","methodology":"FTSE","position":"compliant","source_url":"https://www.sec.gov/Archives/edgar/data/1683471/...","stale":false,"verified_on":"2026-05-08"}],"summary":{"compliant_count":146,"compliant_weight":0.9283,"non_compliant_count":40,"non_compliant_weight":0.0599,"screened_count":186,"total_holdings":197,"unscreened_count":11,"unscreened_weight":0.0065},"symbol":"HLAL"}},"EightKEvent":{"properties":{"accession_number":{"type":"string","title":"Accession Number","description":"SEC EDGAR accession number uniquely identifying the filing"},"filing_date":{"type":"string","title":"Filing Date","description":"Date the 8-K was filed (YYYY-MM-DD)"},"filing_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filing Url","description":"Direct URL to view the filing on SEC EDGAR"},"compliance_relevant":{"type":"boolean","title":"Compliance Relevant","description":"True when at least one item can move a Shariah-compliance verdict"},"items":{"items":{"$ref":"#/components/schemas/EightKItemModel"},"type":"array","title":"Items","description":"The 8-K's reportable items, parsed from its SEC item codes"}},"type":"object","required":["accession_number","filing_date","compliance_relevant","items"],"title":"EightKEvent","description":"An 8-K filing with its parsed reportable items."},"EightKEventsResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol of the company"},"cik":{"type":"string","title":"Cik","description":"SEC Central Index Key (CIK) number for the company"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name","description":"Official company name as registered with the SEC"},"count":{"type":"integer","title":"Count","description":"Number of 8-K events returned"},"events":{"items":{"$ref":"#/components/schemas/EightKEvent"},"type":"array","title":"Events","description":"Parsed 8-K events, most recent first"}},"type":"object","required":["symbol","cik","count","events"],"title":"EightKEventsResponse","description":"Parsed 8-K event feed for a company.","example":{"cik":"0000320193","company_name":"Apple Inc.","count":1,"events":[{"accession_number":"0000320193-26-000012","compliance_relevant":true,"filing_date":"2026-02-01","filing_url":"https://www.sec.gov/Archives/edgar/data/320193/000032019326000012/ex.htm","items":[{"code":"2.03","compliance_relevant":true,"label":"Creation of a Direct Financial Obligation"},{"code":"9.01","compliance_relevant":false,"label":"Financial Statements and Exhibits"}]}],"symbol":"AAPL"}},"EightKItemModel":{"properties":{"code":{"type":"string","title":"Code","description":"SEC 8-K item code, e.g. '2.03'"},"label":{"type":"string","title":"Label","description":"Human-readable event title"},"compliance_relevant":{"type":"boolean","title":"Compliance Relevant","description":"Whether this item can move a Shariah-compliance verdict"}},"type":"object","required":["code","label","compliance_relevant"],"title":"EightKItemModel","description":"One 8-K reportable item."},"EndpointStat":{"properties":{"endpoint":{"type":"string","title":"Endpoint","description":"API endpoint path"},"method":{"type":"string","title":"Method","description":"HTTP method (GET, POST, etc.)"},"count":{"type":"integer","title":"Count","description":"Number of requests to this endpoint"},"total_tokens":{"type":"integer","title":"Total Tokens","description":"Total tokens charged for this endpoint","default":0}},"type":"object","required":["endpoint","method","count"],"title":"EndpointStat","description":"Hit count for a single API endpoint.","example":{"count":30,"endpoint":"/api/screen","method":"GET","total_tokens":150}},"EquitiesStatsResponse":{"properties":{"count":{"type":"integer","title":"Count","description":"Total count of items in this category","default":0},"sectors":{"type":"integer","title":"Sectors","description":"Number of distinct sectors","default":0},"countries":{"type":"integer","title":"Countries","description":"Number of distinct countries","default":0}},"type":"object","title":"EquitiesStatsResponse"},"FilingsListResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol of the company"},"cik":{"type":"string","title":"Cik","description":"SEC Central Index Key (CIK) number for the company"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name","description":"Official company name as registered with the SEC"},"count":{"type":"integer","title":"Count","description":"Number of filings returned"},"filings":{"items":{"$ref":"#/components/schemas/SECFilingResponse"},"type":"array","title":"Filings","description":"List of SEC filing records"}},"type":"object","required":["symbol","cik","count","filings"],"title":"FilingsListResponse","description":"Paginated list of SEC filings for a company.","example":{"cik":"0000320193","company_name":"Apple Inc.","count":1,"filings":[{"accession_number":"0000320193-23-000106","filing_date":"2023-11-03","filing_type":"10-K","filing_url":"https://www.sec.gov/Archives/edgar/data/320193/000032019323000106/aapl-20230930.htm","primary_doc_description":"10-K Annual Report","primary_document":"aapl-20230930.htm"}],"symbol":"AAPL"}},"FundamentalsProvenance":{"properties":{"total_debt":{"type":"string","title":"Total Debt","description":"Source of the total-debt figure: 'sec' or 'yfinance'."},"total_assets":{"type":"string","title":"Total Assets","description":"Source of the total-assets figure."},"cash":{"type":"string","title":"Cash","description":"Source of the cash-and-investments figure."},"receivables":{"type":"string","title":"Receivables","description":"Source of the accounts-receivable figure."},"total_revenue":{"type":"string","title":"Total Revenue","description":"Source of the total-revenue figure."},"interest_income":{"type":"string","title":"Interest Income","description":"Source of the interest-income figure."}},"type":"object","required":["total_debt","total_assets","cash","receivables","total_revenue","interest_income"],"title":"FundamentalsProvenance","description":"Per-metric source attribution for the fundamentals behind a verdict.\n\nEach value is `sec` (SEC XBRL) or `yfinance`. Populated only when the\nSEC-XBRL financial provider screened the name; a screen result's\n`fundamentals_provenance` is null for yfinance-only screens."},"GenerateKeyRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email","description":"Email address to associate with the new API key"},"marketing_opt_in":{"type":"boolean","title":"Marketing Opt In","description":"Opt in to occasional product updates and onboarding tips. Defaults to False; transactional emails (key delivery, payment receipts, quota alerts) are always sent regardless.","default":false}},"type":"object","required":["email"],"title":"GenerateKeyRequest","description":"Request body for generating a new free-trial API key.","example":{"email":"dev@example.com","marketing_opt_in":false}},"GenerateKeyResponse":{"properties":{"api_key":{"type":"string","title":"Api Key","description":"The generated API key"},"email":{"type":"string","title":"Email","description":"Email address associated with the key"},"plan":{"type":"string","title":"Plan","description":"Plan tier assigned to this key (e.g. free)"},"tokens_limit":{"type":"integer","title":"Tokens Limit","description":"Monthly token allowance"},"tokens_used":{"type":"integer","title":"Tokens Used","description":"Tokens consumed so far this period"},"requests_limit":{"type":"integer","title":"Requests Limit","description":"Maximum number of requests allowed"},"requests_used":{"type":"integer","title":"Requests Used","description":"Number of requests consumed so far"},"billing_period_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Period End","description":"ISO-8601 timestamp when the current billing period ends"},"created_at":{"type":"string","title":"Created At","description":"ISO-8601 timestamp when the key was created"}},"type":"object","required":["api_key","email","plan","tokens_limit","tokens_used","requests_limit","requests_used","created_at"],"title":"GenerateKeyResponse","description":"Response returned after successfully generating an API key.","example":{"api_key":"ht_abc123def456","billing_period_end":"2025-07-01T12:00:00Z","created_at":"2025-06-01T12:00:00Z","email":"dev@example.com","plan":"free","requests_limit":50,"requests_used":0,"tokens_limit":500,"tokens_used":0}},"GlossaryResponse":{"properties":{"count":{"type":"integer","title":"Count","description":"Number of glossary terms returned"},"query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Query","description":"The search query used to filter terms, if any"},"terms":{"items":{"$ref":"#/components/schemas/GlossaryTermResponse"},"type":"array","title":"Terms","description":"List of matching glossary terms"}},"type":"object","required":["count","terms"],"title":"GlossaryResponse","description":"Collection of Islamic finance glossary terms, optionally filtered.","example":{"count":2,"query":"riba","terms":[{"arabic":"ربا","category":"prohibited_elements","definition":"Interest or usury, prohibited in Islamic finance.","references":["Quran 2:275"],"term":"Riba"},{"arabic":"ربا الفضل","category":"prohibited_elements","definition":"Excess in exchange of commodities of the same type.","references":[],"term":"Riba al-Fadl"}]}},"GlossaryTermResponse":{"properties":{"term":{"type":"string","title":"Term","description":"English transliteration of the Islamic finance term"},"arabic":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Arabic","description":"Original Arabic script for the term"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","description":"Topical category, e.g. 'prohibited_elements', 'contracts', 'instruments'"},"definition":{"type":"string","title":"Definition","description":"Detailed explanation of the term in the context of Islamic finance"},"references":{"items":{"type":"string"},"type":"array","title":"References","description":"Scholarly or scriptural references supporting the definition","default":[]}},"type":"object","required":["term","definition"],"title":"GlossaryTermResponse","description":"A single Islamic finance glossary term with its definition.","example":{"arabic":"ربا","category":"prohibited_elements","definition":"Interest or usury. Any excess compensation without due consideration, prohibited in Islamic finance as it represents unjust enrichment.","references":["Quran 2:275","AAOIFI Shariah Standard No. 3"],"term":"Riba"}},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"message":{"type":"string","title":"Message","description":"Human-readable status message indicating API health"}},"type":"object","required":["message"],"title":"HealthResponse","description":"Response model for the health check endpoint.","example":{"message":"Shariah Screener API is running"}},"Holding":{"properties":{"isin":{"type":"string","title":"Isin"},"units":{"type":"number","title":"Units"}},"type":"object","required":["isin","units"],"title":"Holding"},"IndexInfo":{"properties":{"name":{"type":"string","title":"Name","description":"Index identifier, e.g. 'SP500', 'DJIA', 'NASDAQ100'"},"estimated_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Count","description":"Approximate number of tickers in the index"},"description":{"type":"string","title":"Description","description":"Human-readable description of the index"}},"type":"object","required":["name","description"],"title":"IndexInfo","example":{"description":"S&P 500 — large-cap US equities","estimated_count":503,"name":"SP500"}},"IndicesResponse":{"properties":{"indices":{"items":{"$ref":"#/components/schemas/IndexInfo"},"type":"array","title":"Indices","description":"Available stock indices for bulk screening"}},"type":"object","required":["indices"],"title":"IndicesResponse","example":{"indices":[{"description":"S&P 500 — large-cap US equities","estimated_count":503,"name":"SP500"},{"description":"Dow Jones Industrial Average","estimated_count":30,"name":"DJIA"}]}},"KeyUsageResponse":{"properties":{"api_key":{"type":"string","title":"Api Key","description":"The API key these stats belong to"},"email":{"type":"string","title":"Email","description":"Email associated with the key"},"plan":{"type":"string","title":"Plan","description":"Current plan tier"},"tokens_used":{"type":"integer","title":"Tokens Used","description":"Tokens consumed this billing period"},"tokens_limit":{"type":"integer","title":"Tokens Limit","description":"Monthly token allowance (-1 = unlimited)"},"requests_used":{"type":"integer","title":"Requests Used","description":"Total requests consumed"},"requests_limit":{"type":"integer","title":"Requests Limit","description":"Maximum requests allowed under the plan"},"billing_period_start":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Period Start","description":"Start of current billing period"},"billing_period_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Period End","description":"End of current billing period"},"is_active":{"type":"boolean","title":"Is Active","description":"Whether the key is currently active"},"created_at":{"type":"string","title":"Created At","description":"ISO-8601 creation timestamp"},"updated_at":{"type":"string","title":"Updated At","description":"ISO-8601 timestamp of last usage update"},"top_endpoints":{"items":{"$ref":"#/components/schemas/EndpointStat"},"type":"array","title":"Top Endpoints","description":"Most frequently called endpoints","default":[]}},"type":"object","required":["api_key","email","plan","tokens_used","tokens_limit","requests_used","requests_limit","is_active","created_at","updated_at"],"title":"KeyUsageResponse","description":"Detailed usage statistics for an API key.","example":{"api_key":"ht_abc123def456","billing_period_end":"2025-07-01T12:00:00Z","billing_period_start":"2025-06-01T12:00:00Z","created_at":"2025-06-01T12:00:00Z","email":"dev@example.com","is_active":true,"plan":"starter","requests_limit":2500,"requests_used":42,"tokens_limit":2500,"tokens_used":142,"top_endpoints":[{"count":30,"endpoint":"/api/screen","method":"GET","total_tokens":150}],"updated_at":"2025-06-15T08:30:00Z"}},"MethodologiesResponse":{"properties":{"count":{"type":"integer","title":"Count","description":"Number of methodologies available"},"methodologies":{"items":{"$ref":"#/components/schemas/MethodologyDetailResponse"},"type":"array","title":"Methodologies","description":"List of screening methodology details"}},"type":"object","required":["count","methodologies"],"title":"MethodologiesResponse","description":"List of all available Shariah screening methodologies.","example":{"count":2,"methodologies":[{"full_name":"Accounting and Auditing Organization for Islamic Financial Institutions","id":"aaoifi","name":"AAOIFI"},{"full_name":"Securities Commission Malaysia Shariah Advisory Council","id":"sec","name":"SEC Malaysia"}]}},"MethodologyBreakdown":{"properties":{"compliant":{"type":"integer","title":"Compliant","description":"Symbols this methodology scored as compliant."},"non_compliant":{"type":"integer","title":"Non Compliant","description":"Symbols this methodology scored as non-compliant."},"insufficient_data":{"type":"integer","title":"Insufficient Data","description":"Symbols this methodology could not score because the required inputs were missing (e.g. AAOIFI receivables ratio, MSCI interest-income breakdown). Previously folded into `non_compliant`.","default":0},"errors":{"type":"integer","title":"Errors","description":"Symbols whose entire screening failed (yfinance fetch error, unknown ticker, etc.) — counted here per-methodology because no methodology verdict was produced for them.","default":0}},"type":"object","required":["compliant","non_compliant"],"title":"MethodologyBreakdown","description":"Per-methodology bucket counts for a bulk screening run.\n\nBuckets are mutually exclusive and sum to `total_screened`:\n  compliant + non_compliant + insufficient_data + errors == total"},"MethodologyDetailResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Short identifier for the methodology, e.g. 'aaoifi'"},"name":{"type":"string","title":"Name","description":"Common name or abbreviation, e.g. 'AAOIFI'"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name","description":"Full official name of the organization"},"established":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Established","description":"Year the organization was established"},"headquarters":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headquarters","description":"City and country of the organization's headquarters"},"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis","description":"Foundation or basis of the screening methodology"},"overview":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Overview","description":"General overview of the methodology and its adoption"},"screening_process":{"items":{"type":"string"},"type":"array","title":"Screening Process","description":"Ordered steps in the screening process","default":[]},"thresholds":{"additionalProperties":true,"type":"object","title":"Thresholds","description":"Financial ratio thresholds used in compliance screening","default":{}},"distinguishing_features":{"items":{"type":"string"},"type":"array","title":"Distinguishing Features","description":"Key features that distinguish this methodology from others","default":[]},"shariah_board":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shariah Board","description":"Name of the Shariah supervisory board"},"references":{"items":{"type":"string"},"type":"array","title":"References","description":"Published standards or scholarly references","default":[]}},"type":"object","required":["id","name"],"title":"MethodologyDetailResponse","description":"Detailed information about a Shariah screening methodology.","example":{"basis":"Shariah standards developed by an independent board of scholars","distinguishing_features":["Uses total assets as denominator for financial ratios","Stricter thresholds compared to market-cap-based methodologies"],"established":1991,"full_name":"Accounting and Auditing Organization for Islamic Financial Institutions","headquarters":"Manama, Bahrain","id":"aaoifi","name":"AAOIFI","overview":"AAOIFI sets accounting, auditing, governance, and Shariah standards adopted by Islamic financial institutions in over 45 countries.","references":["AAOIFI Shariah Standard No. 21"],"screening_process":["Business activity screening for haram revenue","Financial ratio screening using total assets as denominator"],"shariah_board":"AAOIFI Shariah Board","thresholds":{"max_debt_to_total_assets":0.3,"max_haram_revenue_percentage":0.05,"max_interest_income_to_revenue":0.05}}},"MethodologyEntry":{"properties":{"is_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Compliant","description":"Tri-state verdict: true / false / null (insufficient inputs to score)."},"verified":{"type":"boolean","title":"Verified","description":"Whether this methodology has been audited end-to-end against real benchmark holdings. True for AAOIFI/FTSE/MSCI; false for DJIM/SP (trailing-average market-cap normalization pending).","default":false},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Short explanation of why the verdict came out this way (e.g. 'debt/MC = 0.42 > 0.33')."}},"type":"object","title":"MethodologyEntry","description":"Per-methodology compliance signal carried inside `by_methodology`.\n\nMirrors the legacy flat `<methodology>_compliant` boolean but exposes\nthe audit status alongside the verdict so consumers can filter on\n`verified=true` for scholar-grade signals."},"NewsArticleResponse":{"properties":{"title":{"type":"string","title":"Title","description":"Headline of the news article"},"link":{"type":"string","title":"Link","description":"URL to the full article"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary","description":"Brief summary or excerpt of the article content"},"published":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Published","description":"ISO 8601 publication timestamp"},"source_id":{"type":"string","title":"Source Id","description":"Unique identifier for the news source"},"source_name":{"type":"string","title":"Source Name","description":"Human-readable name of the news source"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","description":"Topic category, e.g. 'islamic_finance', 'market', 'regulation'"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url","description":"URL to a thumbnail image for the article"},"sentiment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sentiment","description":"Sentiment label: 'positive', 'negative', or 'neutral'"},"sentiment_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sentiment Score","description":"Numerical sentiment score from -1.0 to 1.0"},"relevance_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Relevance Score","description":"Relevance score from 0.0 to 1.0 indicating how closely the article matches the query"},"freshness_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Freshness Score","description":"Freshness score from 0.0 to 1.0 based on recency of publication"},"compliance_relevance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compliance Relevance","description":"Whether the article describes a corporate event likely to move the Shariah verdict (debt issuance, M&A, dividend policy, distress). One of 'high' / 'medium' / 'low'. Per-article tag, set even when the request omits the compliance_relevance filter."},"compliance_categories":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Compliance Categories","description":"Specific verdict-moving event categories detected: 'debt_issuance', 'm_and_a', 'dividend_change', 'equity_action', 'distress'. Empty when nothing was detected."},"compliance_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Compliance Score","description":"Raw compliance-relevance score (0+); higher = more verdict-moving signals matched"}},"type":"object","required":["title","link","source_id","source_name"],"title":"NewsArticleResponse","description":"A single news article with metadata, sentiment, and scoring.","example":{"category":"islamic_finance","freshness_score":0.88,"link":"https://example.com/articles/aaoifi-sukuk-update","published":"2026-03-20T14:30:00Z","relevance_score":0.95,"sentiment":"positive","sentiment_score":0.72,"source_id":"islamic_finance_news","source_name":"Islamic Finance News","summary":"The Accounting and Auditing Organization for Islamic Financial Institutions has released revised standards for Sukuk structuring.","thumbnail_url":"https://example.com/images/sukuk-thumb.jpg","title":"AAOIFI Updates Shariah Standards for Sukuk Issuance"}},"NewsListResponse":{"properties":{"count":{"type":"integer","title":"Count","description":"Number of articles in the current page"},"page":{"type":"integer","title":"Page","description":"Current page number (1-indexed)"},"page_size":{"type":"integer","title":"Page Size","description":"Maximum number of articles per page"},"total":{"type":"integer","title":"Total","description":"Total number of articles matching the query"},"articles":{"items":{"$ref":"#/components/schemas/NewsArticleResponse"},"type":"array","title":"Articles","description":"List of news articles for this page"}},"type":"object","required":["count","page","page_size","total","articles"],"title":"NewsListResponse","description":"Paginated list of news articles.","example":{"articles":[{"category":"islamic_finance","link":"https://example.com/articles/aaoifi-sukuk-update","published":"2026-03-20T14:30:00Z","sentiment":"positive","sentiment_score":0.72,"source_id":"islamic_finance_news","source_name":"Islamic Finance News","summary":"Revised standards for Sukuk structuring released.","title":"AAOIFI Updates Shariah Standards for Sukuk Issuance"}],"count":2,"page":1,"page_size":20,"total":2}},"NewsSourceResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier for the source"},"name":{"type":"string","title":"Name","description":"Display name of the news source"},"url":{"type":"string","title":"Url","description":"RSS feed or API URL for the source"},"category":{"type":"string","title":"Category","description":"Category of the source, e.g. 'islamic_finance', 'market'"},"enabled":{"type":"boolean","title":"Enabled","description":"Whether this source is currently active"}},"type":"object","required":["id","name","url","category","enabled"],"title":"NewsSourceResponse","description":"A configured news feed source.","example":{"category":"islamic_finance","enabled":true,"id":"islamic_finance_news","name":"Islamic Finance News","url":"https://www.islamicfinancenews.com/feed"}},"NewsSourcesResponse":{"properties":{"count":{"type":"integer","title":"Count","description":"Total number of configured news sources"},"sources":{"items":{"$ref":"#/components/schemas/NewsSourceResponse"},"type":"array","title":"Sources","description":"List of news sources"}},"type":"object","required":["count","sources"],"title":"NewsSourcesResponse","description":"List of all configured news sources.","example":{"count":1,"sources":[{"category":"islamic_finance","enabled":true,"id":"islamic_finance_news","name":"Islamic Finance News","url":"https://www.islamicfinancenews.com/feed"}]}},"NormalizedFactModel":{"properties":{"value":{"type":"number","title":"Value","description":"The normalized numeric value (USD)."},"concept":{"type":"string","title":"Concept","description":"us-gaap concept(s) the value derived from; '+'-joined when summed."},"period_end":{"type":"string","title":"Period End","description":"ISO date of the reported period end."},"form":{"type":"string","title":"Form","description":"Filing form type, e.g. '10-K' or '10-Q'."},"accession":{"type":"string","title":"Accession","description":"SEC accession number of the source filing."},"filed":{"type":"string","title":"Filed","description":"ISO date the source filing was filed."}},"type":"object","required":["value","concept","period_end","form","accession","filed"],"title":"NormalizedFactModel","description":"A canonical metric value with its XBRL provenance."},"OHLCPointResponse":{"properties":{"Date":{"type":"string","title":"Date","description":"Trading date in ISO-8601 format"},"Open":{"type":"number","title":"Open","description":"Opening price"},"High":{"type":"number","title":"High","description":"Highest price during the period"},"Low":{"type":"number","title":"Low","description":"Lowest price during the period"},"Close":{"type":"number","title":"Close","description":"Closing price"},"Volume":{"type":"integer","title":"Volume","description":"Number of shares traded"}},"type":"object","required":["Date","Open","High","Low","Close","Volume"],"title":"OHLCPointResponse","example":{"Close":187.44,"Date":"2025-03-21","High":188.5,"Low":185.73,"Open":186.12,"Volume":54638921}},"PlanInfo":{"properties":{"name":{"type":"string","title":"Name","description":"Machine-readable plan identifier"},"display_name":{"type":"string","title":"Display Name","description":"Human-readable plan name"},"price_monthly":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Monthly","description":"Monthly price in USD, null for free tier"},"tokens_limit":{"type":"integer","title":"Tokens Limit","description":"Monthly token allowance (-1 = unlimited)"},"requests_limit":{"type":"integer","title":"Requests Limit","description":"Monthly API request quota"},"overage_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Overage Rate","description":"Per-token overage rate in USD, null if no overage"},"features":{"items":{"type":"string"},"type":"array","title":"Features","description":"List of features included in this plan"},"is_popular":{"type":"boolean","title":"Is Popular","description":"Whether to highlight this plan in the UI","default":false}},"type":"object","required":["name","display_name","tokens_limit","requests_limit","features"],"title":"PlanInfo","description":"Details of an available API subscription plan.","example":{"display_name":"Starter","features":["2,500 tokens/mo","All endpoints","Email support"],"is_popular":false,"name":"starter","overage_rate":0.01,"price_monthly":19,"requests_limit":2500,"tokens_limit":2500}},"PlansResponse":{"properties":{"plans":{"items":{"$ref":"#/components/schemas/PlanInfo"},"type":"array","title":"Plans","description":"Available API subscription plans"}},"type":"object","required":["plans"],"title":"PlansResponse","description":"List of all available API plans.","example":{"plans":[{"display_name":"Free","features":["500 tokens for testing"],"is_popular":false,"name":"free","requests_limit":50,"tokens_limit":500}]}},"PortalRequest":{"properties":{"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key","description":"Deprecated — set the `X-API-Key` header instead. If provided here it must match the header value."}},"type":"object","title":"PortalRequest","description":"Request body for creating a Stripe Customer Portal session.\n\nAuthentication is via the `X-API-Key` header. The `api_key` body\nfield is retained for backwards compat; if provided it must match\nthe header value, otherwise the request is rejected.","example":{}},"PortalResponse":{"properties":{"portal_url":{"type":"string","title":"Portal Url","description":"URL of the Stripe Customer Portal session"}},"type":"object","required":["portal_url"],"title":"PortalResponse","description":"Response with a Stripe Customer Portal URL.","example":{"portal_url":"https://billing.stripe.com/p/session/test_xyz"}},"PortfolioHoldingReport":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol of the holding"},"is_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Compliant","description":"Whether the holding passes Shariah compliance screening; null if an error occurred"},"screening":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Screening","description":"Detailed screening results, if available"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Error message if screening could not be completed for this holding"}},"additionalProperties":false,"type":"object","required":["symbol"],"title":"PortfolioHoldingReport","description":"Screening result for a single holding within a portfolio report.","example":{"is_compliant":true,"screening":{"business_screening":{"passed":true},"financial_screening":{"passed":true},"methodology":"aaoifi"},"symbol":"AAPL"}},"PortfolioImpactBody":{"properties":{"holdings":{"items":{"$ref":"#/components/schemas/Holding"},"type":"array","title":"Holdings"}},"type":"object","required":["holdings"],"title":"PortfolioImpactBody"},"PortfolioReportRequest":{"properties":{"symbols":{"items":{"type":"string"},"type":"array","title":"Symbols","description":"List of ticker symbols to include in the portfolio report"}},"type":"object","required":["symbols"],"title":"PortfolioReportRequest","description":"Request body for generating a portfolio-level compliance report.","example":{"symbols":["AAPL","MSFT","AMZN"]}},"PortfolioReportResponse":{"properties":{"report_generated_at":{"type":"string","title":"Report Generated At","description":"ISO 8601 timestamp when the report was generated"},"total":{"type":"integer","title":"Total","description":"Total number of holdings analyzed"},"compliant":{"type":"integer","title":"Compliant","description":"Number of holdings that passed Shariah compliance screening"},"non_compliant":{"type":"integer","title":"Non Compliant","description":"Number of holdings that failed Shariah compliance screening"},"errors":{"type":"integer","title":"Errors","description":"Number of holdings where screening could not be completed"},"compliance_percentage":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Compliance Percentage","description":"Percentage of successfully screened holdings that are compliant"},"holdings":{"items":{"$ref":"#/components/schemas/PortfolioHoldingReport"},"type":"array","title":"Holdings","description":"Individual screening results for each holding in the portfolio"}},"type":"object","required":["report_generated_at","total","compliant","non_compliant","errors","holdings"],"title":"PortfolioReportResponse","description":"Aggregated Shariah compliance report for a portfolio of stocks.","example":{"compliance_percentage":66.67,"compliant":2,"errors":0,"holdings":[{"is_compliant":true,"screening":{"methodology":"aaoifi"},"symbol":"AAPL"},{"is_compliant":true,"screening":{"methodology":"aaoifi"},"symbol":"MSFT"},{"is_compliant":false,"screening":{"methodology":"aaoifi"},"symbol":"AMZN"}],"non_compliant":1,"report_generated_at":"2026-03-24T12:00:00Z","total":3}},"PortfolioScanRequest":{"properties":{"symbols":{"items":{"type":"string"},"type":"array","maxItems":100,"title":"Symbols","description":"List of ticker symbols to screen (e.g. ['AAPL', 'MSFT', 'GOOGL'])."},"force_refresh":{"type":"boolean","title":"Force Refresh","description":"When true, bypass cached screening results and re-screen from scratch.","default":false}},"type":"object","required":["symbols"],"title":"PortfolioScanRequest","description":"Request to scan a portfolio of stock symbols for Shariah compliance.","example":{"force_refresh":false,"symbols":["AAPL","MSFT","GOOGL"]}},"PortfolioScanResponse":{"properties":{"results":{"additionalProperties":{"$ref":"#/components/schemas/ScreeningResultResponse"},"type":"object","title":"Results","description":"Mapping of ticker symbol to its screening result."},"summary":{"$ref":"#/components/schemas/PortfolioSummaryResponse","description":"Aggregate compliance statistics for the portfolio."}},"type":"object","required":["results","summary"],"title":"PortfolioScanResponse","description":"Full portfolio scan result with per-symbol details and summary statistics.","example":{"results":{"AAPL":{"compliance_status":"compliant","name":"Apple Inc.","purification_rate":0.025,"symbol":"AAPL"},"MSFT":{"compliance_status":"compliant","name":"Microsoft Corp.","purification_rate":0.031,"symbol":"MSFT"}},"summary":{"avg_purification_rate":0.028,"compliant":2,"non_compliant":0,"pending":0,"total":2}}},"PortfolioSummaryResponse":{"properties":{"total":{"type":"integer","title":"Total","description":"Total number of symbols scanned."},"compliant":{"type":"integer","title":"Compliant","description":"Number of Shariah-compliant symbols."},"non_compliant":{"type":"integer","title":"Non Compliant","description":"Number of non-compliant symbols."},"pending":{"type":"integer","title":"Pending","description":"Number of symbols still pending screening (data unavailable)."},"avg_purification_rate":{"type":"number","title":"Avg Purification Rate","description":"Average purification rate across all screened holdings (e.g. 0.03 = 3%)."}},"type":"object","required":["total","compliant","non_compliant","pending","avg_purification_rate"],"title":"PortfolioSummaryResponse","description":"Aggregate compliance statistics for a portfolio scan.","example":{"avg_purification_rate":0.028,"compliant":2,"non_compliant":1,"pending":0,"total":3}},"PurificationCalculateRequest":{"properties":{"holdings":{"items":{"$ref":"#/components/schemas/PurificationHolding"},"type":"array","title":"Holdings","description":"List of holdings with dividend income to purify."}},"type":"object","required":["holdings"],"title":"PurificationCalculateRequest","description":"Request to calculate dividend purification amounts for a set of holdings.","example":{"holdings":[{"dividend_income":320.0,"symbol":"MSFT"},{"dividend_income":150.0,"symbol":"AAPL"}]}},"PurificationCalculateResponse":{"properties":{"total_dividend_income":{"type":"number","title":"Total Dividend Income","description":"Sum of all dividend income in USD."},"total_purification":{"type":"number","title":"Total Purification","description":"Total amount to purify across all holdings in USD."},"total_halal":{"type":"number","title":"Total Halal","description":"Total halal dividend amount after purification in USD."},"holdings":{"items":{"$ref":"#/components/schemas/PurificationHoldingResult"},"type":"array","title":"Holdings","description":"Per-holding purification details."},"disclaimers":{"anyOf":[{"items":{"$ref":"#/components/schemas/Disclaimer"},"type":"array"},{"type":"null"}],"title":"Disclaimers","description":"Attached by middleware; see /api/disclaimers."}},"type":"object","required":["total_dividend_income","total_purification","total_halal","holdings"],"title":"PurificationCalculateResponse","description":"Aggregate purification calculation across all holdings.","example":{"holdings":[{"dividend_income":320.0,"halal_amount":310.08,"is_compliant":true,"purification_amount":9.92,"purification_rate":0.031,"symbol":"MSFT"},{"dividend_income":150.0,"halal_amount":146.25,"is_compliant":true,"purification_amount":3.75,"purification_rate":0.025,"symbol":"AAPL"}],"total_dividend_income":470.0,"total_halal":456.33,"total_purification":13.67}},"PurificationGuideResponse":{"properties":{"overview":{"additionalProperties":true,"type":"object","title":"Overview","description":"General overview of the purification concept","default":{}},"purification_formula":{"additionalProperties":true,"type":"object","title":"Purification Formula","description":"Formula and methodology for calculating the amount to purify","default":{}},"capital_gains_purification":{"additionalProperties":true,"type":"object","title":"Capital Gains Purification","description":"Guidance on purification of capital gains from stock sales","default":{}},"zakat_on_investments":{"additionalProperties":true,"type":"object","title":"Zakat On Investments","description":"Zakat calculation guidance for investment portfolios","default":{}},"scholarly_references":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Scholarly References","description":"Scholarly sources and standards referenced in the guide","default":[]}},"additionalProperties":false,"type":"object","title":"PurificationGuideResponse","description":"Guide for purifying investment returns from non-compliant income.","example":{"capital_gains_purification":{"description":"Scholars differ on whether capital gains require purification."},"overview":{"description":"Purification is the process of cleansing investment returns from haram income by donating a proportional amount to charity."},"purification_formula":{"description":"Calculate the impure portion of dividends received and donate it.","formula":"(Haram Revenue / Total Revenue) x Dividend Received"},"scholarly_references":[{"source":"AAOIFI Shariah Standard No. 21","topic":"Purification of unlawful income"}],"zakat_on_investments":{"description":"2.5% annual zakat on qualifying investment holdings.","rate":0.025}}},"PurificationHolding":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol (e.g. 'AAPL')."},"dividend_income":{"type":"number","minimum":0.0,"title":"Dividend Income","description":"Dividend income received from this holding in USD."}},"type":"object","required":["symbol","dividend_income"],"title":"PurificationHolding","description":"A stock holding with dividend income for purification calculation.","example":{"dividend_income":320.0,"symbol":"MSFT"}},"PurificationHoldingResult":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol."},"dividend_income":{"type":"number","title":"Dividend Income","description":"Dividend income in USD."},"purification_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Purification Rate","description":"Company-specific purification rate (e.g. 0.031 = 3.1%). Null if unknown."},"purification_amount":{"type":"number","title":"Purification Amount","description":"Dollar amount to purify (donate) from this holding's dividends."},"halal_amount":{"type":"number","title":"Halal Amount","description":"Remaining halal dividend amount after purification."},"is_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Compliant","description":"Whether the holding is Shariah-compliant. Null if unscreened."}},"type":"object","required":["symbol","dividend_income","purification_amount","halal_amount"],"title":"PurificationHoldingResult","description":"Purification result for a single holding.","example":{"dividend_income":320.0,"halal_amount":310.08,"is_compliant":true,"purification_amount":9.92,"purification_rate":0.031,"symbol":"MSFT"}},"PurifiedDividend":{"properties":{"date":{"type":"string","title":"Date","description":"Payment date in YYYY-MM-DD format."},"amount":{"type":"number","title":"Amount","description":"Original dividend amount per share in USD."},"purification_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Purification Rate","description":"Purification rate applied to this dividend (e.g. 0.031 = 3.1%)."},"purification_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Purification Amount","description":"Dollar amount to purify (donate) from this dividend."},"halal_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Halal Amount","description":"Remaining halal amount after purification."}},"type":"object","required":["date","amount"],"title":"PurifiedDividend","description":"A dividend payment with purification details applied.","example":{"amount":0.83,"date":"2025-12-11","halal_amount":0.804,"purification_amount":0.026,"purification_rate":0.031}},"QuoteResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol"},"name":{"type":"string","title":"Name","description":"Company or asset name"},"price":{"type":"number","title":"Price","description":"Last traded price in USD"},"change":{"type":"number","title":"Change","description":"Absolute price change since previous close"},"changePercent":{"type":"number","title":"Changepercent","description":"Percentage price change since previous close"},"volume":{"type":"integer","title":"Volume","description":"Trading volume for the current session"},"high":{"type":"number","title":"High","description":"Session high price"},"low":{"type":"number","title":"Low","description":"Session low price"},"open":{"type":"number","title":"Open","description":"Session opening price"},"previousClose":{"type":"number","title":"Previousclose","description":"Previous session closing price"},"marketCap":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Marketcap","description":"Market capitalization in USD"},"peRatio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Peratio","description":"Price-to-earnings ratio (trailing twelve months)"},"dividendYield":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dividendyield","description":"Annual dividend yield as a decimal"},"beta":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Beta","description":"Beta coefficient relative to the market"},"disclaimers":{"anyOf":[{"items":{"$ref":"#/components/schemas/Disclaimer"},"type":"array"},{"type":"null"}],"title":"Disclaimers","description":"Attached by middleware; see /api/disclaimers."}},"type":"object","required":["symbol","name","price","change","changePercent","volume","high","low","open","previousClose"],"title":"QuoteResponse","example":{"beta":1.28,"change":1.32,"changePercent":0.71,"dividendYield":0.0055,"high":188.5,"low":185.73,"marketCap":2890000000000,"name":"Apple Inc.","open":186.12,"peRatio":29.5,"previousClose":186.12,"price":187.44,"symbol":"AAPL","volume":54638921}},"RecentRequestEntry":{"properties":{"endpoint":{"type":"string","title":"Endpoint","description":"API endpoint that was called"},"method":{"type":"string","title":"Method","description":"HTTP method used"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code","description":"HTTP status code returned"},"tokens_charged":{"type":"integer","title":"Tokens Charged","description":"Tokens charged for this request","default":0},"timestamp":{"type":"string","title":"Timestamp","description":"ISO-8601 timestamp of the request"}},"type":"object","required":["endpoint","method","timestamp"],"title":"RecentRequestEntry","description":"A single recent API request log entry.","example":{"endpoint":"/api/screen","method":"GET","status_code":200,"timestamp":"2025-06-15T14:32:00Z","tokens_charged":5}},"RecentRequestsResponse":{"properties":{"api_key":{"type":"string","title":"Api Key","description":"The API key these requests belong to"},"requests":{"items":{"$ref":"#/components/schemas/RecentRequestEntry"},"type":"array","title":"Requests","description":"Recent API request log entries"}},"type":"object","required":["api_key","requests"],"title":"RecentRequestsResponse","description":"List of the most recent API requests for a key.","example":{"api_key":"ht_abc123def456","requests":[{"endpoint":"/api/screen","method":"GET","status_code":200,"timestamp":"2025-06-15T14:32:00Z","tokens_charged":5}]}},"RegenerateKeyResponse":{"properties":{"old_key":{"type":"string","title":"Old Key","description":"The deactivated API key"},"new_key":{"type":"string","title":"New Key","description":"The newly generated replacement key"},"email":{"type":"string","title":"Email","description":"Email associated with the key"},"plan":{"type":"string","title":"Plan","description":"Plan tier carried over to the new key"}},"type":"object","required":["old_key","new_key","email","plan"],"title":"RegenerateKeyResponse","description":"Response returned after regenerating an API key.","example":{"email":"dev@example.com","new_key":"ht_xyz789ghi012","old_key":"ht_abc123def456","plan":"starter"}},"RevokeKeyRequest":{"properties":{"key_prefix":{"type":"string","title":"Key Prefix","description":"Public 10-char prefix (e.g. ht_abc12345)"}},"type":"object","required":["key_prefix"],"title":"RevokeKeyRequest","description":"Internal-only: revoke a key by its public prefix."},"RunHistoryItem":{"properties":{"run_id":{"type":"string","title":"Run Id"},"index_name":{"type":"string","title":"Index Name"},"status":{"type":"string","title":"Status"},"total":{"type":"integer","title":"Total"},"done":{"type":"integer","title":"Done"},"failed_count":{"type":"integer","title":"Failed Count","default":0},"compliance_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Compliance Rate","description":"Overall compliance rate for this run (available after completion)"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"finished_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finished At"},"duration_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Seconds"}},"additionalProperties":false,"type":"object","required":["run_id","index_name","status","total","done"],"title":"RunHistoryItem"},"RunHistoryResponse":{"properties":{"runs":{"items":{"$ref":"#/components/schemas/RunHistoryItem"},"type":"array","title":"Runs"},"total_runs":{"type":"integer","title":"Total Runs"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"}},"type":"object","required":["runs","total_runs","page","page_size"],"title":"RunHistoryResponse","example":{"page":1,"page_size":20,"runs":[{"compliance_rate":62.03,"created_at":"2025-01-15T08:00:00Z","done":503,"duration_seconds":765,"failed_count":3,"finished_at":"2025-01-15T08:12:45Z","index_name":"SP500","run_id":"run_2025-01-15_sp500","status":"completed","total":503}],"total_runs":1}},"RunResultsResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"index_name":{"type":"string","title":"Index Name"},"total_results":{"type":"integer","title":"Total Results","description":"Total number of results matching the applied filters"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"results":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Results","description":"List of per-symbol screening result dictionaries"}},"additionalProperties":false,"type":"object","required":["run_id","index_name","total_results","page","page_size","results"],"title":"RunResultsResponse","example":{"index_name":"SP500","page":1,"page_size":50,"results":[{"is_compliant":true,"purification_rate":0.012,"sector":"Technology","symbol":"AAPL"}],"run_id":"run_2025-01-15_sp500","total_results":503}},"RunSummaryOverall":{"properties":{"compliant":{"type":"integer","title":"Compliant"},"non_compliant":{"type":"integer","title":"Non Compliant"},"errors":{"type":"integer","title":"Errors"},"compliance_rate":{"type":"number","title":"Compliance Rate","description":"Overall compliance rate as a percentage"}},"type":"object","required":["compliant","non_compliant","errors","compliance_rate"],"title":"RunSummaryOverall"},"RunSummaryResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"index_name":{"type":"string","title":"Index Name"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"duration_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Seconds","description":"Wall-clock time in seconds from start to finish"},"total_screened":{"type":"integer","title":"Total Screened"},"overall":{"$ref":"#/components/schemas/RunSummaryOverall"},"by_methodology":{"additionalProperties":{"$ref":"#/components/schemas/MethodologyBreakdown"},"type":"object","title":"By Methodology","description":"Compliance breakdown per screening methodology"},"by_sector":{"additionalProperties":{"$ref":"#/components/schemas/SectorBreakdown"},"type":"object","title":"By Sector","description":"Compliance breakdown per GICS sector"},"top_compliant":{"items":{"$ref":"#/components/schemas/TopCompliantItem"},"type":"array","title":"Top Compliant","description":"Top compliant symbols ranked by number of passing methodologies"}},"type":"object","required":["run_id","index_name","total_screened","overall","by_methodology","by_sector","top_compliant"],"title":"RunSummaryResponse","example":{"by_methodology":{"aaoifi":{"compliant":298,"errors":6,"insufficient_data":21,"non_compliant":178},"djim":{"compliant":334,"errors":6,"insufficient_data":21,"non_compliant":142}},"by_sector":{"Healthcare":{"compliance_rate":65.08,"compliant":41,"total":63},"Technology":{"compliance_rate":66.67,"compliant":52,"total":78}},"completed_at":"2025-01-15T08:12:45Z","duration_seconds":765,"index_name":"SP500","overall":{"compliance_rate":62.03,"compliant":312,"errors":6,"non_compliant":185},"run_id":"run_2025-01-15_sp500","top_compliant":[{"methodology_count":5,"purification_rate":0.012,"symbol":"AAPL"},{"methodology_count":5,"purification_rate":0.008,"symbol":"MSFT"}],"total_screened":503}},"SECFilingResponse":{"properties":{"accession_number":{"type":"string","title":"Accession Number","description":"SEC EDGAR accession number uniquely identifying the filing"},"filing_type":{"type":"string","title":"Filing Type","description":"SEC form type, e.g. '10-K', '10-Q', '8-K', 'DEF 14A'"},"filing_date":{"type":"string","title":"Filing Date","description":"Date the filing was submitted (YYYY-MM-DD)"},"primary_document":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Document","description":"Filename of the primary document in the filing"},"primary_doc_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Doc Description","description":"Human-readable description of the primary document"},"filing_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filing Url","description":"Direct URL to view the filing on SEC EDGAR"}},"type":"object","required":["accession_number","filing_type","filing_date"],"title":"SECFilingResponse","description":"A single SEC filing record.","example":{"accession_number":"0000320193-23-000106","filing_date":"2023-11-03","filing_type":"10-K","filing_url":"https://www.sec.gov/Archives/edgar/data/320193/000032019323000106/aapl-20230930.htm","primary_doc_description":"10-K Annual Report","primary_document":"aapl-20230930.htm"}},"ScreeningCriteriaResponse":{"properties":{"business_screening":{"additionalProperties":true,"type":"object","title":"Business Screening","description":"Criteria for screening a company's core business activities against prohibited sectors","default":{}},"financial_screening":{"additionalProperties":true,"type":"object","title":"Financial Screening","description":"Financial ratio thresholds for debt, interest income, and cash holdings","default":{}}},"additionalProperties":false,"type":"object","title":"ScreeningCriteriaResponse","description":"Business and financial screening criteria used for Shariah compliance.","example":{"business_screening":{"max_haram_revenue_percentage":0.05,"prohibited_sectors":["Conventional banking and insurance","Alcohol production and distribution","Pork-related products","Gambling and entertainment","Tobacco","Weapons and defense"]},"financial_screening":{"max_cash_and_interest_bearing_to_total_assets":0.3,"max_debt_to_total_assets":0.3,"max_interest_income_to_revenue":0.05}}},"ScreeningReportResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol of the screened company"},"report_generated_at":{"type":"string","title":"Report Generated At","description":"ISO 8601 timestamp when the report was generated"},"screening":{"additionalProperties":true,"type":"object","title":"Screening","description":"Detailed screening results including business and financial ratio checks"}},"additionalProperties":false,"type":"object","required":["symbol","report_generated_at","screening"],"title":"ScreeningReportResponse","description":"Full Shariah compliance screening report for a single stock.","example":{"report_generated_at":"2026-03-24T12:00:00Z","screening":{"business_screening":{"haram_revenue_percentage":0.02,"passed":true},"financial_screening":{"debt_to_total_assets":0.25,"interest_income_to_revenue":0.01,"passed":true},"is_compliant":true,"methodology":"aaoifi"},"symbol":"AAPL"}},"ScreeningResultResponse":{"properties":{"symbol":{"type":"string","title":"Symbol"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Issuer / fund display name."},"asset_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Asset Type","description":"Asset class label derived during screening: 'Equity', 'ETF', 'ClosedEndFund', 'REIT', etc. Drives downstream methodology dispatch."},"last_checked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string"},{"type":"null"}],"title":"Last Checked At"},"is_stale":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Stale","description":"True when `last_checked_at` is older than SCREENING_STALENESS_HOURS (default 24h). Hint for clients to surface a 'refresh' affordance; does not gate cache invalidation (cache expiry is 7d)."},"is_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Compliant","description":"Overall Shariah compliance verdict (True = compliant under at least one methodology)"},"shariah_compliance_status":{"anyOf":[{"type":"string","enum":["compliant","non_compliant","insufficient_data"]},{"type":"null"}],"title":"Shariah Compliance Status","description":"Canonical string mirror of `is_compliant` in lowercase vocabulary (matches the ETF response and `MethodologyVerdict`). Synthesized by the service normalizer if absent on cached rows."},"business_screen_pass":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Business Screen Pass","description":"Whether the company's primary business activities are permissible"},"business_screen_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Screen Reason","description":"Human-readable explanation for the business screen verdict"},"financial_screen_pass":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Financial Screen Pass","description":"Whether the company passes all financial ratio thresholds"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"sector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sector"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"long_business_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Long Business Summary"},"total_assets":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Assets"},"total_debt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Debt"},"cash_and_equivalents":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cash And Equivalents"},"accounts_receivable":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Accounts Receivable"},"total_revenue":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Revenue"},"interest_income":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Interest Income"},"debt_to_assets_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Debt To Assets Ratio","description":"Total debt / total assets — must be below threshold (e.g. 33% for AAOIFI)"},"cash_to_assets_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cash To Assets Ratio","description":"Cash and equivalents / total assets"},"accounts_receivable_to_assets_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Accounts Receivable To Assets Ratio","description":"Accounts receivable / total assets"},"interest_income_to_revenue_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Interest Income To Revenue Ratio","description":"Interest income / total revenue — measures impermissible income proportion"},"debt_to_market_cap_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Debt To Market Cap Ratio","description":"Total debt / market capitalization (used by DJIM, S&P methodologies)"},"cash_to_market_cap_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cash To Market Cap Ratio"},"receivables_to_market_cap_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Receivables To Market Cap Ratio"},"liquidity_to_market_cap_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Liquidity To Market Cap Ratio"},"liquidity_to_assets_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Liquidity To Assets Ratio"},"purification_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Purification Rate","description":"Percentage of dividend income to purify (donate) due to impermissible revenue"},"aaoifi_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Aaoifi Compliant","description":"Compliance under AAOIFI (Accounting and Auditing Organization for Islamic Financial Institutions) standards"},"djim_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Djim Compliant","description":"Compliance under Dow Jones Islamic Market Index methodology"},"ftse_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Ftse Compliant","description":"Compliance under FTSE Shariah Index methodology"},"msci_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Msci Compliant","description":"Compliance under MSCI Islamic Index methodology"},"sp_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Sp Compliant","description":"Compliance under S&P Shariah Index methodology"},"methodology_summary":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Methodology Summary","description":"Mapping of methodology name to compliance verdict: true = compliant, false = non-compliant, null = insufficient data (see data_quality.methodologies_insufficient)."},"by_methodology":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/MethodologyEntry"},"type":"object"},{"type":"null"}],"title":"By Methodology","description":"Structured per-methodology block. Mirrors `methodology_summary` for the verdict but adds an `verified` audit flag and a `reason` string. Synthesized by the service normalizer if absent on cached rows."},"data_quality":{"anyOf":[{"$ref":"#/components/schemas/DataQualityInfo"},{"type":"null"}],"description":"Diagnostic block reporting missing inputs and which methodologies abstained. Null when every methodology had full inputs."},"compliance_explanation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compliance Explanation","description":"Plain-English summary of the compliance verdict: which methodologies pass, which fail, and which ratio tripped the failures. Empty for ticker_unknown or rows where the financial screen could not run."},"fundamentals_provenance":{"anyOf":[{"$ref":"#/components/schemas/FundamentalsProvenance"},{"type":"null"}],"description":"Per-metric attribution of the verdict's fundamentals to their source (SEC XBRL vs yfinance). Populated when the SEC-XBRL provider screened the name; null for yfinance-only screens."},"return_on_equity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Return On Equity"},"net_profit_margin":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Net Profit Margin"},"revenue_growth":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Revenue Growth"},"pe_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pe Ratio"},"pb_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pb Ratio"},"intrinsic_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Intrinsic Value"},"dcf_upside_percentage":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dcf Upside Percentage","description":"Upside/downside percentage based on DCF intrinsic value vs current price"},"momentum_trend":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Momentum Trend"},"rsi_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rsi Status"},"current_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Ratio"},"market_cap":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Market Cap"},"beta":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Beta"},"dividend_yield":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dividend Yield"},"disposition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disposition","description":"ETF-only. Non-verdict scholar-derived label: 'scholar_certified', 'data_quality_flag', 'contested', 'unrated'. See v2 cert spec §11."},"scholar_attestations":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Scholar Attestations","description":"ETF-only. List of scholar-board attestations; empty list when none on file."},"holdings_analysis":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Holdings Analysis","description":"ETF-only. Aggregate holdings-based compliance metrics (compliant_weight, etc.)."},"detail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail Url","description":"ETF-only. Path to the richer first-class ETF endpoint (`/api/etf/{symbol}/screen`)."},"disclaimers":{"anyOf":[{"items":{"$ref":"#/components/schemas/Disclaimer"},"type":"array"},{"type":"null"}],"title":"Disclaimers","description":"Per-response disclaimers attached by the DisclaimerMiddleware. See `GET /api/disclaimers` for the full registry."}},"additionalProperties":true,"type":"object","required":["symbol"],"title":"ScreeningResultResponse","example":{"aaoifi_compliant":true,"accounts_receivable":60932000000,"accounts_receivable_to_assets_ratio":0.173,"business_screen_pass":true,"business_screen_reason":"Technology hardware and equipment — permissible primary activity","cash_and_equivalents":29965000000,"cash_to_assets_ratio":0.085,"cash_to_market_cap_ratio":0.009,"country":"US","debt_to_assets_ratio":0.315,"debt_to_market_cap_ratio":0.032,"djim_compliant":true,"financial_screen_pass":true,"ftse_compliant":true,"industry":"Consumer Electronics","interest_income":3999000000,"interest_income_to_revenue_ratio":0.01,"is_compliant":true,"last_checked_at":"2025-01-15T12:30:00Z","methodology_summary":{"aaoifi":true,"djim":true,"ftse":true,"msci":true,"sp":true},"msci_compliant":true,"purification_rate":0.012,"sector":"Technology","sp_compliant":true,"symbol":"AAPL","total_assets":352583000000,"total_debt":111088000000,"total_revenue":394328000000}},"SectorBreakdown":{"properties":{"total":{"type":"integer","title":"Total"},"compliant":{"type":"integer","title":"Compliant"},"compliance_rate":{"type":"number","title":"Compliance Rate","description":"Percentage of compliant symbols in this sector (0.0 to 100.0)"}},"type":"object","required":["total","compliant","compliance_rate"],"title":"SectorBreakdown"},"SuggestionResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol"},"name":{"type":"string","title":"Name","description":"Company or asset name"},"sector":{"type":"string","title":"Sector","description":"Sector classification"},"exchange":{"type":"string","title":"Exchange","description":"Exchange where the asset is listed"},"type":{"type":"string","title":"Type","description":"Asset type, e.g. equities, etfs, funds"}},"type":"object","required":["symbol","name","sector","exchange","type"],"title":"SuggestionResponse","example":{"exchange":"NMS","name":"Apple Inc.","sector":"Technology","symbol":"AAPL","type":"equities"}},"TokenCostEntry":{"properties":{"pattern":{"type":"string","title":"Pattern","description":"Endpoint path pattern"},"method":{"type":"string","title":"Method","description":"HTTP method (* = all methods)"},"tokens":{"type":"integer","title":"Tokens","description":"Token cost per request"}},"type":"object","required":["pattern","method","tokens"],"title":"TokenCostEntry","description":"Token cost for an endpoint pattern.","example":{"method":"GET","pattern":"/api/screen","tokens":5}},"TokenCostsResponse":{"properties":{"costs":{"items":{"$ref":"#/components/schemas/TokenCostEntry"},"type":"array","title":"Costs","description":"Token costs per endpoint"}},"type":"object","required":["costs"],"title":"TokenCostsResponse","description":"Full token cost table.","example":{"costs":[{"method":"*","pattern":"/api/health","tokens":0},{"method":"GET","pattern":"/api/screen","tokens":5}]}},"TopCompliantItem":{"properties":{"symbol":{"type":"string","title":"Symbol"},"purification_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Purification Rate","description":"Dividend purification rate for this symbol"},"methodology_count":{"type":"integer","title":"Methodology Count","description":"Number of methodologies under which this symbol is compliant","default":0}},"type":"object","required":["symbol"],"title":"TopCompliantItem"},"TrendingItemResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol"},"name":{"type":"string","title":"Name","description":"Company or asset name"},"change":{"type":"string","title":"Change","description":"Price change as a formatted string"},"price":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price","description":"Current price in USD"},"volume":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Volume","description":"Trading volume for the current session"}},"type":"object","required":["symbol","name","change"],"title":"TrendingItemResponse","example":{"change":"+1.25%","name":"Apple Inc.","price":187.44,"symbol":"AAPL","volume":54638921}},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WatchlistCreateRequest":{"properties":{"name":{"type":"string","title":"Name","description":"Display name for the watchlist"},"symbols":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Symbols","description":"Initial list of stock ticker symbols to include"}},"type":"object","required":["name"],"title":"WatchlistCreateRequest","description":"Request body for creating a new watchlist.","example":{"name":"Halal Tech","symbols":["AAPL","MSFT","GOOGL"]}},"WatchlistResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Unique watchlist identifier"},"name":{"type":"string","title":"Name","description":"Display name of the watchlist"},"symbols":{"items":{"type":"string"},"type":"array","title":"Symbols","description":"Ticker symbols in the watchlist"},"count":{"type":"integer","title":"Count","description":"Number of symbols currently in the watchlist"},"created_at":{"type":"string","title":"Created At","description":"ISO-8601 timestamp when the watchlist was created"},"updated_at":{"type":"string","title":"Updated At","description":"ISO-8601 timestamp of the last modification"}},"additionalProperties":false,"type":"object","required":["id","name","symbols","count","created_at","updated_at"],"title":"WatchlistResponse","description":"Representation of a watchlist with its symbols and metadata.","example":{"count":3,"created_at":"2025-06-01T12:00:00Z","id":"wl_abc123","name":"Halal Tech","symbols":["AAPL","MSFT","GOOGL"],"updated_at":"2025-06-01T12:00:00Z"}},"WatchlistSymbolRequest":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Stock ticker symbol to add (e.g. AAPL)"}},"type":"object","required":["symbol"],"title":"WatchlistSymbolRequest","description":"Request body for adding a single symbol to an existing watchlist.","example":{"symbol":"AMZN"}},"ZakatCalculateRequest":{"properties":{"holdings":{"items":{"$ref":"#/components/schemas/ZakatHolding"},"type":"array","title":"Holdings","description":"List of stock holdings with current market values."},"gold_price_per_gram":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Gold Price Per Gram","description":"Current gold price per gram in USD, used to compute the nisab threshold. If omitted, live gold price is fetched automatically."}},"type":"object","required":["holdings"],"title":"ZakatCalculateRequest","description":"Request to calculate zakat owed on a set of stock holdings.","example":{"gold_price_per_gram":65.0,"holdings":[{"market_value":25000.0,"symbol":"AAPL"},{"market_value":18000.0,"symbol":"MSFT"},{"market_value":12000.0,"symbol":"GOOGL"}]}},"ZakatCalculateResponse":{"properties":{"total_market_value":{"type":"number","title":"Total Market Value","description":"Total market value of all holdings in USD."},"nisab_threshold":{"type":"number","title":"Nisab Threshold","description":"Nisab threshold in USD (85 grams of gold at given price)."},"gold_price_per_gram":{"type":"number","title":"Gold Price Per Gram","description":"Gold price per gram used for nisab calculation."},"is_above_nisab":{"type":"boolean","title":"Is Above Nisab","description":"Whether total holdings exceed the nisab threshold."},"zakat_rate":{"type":"number","title":"Zakat Rate","description":"Zakat rate applied (0.025 = 2.5%)."},"total_zakat":{"type":"number","title":"Total Zakat","description":"Total zakat owed across all holdings in USD. Zero if below nisab."},"holdings":{"items":{"$ref":"#/components/schemas/ZakatHoldingResult"},"type":"array","title":"Holdings","description":"Per-holding zakat breakdown."},"disclaimers":{"anyOf":[{"items":{"$ref":"#/components/schemas/Disclaimer"},"type":"array"},{"type":"null"}],"title":"Disclaimers","description":"Attached by middleware; see /api/disclaimers."}},"type":"object","required":["total_market_value","nisab_threshold","gold_price_per_gram","is_above_nisab","zakat_rate","total_zakat","holdings"],"title":"ZakatCalculateResponse","description":"Complete zakat calculation result with nisab check and per-holding breakdown.","example":{"gold_price_per_gram":65.0,"holdings":[{"market_value":25000.0,"symbol":"AAPL","zakat_amount":625.0},{"market_value":18000.0,"symbol":"MSFT","zakat_amount":450.0},{"market_value":12000.0,"symbol":"GOOGL","zakat_amount":300.0}],"is_above_nisab":true,"nisab_threshold":5525.0,"total_market_value":55000.0,"total_zakat":1375.0,"zakat_rate":0.025}},"ZakatHolding":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol (e.g. 'AAPL')."},"market_value":{"type":"number","minimum":0.0,"title":"Market Value","description":"Current market value of the holding in USD."}},"type":"object","required":["symbol","market_value"],"title":"ZakatHolding","description":"A single stock holding for zakat calculation.","example":{"market_value":25000.0,"symbol":"AAPL"}},"ZakatHoldingResult":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol."},"market_value":{"type":"number","title":"Market Value","description":"Market value of the holding in USD."},"zakat_amount":{"type":"number","title":"Zakat Amount","description":"Zakat owed on this holding in USD (2.5% of value)."}},"type":"object","required":["symbol","market_value","zakat_amount"],"title":"ZakatHoldingResult","description":"Zakat calculation result for a single holding.","example":{"market_value":25000.0,"symbol":"AAPL","zakat_amount":625.0}},"backend__schemas__comparison__CompareResponse":{"properties":{"symbols":{"items":{"type":"string"},"type":"array","title":"Symbols","description":"Symbols that were compared"},"count":{"type":"integer","title":"Count","description":"Number of symbols in the comparison"},"items":{"items":{"$ref":"#/components/schemas/CompareItemResponse"},"type":"array","title":"Items","description":"Per-symbol comparison results"}},"additionalProperties":false,"type":"object","required":["symbols","count","items"],"title":"CompareResponse","description":"Aggregated comparison result for the requested symbols.","example":{"count":2,"items":[{"database":{"sector":"Technology"},"quote":{"price":198.5},"screening":{"status":"COMPLIANT"},"symbol":"AAPL"},{"database":{"sector":"Technology"},"quote":{"price":415.2},"screening":{"status":"COMPLIANT"},"symbol":"MSFT"}],"symbols":["AAPL","MSFT"]}},"backend__schemas__screening__CompareResponse":{"properties":{"run_a":{"type":"string","title":"Run A"},"run_b":{"type":"string","title":"Run B"},"index_name":{"type":"string","title":"Index Name"},"run_a_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run A Date"},"run_b_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run B Date"},"summary":{"$ref":"#/components/schemas/CompareSummary"},"changes":{"items":{"$ref":"#/components/schemas/CompareChange"},"type":"array","title":"Changes"}},"additionalProperties":false,"type":"object","required":["run_a","run_b","index_name","summary","changes"],"title":"CompareResponse","example":{"changes":[{"change":"became_compliant","reason":"Debt-to-assets ratio dropped below 33% threshold","run_a_compliant":false,"run_b_compliant":true,"symbol":"TSLA"}],"index_name":"SP500","run_a":"run_2025-01-01_sp500","run_a_date":"2025-01-01T08:00:00Z","run_b":"run_2025-01-15_sp500","run_b_date":"2025-01-15T08:00:00Z","summary":{"added_symbols":2,"newly_compliant":8,"newly_non_compliant":5,"removed_symbols":1,"unchanged_compliant":304,"unchanged_non_compliant":180}}}},"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Your Halal Terminal API key. Get one free at /api/keys/generate"}}},"tags":[{"name":"health","description":"Health-check and liveness probes — no API key required"},{"name":"screening","description":"Single-symbol and bulk Shariah screening across AAOIFI and custom methodologies"},{"name":"database","description":"Stock database search, autocomplete suggestions, and coverage statistics"},{"name":"market","description":"Real-time quotes, OHLC candles, trending tickers, and full asset details"},{"name":"portfolio","description":"Portfolio-level compliance scanning with position weighting"},{"name":"watchlists","description":"Create, update, and manage personal watchlists"},{"name":"comparison","description":"Side-by-side Shariah compliance comparison for multiple symbols"},{"name":"reports","description":"Generate screening and portfolio compliance reports with CSV export"},{"name":"education","description":"Islamic finance glossary, screening methodologies, and criteria reference"},{"name":"news","description":"Market-wide and per-symbol news aggregation"},{"name":"filings","description":"SEC filings (10-K, 10-Q) and XBRL company facts"},{"name":"dividends","description":"Dividend history, yield data, and Shariah purification calculations"},{"name":"zakat","description":"Zakat and dividend purification calculators"},{"name":"etf","description":"ETF holdings retrieval, per-holding Shariah screening, and purification ratios"},{"name":"sukuk","description":"Sukuk (Islamic fixed income) screening and reference data. Search the structural registry by issuer, country, structure, documentation basis, currency, and maturity; resolve a single instrument by ISIN with its AAOIFI pre- and post-Standard 62 disposition and a per-methodology grid; look up all instruments for an issuer LEI; and score the sukuk sleeve of a portfolio via portfolio-impact. Endpoints: GET /api/sukuk/search, GET /api/sukuk/{isin}, GET /api/sukuk/issuer/{lei}, POST /api/sukuk/portfolio-impact."},{"name":"api-keys","description":"API key generation, usage tracking, and plan management — no API key required"},{"name":"billing","description":"Stripe checkout sessions and webhook handling — no API key required"},{"name":"disclaimers","description":"Canonical disclaimer registry. Resolve the `disclaimers[].id` values attached to other API responses. No API key required."}],"security":[{"ApiKeyAuth":[]}]}