StocksSG API
Programmatic access to SGX-listed company data, board intelligence, financial analytics, and Singapore charity information. 13 endpoints, JSON responses, simple API key auth.
Endpoints
Getting Started
Authentication
Pass your API key in the x-api-key header. Requests without an API key are treated as free tier (10 requests/minute). Keys are SHA-256 hashed before storage — we never see your plaintext key.
curl -H "x-api-key: YOUR_API_KEY" \ https://stocks.com.sg/api/v1/companies?q=DBS
Response Format
All endpoints return JSON with a consistent envelope. Successful responses have a data field and an optional meta field. Errors return an error string.
{
"data": [ ... ],
"meta": { "count": 42 }
}{
"error": "Invalid API key"
}Rate Limits
Rate limits are enforced per API key on a per-minute sliding window.
| Tier | Rate Limit | Access |
|---|---|---|
| Free | 10 requests/min | No API key required |
| Pro | 60 requests/min | API key required |
| Enterprise | 300 requests/min | API key + IP whitelist available |
| Institutional | 1,250 requests/min | API key + IP whitelist available |
Companies
/api/v1/companiesList companies
Returns all SGX-listed companies, optionally filtered by search query or GICS sector.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| q | query | No | Search query (matches company name or ticker) |
| sector | query | No | Filter by GICS sector (e.g. Financials) |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/companies?q=DBS"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/companies",
headers={"x-api-key": "YOUR_KEY"},
params={"q": "DBS"},
)
companies = resp.json()["data"]
print("Found %d companies" % len(companies))const resp = await fetch(
"https://stocks.com.sg/api/v1/companies?q=DBS",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
console.log(`Found ${data.length} companies`);/api/v1/companies/{ticker}Company detail
Returns detailed profile for a single SGX-listed company including sector, market cap, UEN, website, and index membership.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| ticker | path | Yes | SGX ticker symbol (e.g. D05) |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/companies/D05"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/companies/D05",
headers={"x-api-key": "YOUR_KEY"},
)
company = resp.json()["data"]
print(company["company_name"], company["gics_sector"])const resp = await fetch(
"https://stocks.com.sg/api/v1/companies/D05",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
console.log(data.company_name, data.gics_sector);/api/v1/officers/{ticker}Company officers
Returns board members and executives for a company. Filter by type (board/executive), status (current/former), or date range.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| ticker | path | Yes | SGX ticker symbol |
| type | query | No | Filter: board or executive |
| status | query | No | Filter: current or former |
| from | query | No | Appointments from date (YYYY-MM-DD) |
| to | query | No | Appointments up to date (YYYY-MM-DD) |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/officers/D05?type=board&status=current"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/officers/D05",
headers={"x-api-key": "YOUR_KEY"},
params={"type": "board", "status": "current"},
)
officers = resp.json()["data"]["officers"]
for o in officers:
print(o["name"], o["role"])const resp = await fetch(
"https://stocks.com.sg/api/v1/officers/D05?type=board&status=current",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
data.officers.forEach(o => console.log(o.name, o.role));Directors
/api/v1/directorsSearch directors
Search for directors by name, or list current board members for a specific company. One of q or ticker is required.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| q | query | No | Search director name (partial, case-insensitive) |
| ticker | query | No | List board members for this ticker |
| limit | query | No | Max results (default 50, max 200) |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/directors?q=Piyush"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/directors",
headers={"x-api-key": "YOUR_KEY"},
params={"q": "Piyush"},
)
directors = resp.json()["data"]
for d in directors:
print(d["full_name"])const resp = await fetch(
"https://stocks.com.sg/api/v1/directors?q=Piyush",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
data.forEach(d => console.log(d.full_name));/api/v1/degrees-of-separationBoard network — degrees of separation
Finds the shortest connection path between two directors through shared board memberships. BFS algorithm, max 6 degrees.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| from | query | Yes | Source director ID (UUID) |
| to | query | Yes | Target director ID (UUID) |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/degrees-of-separation?from=UUID1&to=UUID2"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/degrees-of-separation",
headers={"x-api-key": "YOUR_KEY"},
params={"from": "UUID1", "to": "UUID2"},
)
result = resp.json()["data"]
if result["connected"]:
print("%d degrees of separation" % result["degrees"])
for node in result["path"]:
print(" %s via %s" % (node["person_name"], node["company_name"] or "start"))const resp = await fetch(
"https://stocks.com.sg/api/v1/degrees-of-separation?from=UUID1&to=UUID2",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
if (data.connected) {
console.log(`${data.degrees} degrees of separation`);
data.path.forEach(n =>
console.log(` ${n.person_name} via ${n.company_name ?? "start"}`)
);
}Analytics
/api/v1/fair-value/{ticker}Fair value estimate
Three-model valuation (DCF, DDM, EV/EBITDA relative) with composite estimate and upside/downside verdict. Not financial advice.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| ticker | path | Yes | SGX ticker symbol |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/fair-value/D05"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/fair-value/D05",
headers={"x-api-key": "YOUR_KEY"},
)
fv = resp.json()["data"]
print("Current: $%.2f" % fv["current_price"])
print("Fair value: $%.2f" % fv["composite_fair_value"])
print("Verdict:", fv["verdict"])const resp = await fetch(
"https://stocks.com.sg/api/v1/fair-value/D05",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
console.log(`Current: $${data.current_price}`);
console.log(`Fair value: $${data.composite_fair_value}`);
console.log(`Verdict: ${data.verdict}`);/api/v1/dividend-safety/{ticker}Dividend safety score
Multi-factor dividend safety assessment: yield, payout ratio, coverage, streak, and REIT-aware scoring. Returns a letter grade (A+ to F) and 0-100 score.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| ticker | path | Yes | SGX ticker symbol |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/dividend-safety/O39"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/dividend-safety/O39",
headers={"x-api-key": "YOUR_KEY"},
)
ds = resp.json()["data"]
print("%s: %s (%d/100)" % (ds["company_name"], ds["grade"], ds["score"]))
print("Yield: %s%%, Streak: %d years" % (ds["dividend_yield_pct"], ds["streak_years"]))const resp = await fetch(
"https://stocks.com.sg/api/v1/dividend-safety/O39",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
console.log(`${data.company_name}: ${data.grade} (${data.score}/100)`);
console.log(`Yield: ${data.dividend_yield_pct}%, Streak: ${data.streak_years}y`);/api/v1/accounting-quality/{ticker}Accounting quality (Beneish M-Score)
Forensic accounting indicators: Beneish M-Score, Sloan Accruals Ratio, and composite quality score. M-Score below -1.78 suggests low manipulation risk.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| ticker | path | Yes | SGX ticker symbol |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/accounting-quality/Z74"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/accounting-quality/Z74",
headers={"x-api-key": "YOUR_KEY"},
)
aq = resp.json()["data"]
print("M-Score:", aq["m_score"])
print("Risk:", aq["manipulation_risk"])const resp = await fetch(
"https://stocks.com.sg/api/v1/accounting-quality/Z74",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
console.log(`M-Score: ${data.m_score}, Risk: ${data.manipulation_risk}`);/api/v1/financial-distress/{ticker}Financial distress (Altman Z-Score)
Altman Z-Score (original + adjusted for non-manufacturing), Piotroski F-Score. Zone classification: safe (>2.99), grey (1.81-2.99), distress (<1.81). REITs excluded from Z-Score.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| ticker | path | Yes | SGX ticker symbol |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/financial-distress/U11"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/financial-distress/U11",
headers={"x-api-key": "YOUR_KEY"},
)
fd = resp.json()["data"]
print("Z-Score: %s, Zone: %s" % (fd["altman_z"], fd["zone"]))
print("Piotroski F-Score: %d/9" % fd["piotroski_f"])const resp = await fetch(
"https://stocks.com.sg/api/v1/financial-distress/U11",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
console.log(`Z-Score: ${data.altman_z}, Zone: ${data.zone}`);
console.log(`Piotroski F-Score: ${data.piotroski_f}/9`);Screener
/api/v1/screenerStock screener
Multi-factor stock screener with fundamental, governance, and market data. Filter by sector, index membership, and market cap range. Sort by any column.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| sector | query | No | GICS sector filter |
| index | query | No | Index: STI, FTSE_ST_MID, or FTSE_ST_SMALL |
| min_mcap | query | No | Minimum market cap (SGD) |
| max_mcap | query | No | Maximum market cap (SGD) |
| sort | query | No | Sort column (default: market_cap_sgd) |
| dir | query | No | Sort direction: asc or desc (default: desc) |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/screener?index=STI&sort=dividend_yield_pct&dir=desc"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/screener",
headers={"x-api-key": "YOUR_KEY"},
params={
"index": "STI",
"sort": "dividend_yield_pct",
"dir": "desc",
},
)
rows = resp.json()["data"]
for r in rows[:10]:
print("%-6s %-30s %s" % (r["ticker"], r["company_name"][:30], r.get("dividend_yield_pct", "N/A")))const params = new URLSearchParams({
index: "STI",
sort: "dividend_yield_pct",
dir: "desc",
});
const resp = await fetch(
`https://stocks.com.sg/api/v1/screener?${params}`,
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
data.slice(0, 10).forEach(r =>
console.log(r.ticker, r.company_name, r.dividend_yield_pct)
);Charities
/api/v1/charitiesList charities
Search Singapore registered charities by name or filter by state. Returns aggregate stats when called without filters (use ?q= or ?state= to filter).
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| q | query | No | Search charity name |
| state | query | No | Filter by registration state |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/charities?q=community"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/charities",
headers={"x-api-key": "YOUR_KEY"},
params={"q": "community"},
)
charities = resp.json()["data"]
print("Found %d charities" % len(charities))const resp = await fetch(
"https://stocks.com.sg/api/v1/charities?q=community",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
console.log(`Found ${data.length} charities`);/api/v1/charities/{slug}Charity detail
Full charity profile with financials, current officers, and charity rating.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| slug | query | Yes | Charity URL slug |
Code examples
curl -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/v1/charities/singapore-red-cross"
import requests
resp = requests.get(
"https://stocks.com.sg/api/v1/charities/singapore-red-cross",
headers={"x-api-key": "YOUR_KEY"},
)
data = resp.json()["data"]
print(data["charity"]["name"])
print("Officers: %d" % len(data["officers"]))const resp = await fetch(
"https://stocks.com.sg/api/v1/charities/singapore-red-cross",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const { data } = await resp.json();
console.log(data.charity.name);
console.log(`Officers: ${data.officers.length}`);Research
/api/deep-research/{ticker}AI deep research report (SSE)
Generates a comprehensive AI-powered research report. Returns a Server-Sent Events stream with progressive markdown content. Each event has a type (section, content, or done) and content field. Requires Pro tier or above.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| ticker | path | Yes | SGX ticker symbol |
Code examples
curl -N -H "x-api-key: YOUR_KEY" \ "https://stocks.com.sg/api/deep-research/D05"
import requests
# SSE streaming
resp = requests.get(
"https://stocks.com.sg/api/deep-research/D05",
headers={"x-api-key": "YOUR_KEY"},
stream=True,
)
for line in resp.iter_lines():
if line:
decoded = line.decode("utf-8")
if decoded.startswith("data: "):
print(decoded[6:])const resp = await fetch(
"https://stocks.com.sg/api/deep-research/D05",
{ headers: { "x-api-key": "YOUR_KEY" } }
);
const reader = resp.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
// Parse SSE events
for (const line of chunk.split("\n")) {
if (line.startsWith("data: ")) {
const event = JSON.parse(line.slice(6));
process.stdout.write(event.content || "");
}
}
}OpenAPI Specification
The full OpenAPI 3.0.3 specification is available for download. Import it into Postman, Insomnia, or any OpenAPI-compatible tool to explore all endpoints, schemas, and example values.
Download openapi.json