{"app":"MF NAV -Open Mutual Fund Data","description":"Every NAV in AMFI's public records: 38,000+ Indian mutual fund schemes, all scheme types (open-ended, closed-ended, interval), April 2006 -present, including matured schemes. Source: AMFI India (Association of Mutual Funds in India).","base_url":"/mf/v1","openapi":"https://api.tigzig.com/mf/v1/openapi.json","docs":"https://api.tigzig.com/mf/v1/docs","data_dictionary":"https://www.tigzig.com/md/mfpro/data-dictionary.md","field_guide":"https://www.tigzig.com/md/mfpro/scheme-universe.md","methodology":"https://www.tigzig.com/md/mfpro/how-the-data-is-built.md","tigzig":"Part of Tigzig: free interactive tools, open-source repos, APIs and MCP servers for analytics and live data across global and Indian markets, macro indicators and filings. Catalog: https://api.tigzig.com/.well-known/api-catalog | Guide: https://www.tigzig.com/llms.txt","stats":{"total_rows":37215991,"total_schemes":38098,"date_range":{"from":"2006-04-01","to":"2026-08-16"}},"endpoints":{"catalog":{"path":"/mf/v1/","method":"GET","description":"This catalog -endpoints, schema, stats"},"nav":{"path":"/mf/v1/nav","method":"GET","description":"NAV data by AMFI code or ISIN. Single-scheme via ?scheme=, bulk via ?schemes= (up to 50). Returns full NAV history unless bounded by since/to. Forgiving inputs: isin/isins accepted as synonyms, param names case-insensitive, a comma list in the singular param routes to bulk, repeated params merge, and in bulk invalid entries never fail the batch (reported in not_found).","params":{"scheme":"AMFI code (numeric, 4-7 digits) or ISIN (12 chars, e.g. INF174K01LT0). Use for single-scheme lookup. `isin=` works as a synonym. All of a scheme's ISINs resolve: payout/growth (ISIN1), IDCW reinvestment (ISIN2), and prior ISINs of renamed schemes - each returns the same full NAV series.","schemes":"Comma-separated list of AMFI codes and/or ISINs, mixed OK. Max 50 per request. Use for bulk. `isins=` works as a synonym; repeated params merge.","latest":"Optional. latest=true returns only the most recent NAV row per scheme (newest within your since/to window, if given). Ideal for 'current NAV' displays - avoids pulling full history for one number.","since":"Optional. NAV from this date onward (YYYY-MM-DD, inclusive).","to":"Optional. NAV up to this date (YYYY-MM-DD, inclusive). Blank = up to latest."},"examples":{"single_amfi":"/mf/v1/nav?scheme=119775","single_isin":"/mf/v1/nav?scheme=INF174K01LT0","single_windowed":"/mf/v1/nav?scheme=119775&since=2024-01-01&to=2024-12-31","bulk_mixed_ids":"/mf/v1/nav?schemes=119775,120468,INF174K01LT0","rest_path_form":"/mf/v1/schemes/119775/nav"},"response_headers":["Last-Modified: the latest NAV date in the response (RFC 7231 HTTP-date).","X-RateLimit-Limit / -Remaining / -Reset: current per-IP budget snapshot."]},"nav_rest":{"path":"/mf/v1/schemes/{code}/nav","method":"GET","description":"REST-canonical single-scheme lookup. {code} accepts AMFI code or ISIN.","example":"/mf/v1/schemes/119775/nav","example_isin":"/mf/v1/schemes/INF174K01LT0/nav"},"search":{"path":"/mf/v1/search","method":"GET","description":"Search AND browse schemes. Text search by name/code, plus metadata filters that work with or without q (pure browse). All text filters are contains-matched and case-insensitive; comma = OR within a filter; different filters AND together; exclude= is the NOT. In-memory, instant (~2ms).","params":{"q":"Scheme-name fragment or numeric scheme code. Min 2 chars. Optional when any filter is present.","amc":"AMC name contains (comma = OR). e.g. amc=icici,aditya birla","group":"Category group contains. 4 values: Equity Scheme, Debt Scheme, Hybrid Scheme, Other Scheme (SEBI 2026 folded Solution Oriented + Fund of Funds into Other Scheme).","category":"SEBI sub-category contains (category=small matches Small Cap Fund). Also matches raw AMFI category text, so old-style pre-2018 schemes (Income, Growth, ELSS) are findable.","type":"Scheme type contains: open / close / interval.","plan":"Direct / Regular / Other.","option":"Growth / IDCW / Bonus / Other.","txic":"TXIC scheme code contains.","isin":"Exact ISIN (comma = OR). Matches payout/growth (isin) AND reinvestment (isin2) identifiers.","active":"true (default for pure-browse) / false / all. NOTE: the live-only default applies to filter-only calls (no q=), which includes ISIN lookups - pass active=all when looking up a scheme that may have matured.","stale":"true/false - data-orphan schemes with only 1-2 NAV rows.","first_date_from":"Launched on/after YYYY-MM-DD.","first_date_to":"Launched on/before YYYY-MM-DD.","last_date_from":"Last NAV on/after YYYY-MM-DD.","last_date_to":"Last NAV on/before YYYY-MM-DD.","exclude":"NOT filter: drop results whose name or AMC contains any of these comma-separated terms.","limit":"Max results per page (default 30, max 100).","offset":"Pagination offset; filter-mode responses include total_matches."},"example":"/mf/v1/search?q=parag parikh","example_browse":"/mf/v1/search?category=small cap&plan=direct&option=growth","example_launch_window":"/mf/v1/search?group=equity&first_date_from=2015-01-01&first_date_to=2020-12-31","note":"q-only calls return the compact legacy shape (scheme_code, scheme_name, isin, isin2, category_sub, is_active, relevance). Any filter present returns enriched rows (all scheme_meta fields) + total_matches + matched_categories. ALWAYS READ isin2 AS WELL AS isin: IDCW-reinvestment unit classes carry their identifier in isin2 and leave isin empty, so ~1,000 schemes look identifier-less if you read isin alone. Zero-match filter calls return the valid vocabulary lists so you can self-correct. STRICT PARAMETERS: an unknown parameter name fails with 400 UNRECOGNIZED_PARAMETER (with did-you-mean + valid list) - a typo can never silently return unfiltered results. Repeated list-filter params MERGE as OR (amc=a&amc=b = amc=a,b); repeated scalars with differing values fail REPEATED_PARAMETER. Hard limits by design: no parentheses/nesting, no per-field NOT (exclude is global, name+AMC text only), no sort parameter - for anything past the filter language, pull /mf/v1/download?format=latest (the full scheme master incl. latest quarterly AAUM) and query locally."},"download":{"path":"/mf/v1/download","method":"GET","description":"Download full NAV dataset as a pre-generated static file","params":{"format":"File format. Full history: csv.gz, csv.zip, tsv.gz, tsv.zip, parquet, sqlite.gz (alias: sqlite), sqlite.zip (filename spellings db.gz / db.zip accepted). Latest-NAV snapshot (one row per scheme, ~38K rows, small): latest (plain CSV), latest.csv.gz, latest.csv.zip, latest.parquet - the FULL SCHEME MASTER: every scheme_meta field + latest quarterly AAUM (aaum_cr_quarterly_avg, aaum_quarter + its ISO twin aaum_quarter_end) + latest NAV. Includes matured schemes' final frozen NAVs (survivorship-bias free); filter is_active for live schemes. Matches the manifest 'format' labels."},"example":"/mf/v1/download?format=parquet","reliability":"These are large binary files (175 MB - 1.4 GB). Every 200 carries Content-Length + ETag + Last-Modified (since 2026-08-01), so verify received bytes against Content-Length (or size_bytes in /downloads/manifest) and integrity-test the archive (gzip -t / unzip -t; parquet starts with PAR1). The download path honours If-None-Match / If-Modified-Since with 304 Not Modified - poll conditionally instead of re-downloading. One caveat before concluding corruption: right after a regeneration, an edge-cached copy can briefly be one generation BEHIND the manifest - a size mismatch on a file that passes its integrity test is staleness, not truncation (the two differ by one day of NAVs). If the archive fails its integrity test or the connection dropped mid-transfer, retry once - the file is usually edge-cached by then and the retry is fast."},"downloads_manifest":{"path":"/mf/v1/downloads/manifest","method":"GET","description":"Download manifest: per-format sizes, row counts, generated_at. Supports ETag/If-None-Match for cheap re-polling (returns 304 Not Modified when unchanged).","example":"/mf/v1/downloads/manifest"}},"schema":{"nav_master":{"columns":["scheme_code","date","nav","scheme_name","isin"],"description":"Daily NAV for all AMFI-registered mutual fund schemes. Both scheme_code (AMFI numeric) and isin (ISO 6166) are 1:1 identifiers for a scheme+plan+option combo."},"scheme_meta":{"columns":["scheme_code","scheme_name","isin","isin2","amc","scheme_type","category","category_sub","category_group_clean","scheme_plan","scheme_option","first_date","last_date","is_active","is_stale","txic_code"],"description":"Scheme master, one row per scheme_code. This is the table every /search filter reads. Full field semantics + caveats: see data_dictionary above.","search_filter_columns":{"amc":"amc","group":"category_group_clean (the cleaned 4-value grouping, NOT the raw category_group)","category":"category_sub, also matching the raw category text (old-style schemes - mostly pre-2018, plus later FMP series under the old headers - have a blank category_sub by design)","type":"scheme_type","plan":"scheme_plan","option":"scheme_option","txic":"txic_code","isin":"isin OR isin2 (Div Reinvestment)","active":"is_active (true = NAV published within the last 45 days, recomputed every sync)","stale":"is_stale (true = data-orphan schemes with only 1-2 NAV rows in AMFI's records)","first_date_from / first_date_to":"first_date","last_date_from / last_date_to":"last_date"}},"latest_snapshot":{"file":"/mf/v1/download?format=latest (also .csv.gz / .csv.zip / .parquet)","description":"The full scheme master + each scheme's latest NAV + latest quarterly AAUM. One row per scheme, ALL ~38,000 (matured schemes carry their final frozen NAV - survivorship-bias free; filter is_active for live only). Rebuilt every sync (3x daily), atomic swap - never half-written.","columns":["scheme_code","isin","isin2","scheme_name","amc","scheme_type","category","category_sub","category_group_clean","category_group","scheme_plan","scheme_option","first_date","last_date","is_active","is_stale","txic_code","aaum_cr_quarterly_avg","aaum_quarter","aaum_quarter_end","nav_date","nav"],"column_notes":{"isin2":"Div Reinvestment ISIN - present only where the IDCW plan has a distinct reinvestment unit class (~6,400 schemes incl. matured). Same scheme_code, same NAV series as `isin`; both resolve on /nav.","category_group":"Raw AMFI group header AS FILED - 20+ values, old and new coexisting through the SEBI Feb-2026 re-filing wave ('Income', 'Income/Debt Oriented Schemes', 'Equity Schemes', 'Fund of Funds Scheme (Domestic)', ...). Useful as a MID-LEVEL grouping between the 4-value category_group_clean and category_sub. For clean 4-way analysis use category_group_clean.","aaum_cr_quarterly_avg":"AMFI's quarterly Average AUM in Crores - the SEBI-standardized average of DAILY net assets over the quarter's calendar days (NOT month-end AUM; will differ from factsheet 'current AUM'). Granularity is the SCHEME code = one plan+option variant: a fund's total AUM = the SUM across its family's codes. NULL where AMFI publishes none (~94% of active schemes covered; matured mostly NULL). A scheme launched mid-quarter is averaged over ALL calendar days, so its first AAUM understates its size.","aaum_quarter":"AMFI's quarter label as filed (e.g. 'June-2026'). Latest AVAILABLE quarter PER SCHEME - AMFI publishes each new quarter AMC-by-AMC over weeks, so quarters legitimately differ across rows. WARNING: sorts alphabetically (March > June) - sort on aaum_quarter_end instead.","aaum_quarter_end":"ISO date twin of aaum_quarter (June-2026 -> 2026-06-30). Sort and filter on this, display the label.","category_group_clean":"The cleaned 4-value grouping: Equity Scheme / Debt Scheme / Hybrid Scheme / Other Scheme (SEBI 2026 folded Solution Oriented + Fund of Funds into Other Scheme). Use THIS for stable 4-way analysis; the raw as-filed header sits beside it in `category_group`.","category_sub":"SEBI sub-category. BLANK by design for ~25,000 old-style schemes AMFI never assigned one - mostly pre-2018 filings, plus later FMP/closed-end series AMFI kept filing under the old Income/Growth headers well past 2018. Their raw text lives in `category`.","is_active":"true = published a NAV within the last 45 days; recomputed every sync.","nav":"For matured schemes this is their FINAL NAV, frozen forever - check nav_date before treating it as current. A small set of matured schemes (~2,300) closed with a final FILED NAV of exactly 0.00 - kept as filed (publish-as-filed policy), so treat a 0.00 on an inactive row as a terminal marker, not a price. In the parquet file nav is a DECIMAL logical type (full as-filed precision): pandas reads it as Python Decimal objects - cast to float before arithmetic (same in the full-history parquet)."}}},"downloads":{"generated_at":"2026-08-16T19:00:07Z","files":{"amfi_nav_master.csv.gz":"236.7 MB","amfi_nav_master.csv.zip":"236.7 MB","amfi_nav_master.tsv.gz":"236.7 MB","amfi_nav_master.tsv.zip":"236.7 MB","amfi_nav_master.parquet":"167.6 MB","amfi_nav_master_latest.csv":"9.3 MB","amfi_nav_master_latest.csv.gz":"1.1 MB","amfi_nav_master_latest.csv.zip":"1.1 MB","amfi_nav_master_latest.parquet":"1.5 MB","amfi_nav_master.db.gz":"1.28 GB","amfi_nav_master.db.zip":"1.28 GB"}},"rate_limit":{"nav_search_manifest":"300 requests per minute per IP.","download_range":"3,000 range requests (HTTP 206) per minute per IP, and 25,000 per day. This is the path a remote DuckDB/pyarrow query takes - one unfiltered scan of the full parquet is roughly 300 range requests, so the daily budget is about 83 full scans.","download_whole_file":"60 whole-file requests (GET/HEAD returning 200/304) per minute per IP, and 500 per day.","concurrency":"Separate from the per-minute limits above: up to 20 requests may be open from one IP at the same moment. This counts requests IN FLIGHT, not requests per minute, so a client firing a wide parallel fan-out can be refused while well under 300/min. Up to 4 execute immediately and the rest queue briefly, so a burst is served slightly slower rather than rejected. Beyond that you get 429 with reason=client_concurrency. Batching with /mf/v1/nav?schemes=A,B,C (up to 50 per call) avoids this entirely - it is both faster and cheaper than parallel single-scheme calls.","reason_values":{"rate":"You exceeded the per-minute limit for your IP. Slow down, or take a bulk download.","client_concurrency":"You had too many requests in flight at once. Reduce parallelism or batch with ?schemes=.","server_concurrency":"Our pool was momentarily saturated across all callers. Nothing is wrong with your integration - honour Retry-After and retry."},"headers":"Rate-limit headers are present on every response, but the set differs by surface. MF endpoints other than /download (origin-served) carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix epoch seconds). /download* (edge-served) carries X-RateLimit-Limit, -Remaining, -Window plus X-RateLimit-Limit-Day, -Remaining-Day, -Window-Day, and no -Reset; its values are for the kind of request you just made, so a 206 reports the range budget and a 200 reports the whole-file budget. THE HEADERS ARE AUTHORITATIVE - read them rather than hardcoding the numbers above. On 429, Retry-After is set and the JSON body carries a `reason` field naming which limit you hit - branch on that rather than on the status code alone, because a rate 429 and a concurrency 429 need different fixes.","note":"Bulk endpoint /nav?schemes=A,B,... (max 50 per call) is the fastest way to fetch many schemes without burning the budget. For full-dataset access use /download. Pace against BOTH the per-minute and the per-day remaining counts on downloads - a job that only watches the per-minute figure can be refused hours later by the daily ceiling."},"error_shape":{"description":"All 4xx and 5xx from this API include a machine-readable `error` object alongside FastAPI's `detail` string.","example":{"detail":"Unrecognized scheme identifier: FOO","error":{"code":"INVALID_IDENTIFIER","message":"Unrecognized scheme identifier: FOO","docs_url":"https://api.tigzig.com/mf/v1/docs"}},"known_codes":["INVALID_IDENTIFIER","INVALID_DATE_FORMAT","BULK_LIMIT_EXCEEDED","MISSING_IDENTIFIER","NOT_FOUND","MANIFEST_UNAVAILABLE","TOO_MANY_REQUESTS","INTERNAL_ERROR"]},"integration_hint":"Please set a descriptive User-Agent with a contact email so we can reach you if a change might affect your integration. Example: `User-Agent: Trackeefy/1.0 (contact@example.com)`. Not enforced. If you expect significant volume, drop a note to amar@harolikar.com and we can discuss a higher rate limit.","source":"https://mfpro.tigzig.com"}