Developers

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

Authentication

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:

X-API-Key header
curl "https://api.pirana.app/v1/companies" \
  -H "X-API-Key: sk-your-key-here"
Authorization: Bearer
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.

Tiers

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.

TierAuthRate limitCredits
AnonymousNo header60 req/minPublic endpoints only
FREEAPI key (FREE owner)120 req/min100 credits / month
PROAPI key (PRO owner)300 req/min5,000 credits / month
ELITEAPI key (ELITE owner)600 req/minUnlimited
Credits

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).

CostApplies to
1 creditDefault — most reads (companies, prices, search, sectors, rankings)
2 creditsfinancials, metrics, ratios, ownership
5 creditsAI search (POST /v1/search/ai)
VariableBundled 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
Errors

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.

CodeMeaningWhat to do
401Missing or invalid API key / JWT.Send a valid X-API-Key or Authorization: Bearer sk-... header.
403Authenticated, 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.
Examples

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
curl "https://api.pirana.app/v1/companies?sector=Financials&limit=20" \
  -H "X-API-Key: sk-your-key-here"
JavaScript
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
curl "https://api.pirana.app/v1/companies/search?q=bank" \
  -H "X-API-Key: sk-your-key-here"
JavaScript
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
curl "https://api.pirana.app/v1/screener?pe_max=15&roe_min=0.15&limit=20" \
  -H "X-API-Key: sk-your-key-here"
JavaScript
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
curl "https://api.pirana.app/v1/company/BBCA.JK" \
  -H "X-API-Key: sk-your-key-here"
JavaScript
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
curl "https://api.pirana.app/v1/rankings?metric=market_cap&limit=10" \
  -H "X-API-Key: sk-your-key-here"
JavaScript
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.