Build on the
Pirana API
End-of-day IDX data for all ~957 Indonesia Stock Exchange companies, over a clean HTTP API. Authenticate with an API key, and every request is metered by your plan. Base URL: https://api.pirana.app
Get a key, send it on every request
Sign in, open Settings → API Keys, and create a key. The full key (sk-…) is shown once — copy it then; only a short prefix is stored afterward. Send it on each request using either header:
curl "https://api.pirana.app/v1/companies" \
-H "X-API-Key: sk-your-key-here"curl "https://api.pirana.app/v1/companies" \
-H "Authorization: Bearer sk-your-key-here"A Bearer value that doesn't start with sk- is treated as a logged-in user's session token instead. Public endpoints also work with no header at all — at the anonymous rate limit, with no credits deducted.
Rate limits & monthly budgets
A key inherits its owner's plan. Rate limits use a rolling 60-second window; the monthly credit budget resets on the 1st.
| Tier | Auth | Rate limit | Credits |
|---|---|---|---|
| Anonymous | No header | 60 req/min | Public endpoints only |
| FREE | API key (FREE owner) | 120 req/min | 100 credits / month |
| PRO | API key (PRO owner) | 300 req/min | 5,000 credits / month |
| ELITE | API key (ELITE owner) | 600 req/min | Unlimited |
What each request costs
Anonymous requests never deduct credits. For authenticated requests, every response carries X-Credits-Consumed and X-Credits-Remaining headers (unlimited for ELITE).
| Cost | Applies to |
|---|---|
| 1 credit | Default — most reads (companies, prices, search, sectors, rankings) |
| 2 credits | financials, metrics, ratios, ownership |
| 5 credits | AI search (POST /v1/search/ai) |
| Variable | Bundled outputs that scale with input — e.g. /v1/brokers/report.xlsx costs max(1, number of tickers) |
| Free | /health, /auth/*, /v1/credits, /docs, /openapi.json, /redoc — no credits deducted |
Status codes to handle
Note the two flavours of 429: a per-minute rate limit (with a Retry-After header) versus an exhausted monthly credit budget. They're handled differently.
| Code | Meaning | What to do |
|---|---|---|
| 401 | Missing or invalid API key / JWT. | Send a valid X-API-Key or Authorization: Bearer sk-... header. |
| 403 | Authenticated, but your tier can't access this — a paid-only endpoint, an over-cap ticker request, or an elite-only route. | Upgrade the key owner's plan, or reduce the request scope. |
| 429 (rate limit) | Too many requests this minute for your tier. | Back off and retry after the seconds in the Retry-After response header. |
| 429 (credits) | Monthly credit budget exhausted (body: "No credits remaining…"). | Wait for the monthly reset, purchase credits, or upgrade the plan. Check X-Credits-Remaining. |
Worked requests
Replace sk-your-key-here with your own key. Each example is a real endpoint — see the full reference for every parameter.
List companies
All ~957 IDX companies. Filter by sector, sub_sector, listing_board; paginate with limit and offset.
curl "https://api.pirana.app/v1/companies?sector=Financials&limit=20" \
-H "X-API-Key: sk-your-key-here"const res = await fetch(
"https://api.pirana.app/v1/companies?sector=Financials&limit=20",
{ headers: { "X-API-Key": "sk-your-key-here" } },
);
const companies = await res.json();Search companies
Search by name or ticker. The q parameter is required.
curl "https://api.pirana.app/v1/companies/search?q=bank" \
-H "X-API-Key: sk-your-key-here"const res = await fetch(
"https://api.pirana.app/v1/companies/search?q=bank",
{ headers: { "X-API-Key": "sk-your-key-here" } },
);
const matches = await res.json();Run the screener
Filter the universe by valuation and quality. FREE keys allow up to 5 active filters; PRO/ELITE are unlimited.
curl "https://api.pirana.app/v1/screener?pe_max=15&roe_min=0.15&limit=20" \
-H "X-API-Key: sk-your-key-here"const params = new URLSearchParams({
pe_max: "15",
roe_min: "0.15",
limit: "20",
});
const res = await fetch(
`https://api.pirana.app/v1/screener?${params}`,
{ headers: { "X-API-Key": "sk-your-key-here" } },
);
const results = await res.json();Company detail
Full profile for one symbol — key stats, subsidiaries, index memberships, and latest news. Use the IDX ticker with the .JK suffix.
curl "https://api.pirana.app/v1/company/BBCA.JK" \
-H "X-API-Key: sk-your-key-here"const res = await fetch(
"https://api.pirana.app/v1/company/BBCA.JK",
{ headers: { "X-API-Key": "sk-your-key-here" } },
);
const company = await res.json();Rankings
Rank companies by a metric. metric is required — e.g. market_cap, roe, revenue, net_income, pe_ratio, dividend_yield_ttm.
curl "https://api.pirana.app/v1/rankings?metric=market_cap&limit=10" \
-H "X-API-Key: sk-your-key-here"const res = await fetch(
"https://api.pirana.app/v1/rankings?metric=market_cap&limit=10",
{ headers: { "X-API-Key": "sk-your-key-here" } },
);
const ranked = await res.json();Ready to build?
Grab a key, explore every endpoint, or see what each plan unlocks.