{"openapi":"3.1.0","info":{"title":"Halal Terminal API","description":"The **Halal Terminal API** is the most comprehensive Islamic finance data\nplatform available — 85 REST endpoints, 25 MCP tools, and 7 AI resources\nacross 21 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/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/generate`, `GET /api/keys/plans`, `GET /api/keys/token-costs`.\nEverything else — including billing checkout/portal — requires the key.\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/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/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** | 500 | $0 | Hard block |\n| **Starter** | 2,500 | $19/mo | $0.01/token |\n| **Pro** | 15,000 | $49/mo | $0.008/token |\n| **Enterprise** | 50,000 | $199/mo | $0.005/token (no hard cap) |\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, watchlist reads) 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/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| 429 | `OVERAGE_CAP_REACHED` | Pay-as-you-go spend cap hit for this billing period (paid plans; resets at `billing_period_end`) |\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-RateLimit-Limit` | Monthly token allowance for your plan (`unlimited` on unmetered plans) |\n| `X-RateLimit-Remaining` | Tokens remaining in the current billing period |\n| `X-RateLimit-Reset` | Unix timestamp when your billing period (and quota) resets |\n| `X-Plan` | Your current plan |\n| `X-Tokens-Charged` | Number of tokens deducted for this request |\n| `X-Tokens-Remaining` | Legacy alias of `X-RateLimit-Remaining` |\n| `X-Tokens-Overage` | Present and set to `true` when the request exceeded the plan allowance |\n\n**Result freshness:** screening verdicts are cached and refreshed on a rolling\nbasis; a cached result can be up to **7 days** old. `GET /api/result/{symbol}`\n(1 token) reads the cache; `POST /api/screen/{symbol}` (5 tokens) recomputes.\nEach result carries `last_checked_at` and `is_stale` so you can decide.\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","termsOfService":"https://halalterminal.com/terms","contact":{"name":"Halal Terminal","url":"https://api.halalterminal.com/"},"license":{"name":"Proprietary","url":"https://api.halalterminal.com/"},"version":"1.0.0"},"servers":[{"url":"https://api.halalterminal.com","description":"Production"}],"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.halalterminal.com/api/screen-bulk/indices\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/screen-bulk/indices\",\n    headers={\"X-API-Key\": \"<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/source-health":{"get":{"tags":["screening"],"summary":"Source Health","description":"Health of every index constituent source.\n\nResolves each index's upstream source and flags any whose count collapsed\nbelow its healthy floor (the failure mode behind the 2026-06 S&P 500 outage).\nCached server-side; pass `force=true` to recompute immediately.","operationId":"source_health_api_screen_bulk_source_health_get","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Force recomputation instead of returning the cached health snapshot.","default":false,"title":"Force"},"description":"Force recomputation instead of returning the cached health snapshot."}],"responses":{"200":{"description":"Health of each index constituent source","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceHealthResponse"}}}},"401":{"description":"API key required or invalid"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/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.halalterminal.com/api/screen-bulk/status?run_id=abc123\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/screen-bulk/status\",\n    params={\"run_id\": \"abc123\"},\n    headers={\"X-API-Key\": \"<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"}],"description":"Specific run ID to check; defaults to the active or most recent run.","title":"Run Id"},"description":"Specific run ID to check; defaults to the active or most recent run."}],"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.halalterminal.com/api/screen-bulk/runs?index_name=SP500&page=1&page_size=10\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/screen-bulk/runs\",\n    params={\"index_name\": \"SP500\", \"page\": 1, \"page_size\": 10},\n    headers={\"X-API-Key\": \"<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"}],"description":"Filter runs by index name, e.g. SP500.","title":"Index Name"},"description":"Filter runs by index name, e.g. SP500."},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter runs by status, e.g. completed or running.","title":"Status"},"description":"Filter runs by status, e.g. completed or running."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","description":"Page number, 1-indexed.","default":1,"title":"Page"},"description":"Page number, 1-indexed."},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","description":"Number of runs per page.","default":20,"title":"Page Size"},"description":"Number of runs per page."}],"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.halalterminal.com/api/screen-bulk/compare?run_a=abc123&run_b=def456\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/screen-bulk/compare\",\n    params={\"run_a\": \"abc123\", \"run_b\": \"def456\"},\n    headers={\"X-API-Key\": \"<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","description":"Run ID of the first (baseline) screening run.","title":"Run A"},"description":"Run ID of the first (baseline) screening run."},{"name":"run_b","in":"query","required":true,"schema":{"type":"string","description":"Run ID of the second (comparison) screening run.","title":"Run B"},"description":"Run ID of the second (comparison) screening run."}],"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.halalterminal.com/api/screen-bulk\" \\\n     -H \"X-API-Key: <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.halalterminal.com/api/screen-bulk\",\n    headers={\"X-API-Key\": \"<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.halalterminal.com/api/screen-bulk/abc123/cancel\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.halalterminal.com/api/screen-bulk/abc123/cancel\",\n    headers={\"X-API-Key\": \"<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","description":"Bulk-run ID returned by POST /api/screen-bulk.","title":"Run Id"},"description":"Bulk-run ID returned by POST /api/screen-bulk."}],"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.halalterminal.com/api/screen-bulk/abc123/results?compliant=true&methodology=aaoifi&page=1&page_size=20\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/screen-bulk/abc123/results\",\n    params={\"compliant\": True, \"methodology\": \"aaoifi\", \"page\": 1},\n    headers={\"X-API-Key\": \"<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","description":"Bulk-run ID returned by POST /api/screen-bulk.","title":"Run Id"},"description":"Bulk-run ID returned by POST /api/screen-bulk."},{"name":"compliant","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter by compliance status.","title":"Compliant"},"description":"Filter by compliance status."},{"name":"methodology","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by methodology, e.g. aaoifi or djim.","title":"Methodology"},"description":"Filter by methodology, e.g. aaoifi or djim."},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by sector.","title":"Sector"},"description":"Filter by sector."},{"name":"has_error","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter to results that errored during screening.","title":"Has Error"},"description":"Filter to results that errored during screening."},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort results by.","title":"Sort By"},"description":"Field to sort results by."},{"name":"sort_order","in":"query","required":false,"schema":{"type":"string","description":"Sort direction, asc or desc.","default":"asc","title":"Sort Order"},"description":"Sort direction, asc or desc."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","description":"Page number, 1-indexed.","default":1,"title":"Page"},"description":"Page number, 1-indexed."},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","description":"Number of results per page.","default":50,"title":"Page Size"},"description":"Number of results per page."}],"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.halalterminal.com/api/screen-bulk/abc123/summary\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/screen-bulk/abc123/summary\",\n    headers={\"X-API-Key\": \"<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","description":"Bulk-run ID returned by POST /api/screen-bulk.","title":"Run Id"},"description":"Bulk-run ID returned by POST /api/screen-bulk."}],"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.halalterminal.com/api/screen-bulk/abc123/export/csv\" \\\n     -H \"X-API-Key: <API_KEY>\" \\\n     -o screening_results.csv\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/screen-bulk/abc123/export/csv\",\n    headers={\"X-API-Key\": \"<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","description":"Bulk-run ID returned by POST /api/screen-bulk.","title":"Run Id"},"description":"Bulk-run ID returned by POST /api/screen-bulk."}],"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.halalterminal.com/api/screen-bulk/abc123/export/json\" \\\n     -H \"X-API-Key: <API_KEY>\" \\\n     -o screening_results.json\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/screen-bulk/abc123/export/json\",\n    headers={\"X-API-Key\": \"<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","description":"Bulk-run ID returned by POST /api/screen-bulk.","title":"Run Id"},"description":"Bulk-run ID returned by POST /api/screen-bulk."}],"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.halalterminal.com/api/screen-bulk/abc123\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.delete(\n    \"https://api.halalterminal.com/api/screen-bulk/abc123\",\n    headers={\"X-API-Key\": \"<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","description":"Bulk-run ID returned by POST /api/screen-bulk.","title":"Run Id"},"description":"Bulk-run ID returned by POST /api/screen-bulk."}],"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.halalterminal.com/api/results/updates?since=2025-01-15T00:00:00Z\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/results/updates\",\n    params={\"since\": \"2025-01-15T00:00:00Z\"},\n    headers={\"X-API-Key\": \"<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","description":"ISO-8601 timestamp; only results modified after this instant are returned.","title":"Since"},"description":"ISO-8601 timestamp; only results modified after this instant are returned."},{"name":"run_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Accepted for forward compatibility; not currently used to filter results.","title":"Run Id"},"description":"Accepted for forward compatibility; not currently used to filter results."}],"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.halalterminal.com/api/results\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/results\",\n    headers={\"X-API-Key\": \"<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. Costs **1 token** per call (including misses).\nThe platform re-screens cached results nightly, most-requested symbols\nfirst, against a 7-day freshness target: `last_checked_at` gives the\nscreening date and `is_stale` is true once a result is older than 7 days.\nReturns 404 if the symbol has never been screened —\n`POST /api/screen/{symbol}` (5 tokens) computes a fresh verdict.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.halalterminal.com/api/result/AAPL\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.get(\n    \"https://api.halalterminal.com/api/result/AAPL\",\n    headers={\"X-API-Key\": \"<API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"get_result_api_result__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."}],"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\nCosts **5 tokens** per call. Results are cached for **7 days**: a call\nwithin that window returns the cached verdict (still 5 tokens — use\n``GET /api/result/{symbol}`` at 1 token if the cache is all you need).\nPass ``?force_refresh=true`` to bypass the 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. ``force_refresh`` is honored\non **Enterprise** plans only; on other plans it is accepted and has no\neffect, and a verdict older than 7 days is recomputed automatically.\nA recomputed verdict carries a new ``last_checked_at``. A first-ever screen of an\nuncached symbol performs live data collection and can take several\nseconds; subsequent calls are fast.\n\n**curl example:**\n```bash\ncurl -X POST \"https://api.halalterminal.com/api/screen/AAPL\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.halalterminal.com/api/screen/AAPL\",\n    headers={\"X-API-Key\": \"<API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"screen_symbol_api_screen__symbol__get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."},{"name":"force_refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass the 7-day result cache and recompute a fresh verdict. Enterprise plans only: on other plans the parameter is accepted and has no effect.","default":false,"title":"Force Refresh"},"description":"Bypass the 7-day result cache and recompute a fresh verdict. Enterprise plans only: on other plans the parameter is accepted and has no effect."}],"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\nCosts **5 tokens** per call. Results are cached for **7 days**: a call\nwithin that window returns the cached verdict (still 5 tokens — use\n``GET /api/result/{symbol}`` at 1 token if the cache is all you need).\nPass ``?force_refresh=true`` to bypass the 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. ``force_refresh`` is honored\non **Enterprise** plans only; on other plans it is accepted and has no\neffect, and a verdict older than 7 days is recomputed automatically.\nA recomputed verdict carries a new ``last_checked_at``. A first-ever screen of an\nuncached symbol performs live data collection and can take several\nseconds; subsequent calls are fast.\n\n**curl example:**\n```bash\ncurl -X POST \"https://api.halalterminal.com/api/screen/AAPL\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```\n\n**Python requests example:**\n```python\nimport requests\n\nresp = requests.post(\n    \"https://api.halalterminal.com/api/screen/AAPL\",\n    headers={\"X-API-Key\": \"<API_KEY>\"},\n)\nprint(resp.json())\n```","operationId":"screen_symbol_api_screen__symbol__post","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."},{"name":"force_refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass the 7-day result cache and recompute a fresh verdict. Enterprise plans only: on other plans the parameter is accepted and has no effect.","default":false,"title":"Force Refresh"},"description":"Bypass the 7-day result cache and recompute a fresh verdict. Enterprise plans only: on other plans the parameter is accepted and has no effect."}],"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","description":"Search the sukuk registry by issuer, country, structure, currency, or\nmaturity window. Returns matching instruments with a total count.","operationId":"search_sukuk_api_sukuk_search_get","parameters":[{"name":"issuer","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by issuer LEI.","title":"Issuer"},"description":"Filter by issuer LEI."},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by issuer country (ISO code or name).","title":"Country"},"description":"Filter by issuer country (ISO code or name)."},{"name":"structure","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by sukuk structure (e.g. ijara, murabaha, wakala).","title":"Structure"},"description":"Filter by sukuk structure (e.g. ijara, murabaha, wakala)."},{"name":"documentation_basis","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by documentation basis (e.g. AAOIFI Standard 62).","title":"Documentation Basis"},"description":"Filter by documentation basis (e.g. AAOIFI Standard 62)."},{"name":"currency","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by issue currency (ISO 4217, e.g. USD).","title":"Currency"},"description":"Filter by issue currency (ISO 4217, e.g. USD)."},{"name":"maturity_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Earliest maturity date, inclusive (YYYY-MM-DD).","title":"Maturity From"},"description":"Earliest maturity date, inclusive (YYYY-MM-DD)."},{"name":"maturity_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Latest maturity date, inclusive (YYYY-MM-DD).","title":"Maturity To"},"description":"Latest maturity date, inclusive (YYYY-MM-DD)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"description":"Maximum number of instruments to return (1-500).","default":100,"title":"Limit"},"description":"Maximum number of instruments to return (1-500)."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","description":"Number of matches to skip, for pagination.","default":0,"title":"Offset"},"description":"Number of matches to skip, for pagination."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Search Sukuk Api Sukuk Search 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/sukuk/issuer/{lei}":{"get":{"tags":["sukuk"],"summary":"Get issuer sukuk","description":"Return an issuer (by Legal Entity Identifier) and every sukuk\ninstrument it has issued. 404 when the LEI is not in the registry.","operationId":"get_issuer_sukuk_api_sukuk_issuer__lei__get","parameters":[{"name":"lei","in":"path","required":true,"schema":{"type":"string","description":"Issuer Legal Entity Identifier (LEI).","title":"Lei"},"description":"Issuer Legal Entity Identifier (LEI)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Issuer Sukuk Api Sukuk Issuer  Lei  Get"}}}},"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/sukuk/portfolio-impact":{"post":{"tags":["sukuk"],"summary":"Sukuk portfolio impact","description":"Evaluate a list of sukuk holdings against the registry, returning\npre- and post-AAOIFI-Standard-62 compliant / non-compliant counts, the\ndata-quality-flag count, and any ISINs that could not be resolved.","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"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sukuk/{isin}":{"get":{"tags":["sukuk"],"summary":"Get sukuk by ISIN","description":"Return a single sukuk instrument by ISIN, with its issuer, scholar\nattestations, and lifecycle events. 404 when the ISIN is not in the\nregistry.","operationId":"get_sukuk_api_sukuk__isin__get","parameters":[{"name":"isin","in":"path","required":true,"schema":{"type":"string","description":"ISIN of the sukuk instrument.","title":"Isin"},"description":"ISIN of the sukuk instrument."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Sukuk Api Sukuk  Isin  Get"}}}},"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/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","description":"Symbol prefix to search for, e.g. AAP.","default":"","title":"Q"},"description":"Symbol prefix to search for, e.g. AAP."}],"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","description":"Free-text search query.","default":"","title":"Q"},"description":"Free-text search query."},{"name":"asset_type","in":"query","required":false,"schema":{"type":"string","description":"Asset category to search, e.g. equities, etfs, funds.","default":"equities","title":"Asset Type"},"description":"Asset category to search, e.g. equities, etfs, funds."},{"name":"sector","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by sector name.","title":"Sector"},"description":"Filter by sector name."},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by country of listing.","title":"Country"},"description":"Filter by country of listing."},{"name":"exchange","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by exchange code.","title":"Exchange"},"description":"Filter by exchange code."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Max results to return.","default":100,"title":"Limit"},"description":"Max results to return."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","description":"Number of results to skip, for pagination.","default":0,"title":"Offset"},"description":"Number of results to skip, for pagination."}],"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."}],"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/symbols/canonical":{"post":{"tags":["symbols"],"summary":"Canonical Symbols","description":"Resolve symbols to the canonical form the screening engine settled on.\n\n**curl example:**\n```bash\ncurl -X POST \"https://api.halalterminal.com/api/symbols/canonical\" \\\n     -H \"X-API-Key: <API_KEY>\" -H \"Content-Type: application/json\" \\\n     -d '{\"symbols\": [\"NL0010273215\", \"ASML.AS\"]}'\n```","operationId":"canonical_symbols_api_symbols_canonical_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanonicalRequest"}}},"required":true},"responses":{"200":{"description":"Canonical form of each symbol the engine has resolved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanonicalResponse"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/fx":{"get":{"tags":["fx"],"summary":"Fx Rates","description":"Rates for converting several currencies into one base.\n\n**curl example:**\n```bash\ncurl -X GET \"https://api.halalterminal.com/api/fx?base=EUR&symbols=USD,GBP\" \\\n     -H \"X-API-Key: <API_KEY>\"\n```","operationId":"fx_rates_api_fx_get","parameters":[{"name":"base","in":"query","required":false,"schema":{"type":"string","description":"Currency to convert into","default":"USD","title":"Base"},"description":"Currency to convert into"},{"name":"symbols","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated currency codes","default":"","title":"Symbols"},"description":"Comma-separated currency codes"}],"responses":{"200":{"description":"Rate per currency, expressed in the base","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FxResponse"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."},{"name":"period","in":"query","required":false,"schema":{"type":"string","description":"Lookback period, e.g. 1d, 5d, 1mo, 1y, 5y, max.","default":"1y","title":"Period"},"description":"Lookback period, e.g. 1d, 5d, 1mo, 1y, 5y, max."},{"name":"interval","in":"query","required":false,"schema":{"type":"string","description":"Candle interval, e.g. 1m, 5m, 1d, 1wk.","default":"1d","title":"Interval"},"description":"Candle interval, e.g. 1m, 5m, 1d, 1wk."}],"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."}],"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."}],"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","description":"Watchlist ID.","title":"Watchlist Id"},"description":"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","description":"Watchlist ID.","title":"Watchlist Id"},"description":"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","description":"Watchlist ID.","title":"Watchlist Id"},"description":"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","description":"Watchlist ID.","title":"Watchlist Id"},"description":"Watchlist ID."},{"name":"symbol","in":"path","required":true,"schema":{"type":"string","description":"Ticker symbol to remove from the watchlist.","title":"Symbol"},"description":"Ticker symbol to remove from the watchlist."}],"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"}],"description":"Free-text search term to filter glossary entries.","title":"Q"},"description":"Free-text search term to filter glossary entries."}],"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","description":"Methodology name or ID (e.g. aaoifi, sec, djim).","title":"Name"},"description":"Methodology name or ID (e.g. aaoifi, sec, djim)."}],"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"}],"description":"Filter by news source name.","title":"Source"},"description":"Filter by news source name."},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by article category.","title":"Category"},"description":"Filter by article category."},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Free-text search query.","title":"Q"},"description":"Free-text search query."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number, 1-indexed.","default":1,"title":"Page"},"description":"Page number, 1-indexed."},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of articles per page.","default":20,"title":"Page Size"},"description":"Number of articles per page."}],"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Max articles to return.","default":50,"title":"Limit"},"description":"Max articles to return."},{"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."},{"name":"filing_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by filing type, e.g. 10-K, 10-Q, 8-K.","title":"Filing Type"},"description":"Filter by filing type, e.g. 10-K, 10-Q, 8-K."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Max filings to return.","default":20,"title":"Limit"},"description":"Max filings to return."}],"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."}],"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}/provenance":{"get":{"tags":["filings"],"summary":"Get Provenance","description":"Compliance provenance for a ticker: which filing carried which verdict\nfigure, and how that figure moved.\n\nFor each financial filing (10-K/10-Q/20-F/40-F) matched to its reporting\nperiod, returns the verdict-driving figures, the self-contained ratios\n(debt/assets, cash/assets, interest/revenue), the change versus the prior\nperiod, and any methodology cap the change crossed. Market-cap-basis\nratios are intentionally excluded (a past period cannot be judged against\ntoday's market cap); the on-verdict debt/MC covers that separately.","operationId":"get_provenance_api_filings__symbol__provenance_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"Max filings to return provenance for.","default":8,"title":"Limit"},"description":"Max filings to return provenance for."}],"responses":{"200":{"description":"Per-filing compliance provenance: figures and ratio deltas","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Provenance Api Filings  Symbol  Provenance Get"}}}},"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."},{"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,"description":"Max events to return.","default":20,"title":"Limit"},"description":"Max events to return."}],"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."}],"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."}],"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/dividends/{symbol}/purification-rate":{"get":{"tags":["dividends"],"summary":"Get Purification Rate As Of","description":"Rate from the latest screening pass on or before ``as_of``; falls back to\nthe current rate (``mode = fallback_current``) when no pass precedes the date.","operationId":"get_purification_rate_as_of_api_dividends__symbol__purification_rate_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","description":"Ticker symbol, e.g. IBM.","title":"Symbol"},"description":"Ticker symbol, e.g. IBM."},{"name":"as_of","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Date, YYYY-MM-DD.","title":"As Of"},"description":"Date, YYYY-MM-DD."}],"responses":{"200":{"description":"Purification rate in force at the given date.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurificationRateAsOfResponse"}}}},"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","description":"Ticker symbol to generate the screening report for.","title":"Symbol"},"description":"Ticker symbol to generate the screening report for."}],"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","description":"ETF ticker symbol.","title":"Symbol"},"description":"ETF ticker 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","description":"ETF ticker symbol.","title":"Symbol"},"description":"ETF ticker 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","description":"ETF ticker symbol.","title":"Symbol"},"description":"ETF ticker symbol."},{"name":"force_refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass cached results when true. Only enterprise and internal plans honor this; other plans treat it as false.","default":false,"title":"Force Refresh"},"description":"Bypass cached results when true. Only enterprise and internal plans honor this; other plans treat it as false."}],"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","description":"ETF ticker symbol.","title":"Symbol"},"description":"ETF ticker 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","description":"ETF ticker symbol.","title":"Symbol"},"description":"ETF ticker 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/etf/directory":{"get":{"tags":["etf"],"summary":"Rated-ETF directory","description":"Directory of every rated ETF, with issuer and Shariah-label facets.\n\nBacks the terminal's ETF explorer. The universe is the funds that carry a\nrating (screened at least once), not the 40k-row catalog: an explorer over\nfunds we cannot say anything about would be listing, not exploring.\n\n``labelled=shariah`` filters to funds that present themselves as Shariah\nor Islamic in their own name; ``conventional`` is the complement. The flag\nreflects the fund's self-description, never our verdict — a labelled fund\ncan fail and a conventional one can pass, which is exactly what the\nexplorer exists to show.","operationId":"etf_directory_api_etf_directory_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","description":"Free-text search over ticker and fund name.","default":"","title":"Q"},"description":"Free-text search over ticker and fund name."},{"name":"family","in":"query","required":false,"schema":{"type":"string","description":"Filter by issuer family (e.g. iShares, Invesco).","default":"","title":"Family"},"description":"Filter by issuer family (e.g. iShares, Invesco)."},{"name":"labelled","in":"query","required":false,"schema":{"type":"string","description":"Self-description filter: \"shariah\", \"conventional\", or \"\" for all.","default":"","title":"Labelled"},"description":"Self-description filter: \"shariah\", \"conventional\", or \"\" for all."},{"name":"status","in":"query","required":false,"schema":{"type":"string","description":"Verdict filter: \"compliant\", \"non_compliant\", \"insufficient_data\", or \"\" for all.","default":"","title":"Status"},"description":"Verdict filter: \"compliant\", \"non_compliant\", \"insufficient_data\", or \"\" for all."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum funds to return.","default":100,"title":"Limit"},"description":"Maximum funds to return."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","description":"Number of matches to skip, for pagination.","default":0,"title":"Offset"},"description":"Number of matches to skip, for pagination."}],"responses":{"200":{"description":"Rated-ETF directory with issuer and label facets.","content":{"application/json":{"schema":{}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"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. Generating again for the same email deactivates the prior\nfree key and carries its usage forward — it never resets the quota.\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","description":"API key whose usage to read.","title":"Api Key"},"description":"API key whose usage to read."}],"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","description":"API key whose usage to read.","title":"Api Key"},"description":"API key whose usage to read."},{"name":"days","in":"query","required":false,"schema":{"type":"integer","description":"Trailing days to include.","default":30,"title":"Days"},"description":"Trailing days to include."}],"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","description":"API key whose usage to read.","title":"Api Key"},"description":"API key whose usage to read."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum number of recent requests to return.","default":20,"title":"Limit"},"description":"Maximum number of recent requests to return."}],"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","description":"API key to deactivate and replace.","title":"Api Key"},"description":"API key to deactivate and replace."}],"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","description":"Trailing days to include.","default":30,"title":"Days"},"description":"Trailing days to include."}],"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","description":"Maximum number of recent requests to return.","default":20,"title":"Limit"},"description":"Maximum number of recent requests to return."}],"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 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":"Checkout session URL and ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"400":{"description":"No 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":"Payment processing is temporarily unavailable"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/portal":{"post":{"tags":["billing"],"summary":"Create Portal Session","description":"Create a billing 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 billing 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":"Billing 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":"Billing portal not configured or not enabled"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."},{"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"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."}],"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"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"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","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."},{"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"}}}},"401":{"description":"API key required or invalid"},"429":{"description":"Quota exceeded"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/insights/{symbol}/cashflow":{"get":{"tags":["insights"],"summary":"Annual cash flow and capital allocation from XBRL facts","description":"Per-fiscal-year cash flow and capital allocation from the SEC XBRL\ncompany-facts cache: operating cash flow, capex, free cash flow, dividends,\nbuybacks, debt issued/repaid, acquisitions, plus stock-based compensation\nand D&A. Annual only, so each figure ties to the audited 10-K.\n\nAnswers what a company earns in cash and what it does with it — e.g. Oracle\nran free cash flow negative funding a debt-financed capex build-out, while\nApple returns more than its free cash flow to shareholders.","operationId":"get_cashflow_api_insights__symbol__cashflow_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."},{"name":"years","in":"query","required":false,"schema":{"type":"integer","maximum":15,"minimum":1,"description":"Number of recent fiscal years to return.","default":5,"title":"Years"},"description":"Number of recent fiscal years to return."}],"responses":{"200":{"description":"Per-fiscal-year operating cash flow, capex, free cash flow, and capital-allocation flows","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Cashflow Api Insights  Symbol  Cashflow 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/insights/{symbol}/peer-percentiles":{"get":{"tags":["insights"],"summary":"Where a symbol ranks within its sector","description":"Rank a symbol against its sector peers on margin, ROE, growth, leverage,\nand valuation multiples. Each metric returns the symbol's value, its\npercentile within the sector, the sector median, and the peer count — an\nabsolute number turned into a judgement. Universe-wide from the screening\nrecord, so it is not limited to SEC filers.","operationId":"get_peer_percentiles_api_insights__symbol__peer_percentiles_get","parameters":[{"name":"symbol","in":"path","required":true,"schema":{"type":"string","description":"Ticker symbol, e.g. AAPL.","title":"Symbol"},"description":"Ticker symbol, e.g. AAPL."}],"responses":{"200":{"description":"Per-metric sector percentile, median, and peer count","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Peer Percentiles Api Insights  Symbol  Peer Percentiles 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/disclaimers":{"get":{"tags":["disclaimers"],"summary":"Canonical disclaimer registry","description":"Return every disclaimer the API may attach to a response, keyed by\nstable ID, so a client can render the long-form text or translate it\nlocally instead of embedding copies. No API key required.","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","description":"Look up one disclaimer by its stable ID. 404 when the ID is unknown.","operationId":"get_disclaimer_api_disclaimers__disclaimer_id__get","parameters":[{"name":"disclaimer_id","in":"path","required":true,"schema":{"type":"string","description":"Stable disclaimer ID from the registry.","title":"Disclaimer Id"},"description":"Stable disclaimer ID from the registry."}],"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":[]}},"/api/terminal/agent":{"post":{"tags":["terminal-agent"],"summary":"Terminal AI research agent","description":"Drive the terminal's AI research assistant: a tool-calling loop over the\nplatform's own data (screening, filings, watchlist, portfolio). Restricted\nto the internal plan; other keys receive 404 so the endpoint stays\ninvisible. Streams the assistant's turns back to the caller.","operationId":"terminal_agent_api_terminal_agent_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"400":{"description":"messages must contain at least one user/assistant turn"},"401":{"description":"API key required or invalid"},"404":{"description":"Not available for this API key's plan"},"429":{"description":"Quota exceeded"},"503":{"description":"AI backend unavailable"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AgentMessage":{"properties":{"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"}},"type":"object","required":["role","content"],"title":"AgentMessage"},"AgentRequest":{"properties":{"messages":{"items":{"$ref":"#/components/schemas/AgentMessage"},"type":"array","title":"Messages","description":"Conversation so far (user/assistant turns)."},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"Override the reasoning model (else env default)."},"max_turns":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Turns","description":"Max tool-calling turns (1-10)."}},"type":"object","required":["messages"],"title":"AgentRequest"},"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}},"CanonicalRequest":{"properties":{"symbols":{"items":{"type":"string"},"type":"array","maxItems":1000,"title":"Symbols"}},"type":"object","title":"CanonicalRequest"},"CanonicalResponse":{"properties":{"resolved":{"additionalProperties":{"type":"string"},"type":"object","title":"Resolved","description":"Input symbol to canonical symbol, for the subset that has one."}},"type":"object","title":"CanonicalResponse"},"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 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":"Hosted checkout page URL — open in the user's browser"},"session_id":{"type":"string","title":"Session Id","description":"Checkout session identifier"}},"type":"object","required":["checkout_url","session_id"],"title":"CheckoutResponse","description":"Response containing the checkout session URL.","example":{"checkout_url":"https://checkout.example.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')."},"quality_flags":{"items":{"type":"string"},"type":"array","title":"Quality Flags","description":"Why a field was dropped by a data-quality guard rather than simply being absent upstream: 'source_divergence' (two independent figures disagree beyond tolerance), 'discontinuous_column' (a balance-sheet item jumped implausibly between consecutive reports), 'period_mismatch' (an annual numerator over a quarterly denominator), 'filed_figure_incomplete' (a regulatory filing omits a debt component). Distinguishes 'we refused to answer' from 'nobody reported it'."},"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."},"holdings":{"items":{"$ref":"#/components/schemas/ETFHoldingScreeningResult"},"type":"array","title":"Holdings","description":"Screened holdings (symbol, weight, compliance, purification), sorted by weight. Powers the full look-through and flagged-holdings filter. Per-holding financial ratios and methodology detail are fetched on demand via /api/screen/{symbol}."}},"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":6,"minItems":1,"title":"Symbols","description":"List of 1-6 ETF ticker symbols. One symbol screens a single fund; two or more compare them side by side."}},"type":"object","required":["symbols"],"title":"ETFCompareRequest","description":"Request body to screen one ETF or compare up to six 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":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Symbol","description":"Ticker symbol of the holding, or null for a weighted line with no listing of its own."},"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","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":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Symbol","description":"Ticker symbol of the underlying holding, or null for a weighted line with no listing of its own (e.g. a loyalty share class kept in the denominator)."},"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","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":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Symbol","description":"Ticker symbol of the holding, or null for a weighted line with no listing of its own."},"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","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."},"FxResponse":{"properties":{"base":{"type":"string","title":"Base","description":"Currency the rates convert into"},"rates":{"additionalProperties":{"type":"number"},"type":"object","title":"Rates","description":"Currency code to how many base units one of it buys"},"missing":{"items":{"type":"string"},"type":"array","title":"Missing","description":"Currencies no rate could be found for. Callers must not treat these as 1."}},"type":"object","required":["base"],"title":"FxResponse"},"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":[]},"price_monthly":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Monthly","description":"Actual monthly price in USD from the key's Stripe subscription (reflects custom pricing). Null when no subscription is attached."}},"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"}]}},"MethodologyBasisShadow":{"properties":{"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis","description":"The alternate basis used for the shadow: 'total_assets' or 'market_cap'."},"is_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Compliant","description":"Tri-state verdict on the alternate basis."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Failure/abstention explanation on the alternate basis, when not compliant."}},"type":"object","title":"MethodologyBasisShadow","description":"Shadow verdict for an alternate ratio basis (see MethodologyEntry.alternate_basis)."},"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":[]},"verdict_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verdict Scope","description":"What the compliance verdict asserts. Halal Terminal applies the methodology's Shariah ratio thresholds to the latest reported financials. Index providers add construction rules — entry buffers, multi-period averaging, delayed removal — that manage fund turnover rather than express a Shariah criterion. Read this before comparing a verdict to actual index membership."},"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)."},"disposition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disposition","description":"Three-state disposition for this methodology: 'compliant', 'questionable', 'non_compliant', or 'insufficient_data'. 'questionable' means the screens passed (is_compliant=true) but an advisory flag from THIS methodology's text applies (e.g. undisclosed weapons/defense revenue under DJIM/FTSE/MSCI); AAOIFI and S&P, whose texts carry no defense exclusion, stay 'compliant' on the same company. See the top-level questionable_business block for the reason."},"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')."},"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis","description":"Ratio denominator this methodology screens against: 'total_assets' or 'market_cap'."},"alternate_basis":{"anyOf":[{"$ref":"#/components/schemas/MethodologyBasisShadow"},{"type":"null"}],"description":"AAOIFI only: shadow verdict computed with the same AAOIFI thresholds on the opposite ratio basis. The primary AAOIFI verdict follows Std 21 §3/4 (market capitalization); the shadow reports the total-assets reading. On small caps the two can legitimately disagree."},"bases_disagree":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Bases Disagree","description":"AAOIFI only: true when the primary verdict and the alternate-basis shadow verdict are both known and differ. Explains divergence between screeners without either result being a data error."},"mc_trailing_basis":{"anyOf":[{"$ref":"#/components/schemas/MethodologyTrailingShadow"},{"type":"null"}],"description":"AAOIFI only: transparent second reading on a trailing-average market cap (12 months, the common institutional convention). The primary AAOIFI verdict stays on spot MC; Std 21 is silent on spot vs trailing-average, and a name near the 30% line can read differently once the volatile spot MC is smoothed. Absent when no genuine trailing average is available (currency mismatch, IPO too recent for history, or a spot fallback)."},"mc_trailing_disagrees":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Mc Trailing Disagrees","description":"AAOIFI only: true when the primary spot-MC verdict and the trailing-MC reading are both known and differ."}},"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."},"MethodologyTrailingShadow":{"properties":{"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Basis","description":"Label of the trailing basis used, e.g. 'MC12mo'."},"window_months":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Window Months","description":"Length of the trailing-average window in months (e.g. 12)."},"is_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Compliant","description":"Tri-state AAOIFI verdict on the trailing-average MC."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Explanation on the trailing basis, e.g. 'debt/MC12mo 31.5% > 30%'."},"debt_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Debt Ratio","description":"Interest-bearing debt divided by the trailing-average market cap."}},"type":"object","title":"MethodologyTrailingShadow","description":"Trailing-average-MC reading of AAOIFI (see MethodologyEntry.mc_trailing_basis)."},"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 billing 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 billing portal session"}},"type":"object","required":["portal_url"],"title":"PortalResponse","description":"Response with a billing portal URL.","example":{"portal_url":"https://billing.example.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,"engine_version":"abc1234","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%)."},"engine_version":{"type":"string","title":"Engine Version","description":"Build identifier of the screening engine that produced this scan."}},"type":"object","required":["total","compliant","non_compliant","pending","avg_purification_rate","engine_version"],"title":"PortfolioSummaryResponse","description":"Aggregate compliance statistics for a portfolio scan.","example":{"avg_purification_rate":0.028,"compliant":2,"engine_version":"abc1234","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"}},"PurificationRateAsOfResponse":{"properties":{"symbol":{"type":"string","title":"Symbol","description":"Ticker symbol."},"as_of":{"type":"string","title":"As Of","description":"Requested date, YYYY-MM-DD."},"rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Rate","description":"Purification rate in percent (e.g. 0.96), null when unknown."},"screened_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screened At","description":"Timestamp of the screening pass that supplied the rate."},"mode":{"type":"string","title":"Mode","description":"'as_of' when a pass on or before the date exists, else 'fallback_current'."},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note","description":"Set when the rate was adjusted from the legacy screening convention."}},"type":"object","required":["symbol","as_of","mode"],"title":"PurificationRateAsOfResponse","description":"Purification rate in force at a date, from the screening history.","example":{"as_of":"2026-05-08","mode":"as_of","note":"legacy 100 percent convention replaced by the impure revenue share","rate":0.96,"screened_at":"2026-05-01T08:00:00+00:00","symbol":"IBM"}},"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 `currency`"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency","description":"Currency the venue quotes this instrument in, ISO code. Sub-unit venues are folded into their parent, so a London line reports GBP and a price in pounds. Null when the upstream did not say."},"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 `currency`"},"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 the 7-day refresh policy (SCREENING_STALENESS_HOURS, default 168). The platform re-screens cached results nightly, most-requested symbols first."},"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 — the AAOIFI debt screen since June 2026, and an input to DJIM and S&P. Computed on the same capitalization the AAOIFI verdict was rendered against: spot market cap by default, or the trailing average when a trailing basis is in force for that screen."},"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":"Pass/fail for AAOIFI (Shari'ah Standard 21). For ratio, basis and reason, see by_methodology.AAOIFI."},"djim_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Djim Compliant","description":"Pass/fail for the Dow Jones Islamic Market methodology. Detail in by_methodology.DJIM."},"ftse_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Ftse Compliant","description":"Pass/fail for the FTSE Shariah methodology. Detail in by_methodology.FTSE."},"msci_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Msci Compliant","description":"Pass/fail for the MSCI Islamic methodology. Detail in by_methodology.MSCI."},"sp_compliant":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Sp Compliant","description":"Pass/fail for the S&P Shariah methodology. Detail in by_methodology.SP."},"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."},"questionable_business":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Questionable Business","description":"ADVISORY (does not affect the verdict): {flag, reasons} when the issuer's video-game portfolio includes simulated-gambling content (social casino, slots, poker). Video gaming itself passes the business screen; this flag marks the scholars-differ cases the way analyst-based screeners label them 'questionable'."},"ifi_exempt":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Ifi Exempt","description":"True when the issuer is a certified Islamic financial institution (curated registry / regulated name markers): exempt from the conventional-finance exclusion and the accounting screens per the DJIM/MSCI/S&P IFI carve-outs. Null for ordinary issuers."},"business_income":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Business Income","description":"ADVISORY (does not affect the verdict): per-segment revenue breakdown extracted from the issuer's latest 10-K, with each segment classified permissible / impermissible / questionable / unknown by a versioned rules map. Includes the combined impure ratio (interest + impermissible) and a separate with-questionable figure — the split where reputable screeners legitimately differ. Null when no segment analysis exists yet."},"fx_normalization":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Fx Normalization","description":"Present when the issuer reports financials in a different currency than its listing (ADR-style): {rate, from, to} used to convert the market-cap-ratio numerators into the listing currency. Null when no mismatch existed or no rate could be resolved (in which case MC-basis methodologies abstain)."},"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"},"SourceHealthItem":{"properties":{"name":{"type":"string","title":"Name","description":"Index name, e.g. 'S&P 500'"},"count":{"type":"integer","title":"Count","description":"Constituents the source returned on the last check"},"floor":{"type":"integer","title":"Floor","description":"Minimum healthy constituent count for this index"},"status":{"type":"string","enum":["ok","degraded","failed"],"title":"Status","description":"ok = at/above floor, degraded = below floor, failed = empty"}},"type":"object","required":["name","count","floor","status"],"title":"SourceHealthItem"},"SourceHealthResponse":{"properties":{"checked_at":{"type":"string","title":"Checked At","description":"ISO timestamp of the underlying check"},"ttl_seconds":{"type":"integer","title":"Ttl Seconds","description":"How long this result is cached server-side"},"cached":{"type":"boolean","title":"Cached","description":"True if served from cache rather than freshly computed"},"summary":{"$ref":"#/components/schemas/SourceHealthSummary"},"indices":{"items":{"$ref":"#/components/schemas/SourceHealthItem"},"type":"array","title":"Indices","description":"Per-index health, broken sources first"}},"type":"object","required":["checked_at","ttl_seconds","cached","summary","indices"],"title":"SourceHealthResponse","example":{"cached":true,"checked_at":"2026-06-24T09:00:00+00:00","indices":[{"count":503,"floor":450,"name":"S&P 500","status":"ok"}],"summary":{"degraded":0,"failed":0,"healthy":21,"status":"ok","total":21},"ttl_seconds":21600}},"SourceHealthSummary":{"properties":{"total":{"type":"integer","title":"Total","description":"Number of index sources checked"},"healthy":{"type":"integer","title":"Healthy","description":"Sources at or above their floor"},"degraded":{"type":"integer","title":"Degraded","description":"Sources below their floor but non-empty"},"failed":{"type":"integer","title":"Failed","description":"Sources that returned nothing"},"status":{"type":"string","enum":["ok","alert"],"title":"Status","description":"alert if any source is degraded or failed, else ok"}},"type":"object","required":["total","healthy","degraded","failed","status"],"title":"SourceHealthSummary"},"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":"auth","description":"Manage the calling API key via the `X-API-Key` header (key never appears in the URL): inspect plan, quota, and identity (`/api/auth/me`), review daily and recent usage, and rotate the key (`/api/auth/me/regenerate`). Path-clean replacement for the deprecated `/api/keys/{api_key}/*` endpoints."},{"name":"billing","description":"Upgrade and manage your subscription. `POST /api/billing/checkout` returns a hosted checkout URL to upgrade a plan; `POST /api/billing/portal` returns a billing-portal URL to update payment method, view invoices, and cancel. Both authenticate via the `X-API-Key` header."},{"name":"disclaimers","description":"Canonical disclaimer registry. Resolve the `disclaimers[].id` values attached to other API responses. No API key required."}],"security":[{"ApiKeyAuth":[]}]}