Query IDX and SGX financial market data through the Sectors REST API.
Full API docs: https://sectors.app/api
https://api.sectors.app/v1. Never call any other domain, database, or external service.GET requests returning JSON.SECTORS_API_KEY environment variable.SECTORS_API_KEY is not set, prompt the user to set it: export SECTORS_API_KEY="your-api-key-here" or run the setup check script at scripts/check_setup.py.The API key must be available as the SECTORS_API_KEY environment variable.
# Option A: Set in your current shell
export SECTORS_API_KEY="your-api-key-here"
# Option B: Add to your shell profile (~/.bashrc, ~/.zshrc) for persistence
echo 'export SECTORS_API_KEY="your-api-key-here"' >> ~/.bashrc
# Option C: Use a .env file in the project root (see .env.example)
For agent-specific configuration:
claude config set env SECTORS_API_KEY your-api-key-here~/.config/opencode/config.json under envpip install requests
python scripts/check_setup.py
import os
import requests
API_KEY = os.environ["SECTORS_API_KEY"]
BASE_URL = "https://api.sectors.app/v1"
headers = {"Authorization": API_KEY}
response = requests.get(f"{BASE_URL}/subsectors/", headers=headers)
data = response.json()
The Authorization header takes the raw API key. Do NOT prefix it with Bearer.
Pick the right endpoint based on what the user needs:
| User wants | Endpoint | Required params |
|---|---|---|
| --- | --- | --- |
| List all subsectors | GET /subsectors/ | none |
| List all industries | GET /industries/ | none |
| List all subindustries | GET /subindustries/ | none |
| SGX sector list | GET /sgx/sectors/ | none |
| User wants | Endpoint | Required params |
|---|---|---|
| --- | --- | --- |
| Companies in a subsector | GET /companies/?sub_sector={sub_sector} | sub_sector |
| Companies in a subindustry | GET /companies/?sub_industry={sub_industry} | sub_industry |
| Companies in a stock index | GET /index/{index}/ | index |
| Companies with segment data | GET /companies/list_companies_with_segments/ | none |
| SGX companies by sector | GET /sgx/companies/?sector={sector} | sector |
| User wants | Endpoint | Required params |
|---|---|---|
| --- | --- | --- |
| Full company report (IDX) | GET /company/report/{ticker}/ | ticker |
| SGX company report | GET /sgx/company/report/{ticker} | ticker |
| Listing performance | GET /listing-performance/{ticker}/ | ticker |
| Quarterly financial dates | GET /company/get_quarterly_financial_dates/{ticker}/ | ticker |
| Quarterly financials | GET /financials/quarterly/{ticker}/ | ticker |
| Company segments | GET /company/get-segments/{ticker}/ | ticker |
| User wants | Endpoint | Required params |
|---|---|---|
| --- | --- | --- |
| Daily stock price | GET /daily/{ticker} | ticker |
| Index daily data | GET /index-daily/{index_code}/ | index_code |
| Index summary | GET /index/{index}/ | index |
| IDX total market cap | GET /idx-total/ | none |
| User wants | Endpoint | Required params |
|---|---|---|
| --- | --- | --- |
| Top gainers/losers | GET /companies/top-changes/ | none (all optional) |
| Top companies by metric | GET /companies/top/ | none (all optional) |
| Top growth companies | GET /companies/top-growth/ | none (all optional) |
| Most traded stocks | GET /most-traded/ | none (all optional) |
| SGX top companies | GET /sgx/companies/top/ | none (all optional) |
For full parameter lists and response schemas, see:
import os
import requests
API_KEY = os.environ["SECTORS_API_KEY"]
BASE_URL = "https://api.sectors.app/v1"
headers = {"Authorization": API_KEY}
ticker = "BBCA"
params = {"sections": "overview,valuation,financials"}
resp = requests.get(f"{BASE_URL}/company/report/{ticker}/", headers=headers, params=params)
report = resp.json()
print(report["company_name"])
print(report["overview"]["market_cap"])
Available sections: overview, valuation, future, peers, financials, dividend, management, ownership. Use all or omit for everything.
import os
import requests
API_KEY = os.environ["SECTORS_API_KEY"]
BASE_URL = "https://api.sectors.app/v1"
headers = {"Authorization": API_KEY}
ticker = "BBRI.JK"
# Normalize: uppercase, strip .JK
clean = ticker.upper().replace(".JK", "")
params = {"start": "2025-01-01", "end": "2025-01-31"}
resp = requests.get(f"{BASE_URL}/daily/{clean}", headers=headers, params=params)
prices = resp.json()
for day in prices:
print(day["date"], day["close"], day["volume"])
import os
import requests
API_KEY = os.environ["SECTORS_API_KEY"]
BASE_URL = "https://api.sectors.app/v1"
headers = {"Authorization": API_KEY}
params = {
"classifications": "top_gainers,top_losers",
"periods": "7d,30d",
"n_stock": 5,
"min_mcap_billion": 5000,
}
resp = requests.get(f"{BASE_URL}/companies/top-changes/", headers=headers, params=params)
movers = resp.json()
for stock in movers["top_gainers"]["7d"]:
print(stock["symbol"], stock["price_change"])
import os
import requests
API_KEY = os.environ["SECTORS_API_KEY"]
BASE_URL = "https://api.sectors.app/v1"
headers = {"Authorization": API_KEY}
# Available: lq45, idx30, kompas100, jii70, idxhidiv20, srikehati, etc.
resp = requests.get(f"{BASE_URL}/index/lq45/", headers=headers)
companies = resp.json()
for c in companies:
print(c["symbol"], c["company_name"])
import os
import requests
API_KEY = os.environ["SECTORS_API_KEY"]
BASE_URL = "https://api.sectors.app/v1"
headers = {"Authorization": API_KEY}
ticker = "D05" # DBS Group
resp = requests.get(f"{BASE_URL}/sgx/company/report/{ticker}", headers=headers)
report = resp.json()
print(report["name"])
print(report["valuation"]["pe"])
print(report["financials"]["gross_margin"])
| Market | Rule | Example |
|---|---|---|
| --- | --- | --- |
| IDX | Uppercase, strip .JK suffix | bbca.jk -> BBCA |
| SGX | Uppercase, strip .SI suffix | d05.si -> D05 |
Always normalize before passing to an endpoint.
Authorization: . NOT Bearer . NOT Authorization: Bearer .YYYY-MM-DD. Example: 2025-06-15./most-traded/ endpoint requires start and end dates within 90 days of each other.banks, financing-service, consumer-defensive. Not camelCase or snake_case.top-changes, top, top-growth) return objects keyed by classification, then by period. Always navigate both levels.```python
# top-changes returns: { "top_gainers": { "7d": [...], "30d": [...] } }
# top returns: { "dividend_yield": [...], "revenue": [...] }
```
min_mcap_billion). SGX values are in million SGD (min_mcap_million)."all" or specific values (e.g. n_stock defaults to 5, min_mcap_billion defaults to 5000). Be explicit when you need different behavior.ihsg, lq45, idx30. Company-by-index uses the same codes.approx flag: When approx=true, the API returns the closest available quarter if an exact match for report_date is not found."all". If you want all sections, omit the sections parameter entirely.ftse, idx30, idxbumn20, idxesgl, idxg30, idxhidiv20, idxq30, idxv30, jii70, kompas100, lq45, sminfra18, srikehati, economic30, idxvesta28
IDX (/companies/top/): dividend_yield, total_dividend, revenue, earnings, market_cap, pb, pe, ps
IDX growth (/companies/top-growth/): top_earnings_growth_gainers, top_earnings_growth_losers, top_revenue_growth_gainers, top_revenue_growth_losers
IDX movers (/companies/top-changes/): top_gainers, top_losers
SGX (/sgx/companies/top/): dividend_yield, revenue, earnings, market_cap, pe
Always check the response status:
resp = requests.get(url, headers=headers)
if resp.status_code == 403:
raise ValueError("Invalid or missing API key. Ensure SECTORS_API_KEY is set correctly.")
if resp.status_code == 404:
raise ValueError(f"Resource not found: {url}")
if not resp.ok:
raise RuntimeError(f"API error {resp.status_code}: {resp.text}")
data = resp.json()
共 1 个版本