# Punji Public API - Developer Reference

Punji's public API gives programmatic access to Indian mutual fund and stock
market data: fund/stock lookup, returns, risk metrics, holdings, category
leaderboards, AMC/fund-manager info, industry fund-flow data, and fund/stock
comparison.

**Base URL:** `https://api.punji.ai/v1/`
**Auth header:** `X-API-Key: <your-key>` on every request.

All endpoints are `GET` unless noted. Responses are JSON.

---

## Getting an API key

1. Sign in at chat.punji.ai.
2. Go to Settings → API Keys.
3. Click "Get free API access" - this auto-activates the free evaluation
   plan and unlocks key creation.
4. Create a key. The plaintext key is shown **once** - store it immediately.
5. Use `/rotate` (via the same Settings page, or the key-management endpoints
   under `/punji/api-keys` on the main app - not the public data API) to
   revoke-and-reissue a key. There is no way to recover a lost plaintext key;
   rotate instead.

---

## Auth & error codes

| Status | Meaning |
|---|---|
| `401` | Missing, invalid, or revoked API key - or your account is not active. |
| `402` | Your subscription isn't active (never activated, expired, or suspended). |
| `404` | Resource not found (e.g. unknown fund/stock slug), or an unrecognized path. |
| `422` | Bad request - missing required param, invalid enum value, or a param combination that isn't allowed. |

A `401` never distinguishes "key doesn't exist" from "key is malformed" - 
both look identical, by design.

---

## Rate limits & pricing

Currently one public self-serve plan:

| Plan | Price | Quota |
|---|---|---|
| **API Free (evaluation)** | ₹0 | 50 data-API calls, resets monthly |

This is the only self-serve API plan live today. Higher-volume/paid tiers
are not yet generally available - contact Punji directly if you need more
than the free quota.

---

## Conventions

- **Identifiers:** every fund and stock is addressed by a `slug` (a stable,
  URL-safe identifier returned by search/resolve endpoints). ISIN is also
  accepted for direct lookup (`/schemes/by-isin/{isin}`, `/stocks/by-isin/{isin}`)
  since it's a standard external identifier - but slug is otherwise the only
  key.
- **Resolving natural-language input:** if you have a fund/stock/index name
  from user input rather than a known slug, call the resource's `/resolve`
  endpoint first (fuzzy match) and use `candidates[0].slug` when
  `status == "resolved"`; when `status == "ambiguous"`, show the top
  candidates for disambiguation rather than guessing.
- **Pagination:** list endpoints return `{items, total, limit, offset}`.
- **Plan/option:** mutual fund schemes come in `Direct`/`Regular` plans and
  `Growth`/`IDCW`/`Bonus` options - most return/analytics endpoints operate
  on a specific scheme (i.e. a specific plan+option combination), so make
  sure you've resolved to the right variant.
- Fields that don't apply to a given fund/stock (e.g. debt-only metrics on
  an equity fund) are omitted from the response rather than sent as `null`.

---

## Endpoints reference

### Mutual fund schemes - `/schemes/*`

| Method | Path | Params | Description |
|---|---|---|---|
| GET | `/schemes/search` | `q`+`query_type` (scheme_name\|manager\|amc), `manager_exact`, `amc`, `category`, `asset_class`, `plan`, `option`, `is_active`, `limit`, `offset` | Filtered fund listing. At least one filter required. |
| GET | `/schemes/resolve` | `q` (required), `prefer_plan`, `prefer_option`, `top` | Fuzzy natural-language → scheme slug resolver. |
| GET | `/schemes/by-amfi-codes` | `codes` (comma-separated) | Bulk lookup by AMFI code, max 200. |
| GET | `/schemes/by-isin/{isin}` | - | Scheme detail by ISIN. |
| GET | `/schemes/{slug}` | - | Full scheme detail. |
| GET | `/schemes/{slug}/nav/latest` | - | Latest NAV only (no historical NAV series). |
| GET | `/schemes/{slug}/returns/rolling` | `years` (e.g. `1,3,5,7,10`) | Rolling-window annualized returns. |
| GET | `/schemes/{slug}/returns/discrete` | `period_type` (CY\|FY\|TR) | Discrete period-to-period returns (NAV-delta basis). |
| GET | `/schemes/{slug}/returns/sip` | `years` | SIP returns for given lookback windows. |
| GET | `/schemes/{slug}/returns/point-to-point` | `from`, `to` (YYYY-MM-DD, required) | Absolute return + CAGR between two dates. |
| GET | `/schemes/{slug}/risk` | `years` (1\|3\|5\|7\|10, default 3) | Risk metrics (volatility, drawdown, etc.) for the window. |
| GET | `/schemes/{slug}/ranks` | - | All category-ranking metrics for this scheme, with display metadata. |
| GET | `/schemes/{slug}/analytics` | `months` (1-3) | Factsheet-derived analytics (PE, PB, duration, credit/market-cap mix). `months>1` returns a time series. |
| GET | `/schemes/{slug}/holdings/sectors` | - | Sector-level portfolio breakdown, latest month. |
| GET | `/schemes/{slug}/holdings/securities` | `limit` (≤50, ≤10 if `sector`/`country` set), `sector`, `country` (ISO-2), `asset_class` (EQUITY\|DEBT) | Top-N individual holdings. |
| GET | `/schemes/{slug}/similar` | `limit`, `window_years` | Behaviorally similar funds (by risk/return profile), same asset class, Direct+Growth only. |
| GET | `/schemes/{slug}/health` | `years` (3 or 5) | Punji Fund Health Score: Quality/Safety/Compound, each 0-100 with a letter grade. |
| GET | `/schemes/{slug}/market-position` | `quarters` (≤66) | Category AUM share over time, quarter-on-quarter deltas, relative growth. |
| GET | `/schemes/{slug}/idcw-history` | `limit` (≤500) | Dividend (IDCW) declaration history, Direct plan only. |

### Category leaderboards - `/categories/*`

| Method | Path | Params | Description |
|---|---|---|---|
| GET | `/categories/{slug}/leaderboard` | `metric` (required, from `/taxonomy/ranking-metrics`), `window` (required - `latest`, `1Y`/`3Y`/`5Y`/`7Y`/`10Y`, or current/prior CY/FY), `plan` (Direct\|Regular, required), `group_by=amc` (optional AMC rollup), `limit`, `offset` | Ranked scheme (or AMC) leaderboard for a category+metric+window. Result size is capped relative to category cohort size regardless of `limit`. |

To list funds in a category without ranking, use
`/schemes/search?category={slug}`.

### AMCs - `/amcs/*`

| Method | Path | Params | Description |
|---|---|---|---|
| GET | `/amcs/ranking` | `limit` (≤50) | Top AMCs by total AUM, latest month. |

To list funds by AMC, use `/schemes/search?amc={slug}`.

### Stocks - `/stocks/*`

| Method | Path | Params | Description |
|---|---|---|---|
| GET | `/stocks/search` | `name`, `sector`, `mcap_category`, `limit`, `offset` | Filtered stock listing (not ranked by any computed metric). |
| GET | `/stocks/resolve` | `q` (required), `top` | Fuzzy natural-language → stock slug resolver. |
| GET | `/stocks/by-isin/{isin}` | - | Stock detail by ISIN. |
| GET | `/stocks/{slug}` | - | Full stock detail. |
| GET | `/stocks/{slug}/technicals` | - | Technical indicators. |
| GET | `/stocks/{slug}/earnings` | - | Last 4 quarters of earnings. |
| GET | `/stocks/{slug}/quality` | - | Quality score. |
| GET | `/stocks/{slug}/corp-actions` | - | Corporate actions (splits, bonuses, dividends). |
| GET | `/stocks/{slug}/shareholding` | - | Shareholding pattern by category. |
| GET | `/stocks/{slug}/deals` | `limit` (≤100) | Recent bulk/block deals. |
| GET | `/stocks/{slug}/fo-sentiment` | - | Futures & options sentiment indicators. |

### Indices - `/indices/*`

| Method | Path | Params | Description |
|---|---|---|---|
| GET | `/indices/resolve` | `q` (required), `top` | Fuzzy natural-language → index slug resolver. |
| GET | `/indices/{slug}` | - | Index detail. |
| GET | `/indices/{slug}/technicals` | - | Technical indicators. |
| GET | `/indices/{slug}/earnings` | - | Index-level earnings series. |
| GET | `/indices/{slug}/constituents` | - | Current constituent list. |

### Fund managers - `/taxonomy/fund-managers`

Listed under Taxonomy below (name search only - no full catalog dump).

### Industry / fund flows - `/industry/*`

| Method | Path | Params | Description |
|---|---|---|---|
| GET | `/industry/flows` | `period` (YYYY-MM, default latest), `asset_class`, `flow_reversal` (bool) | All-category fund-flow snapshot for a month: net flows, AUM, folio growth, market share, and derived flow signals per category. |
| GET | `/industry/flows/{slug}` | `months` (≤64) | Time series of the same signals for one category, back to Jan 2021. |

### Taxonomy (reference/enum data) - `/taxonomy/*`

| Method | Path | Params | Description |
|---|---|---|---|
| GET | `/taxonomy/asset-classes` | - | List of asset classes. |
| GET | `/taxonomy/categories` | - | List of fund categories. |
| GET | `/taxonomy/ranking-metrics` | - | Valid `metric` values for `/categories/{slug}/leaderboard` and `/schemes/{slug}/ranks`. |
| GET | `/taxonomy/amcs` | `is_active` | List of AMCs. |
| GET | `/taxonomy/fof-sub-themes` | - | FoF-Overseas sub-theme taxonomy with scheme counts. |
| GET | `/taxonomy/fund-managers` | `q` (required, ≥2 chars), `amc` | Fund manager name search (no unfiltered catalog listing). |

### Compare - `/compare`

| Method | Path | Body | Description |
|---|---|---|---|
| POST | `/compare` | `{"slugs": [...2-3 scheme slugs...], "include": [...], "look_through": bool}` | Compare 2-3 funds in one call. `include` selects response blocks: `returns`, `risk`, `overlap` (pairwise portfolio overlap), `behaviour` (risk/return-behavior similarity). |

---

## Example requests

Resolve a fund name, then pull its 3Y risk metrics:

```bash
curl -s "https://api.punji.ai/v1/schemes/resolve?q=parag+parikh+flexi+cap" \
  -H "X-API-Key: $PUNJI_API_KEY"

curl -s "https://api.punji.ai/v1/schemes/ppfas-flexi-cap-fund/risk?years=3" \
  -H "X-API-Key: $PUNJI_API_KEY"
```

Compare two funds' returns and portfolio overlap:

```bash
curl -s -X POST "https://api.punji.ai/v1/compare" \
  -H "X-API-Key: $PUNJI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "slugs": ["ppfas-flexi-cap-fund", "quant-flexi-cap-fund"],
        "include": ["returns", "risk", "overlap"]
      }'
```

Look up a stock and its recent bulk/block deals:

```bash
curl -s "https://api.punji.ai/v1/stocks/resolve?q=reliance+industries" \
  -H "X-API-Key: $PUNJI_API_KEY"

curl -s "https://api.punji.ai/v1/stocks/reliance-industries/deals?limit=10" \
  -H "X-API-Key: $PUNJI_API_KEY"
```
