# India API (api.dharun.dev) > Free JSON APIs for Indian data: pincodes, IFSC and banks, GSTIN and PAN checks, holidays and working days, RTO codes, company logos, UPI QR codes, number to words in lakh and crore, and more. No API key, no sign-up, open CORS, an MCP server for AI assistants. Open source under AGPL-3.0. Base URL: https://api.dharun.dev. Every endpoint is a plain GET under `/v1`; endpoints that take text also accept it as a POST body (text/plain, or JSON `{"text": ...}`). No API key and no sign-up. CORS is open, so browsers can call it directly. JSON responses share one shape: `{ "data": ..., "meta": { ... } }`. `meta.source` names the dataset, its licence, version and the credit it asks for. Lists add `meta.total`, `meta.limit` and `meta.offset`. Errors are `{ "error": { "code", "message" } }` with a matching HTTP status: 400 for bad input, 404 when nothing matches, 429 over the rate limit, 503 while a dataset is not loaded. Rate limit: 600 requests per minute per client; endpoints that do heavy work (images, astronomy, live DNS) count as 10. Image endpoints return the image itself. # Company logos API > Logos and details for companies listed on NSE and BSE. Put a ticker in the URL and get the logo back as SVG or PNG. A symbol can be a ticker (TCS), an exchange-qualified ticker (NSE:TCS, NSE_TCS), a Yahoo Finance symbol (TCS.NS, AAIL.BO) or an ISIN. A bare ticker prefers NSE. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Logo image for a listed company `GET /v1/logos/{symbol}` Returns the image itself, ready for an tag. Unknown symbols return 404 unless fallback=monogram is set. Parameters: - `symbol` (path, required): Ticker, exchange-qualified ticker, Yahoo symbol or ISIN. A .svg or .png suffix selects the format. - `format` (query): Image format. Default svg. One of: svg, png. - `size` (query): PNG width and height in pixels, 16 to 512. Default 128. - `fallback` (query): Return an initials tile instead of 404 for unknown symbols. One of: monogram. - `exchange` (query): Force an exchange. One of: nse, bse. Example: https://api.dharun.dev/v1/logos/TCS (returns the image itself) ## Details of a listed company `GET /v1/companies/{symbol}` Name, sector, industry, ISIN, market capitalisation, index memberships and logo URLs. Parameters: - `symbol` (path, required): Ticker, exchange-qualified ticker, Yahoo symbol or ISIN. - `exchange` (query): Force an exchange. One of: nse, bse. Example: https://api.dharun.dev/v1/companies/RELIANCE Response, with lists and long text shortened: ```json { "data": { "id": "NSE:RELIANCE", "exchange": "NSE", "ticker": "RELIANCE", "company": "Reliance Industries Limited", "sector": "Energy Minerals", "industry": "Oil Refining/Marketing", "oneLine": "Reliance Industries Limited operates in the Oil Refining/Marketing industry within the Energy Minerals sector.", "isin": "INE002A01018", "currency": "INR", "marketCap": 18484771071653, "isIndexConstituent": true, "indexes": [ "Nifty 50", "Nifty 500", "Nifty Infrastructure" ], "logo": { "png": "https://api.dharun.dev/v1/logos/NSE:RELIANCE?format=png&size=128", "svg": "https://api.dharun.dev/v1/logos/NSE:RELIANCE" }, "links": { "self": "https://api.dharun.dev/v1/companies/NSE:RELIANCE" } }, "meta": { "source": { "name": "Indian listed company logos", "url": "https://github.com/dharunashokkumar/api.dharun.dev", "licence": "Logos are trademarks of the companies they identify", "retrieved": "2026-04-29", "attribution": "Company logos and trademarks belong to their respective owners." } } } ``` ## Search listed companies `GET /v1/companies` Searches ticker, company name, sector, industry, ISIN and index names. Best match first. Parameters: - `q` (query): Search text. - `exchange` (query): Limit to one exchange. One of: nse, bse. - `sector` (query): Exact sector name. - `index` (query): Index name, for example Nifty 50. - `limit` (query): Results per page, 1 to 100. - `offset` (query): Results to skip. Example: https://api.dharun.dev/v1/companies?q=tata&limit=5 Response, with lists and long text shortened: ```json { "data": [ { "id": "NSE:TATASTEEL", "exchange": "NSE", "ticker": "TATASTEEL", "company": "Tata Steel Limited", "sector": "Non-Energy Minerals", "industry": "Steel", "oneLine": "Tata Steel Limited operates in the Steel industry within the Non-Energy Minerals sector.", "isin": "INE081A01020", "currency": "INR", "marketCap": 2665234130371, "isIndexConstituent": true, "indexes": [ "Nifty 50", "Nifty 500", "Nifty Metal" ], "logo": { "png": "https://api.dharun.dev/v1/logos/NSE:TATASTEEL?format=png&size=128", "svg": "https://api.dharun.dev/v1/logos/NSE:TATASTEEL" }, "links": { "self": "https://api.dharun.dev/v1/companies/NSE:TATASTEEL" } }, { "id": "NSE:TATAPOWER", "exchange": "NSE", "ticker": "TATAPOWER", "company": "Tata Power Company Limited", "sector": "Utilities", "industry": "Electric Utilities", "oneLine": "Tata Power Company Limited operates in the Electric Utilities industry within the Utilities sector.", "isin": "INE245A01021", "currency": "INR", "marketCap": 1448766954960, "isIndexConstituent": true, "indexes": [ "Nifty 500", "Nifty Next 50", "Nifty Infrastructure" ], "logo": { "png": "https://api.dharun.dev/v1/logos/NSE:TATAPOWER?format=png&size=128", "svg": "https://api.dharun.dev/v1/logos/NSE:TATAPOWER" }, "links": { "self": "https://api.dharun.dev/v1/companies/NSE:TATAPOWER" } }, { "id": "NSE:TATACAP", "exchange": "NSE", "ticker": "TATACAP", "company": "Tata Capital Ltd.", "sector": "Finance", "industry": "Finance/Rental/Leasing", "oneLine": "Tata Capital Ltd. operates in the Finance/Rental/Leasing industry within the Finance sector.", "isin": "INE976I01016", "currency": "INR", "marketCap": 1415663811500, "isIndexConstituent": true, "indexes": [ "Nifty 500", "Nifty Next 50", "Nifty 200" ], "logo": { "png": "https://api.dharun.dev/v1/logos/NSE:TATACAP?format=png&size=128", "svg": "https://api.dharun.dev/v1/logos/NSE:TATACAP" }, "links": { "self": "https://api.dharun.dev/v1/companies/NSE:TATACAP" } } ], "meta": { "total": 17, "limit": 5, "offset": 0, "source": { "name": "Indian listed company logos", "url": "https://github.com/dharunashokkumar/api.dharun.dev", "licence": "Logos are trademarks of the companies they identify", "retrieved": "2026-04-29", "attribution": "Company logos and trademarks belong to their respective owners." } } } ``` ## Data source - [Indian listed company logos](https://github.com/dharunashokkumar/api.dharun.dev), retrieved 2026-04-29. Licence: Logos are trademarks of the companies they identify. Company logos and trademarks belong to their respective owners. ## Guides - [Show NSE and BSE company logos in your app](https://api.dharun.dev/guides/company-logos.md): Put a listed company's logo in an img tag by ticker or ISIN, as SVG or sized PNG, with an initials tile when no logo exists. --- # IFSC and banks API > IFSC to bank and branch. Branch details for every IFSC in the Reserve Bank's NEFT and RTGS lists: bank, branch, address, MICR and which payment systems the branch supports. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Branch for an IFSC `GET /v1/ifsc/{code}` Parameters: - `code` (path, required): 11-character IFSC. Example: https://api.dharun.dev/v1/ifsc/SBIN0000001 Response: ```json { "data": { "ifsc": "SBIN0000001", "bank": { "code": "SBIN", "name": "State Bank of India" }, "branch": "KOLKATA MAIN", "address": "SAMRIDDHI BHAWAN, 1 STRAND ROAD, KOLKATA 700 001", "city": "Kolkata", "centre": "Kolkata", "district": "Kolkata", "stateCode": "WB", "state": "West Bengal", "contact": null, "micr": "700002021", "swift": null, "imps": true, "neft": true, "rtgs": true, "upi": true }, "meta": { "source": { "name": "IFSC dataset", "url": "https://github.com/razorpay/ifsc/releases/tag/v2.0.62", "licence": "Public domain (dataset), as stated by the publisher", "version": "v2.0.62", "retrieved": "2026-10-13", "attribution": "IFSC data from the open razorpay/ifsc dataset, compiled from Reserve Bank of India and NPCI publications." } } } ``` ## Search a bank's branches `GET /v1/ifsc` Lists branches of one bank, filtered by state, city or text in the branch name or address. Parameters: - `bank` (query, required): Four-letter bank code, for example SBIN. - `q` (query): Text to find in the branch name, address or city. - `state` (query): State code or name, for example TN or Tamil Nadu. - `city` (query): Exact city name. - `limit` (query): Results per page, 1 to 100. - `offset` (query): Results to skip. Example: https://api.dharun.dev/v1/ifsc?bank=SBIN&state=TN&q=namakkal Response, with lists and long text shortened: ```json { "data": [ { "ifsc": "SBIN0011060", "bank": { "code": "SBIN", "name": "State Bank of India" }, "branch": "PARAMATHY VELUR", "address": "DIST NAMAKKAL, TAMIL NADU", "city": "Erode", "centre": "Paramathi", "district": "Paramathi", "stateCode": "TN", "state": "Tamil Nadu", "contact": null, "micr": "638002870", "swift": null, "imps": true, "neft": true, "rtgs": true, "upi": true }, { "ifsc": "SBIN0062472", "bank": { "code": "SBIN", "name": "State Bank of India" }, "branch": "R AND DB RACC NAMAKKAL", "address": "NO.2 DR. SANKARAN ROAD, NAMAKKAL 637001", "city": "Erode", "centre": "Erode", "district": "Erode", "stateCode": "TN", "state": "Tamil Nadu", "contact": null, "micr": null, "swift": null, "imps": true, "neft": true, "rtgs": true, "upi": true }, { "ifsc": "SBIN0018751", "bank": { "code": "SBIN", "name": "State Bank of India" }, "branch": "ERUMAIPATTI", "address": "THURAIYUR MAIN ROAD, ERUMAIPATTI, DIST.NAMAKKAL, TN-637013", "city": "Namakkal", "centre": "Erumaipatti", "district": "Erumaipatti", "stateCode": "TN", "state": "Tamil Nadu", "contact": "+919445864441", "micr": "636002135", "swift": null, "imps": true, "neft": true, "rtgs": true, "upi": true } ], "meta": { "total": 19, "limit": 20, "offset": 0, "source": { "name": "IFSC dataset", "url": "https://github.com/razorpay/ifsc/releases/tag/v2.0.62", "licence": "Public domain (dataset), as stated by the publisher", "version": "v2.0.62", "retrieved": "2026-10-13", "attribution": "IFSC data from the open razorpay/ifsc dataset, compiled from Reserve Bank of India and NPCI publications." } } } ``` ## Bank for a four-letter code `GET /v1/banks/{code}` Parameters: - `code` (path, required): Four-letter bank code. Example: https://api.dharun.dev/v1/banks/HDFC Response: ```json { "data": { "code": "HDFC", "name": "HDFC Bank", "type": "Private", "micr": "400240001", "upi": true, "branches": 11007 }, "meta": { "source": { "name": "IFSC dataset", "url": "https://github.com/razorpay/ifsc/releases/tag/v2.0.62", "licence": "Public domain (dataset), as stated by the publisher", "version": "v2.0.62", "retrieved": "2026-10-13", "attribution": "IFSC data from the open razorpay/ifsc dataset, compiled from Reserve Bank of India and NPCI publications." } } } ``` ## Search banks `GET /v1/banks` Finds banks by name or code, largest branch network first. Parameters: - `q` (query): Text to find in the bank name or code. - `limit` (query): Results per page, 1 to 100. - `offset` (query): Results to skip. Example: https://api.dharun.dev/v1/banks?q=gramin Response, with lists and long text shortened: ```json { "data": [ { "code": "PKGB", "name": "Karnataka Gramin Bank", "upi": false, "branches": 1818 }, { "code": "RMGB", "name": "Rajasthan Marudhara Gramin Bank", "upi": false, "branches": 1650 }, { "code": "MAHG", "name": "Maharashtra Gramin Bank", "upi": false, "branches": 778 } ], "meta": { "total": 44, "limit": 50, "offset": 0, "source": { "name": "IFSC dataset", "url": "https://github.com/razorpay/ifsc/releases/tag/v2.0.62", "licence": "Public domain (dataset), as stated by the publisher", "version": "v2.0.62", "retrieved": "2026-10-13", "attribution": "IFSC data from the open razorpay/ifsc dataset, compiled from Reserve Bank of India and NPCI publications." } } } ``` ## Data source - [IFSC dataset](https://github.com/razorpay/ifsc/releases/tag/v2.0.62), v2.0.62, retrieved 2026-10-13. Licence: Public domain (dataset), as stated by the publisher. IFSC data from the open razorpay/ifsc dataset, compiled from Reserve Bank of India and NPCI publications. ## Guides - [Show the bank and branch for an IFSC code](https://api.dharun.dev/guides/ifsc-bank-branch.md): Turn an IFSC into a bank name, branch and address, and check that the branch takes NEFT, RTGS, IMPS or UPI before you send money there. --- # QR codes and barcodes API > QR codes, UPI payment QR codes and barcodes as SVG or PNG. Generates codes; it does not read them. What you encode is never logged or kept, and the images are not cached by shared caches. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## QR code for any text `GET /v1/qr`, also `POST` Returns the image itself. Text up to about 2,900 bytes at error correction L. POST body: The text to encode. Send it as `text/plain`, or as JSON `{"text": "..."}` with the other options beside it. What you send is never written to the log, and the answer is not cached. Parameters: - `text` (query): Text to encode (or POST it). - `ecc` (query): Error correction: how much damage the code survives. Default M. One of: L, M, Q, H. - `format` (query): Image format. Default svg. One of: svg, png. - `size` (query): 2D codes: width in pixels to stay within, 32 to 2048. Default 256. - `margin` (query): Light border (quiet zone), in modules, 0 to 16. Default 4. - `fg` (query): Dark colour, hex such as 000000. Default black. - `bg` (query): Light colour, hex, or transparent. Default white. Example: https://api.dharun.dev/v1/qr?text=https://api.dharun.dev&format=png&size=256 (returns the image itself) ## UPI payment QR code `GET /v1/upi-qr` A QR code any UPI app can scan to pay, built to NPCI's upi://pay link format. format=json returns the link instead of the image. Nothing is checked with a bank. What you send is never written to the log, and the answer is not cached. Parameters: - `pa` (query, required): Payee UPI ID, such as shop@okaxis. - `pn` (query): Payee name shown in the app. - `am` (query): Amount in rupees, up to two decimals. Leave out to let the payer type it. - `tn` (query): Note shown with the payment, up to 80 characters. - `tr` (query): Your reference for the transaction. - `mc` (query): Merchant category code, four digits. - `format` (query): Image format. Default svg. One of: svg, png. - `size` (query): 2D codes: width in pixels to stay within, 32 to 2048. Default 256. - `margin` (query): Light border (quiet zone), in modules, 0 to 16. Default 4. - `fg` (query): Dark colour, hex such as 000000. Default black. - `bg` (query): Light colour, hex, or transparent. Default white. Example: https://api.dharun.dev/v1/upi-qr?pa=shop@okaxis&pn=Sri%20Murugan%20Stores&am=250&tn=Order%2042 (returns the image itself) ## Barcode `GET /v1/barcode/{type}`, also `POST` Linear barcodes (code128, code39, code93, ean13, ean8, itf, codabar) and 2D codes (datamatrix, pdf417, aztec). Linear codes are sized with scale and height, 2D codes with size. No human-readable text is printed under the bars. POST body: The text to encode. Send it as `text/plain`, or as JSON `{"text": "..."}` with the other options beside it. What you send is never written to the log, and the answer is not cached. Parameters: - `type` (path, required): Kind of barcode. One of: code128, code39, code93, ean13, ean8, itf, codabar, datamatrix, pdf417, aztec. - `text` (query): Text to encode (or POST it). - `scale` (query): Linear codes: pixels per bar module, 1 to 10. Default 2. - `height` (query): Linear codes: bar height in pixels, 10 to 600. Default 80. - `format` (query): Image format. Default svg. One of: svg, png. - `size` (query): 2D codes: width in pixels to stay within, 32 to 2048. Default 256. - `margin` (query): Light border, in modules, 0 to 16. The default depends on the code. - `fg` (query): Dark colour, hex such as 000000. Default black. - `bg` (query): Light colour, hex, or transparent. Default white. Example: https://api.dharun.dev/v1/barcode/ean13?text=890123456789 (returns the image itself) ## Guides - [Make a UPI payment QR code for an amount](https://api.dharun.dev/guides/upi-qr-code.md): Generate a QR code that any UPI app can scan to pay a set amount to your UPI ID, or a upi://pay link for a button on mobile. --- # HSN and SAC codes API > GST classification codes for goods and services. Every HSN code for goods (from the Customs Tariff Act) and SAC code for services (from the GST services classification) with its description, the codes above it and the codes below it. GST rates are not included. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## A code, its parents and children `GET /v1/hsn/{code}` Parameters: - `code` (path, required): 2 to 8 digits; spaces and dots are ignored. SAC codes start with 99. Example: https://api.dharun.dev/v1/hsn/0902 Response, with lists and long text shortened: ```json { "data": { "code": "0902", "kind": "hsn", "level": "heading", "description": "TEA, WHETHER OR NOT FLAVOURED", "parents": [ { "code": "09", "kind": "hsn", "level": "chapter", "description": "Coffee, tea, mate and spices" } ], "children": [ { "code": "090210", "kind": "hsn", "level": "subheading", "description": "GREEN TEA (NOT FERMENTED) IN IMMEDIATE PACKINGS OF A CONTENT NOT EXCEEDING 2" }, { "code": "090220", "kind": "hsn", "level": "subheading", "description": "OTHER GREEN TEA (NOT FERMENTED):" }, { "code": "090230", "kind": "hsn", "level": "subheading", "description": "BLACK TEA (FERMENTED) AND PARTLY FERMENTED TEA, IN IMMEDIATE PACKINGS OF A CONTENT NOT EXCEEDING 3 KG. :" } ] }, "meta": { "source": { "name": "HSN and SAC codes", "url": "https://tutorial.gst.gov.in/downloads/HSN_SAC.xlsx", "licence": "Statute and gazette notification; reproduction permitted by section 52(1)(q) of the Copyright Act, 1957", "version": "051108e31063", "retrieved": "2026-10-13", "attribution": "HSN codes from the First Schedule to the Customs Tariff Act, 1975, and SAC codes from the annexure to notification 11/2017-Central Tax (Rate), in the copy publi…" }, "note": "Codes and descriptions only; GST rates are not included. Descriptions are as published, including their capitals." } } ``` ## Search codes `GET /v1/hsn` Every word of q must appear in the description; digits search by code prefix. Broader codes come first. Parameters: - `q` (query, required): Words of the description, or the start of a code. - `kind` (query): hsn for goods, sac for services. One of: hsn, sac. - `limit` (query): Results per page, 1 to 100. - `offset` (query): Results to skip. Example: https://api.dharun.dev/v1/hsn?q=green%20tea Response, with lists and long text shortened: ```json { "data": [ { "code": "090210", "kind": "hsn", "level": "subheading", "description": "GREEN TEA (NOT FERMENTED) IN IMMEDIATE PACKINGS OF A CONTENT NOT EXCEEDING 2" }, { "code": "090220", "kind": "hsn", "level": "subheading", "description": "OTHER GREEN TEA (NOT FERMENTED):" }, { "code": "09022010", "kind": "hsn", "level": "tariff_item", "description": "GREEN TEA IN PACKETS WITH CONTENTS EXCEEDING KG. 3 KG. BUT NOT EXCEEDING 20 KG." } ], "meta": { "total": 6, "limit": 20, "offset": 0, "source": { "name": "HSN and SAC codes", "url": "https://tutorial.gst.gov.in/downloads/HSN_SAC.xlsx", "licence": "Statute and gazette notification; reproduction permitted by section 52(1)(q) of the Copyright Act, 1957", "version": "051108e31063", "retrieved": "2026-10-13", "attribution": "HSN codes from the First Schedule to the Customs Tariff Act, 1975, and SAC codes from the annexure to notification 11/2017-Central Tax (Rate), in the copy publi…" }, "note": "Codes and descriptions only; GST rates are not included. Descriptions are as published, including their capitals." } } ``` ## Data source - [HSN and SAC codes](https://tutorial.gst.gov.in/downloads/HSN_SAC.xlsx), 051108e31063, retrieved 2026-10-13. Licence: Statute and gazette notification; reproduction permitted by section 52(1)(q) of the Copyright Act, 1957. HSN codes from the First Schedule to the Customs Tariff Act, 1975, and SAC codes from the annexure to notification 11/2017-Central Tax (Rate), in the copy published on the GST portal. --- # Mutual fund NAVs API > Latest net asset value of every Indian mutual fund scheme. Every scheme in AMFI's daily NAV file: fund house, category, plan (direct or regular), option (growth, IDCW or bonus), ISINs and the latest NAV with its date. Refreshed by the server several times a day; AMFI publishes each evening. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## A scheme and its NAV `GET /v1/mutual-funds/{code}` Parameters: - `code` (path, required): AMFI scheme code, or the scheme's growth or reinvestment ISIN. Example: https://api.dharun.dev/v1/mutual-funds/122639 Response, with lists and long text shortened: ```json { "data": { "code": 122639, "name": "Parag Parikh Flexi Cap Fund", "fundHouse": "PPFAS Mutual Fund", "type": "Open Ended", "category": "Equity Scheme - Flexi Cap Fund", "plan": "direct", "option": "growth", "planLabel": "Direct Plan", "optionLabel": "Growth", "isinGrowth": "INF879O01027", "isinReinvestment": null, "nav": 89.5841, "navDate": "2026-10-13", "active": true }, "meta": { "source": { "name": "Net asset values of mutual fund schemes", "url": "https://www.amfiindia.com/net-asset-value", "licence": "Published by AMFI under SEBI's disclosure rules", "version": "e73faa484a18", "retrieved": "2026-10-14T17:39:57Z", "attribution": "Net asset values as published by the Association of Mutual Funds in India." }, "note": "NAV as published by AMFI for the date given. A scheme is active when its NAV is no more than 30 days older than the newest NAV in AMFI's file (see meta.source.r…" } } ``` ## Search schemes `GET /v1/mutual-funds` Every word of q must appear in the scheme name, in any order. Only active schemes unless all=true. Parameters: - `q` (query): Words of the scheme name. - `fundHouse` (query): Part of the fund house name, such as hdfc. - `category` (query): Part of the SEBI category, such as Small Cap. - `plan` (query): Plan. One of: direct, regular. - `option` (query): Option. One of: growth, idcw, bonus. - `all` (query): Include wound-up and matured schemes. One of: true. - `limit` (query): Results per page, 1 to 100. - `offset` (query): Results to skip. Example: https://api.dharun.dev/v1/mutual-funds?q=flexi%20cap&plan=direct&option=growth Response, with lists and long text shortened: ```json { "data": [ { "code": 151796, "name": "360 ONE Flexicap Fund", "fundHouse": "360 ONE Mutual Fund", "type": "Open Ended", "category": "Equity Schemes - Flexi Cap Fund", "plan": "direct", "option": "growth", "planLabel": "Direct Plan", "optionLabel": "GROWTH Option", "isinGrowth": "INF579M01AS1", "isinReinvestment": null, "nav": 16.9108, "navDate": "2026-10-14", "active": true }, { "code": 154043, "name": "Abakkus Flexi Cap Fund", "fundHouse": "Abakkus Mutual Fund", "type": "Open Ended", "category": "Equity Scheme - Flexi Cap Fund", "plan": "direct", "option": "growth", "planLabel": "Direct Plan", "optionLabel": "Growth", "isinGrowth": "INF2JJD01136", "isinReinvestment": null, "nav": 10.739, "navDate": "2026-10-14", "active": true }, { "code": 120564, "name": "Aditya Birla Sun Life Flexi Cap Fund", "fundHouse": "Aditya Birla Sun Life Mutual Fund", "type": "Open Ended", "category": "Equity Scheme - Flexi Cap Fund", "plan": "direct", "option": "growth", "planLabel": "Direct Plan", "optionLabel": "GROWTH", "isinGrowth": "INF209K01XX1", "isinReinvestment": null, "nav": 2120.03, "navDate": "2026-10-14", "active": true } ], "meta": { "total": 50, "limit": 20, "offset": 0, "source": { "name": "Net asset values of mutual fund schemes", "url": "https://www.amfiindia.com/net-asset-value", "licence": "Published by AMFI under SEBI's disclosure rules", "version": "e73faa484a18", "retrieved": "2026-10-14T17:39:57Z", "attribution": "Net asset values as published by the Association of Mutual Funds in India." }, "note": "NAV as published by AMFI for the date given. A scheme is active when its NAV is no more than 30 days older than the newest NAV in AMFI's file (see meta.source.r…" } } ``` ## Fund houses `GET /v1/mutual-funds/fund-houses` Example: https://api.dharun.dev/v1/mutual-funds/fund-houses Response, with lists and long text shortened: ```json { "data": [ { "name": "360 ONE Mutual Fund", "schemes": 45, "activeSchemes": 45 }, { "name": "ASK MUTUAL FUND", "schemes": 8, "activeSchemes": 8 }, { "name": "Abakkus Mutual Fund", "schemes": 19, "activeSchemes": 19 } ], "meta": { "total": 55, "source": { "name": "Net asset values of mutual fund schemes", "url": "https://www.amfiindia.com/net-asset-value", "licence": "Published by AMFI under SEBI's disclosure rules", "version": "e73faa484a18", "retrieved": "2026-10-14T17:39:57Z", "attribution": "Net asset values as published by the Association of Mutual Funds in India." } } } ``` ## Data source - [Net asset values of mutual fund schemes](https://www.amfiindia.com/net-asset-value), e73faa484a18, retrieved 2026-10-14T17:39:57Z. Licence: Published by AMFI under SEBI's disclosure rules. Net asset values as published by the Association of Mutual Funds in India. --- # Number to words API > Numbers and rupee amounts in words, the Indian way. Spells numbers with lakh and crore in English, Hindi or Tamil. 1,00,000 is "one lakh". Use style=currency for cheque-style amounts. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Spell out a number `GET /v1/words/{number}` Parameters: - `number` (path, required): The number. Commas, spaces and underscores are ignored. - `lang` (query): Language. Default en. One of: en, hi, ta. - `style` (query): currency gives rupees and paise. Default number. One of: number, currency. Example: https://api.dharun.dev/v1/words/1,25,000.50?style=currency Response: ```json { "data": { "input": "1,25,000.50", "number": "125000.50", "language": "en", "style": "currency", "words": "one lakh twenty-five thousand rupees and fifty paise only" }, "meta": {} } ``` ## Guides - [Write rupee amounts in words for invoices and cheques](https://api.dharun.dev/guides/amount-in-words.md): Spell an amount the Indian way, with lakh and crore, rupees and paise, in English, Hindi or Tamil. --- # Format checks API > Check the format of a GSTIN, PAN or IFSC. Structural checks only: character pattern, state code and, for GSTIN, the check character. Nothing is looked up with a government system, and these values are never written to the request log. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Check an identifier's format `GET /v1/validate/{kind}/{value}` What you send is never written to the log, and the answer is not cached. Parameters: - `kind` (path, required): Which identifier. One of: gstin, pan, ifsc. - `value` (path, required): The identifier to check. Example: https://api.dharun.dev/v1/validate/gstin/27AAPFU0939F1ZV Response: ```json { "data": { "kind": "gstin", "normalized": "27AAPFU0939F1ZV", "valid": true, "parts": { "entityNumber": "1", "holderType": "Firm or Limited Liability Partnership", "pan": "AAPFU0939F", "state": "Maharashtra", "stateCode": "27" } }, "meta": { "note": "This checks the format only. It does not confirm that the identifier was ever issued." } } ``` ## Guides - [Check a GSTIN or PAN before you save it](https://api.dharun.dev/guides/gstin-pan-check.md): Catch typing mistakes in GSTINs and PANs with the check character, and read the state and PAN out of a GSTIN, in JavaScript. - [Show the bank and branch for an IFSC code](https://api.dharun.dev/guides/ifsc-bank-branch.md): Turn an IFSC into a bank name, branch and address, and check that the branch takes NEFT, RTGS, IMPS or UPI before you send money there. --- # Pincodes API > Pincode to post office, district and state. Every post office in the Department of Posts directory, with its district, state, postal division and coordinates. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Post offices for a pincode `GET /v1/pincode/{pincode}` Returns the district and state of the pincode and every post office that uses it. Parameters: - `pincode` (path, required): Six-digit pincode. Example: https://api.dharun.dev/v1/pincode/637001 Response, with lists and long text shortened: ```json { "data": { "pincode": "637001", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "offices": [ { "name": "Namakkal H.O", "type": "Head Office", "delivery": true, "division": "Namakkal", "region": "Western Region, Coimbatore", "circle": "Tamilnadu", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "latitude": 11.2155833, "longitude": 78.1702778 }, { "name": "Namakkal Bazaar S.O", "type": "Post Office", "delivery": false, "division": "Namakkal", "region": "Western Region, Coimbatore", "circle": "Tamilnadu", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "latitude": 11.2240556, "longitude": 78.1703333 }, { "name": "Namakkal Fort S.O", "type": "Post Office", "delivery": false, "division": "Namakkal", "region": "Western Region, Coimbatore", "circle": "Tamilnadu", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "latitude": 11.238, "longitude": 78.166 } ] }, "meta": { "source": { "name": "All India Pincode Directory", "url": "https://www.data.gov.in/resource/all-india-pincode-directory-till-last-month", "licence": "Government Open Data License - India (GODL)", "version": "23760720 bytes", "retrieved": "2026-10-13", "attribution": "Contains data from the All India Pincode Directory, Department of Posts, published on data.gov.in under the Government Open Data License - India." } } } ``` ## Search post offices `GET /v1/pincode` Find post offices by the start of their name, by the start of a pincode, or list a district. Parameters: - `q` (query): Start of a post office name (2+ characters) or start of a pincode. - `state` (query): State code or name, for example TN or Tamil Nadu. - `district` (query): Exact district name. - `limit` (query): Results per page, 1 to 100. - `offset` (query): Results to skip. Example: https://api.dharun.dev/v1/pincode?q=namakkal&state=TN Response, with lists and long text shortened: ```json { "data": [ { "pincode": "637001", "name": "Namakkal Bazaar S.O", "type": "Post Office", "delivery": false, "division": "Namakkal", "region": "Western Region, Coimbatore", "circle": "Tamilnadu", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "latitude": 11.2240556, "longitude": 78.1703333 }, { "pincode": "637003", "name": "Namakkal District Court Buildings S.O", "type": "Post Office", "delivery": false, "division": "Namakkal", "region": "Western Region, Coimbatore", "circle": "Tamilnadu", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "latitude": 11.2497338, "longitude": 78.1265014 }, { "pincode": "637001", "name": "Namakkal Fort S.O", "type": "Post Office", "delivery": false, "division": "Namakkal", "region": "Western Region, Coimbatore", "circle": "Tamilnadu", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "latitude": 11.238, "longitude": 78.166 } ], "meta": { "total": 4, "limit": 20, "offset": 0, "source": { "name": "All India Pincode Directory", "url": "https://www.data.gov.in/resource/all-india-pincode-directory-till-last-month", "licence": "Government Open Data License - India (GODL)", "version": "23760720 bytes", "retrieved": "2026-10-13", "attribution": "Contains data from the All India Pincode Directory, Department of Posts, published on data.gov.in under the Government Open Data License - India." } } } ``` ## Post offices near a point `GET /v1/pincode/near` Post offices within a radius of a latitude and longitude, nearest first, with the distance. Positions come from the Department of Posts and some are approximate. Parameters: - `lat` (query, required): Latitude in decimal degrees. - `lng` (query, required): Longitude in decimal degrees. - `radius` (query): Kilometres, 1 to 50. Default 5. - `limit` (query): Results, 1 to 100. Default 10. Example: https://api.dharun.dev/v1/pincode/near?lat=11.2189&lng=78.1674&radius=5 Response, with lists and long text shortened: ```json { "data": [ { "pincode": "636142", "name": "Mullukurichi S.O", "type": "Post Office", "delivery": true, "division": "Salem East", "region": "Western Region, Coimbatore", "circle": "Tamilnadu", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "latitude": 11.2155833, "longitude": 78.1702778, "distanceKm": 0.48 }, { "pincode": "637001", "name": "Namakkal H.O", "type": "Head Office", "delivery": true, "division": "Namakkal", "region": "Western Region, Coimbatore", "circle": "Tamilnadu", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "latitude": 11.2155833, "longitude": 78.1702778, "distanceKm": 0.48 }, { "pincode": "637411", "name": "Semmedu S.O", "type": "Post Office", "delivery": true, "division": "Namakkal", "region": "Western Region, Coimbatore", "circle": "Tamilnadu", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "latitude": 11.2155833, "longitude": 78.1702778, "distanceKm": 0.48 } ], "meta": { "total": 20, "limit": 10, "offset": 0, "source": { "name": "All India Pincode Directory", "url": "https://www.data.gov.in/resource/all-india-pincode-directory-till-last-month", "licence": "Government Open Data License - India (GODL)", "version": "23760720 bytes", "retrieved": "2026-10-13", "attribution": "Contains data from the All India Pincode Directory, Department of Posts, published on data.gov.in under the Government Open Data License - India." }, "note": "Positions come from the Department of Posts directory, where about one office in ten has none and some are approximate. The nearest office is not always the one…" } } ``` ## Data source - [All India Pincode Directory](https://www.data.gov.in/resource/all-india-pincode-directory-till-last-month), 23760720 bytes, retrieved 2026-10-13. Licence: Government Open Data License - India (GODL). Contains data from the All India Pincode Directory, Department of Posts, published on data.gov.in under the Government Open Data License - India. ## Guides - [Fill city and state from a pincode in a web form](https://api.dharun.dev/guides/pincode-autofill.md): Look up the district and state as soon as someone types a six-digit pincode, with plain JavaScript and no API key. --- # RTO codes API > Vehicle registration code to transport office. Which Regional Transport Office a number plate belongs to: TN-28 is Namakkal (North). Accepts a code or a whole registration number. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Office for an RTO code `GET /v1/rto/{code}` Parameters: - `code` (path, required): RTO code (TN-28, TN28) or a registration number (TN28AB1234). Example: https://api.dharun.dev/v1/rto/TN-28 Response, with lists and long text shortened: ```json { "data": { "code": "TN-28", "office": "Namakkal (North)", "jurisdiction": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "notes": null }, "meta": { "source": { "name": "List of Regional Transport Office districts in India", "url": "https://en.wikipedia.org/w/index.php?title=List_of_Regional_Transport_Office_districts_in_India&oldid=1377425763", "licence": "CC BY-SA 4.0", "version": "revision 1377425763", "retrieved": "2026-10-13", "attribution": "RTO codes adapted from the Wikipedia article \"List of Regional Transport Office districts in India\", licensed CC BY-SA 4.0. This dataset is shared under the sam…" } } } ``` ## List or search RTO codes `GET /v1/rto` Parameters: - `state` (query): State code or name, for example TN or Tamil Nadu. - `q` (query): Text to find in the office name or jurisdiction. - `limit` (query): Results per page, 1 to 100. - `offset` (query): Results to skip. Example: https://api.dharun.dev/v1/rto?state=TN&q=chennai Response, with lists and long text shortened: ```json { "data": [ { "code": "TN-01", "office": "Chennai (Central): Ayanavaram", "jurisdiction": "Chennai", "stateCode": "TN", "state": "Tamil Nadu", "notes": "SETC & MTC buses are registered here under TN 01 N XXXX." }, { "code": "TN-02", "office": "Chennai (North West): Anna Nagar", "jurisdiction": "Chennai", "stateCode": "TN", "state": "Tamil Nadu", "notes": null }, { "code": "TN-03", "office": "Chennai (North East): Tondiarpet", "jurisdiction": "Chennai", "stateCode": "TN", "state": "Tamil Nadu", "notes": null } ], "meta": { "total": 11, "limit": 50, "offset": 0, "source": { "name": "List of Regional Transport Office districts in India", "url": "https://en.wikipedia.org/w/index.php?title=List_of_Regional_Transport_Office_districts_in_India&oldid=1377425763", "licence": "CC BY-SA 4.0", "version": "revision 1377425763", "retrieved": "2026-10-13", "attribution": "RTO codes adapted from the Wikipedia article \"List of Regional Transport Office districts in India\", licensed CC BY-SA 4.0. This dataset is shared under the sam…" } } } ``` ## Data source - [List of Regional Transport Office districts in India](https://en.wikipedia.org/w/index.php?title=List_of_Regional_Transport_Office_districts_in_India&oldid=1377425763), revision 1377425763, retrieved 2026-10-13. Licence: CC BY-SA 4.0. RTO codes adapted from the Wikipedia article "List of Regional Transport Office districts in India", licensed CC BY-SA 4.0. This dataset is shared under the same licence. --- # Railway stations API > Indian Railways station codes to stations, and back. About 4,000 stations with their code, state, railway zone and elevation, from Wikipedia's list of railway stations in India. No official open list exists; this one is kept by volunteers, so some codes are out of date and many entries lack a state or zone. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Station for a code `GET /v1/stations/{code}` Parameters: - `code` (path, required): Station code, such as MAS or NDLS. Example: https://api.dharun.dev/v1/stations/MAS Response: ```json { "data": { "code": "MAS", "name": "Puratchi Thalaivar Dr. M.G. Ramachandran Central Railway Station", "stateCode": "TN", "state": "Tamil Nadu", "zone": { "code": "SR", "name": "Southern" }, "elevationM": 3 }, "meta": { "source": { "name": "List of railway stations in India", "url": "https://en.wikipedia.org/w/index.php?title=List_of_railway_stations_in_India&oldid=1371613797", "licence": "CC BY-SA 4.0", "version": "revision 1371613797", "retrieved": "2026-10-13", "attribution": "Station codes adapted from the Wikipedia article \"List of railway stations in India\", licensed CC BY-SA 4.0. This dataset is shared under the same licence." }, "note": "From a community-kept list: a few codes are out of date (Mumbai CSMT is listed under its old code CSTM) and many stations lack a state or zone." } } ``` ## Search stations `GET /v1/stations` By name (an exact code comes first, then names starting with the text), state or zone. Parameters: - `q` (query): Part of a station name, or a code. - `state` (query): State code or name, for example TN or Tamil Nadu. - `zone` (query): Zone code, such as SR. See /v1/stations/zones. - `limit` (query): Results per page, 1 to 100. - `offset` (query): Results to skip. Example: https://api.dharun.dev/v1/stations?q=chennai Response, with lists and long text shortened: ```json { "data": [ { "code": "MSB", "name": "Chennai Beach", "stateCode": "TN", "state": "Tamil Nadu", "zone": null, "elevationM": null }, { "code": "MS", "name": "Chennai Egmore", "stateCode": "TN", "state": "Tamil Nadu", "zone": null, "elevationM": null }, { "code": "MSF", "name": "Chennai Fort", "stateCode": "TN", "state": "Tamil Nadu", "zone": null, "elevationM": null } ], "meta": { "total": 5, "limit": 20, "offset": 0, "source": { "name": "List of railway stations in India", "url": "https://en.wikipedia.org/w/index.php?title=List_of_railway_stations_in_India&oldid=1371613797", "licence": "CC BY-SA 4.0", "version": "revision 1371613797", "retrieved": "2026-10-13", "attribution": "Station codes adapted from the Wikipedia article \"List of railway stations in India\", licensed CC BY-SA 4.0. This dataset is shared under the same licence." }, "note": "From a community-kept list: a few codes are out of date (Mumbai CSMT is listed under its old code CSTM) and many stations lack a state or zone." } } ``` ## Railway zones `GET /v1/stations/zones` Example: https://api.dharun.dev/v1/stations/zones Response, with lists and long text shortened: ```json { "data": [ { "code": "CR", "name": "Central" }, { "code": "ER", "name": "Eastern" }, { "code": "ECR", "name": "East Central" } ], "meta": { "total": 19 } } ``` ## Data source - [List of railway stations in India](https://en.wikipedia.org/w/index.php?title=List_of_railway_stations_in_India&oldid=1371613797), revision 1371613797, retrieved 2026-10-13. Licence: CC BY-SA 4.0. Station codes adapted from the Wikipedia article "List of railway stations in India", licensed CC BY-SA 4.0. This dataset is shared under the same licence. --- # Constituencies API > Which assembly and Lok Sabha constituency a place is in. The assembly (MLA) and parliamentary (MP) constituency of a point or a pincode, with number, name, reserved category, district and state. From the DataMeet community's maps; boundaries are approximate near their edges, assembly seats in six states predate the latest delimitation, and sitting members are not given. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Constituencies of a place `GET /v1/constituency` Parameters: - `pincode` (query): Indian pincode (the average position of its post offices). - `lat` (query): Latitude, if no pincode. - `lng` (query): Longitude, if no pincode. Example: https://api.dharun.dev/v1/constituency?pincode=637001 Response, with lists and long text shortened: ```json { "data": { "latitude": 11.22189, "longitude": 78.16721, "pincode": "637001", "assembly": { "number": 94, "name": "Namakkal", "reserved": "GEN", "stateCode": "TN", "state": "Tamil Nadu", "district": "Namakkal", "parliamentNumber": 16, "parliamentName": "Namakkal" }, "parliament": { "number": 16, "name": "Namakkal", "nameHindi": "नामाक्कल", "reserved": "GEN", "stateCode": "TN", "state": "Tamil Nadu", "wikidata": "Q6961238" } }, "meta": { "source": { "name": "Maps of assembly and parliamentary constituencies", "url": "https://github.com/datameet/maps/tree/b3fbbde595310b397a55d718e0958ce249a4fa1f", "licence": "Assembly boundaries CC BY 2.5 India; parliamentary boundaries (simplified, 2019) CC0", "version": "commit b3fbbde59531", "retrieved": "2026-10-13", "attribution": "Constituency boundaries from the DataMeet India community's maps (assembly: CC BY 2.5 India; parliamentary: CC0)." }, "note": "Boundaries from community maps, approximate near edges. Assembly seats in Arunachal Pradesh, Assam, Jammu and Kashmir, Jharkhand, Manipur and Nagaland predate t…" } } ``` ## Data source - [Maps of assembly and parliamentary constituencies](https://github.com/datameet/maps/tree/b3fbbde595310b397a55d718e0958ce249a4fa1f), commit b3fbbde59531, retrieved 2026-10-13. Licence: Assembly boundaries CC BY 2.5 India; parliamentary boundaries (simplified, 2019) CC0. Constituency boundaries from the DataMeet India community's maps (assembly: CC BY 2.5 India; parliamentary: CC0). --- # Airports API > Airport codes to airports, and airports by city. Every airport in the world with an IATA code, plus every Indian airfield and heliport, from OurAirports. Indian airports carry their state code. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Airport for a code `GET /v1/airports/{code}` Parameters: - `code` (path, required): IATA code (MAA) or ICAO code (VOMM). Example: https://api.dharun.dev/v1/airports/MAA Response: ```json { "data": { "iata": "MAA", "icao": "VOMM", "ident": "VOMM", "name": "Chennai International Airport", "type": "large_airport", "city": "Chennai", "stateCode": "TN", "country": "IN", "countryName": "India", "latitude": 12.990005, "longitude": 80.169296, "elevationFt": 52, "scheduledService": true, "wikipedia": "https://en.wikipedia.org/wiki/Chennai_International_Airport" }, "meta": { "source": { "name": "OurAirports", "url": "https://ourairports.com/data/", "licence": "Public domain", "version": "9509 airports kept", "retrieved": "2026-10-13", "attribution": "Airport data from OurAirports, released into the public domain." } } } ``` ## Search airports `GET /v1/airports` By name, city or code; airports with scheduled flights and larger airports first. Parameters: - `q` (query): Name, city or code, 2 or more characters. - `country` (query): Two-letter ISO country code, such as IN. - `state` (query): State code or name, for example TN or Tamil Nadu. - `type` (query): Kind of airfield. One of: large_airport, medium_airport, small_airport, heliport, seaplane_base. - `limit` (query): Results per page, 1 to 100. - `offset` (query): Results to skip. Example: https://api.dharun.dev/v1/airports?q=chennai Response, with lists and long text shortened: ```json { "data": [ { "iata": "MAA", "icao": "VOMM", "ident": "VOMM", "name": "Chennai International Airport", "type": "large_airport", "city": "Chennai", "stateCode": "TN", "country": "IN", "countryName": "India", "latitude": 12.990005, "longitude": 80.169296, "elevationFt": 52, "scheduledService": true, "wikipedia": "https://en.wikipedia.org/wiki/Chennai_International_Airport" }, { "iata": null, "icao": null, "ident": "VOTX", "name": "Tambaram Air Force Station", "type": "small_airport", "city": "Chennai", "stateCode": "TN", "country": "IN", "countryName": "India", "latitude": 12.9072, "longitude": 80.121902, "elevationFt": 90, "scheduledService": false, "wikipedia": "https://en.wikipedia.org/wiki/Tambaram_Air_Force_Station" }, { "iata": null, "icao": null, "ident": "IN-0260", "name": "Chennai Military Hospital Helipad", "type": "heliport", "city": "Chennai", "stateCode": "TN", "country": "IN", "countryName": "India", "latitude": 13.0196, "longitude": 80.1976, "elevationFt": 52, "scheduledService": false } ], "meta": { "total": 4, "limit": 20, "offset": 0, "source": { "name": "OurAirports", "url": "https://ourairports.com/data/", "licence": "Public domain", "version": "9509 airports kept", "retrieved": "2026-10-13", "attribution": "Airport data from OurAirports, released into the public domain." } } } ``` ## Data source - [OurAirports](https://ourairports.com/data/), 9509 airports kept, retrieved 2026-10-13. Licence: Public domain. Airport data from OurAirports, released into the public domain. --- # States API > States and union territories with their codes. All 28 states and 8 union territories with the two-letter code, GST state code and vehicle registration prefixes. The other APIs accept these codes in their state filter. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## All states and union territories `GET /v1/states` Example: https://api.dharun.dev/v1/states Response, with lists and long text shortened: ```json { "data": [ { "code": "AN", "name": "Andaman and Nicobar Islands", "type": "union_territory", "gstCode": "35", "vehicleCodes": [ "AN" ] }, { "code": "AP", "name": "Andhra Pradesh", "type": "state", "gstCode": "37", "vehicleCodes": [ "AP" ] }, { "code": "AR", "name": "Arunachal Pradesh", "type": "state", "gstCode": "12", "vehicleCodes": [ "AR" ] } ], "meta": { "total": 36 } } ``` ## One state `GET /v1/states/{code}` Parameters: - `code` (path, required): State code, vehicle prefix or name. Example: https://api.dharun.dev/v1/states/TN Response: ```json { "data": { "code": "TN", "name": "Tamil Nadu", "type": "state", "gstCode": "33", "vehicleCodes": [ "TN" ] }, "meta": {} } ``` ## Guides - [Check a GSTIN or PAN before you save it](https://api.dharun.dev/guides/gstin-pan-check.md): Catch typing mistakes in GSTINs and PANs with the check character, and read the state and PAN out of a GSTIN, in JavaScript. - [Fill city and state from a pincode in a web form](https://api.dharun.dev/guides/pincode-autofill.md): Look up the district and state as soon as someone types a six-digit pincode, with plain JavaScript and no API key. --- # Holidays API > Bank, government and stock market holidays. Holidays for a year, filterable by kind and state. Each entry says who observes it. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Holidays in a year `GET /v1/holidays/{year}` Parameters: - `year` (path, required): Four-digit year. - `type` (query): Kind of holiday. clearing days are ones on which the market trades but nothing settles. One of: bank, central_gazetted, central_restricted, market, clearing. - `state` (query): State code or name, for example TN or Tamil Nadu. - `month` (query): Month number, 1 to 12. Example: https://api.dharun.dev/v1/holidays/2026?type=market Response, with lists and long text shortened: ```json { "data": [ { "date": "2026-01-15", "weekday": "Thursday", "name": "Municipal Corporation Election - Maharashtra", "type": "market", "region": "NSE equities", "states": [ "*" ] }, { "date": "2026-01-26", "weekday": "Monday", "name": "Republic Day", "type": "market", "region": "NSE equities", "states": [ "*" ] }, { "date": "2026-02-15", "weekday": "Sunday", "name": "Mahashivratri", "type": "market", "region": "NSE equities", "states": [ "*" ] } ], "meta": { "total": 20, "source": { "name": "Trading and clearing holidays, NSE equities", "url": "https://www.nseindia.com/resources/exchange-communication-holidays", "licence": "Official publication", "version": "2026", "retrieved": "2026-10-13", "attribution": "Trading and clearing holidays from the National Stock Exchange of India, capital market segment." }, "note": "Compiled from official notifications. Dates of festivals fixed by moon sighting can change; check the issuing authority before relying on a date." } } ``` ## Data source - [Bank holidays in India](https://www.rbi.org.in/Scripts/HolidayMatrixDisplay.aspx), 2026, retrieved 2026-10-13. Licence: Official publication. Bank holidays from the Reserve Bank of India holiday matrix, by regional office. - [Central government holidays](https://dopt.gov.in/), 2026, 2027, retrieved 2026-10-13. Licence: Official publication. Gazetted and restricted holidays for central government offices, from the yearly Department of Personnel and Training memorandum. - [Trading and clearing holidays, NSE equities](https://www.nseindia.com/resources/exchange-communication-holidays), 2026, retrieved 2026-10-13. Licence: Official publication. Trading and clearing holidays from the National Stock Exchange of India, capital market segment. ## Guides - [Bank holidays, working days and T+1 settlement dates](https://api.dharun.dev/guides/working-days.md): Find whether a date is a bank holiday in a state, the next working day, N working days ahead, and NSE settlement dates, in Python. --- # Working days API > Bank, market, settlement and government working days. Is a date a working day, what is the next one, and what date is N working days away. Bank days follow the Reserve Bank's holidays for a state plus Sundays and the second and fourth Saturdays; market and settlement days follow NSE's trading and clearing holidays. Only years with a published holiday list are answered. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Is a date a working day `GET /v1/working-days/{date}` Whether the date is a working day and why not, the previous and next working days, and with add=N the date N working days later (negative for earlier). A T+1 settlement date is calendar=settlement&add=1. Parameters: - `date` (path, required): Date, YYYY-MM-DD. - `calendar` (query): bank (default; needs state), market (NSE trading), settlement (NSE clearing) or central (central government offices). One of: bank, market, settlement, central. - `state` (query): State code or name. Required for the bank calendar. - `office` (query): Bank calendar only. One Reserve Bank office's list, such as Srinagar or Kochi, for a state with several offices (Maharashtra, Uttar Pradesh, Jammu and Kashmir, Kerala). Without it, a day off at any of the state's offices counts. - `add` (query): Working days to add, -366 to 366. Example: https://api.dharun.dev/v1/working-days/2026-01-16?calendar=bank&state=TN&add=3 Response: ```json { "data": { "date": "2026-01-16", "weekday": "Friday", "calendar": "bank", "state": "TN", "working": false, "reasons": [ "Thiruvalluvar Day/Kanuma" ], "previousWorkingDay": "2026-01-14", "nextWorkingDay": "2026-01-19", "add": 3, "shifted": "2026-01-21" }, "meta": { "source": { "name": "Bank holidays in India", "url": "https://www.rbi.org.in/Scripts/HolidayMatrixDisplay.aspx", "licence": "Official publication", "version": "2026", "retrieved": "2026-10-13", "attribution": "Bank holidays from the Reserve Bank of India holiday matrix, by regional office." }, "note": "Sundays, the second and fourth Saturdays, and the Reserve Bank's holidays for the state's regional office." } } ``` ## Count working days between two dates `GET /v1/working-days` Counts working days from one date to another, both included, and lists each day off with its reason. At most 366 days. Parameters: - `from` (query, required): First date, YYYY-MM-DD. - `to` (query, required): Last date, YYYY-MM-DD. - `calendar` (query): bank (default; needs state), market (NSE trading), settlement (NSE clearing) or central (central government offices). One of: bank, market, settlement, central. - `state` (query): State code or name. Required for the bank calendar. - `office` (query): Bank calendar only. One Reserve Bank office's list, such as Srinagar or Kochi, for a state with several offices (Maharashtra, Uttar Pradesh, Jammu and Kashmir, Kerala). Without it, a day off at any of the state's offices counts. Example: https://api.dharun.dev/v1/working-days?from=2026-01-01&to=2026-01-31&calendar=market Response, with lists and long text shortened: ```json { "data": { "from": "2026-01-01", "to": "2026-01-31", "calendar": "market", "days": 31, "workingDays": 20, "daysOff": [ { "date": "2026-01-03", "weekday": "Saturday", "reasons": [ "Saturday" ] }, { "date": "2026-01-04", "weekday": "Sunday", "reasons": [ "Sunday" ] }, { "date": "2026-01-10", "weekday": "Saturday", "reasons": [ "Saturday" ] } ] }, "meta": { "source": { "name": "Trading and clearing holidays, NSE equities", "url": "https://www.nseindia.com/resources/exchange-communication-holidays", "licence": "Official publication", "version": "2026", "retrieved": "2026-10-13", "attribution": "Trading and clearing holidays from the National Stock Exchange of India, capital market segment." }, "note": "Weekends and NSE trading holidays. Special sessions, such as Muhurat trading or a Saturday budget session, are announced separately by the exchange." } } ``` ## Is the stock market open `GET /v1/market/status` NSE equities session at a moment: pre_open, open, closing or closed, the reason it is closed, and when it next opens. Without at, the current moment. Parameters: - `at` (query): Moment with its offset, RFC 3339, for example 2026-10-13T10:30:00+05:30. Example: https://api.dharun.dev/v1/market/status?at=2026-01-26T10:00:00%2B05:30 Response: ```json { "data": { "at": "2026-01-26T10:00:00+05:30", "exchange": "NSE equities", "session": "closed", "open": false, "reasons": [ "Republic Day" ], "hours": { "preOpen": "09:00-09:15", "normal": "09:15-15:30", "closing": "15:30-16:00" }, "nextOpen": "2026-01-27T09:15:00+05:30" }, "meta": { "source": { "name": "Trading and clearing holidays, NSE equities", "url": "https://www.nseindia.com/resources/exchange-communication-holidays", "licence": "Official publication", "version": "2026", "retrieved": "2026-10-13", "attribution": "Trading and clearing holidays from the National Stock Exchange of India, capital market segment." }, "note": "Regular NSE equities hours. Special sessions (Muhurat trading, Saturday budget sessions, mock sessions) are announced separately by the exchange." } } ``` ## Data source - [Bank holidays in India](https://www.rbi.org.in/Scripts/HolidayMatrixDisplay.aspx), 2026, retrieved 2026-10-13. Licence: Official publication. Bank holidays from the Reserve Bank of India holiday matrix, by regional office. - [Trading and clearing holidays, NSE equities](https://www.nseindia.com/resources/exchange-communication-holidays), 2026, retrieved 2026-10-13. Licence: Official publication. Trading and clearing holidays from the National Stock Exchange of India, capital market segment. - [Central government holidays](https://dopt.gov.in/), 2026, 2027, retrieved 2026-10-13. Licence: Official publication. Gazetted and restricted holidays for central government offices, from the yearly Department of Personnel and Training memorandum. ## Guides - [Bank holidays, working days and T+1 settlement dates](https://api.dharun.dev/guides/working-days.md): Find whether a date is a bank holiday in a state, the next working day, N working days ahead, and NSE settlement dates, in Python. --- # Panchang API > Hindu almanac for any date and place: tithi, nakshatra, Rahu kalam and more. Computed, not looked up, from the positions of the Sun and the Moon (within seconds of NASA JPL Horizons), with the Lahiri ayanamsa. Gives the five elements with the moments they change, sunrise, sunset, moonrise and moonset, Rahu kalam, Yamagandam, Gulika kalam and Abhijit muhurta, the Tamil month and day, the lunar month both ways it is reckoned, and the Shaka and Vikram years. Names come in English transliteration and, where the Tamil calendar has its own, in Tamil. Festival dates are not given. Counts as 10 requests against the rate limit. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Panchang for a date `GET /v1/panchang/{date}` For a pincode, a latitude and longitude, or (by default) New Delhi. Times are in the time zone asked for. Parameters: - `date` (path, required): YYYY-MM-DD, 1900 to 2100, or today. - `pincode` (query): Indian pincode of the place. - `lat` (query): Latitude, if no pincode. - `lng` (query): Longitude, if no pincode. - `tz` (query): IANA time zone for the times. Default Asia/Kolkata. Example: https://api.dharun.dev/v1/panchang/2026-01-14?pincode=600001 Response, with lists and long text shortened: ```json { "data": { "place": { "latitude": 13.0949, "longitude": 80.287, "timeZone": "Asia/Kolkata", "pincode": "600001", "name": "Chennai" }, "date": "2026-01-14", "weekday": { "name": "Budhavara", "tamil": "புதன்" }, "sunrise": "2026-01-14T06:34:53+05:30", "sunset": "2026-01-14T18:00:50+05:30", "moonrise": "2026-01-14T02:42:07+05:30", "moonset": "2026-01-14T14:13:06+05:30", "tithi": [ { "number": 26, "name": "Ekadashi", "tamil": "ஏகாதசி", "paksha": "krishna", "start": "2026-01-13T15:18:29+05:30", "end": "2026-01-14T17:53:18+05:30" }, { "number": 27, "name": "Dvadashi", "tamil": "துவாதசி", "paksha": "krishna", "start": "2026-01-14T17:53:18+05:30", "end": "2026-01-15T20:17:01+05:30" } ], "nakshatra": [ { "number": 17, "name": "Anuradha", "tamil": "அனுஷம்", "pada": 1, "start": "2026-01-14T00:06:48+05:30", "end": "2026-01-15T03:03:59+05:30" }, { "number": 18, "name": "Jyeshtha", "tamil": "கேட்டை", "start": "2026-01-15T03:03:59+05:30", "end": "2026-01-16T05:47:53+05:30" } ], "yoga": [ { "number": 10, "name": "Ganda", "start": "2026-01-13T19:04:54+05:30", "end": "2026-01-14T19:55:53+05:30" }, { "number": 11, "name": "Vriddhi", "start": "2026-01-14T19:55:53+05:30", "end": "2026-01-15T20:38:09+05:30" } ], "karana": [ { "number": 52, "name": "Balava", "start": "2026-01-14T04:36:41+05:30", "end": "2026-01-14T17:53:18+05:30" }, { "number": 53, "name": "Kaulava", "start": "2026-01-14T17:53:18+05:30", "end": "2026-01-15T07:07:06+05:30" } ], "sunSign": { "name": "Dhanu", "tamil": "தனுசு" }, "moonSign": { "name": "Vrishchika", "tamil": "விருச்சிகம்" }, "tamilMonth": { "name": "Thai", "tamil": "தை", "day": 1 }, "tamilYear": { "name": "Vishvavasu", "tamil": "விசுவாவசு" }, "lunarMonth": { "amanta": "Pausha", "purnimanta": "Magha", "adhika": false }, "shakaYear": 1947, "vikramSamvat": 2082, "rahuKalam": { "start": "2026-01-14T12:17:51+05:30", "end": "2026-01-14T13:43:36+05:30" }, "yamagandam": { "start": "2026-01-14T08:00:37+05:30", "end": "2026-01-14T09:26:22+05:30" }, "gulikaKalam": { "start": "2026-01-14T10:52:06+05:30", "end": "2026-01-14T12:17:51+05:30" }, "abhijitMuhurta": { "start": "2026-01-14T11:54:59+05:30", "end": "2026-01-14T12:40:43+05:30" }, "ayanamsa": 24.222541 }, "meta": { "note": "Computed from the positions of the Sun and the Moon (NREL SPA and Meeus, within seconds of NASA JPL Horizons), sidereal with the Lahiri ayanamsa as defined by t…" } } ``` --- # Sun and moon API > Sunrise, sunset, twilight, moonrise and the moon's phase for any date and place. The astronomy of a day without the almanac: sunrise, sunset, solar noon and day length; civil, nautical and astronomical twilight; moonrise and moonset; the moon's phase, how much of it is lit and its age; and the next new, first quarter, full and last quarter moons. Computed with the same code as the panchang, and checked against NASA's JPL ephemeris. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Sun and moon for a date `GET /v1/sun-moon/{date}` For a pincode, a latitude and longitude, or (by default) New Delhi. A twilight time is null where the sun does not sink that far, and moonrise or moonset is null on the day each month the moon does not rise or set. The phase names a principal phase (new moon, first quarter, full moon, last quarter) for the whole date it falls on. Parameters: - `date` (path, required): YYYY-MM-DD, 1900 to 2100, or today. - `pincode` (query): Indian pincode of the place. - `lat` (query): Latitude, -66 to 66, if no pincode. - `lng` (query): Longitude, if no pincode. - `tz` (query): IANA time zone for the times. Default Asia/Kolkata. Example: https://api.dharun.dev/v1/sun-moon/2026-10-14?pincode=600001 Response, with lists and long text shortened: ```json { "data": { "place": { "latitude": 13.0949, "longitude": 80.287, "timeZone": "Asia/Kolkata", "pincode": "600001", "name": "Chennai" }, "date": "2026-10-14", "sun": { "sunrise": "2026-10-14T05:59:05+05:30", "sunset": "2026-10-14T17:50:35+05:30", "solarNoon": "2026-10-14T11:54:55+05:30", "dayLengthMinutes": 711.5, "noonElevation": 68.74, "civilTwilight": { "dawn": "2026-10-14T05:37:41+05:30", "dusk": "2026-10-14T18:11:59+05:30" }, "nauticalTwilight": { "dawn": "2026-10-14T05:12:53+05:30", "dusk": "2026-10-14T18:36:46+05:30" }, "astronomicalTwilight": { "dawn": "2026-10-14T04:48:09+05:30", "dusk": "2026-10-14T19:01:30+05:30" } }, "moon": { "moonrise": "2026-10-14T08:55:43+05:30", "moonset": "2026-10-14T20:26:23+05:30", "phase": "waxing crescent", "illumination": 13, "ageDays": 3.6, "nextPhases": { "newMoon": "2026-11-09T12:32:14+05:30", "firstQuarter": "2026-10-18T21:42:39+05:30", "fullMoon": "2026-10-26T09:41:43+05:30", "lastQuarter": "2026-11-02T01:58:29+05:30" } } }, "meta": { "note": "Computed from the positions of the Sun and the Moon (NREL SPA and Meeus). Sunrise, sunset and twilight agree with the JPL ephemeris to within seconds; moonrise …" } } ``` --- # Thirukkural API > All 1,330 kurals in Tamil with English translations. Thiruvalluvar's Thirukkural with a transliteration, G.U. Pope's verse translation (1886) and the prose translation by W.H. Drew and John Lazarus (1840, 1885), organised into 3 paals, 13 iyals and 133 chapters. Only text that is free to share is served; modern commentaries are added once their release into the public domain is confirmed. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## A kural by number `GET /v1/thirukkural/{number}` Parameters: - `number` (path, required): 1 to 1330. Example: https://api.dharun.dev/v1/thirukkural/1 Response, with lists and long text shortened: ```json { "data": { "number": 1, "lines": [ "அகர முதல எழுத்தெல்லாம் ஆதி", "பகவன் முதற்றே உலகு." ], "transliteration": [ "Akara Mudhala Ezhuththellaam Aadhi", "Pakavan Mudhatre Ulaku" ], "translations": { "drewLazarus": "As the letter A is the first of all letters, so the eternal God is first in the world", "pope": "A, as its first of letters, every speech maintains; The \"Primal Deity\" is first through all the world's domains" }, "chapter": { "number": 1, "name": "கடவுள் வாழ்த்து", "translation": "The Praise of God", "transliteration": "Katavul Vaazhththu" }, "iyal": { "number": 1, "name": "பாயிரவியல்", "translation": "Prologue", "transliteration": "Paayiraviyal" }, "paal": { "number": 1, "name": "அறத்துப்பால்", "translation": "Virtue", "transliteration": "Araththuppaal" } }, "meta": { "source": { "name": "Thirukkural", "url": "https://github.com/tk120404/thirukkural/tree/cf3ff6c5a73c23b4092913156830457caab65fd4", "licence": "Public domain text and translations; the compilation is Apache-2.0", "version": "commit cf3ff6c5a73c", "retrieved": "2026-10-13", "attribution": "Thirukkural text with English translations by G.U. Pope (1886) and by W.H. Drew and John Lazarus (1840, 1885), from the tk120404/thirukkural compilation (Apache…" }, "note": "translations.pope is G.U. Pope's verse translation (1886); translations.drewLazarus is the prose translation by W.H. Drew and John Lazarus (1840, 1885)." } } ``` ## Search kurals `GET /v1/thirukkural` Finds kurals containing the text, in Tamil, the transliteration or either translation; or lists a chapter or a paal. Parameters: - `q` (query): Text to find, 2 or more characters, Tamil or English. - `chapter` (query): Chapter (அதிகாரம்), 1 to 133. - `paal` (query): 1 virtue (அறத்துப்பால்), 2 wealth (பொருட்பால்), 3 love (காமத்துப்பால்). - `limit` (query): Results per page, 1 to 100. - `offset` (query): Results to skip. Example: https://api.dharun.dev/v1/thirukkural?q=rain Response, with lists and long text shortened: ```json { "data": [ { "number": 11, "lines": [ "வான்நின்று உலகம் வழங்கி வருதலால்", "தான்அமிழ்தம் என்றுணரற் பாற்று." ], "transliteration": [ "Vaannindru Ulakam Vazhangi Varudhalaal", "Thaanamizhdham Endrunarar Paatru" ], "translations": { "drewLazarus": "By the continuance of rain the world is preserved in existence; it is therefore worthy to be called ambrosia", "pope": "The world its course maintains through life that rain unfailing gives; Thus rain is known the true ambrosial food of all that lives" }, "chapter": { "number": 2, "name": "வான்சிறப்பு", "translation": "The Blessing of Rain", "transliteration": "Vaansirappu" }, "iyal": { "number": 1, "name": "பாயிரவியல்", "translation": "Prologue", "transliteration": "Paayiraviyal" }, "paal": { "number": 1, "name": "அறத்துப்பால்", "translation": "Virtue", "transliteration": "Araththuppaal" } }, { "number": 12, "lines": [ "துப்பார்க்குத் துப்பாய துப்பாக்கித் துப்பார்க்குத்", "துப்பாய தூஉம் மழை." ], "transliteration": [ "Thuppaarkkuth Thuppaaya Thuppaakkith Thuppaarkkuth", "Thuppaaya Thooum Mazhai" ], "translations": { "drewLazarus": "Rain produces good food, and is itself food", "pope": "The rain makes pleasant food for eaters rise; As food itself, thirst-quenching draught supplies" }, "chapter": { "number": 2, "name": "வான்சிறப்பு", "translation": "The Blessing of Rain", "transliteration": "Vaansirappu" }, "iyal": { "number": 1, "name": "பாயிரவியல்", "translation": "Prologue", "transliteration": "Paayiraviyal" }, "paal": { "number": 1, "name": "அறத்துப்பால்", "translation": "Virtue", "transliteration": "Araththuppaal" } }, { "number": 13, "lines": [ "விண்இன்று பொய்ப்பின் விரிநீர் வியனுலகத்து", "உள்நின்று உடற்றும் பசி." ], "transliteration": [ "Vinindru Poippin Virineer Viyanulakaththu", "Ulnindru Utatrum Pasi" ], "translations": { "drewLazarus": "If the cloud, withholding rain, deceive (our hopes) hunger will long distress the sea-girt spacious world", "pope": "If clouds, that promised rain, deceive, and in the sky remain, Famine, sore torment, stalks o'er earth's vast ocean-girdled plain" }, "chapter": { "number": 2, "name": "வான்சிறப்பு", "translation": "The Blessing of Rain", "transliteration": "Vaansirappu" }, "iyal": { "number": 1, "name": "பாயிரவியல்", "translation": "Prologue", "transliteration": "Paayiraviyal" }, "paal": { "number": 1, "name": "அறத்துப்பால்", "translation": "Virtue", "transliteration": "Araththuppaal" } } ], "meta": { "total": 78, "limit": 10, "offset": 0, "source": { "name": "Thirukkural", "url": "https://github.com/tk120404/thirukkural/tree/cf3ff6c5a73c23b4092913156830457caab65fd4", "licence": "Public domain text and translations; the compilation is Apache-2.0", "version": "commit cf3ff6c5a73c", "retrieved": "2026-10-13", "attribution": "Thirukkural text with English translations by G.U. Pope (1886) and by W.H. Drew and John Lazarus (1840, 1885), from the tk120404/thirukkural compilation (Apache…" }, "note": "translations.pope is G.U. Pope's verse translation (1886); translations.drewLazarus is the prose translation by W.H. Drew and John Lazarus (1840, 1885)." } } ``` ## Kural of the day `GET /v1/thirukkural/today` The same kural for everyone on a day in India, a different one the next day. Parameters: - `date` (query): A date, YYYY-MM-DD. Default today in India. Example: https://api.dharun.dev/v1/thirukkural/today?date=2026-10-13 Response, with lists and long text shortened: ```json { "data": { "number": 702, "lines": [ "ஐயப் படாஅது அகத்தது உணர்வானைத்", "தெய்வத்தோ டொப்பக் கொளல்." ], "transliteration": [ "Aiyap Pataaadhu Akaththadhu Unarvaanaith", "Theyvaththo Toppak Kolal" ], "translations": { "drewLazarus": "He is to be esteemed a god who is able to ascertain without a doubt what is within (one's mind)", "pope": "Undoubting, who the minds of men can scan, As deity regard that gifted man" }, "chapter": { "number": 71, "name": "குறிப்பறிதல்", "translation": "The Knowledge of Indications", "transliteration": "Kuripparidhal" }, "iyal": { "number": 6, "name": "அமைச்சியல்", "translation": "Minister of State", "transliteration": "Amaichiyal" }, "paal": { "number": 2, "name": "பொருட்பால்", "translation": "Wealth", "transliteration": "Porutpaal" } }, "meta": { "source": { "name": "Thirukkural", "url": "https://github.com/tk120404/thirukkural/tree/cf3ff6c5a73c23b4092913156830457caab65fd4", "licence": "Public domain text and translations; the compilation is Apache-2.0", "version": "commit cf3ff6c5a73c", "retrieved": "2026-10-13", "attribution": "Thirukkural text with English translations by G.U. Pope (1886) and by W.H. Drew and John Lazarus (1840, 1885), from the tk120404/thirukkural compilation (Apache…" }, "note": "translations.pope is G.U. Pope's verse translation (1886); translations.drewLazarus is the prose translation by W.H. Drew and John Lazarus (1840, 1885)." } } ``` ## A random kural `GET /v1/thirukkural/random` Example: https://api.dharun.dev/v1/thirukkural/random Response, with lists and long text shortened: ```json { "data": { "number": 437, "lines": [ "செயற்பால செய்யா திவறியான் செல்வம்", "உயற்பால தன்றிக் கெடும்." ], "transliteration": [ "Seyarpaala Seyyaa Thivariyaan Selvam", "Uyarpaala Thandrik Ketum" ], "translations": { "drewLazarus": "The wealth of the avaricious man, who does not expend it for the purposes for which he ought to expend it will waste away and not continue", "pope": "Who leaves undone what should be done, with niggard mind, His wealth shall perish, leaving not a wrack behind" }, "chapter": { "number": 44, "name": "குற்றங்கடிதல்", "translation": "The Correction of Faults", "transliteration": "Kutrangatidhal" }, "iyal": { "number": 5, "name": "அரசியல்", "translation": "Royalty", "transliteration": "Arasiyal" }, "paal": { "number": 2, "name": "பொருட்பால்", "translation": "Wealth", "transliteration": "Porutpaal" } }, "meta": { "source": { "name": "Thirukkural", "url": "https://github.com/tk120404/thirukkural/tree/cf3ff6c5a73c23b4092913156830457caab65fd4", "licence": "Public domain text and translations; the compilation is Apache-2.0", "version": "commit cf3ff6c5a73c", "retrieved": "2026-10-13", "attribution": "Thirukkural text with English translations by G.U. Pope (1886) and by W.H. Drew and John Lazarus (1840, 1885), from the tk120404/thirukkural compilation (Apache…" }, "note": "translations.pope is G.U. Pope's verse translation (1886); translations.drewLazarus is the prose translation by W.H. Drew and John Lazarus (1840, 1885)." } } ``` ## All 133 chapters `GET /v1/thirukkural/chapters` Example: https://api.dharun.dev/v1/thirukkural/chapters Response, with lists and long text shortened: ```json { "data": [ { "number": 1, "name": "கடவுள் வாழ்த்து", "translation": "The Praise of God", "transliteration": "Katavul Vaazhththu", "iyal": { "number": 1, "name": "பாயிரவியல்", "translation": "Prologue", "transliteration": "Paayiraviyal" }, "paal": { "number": 1, "name": "அறத்துப்பால்", "translation": "Virtue", "transliteration": "Araththuppaal" }, "first": 1, "last": 10, "links": { "kurals": "https://api.dharun.dev/v1/thirukkural?chapter=1" } }, { "number": 2, "name": "வான்சிறப்பு", "translation": "The Blessing of Rain", "transliteration": "Vaansirappu", "iyal": { "number": 1, "name": "பாயிரவியல்", "translation": "Prologue", "transliteration": "Paayiraviyal" }, "paal": { "number": 1, "name": "அறத்துப்பால்", "translation": "Virtue", "transliteration": "Araththuppaal" }, "first": 11, "last": 20, "links": { "kurals": "https://api.dharun.dev/v1/thirukkural?chapter=2" } }, { "number": 3, "name": "நீத்தார் பெருமை", "translation": "The Greatness of Ascetics", "transliteration": "Neeththaar Perumai", "iyal": { "number": 1, "name": "பாயிரவியல்", "translation": "Prologue", "transliteration": "Paayiraviyal" }, "paal": { "number": 1, "name": "அறத்துப்பால்", "translation": "Virtue", "transliteration": "Araththuppaal" }, "first": 21, "last": 30, "links": { "kurals": "https://api.dharun.dev/v1/thirukkural?chapter=3" } } ], "meta": { "total": 133, "source": { "name": "Thirukkural", "url": "https://github.com/tk120404/thirukkural/tree/cf3ff6c5a73c23b4092913156830457caab65fd4", "licence": "Public domain text and translations; the compilation is Apache-2.0", "version": "commit cf3ff6c5a73c", "retrieved": "2026-10-13", "attribution": "Thirukkural text with English translations by G.U. Pope (1886) and by W.H. Drew and John Lazarus (1840, 1885), from the tk120404/thirukkural compilation (Apache…" } } } ``` ## One chapter `GET /v1/thirukkural/chapters/{number}` Parameters: - `number` (path, required): 1 to 133. Example: https://api.dharun.dev/v1/thirukkural/chapters/2 Response, with lists and long text shortened: ```json { "data": { "number": 2, "name": "வான்சிறப்பு", "translation": "The Blessing of Rain", "transliteration": "Vaansirappu", "iyal": { "number": 1, "name": "பாயிரவியல்", "translation": "Prologue", "transliteration": "Paayiraviyal" }, "paal": { "number": 1, "name": "அறத்துப்பால்", "translation": "Virtue", "transliteration": "Araththuppaal" }, "first": 11, "last": 20, "links": { "kurals": "https://api.dharun.dev/v1/thirukkural?chapter=2" } }, "meta": { "source": { "name": "Thirukkural", "url": "https://github.com/tk120404/thirukkural/tree/cf3ff6c5a73c23b4092913156830457caab65fd4", "licence": "Public domain text and translations; the compilation is Apache-2.0", "version": "commit cf3ff6c5a73c", "retrieved": "2026-10-13", "attribution": "Thirukkural text with English translations by G.U. Pope (1886) and by W.H. Drew and John Lazarus (1840, 1885), from the tk120404/thirukkural compilation (Apache…" } } } ``` ## Data source - [Thirukkural](https://github.com/tk120404/thirukkural/tree/cf3ff6c5a73c23b4092913156830457caab65fd4), commit cf3ff6c5a73c, retrieved 2026-10-13. Licence: Public domain text and translations; the compilation is Apache-2.0. Thirukkural text with English translations by G.U. Pope (1886) and by W.H. Drew and John Lazarus (1840, 1885), from the tk120404/thirukkural compilation (Apache-2.0). --- # Text tools API > Chunk documents, redact Indian identifiers, count tokens, detect language. Tools for working with text, especially in AI and retrieval pipelines. Send short text as ?text=, or POST it as text/plain, or as JSON {"text": ...} with the options beside it. Nothing you send is logged or kept. Each request counts as 10 against the rate limit. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Split a document into chunks `GET /v1/text/chunk`, also `POST` Splits at headings, paragraphs, sentences and words, in that order of preference, so chunks stay readable. Markdown chunks never cross a heading and carry their heading path. Each chunk is an exact slice of the input with its character offsets. POST body: The document, plain text or Markdown. Send it as `text/plain`, or as JSON `{"text": "..."}` with the other options beside it. What you send is never written to the log, and the answer is not cached. Parameters: - `text` (query): The text (or POST it). - `size` (query): Largest chunk in characters, overlap included, 100 to 20000. Default 1000. - `overlap` (query): Characters repeated from the previous chunk, up to half the size. Default a tenth of the size. - `format` (query): Default auto: Markdown if the text has headings or code fences. One of: auto, markdown, text. Example: https://api.dharun.dev/v1/text/chunk?size=200&overlap=20&text=%23+Setup%0A%0AInstall+Go.+Clone+the+repository.%0A%0A%23+Deploy%0A%0APush+to+main. Response: ```json { "data": { "format": "markdown", "size": 200, "chunks": [ { "index": 0, "text": "# Setup\n\nInstall Go. Clone the repository.", "start": 0, "end": 42, "chars": 42, "heading": "Setup" }, { "index": 1, "text": "# Deploy\n\nPush to main.", "start": 44, "end": 67, "chars": 23, "heading": "Deploy" } ] }, "meta": { "total": 2, "note": "Sizes and offsets count characters (Unicode code points). Each chunk is exactly text[start:end]." } } ``` ## Redact Indian personal identifiers `GET /v1/text/redact`, also `POST` Masks Aadhaar numbers (Verhoeff-checked), PAN, GSTIN (checksum-checked), card numbers (Luhn-checked), Indian mobile numbers, email addresses, UPI IDs, vehicle numbers, voter IDs, passport numbers and IP addresses. Returns where each was found, never the values. Names and addresses are not detected. POST body: The text to redact. Send it as `text/plain`, or as JSON `{"text": "..."}` with the other options beside it. What you send is never written to the log, and the answer is not cached. Parameters: - `text` (query): The text (or POST it). - `types` (query): Comma-separated kinds to redact; default all. Kinds: email, upi, gstin, card, aadhaar, pan, phone, vehicle, voter_id, passport, ip. - `style` (query): label replaces with [PAN]; partial keeps the last digits, as on a bank statement. Default label. One of: label, partial. Example: https://api.dharun.dev/v1/text/redact?text=Call+98765+43210%2C+PAN+ABCPK1234F Response: ```json { "data": { "text": "Call [PHONE], PAN [PAN]", "findings": [ { "type": "phone", "start": 5, "end": 16 }, { "type": "pan", "start": 22, "end": 32 } ], "counts": { "pan": 1, "phone": 1 } }, "meta": { "note": "Finds identifiers by their structure and check digits. Names and street addresses are not detected." } } ``` ## Count tokens `GET /v1/text/tokens`, also `POST` Exact token counts with OpenAI tokenizers, by encoding or model name. Other vendors do not publish their tokenizers, so their counts are not offered. POST body: The text to count. Send it as `text/plain`, or as JSON `{"text": "..."}` with the other options beside it. What you send is never written to the log, and the answer is not cached. Parameters: - `text` (query): The text (or POST it). - `model` (query): Model name, such as gpt-4o or gpt-4, or an encoding: o200k_base, cl100k_base, p50k_base. Default o200k_base. Example: https://api.dharun.dev/v1/text/tokens?model=gpt-4o&text=%E0%AE%B5%E0%AE%A3%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%AE%E0%AF%8D%2C+how+many+tokens+is+this%3F Response, with lists and long text shortened: ```json { "data": { "tokens": 10, "encoding": "o200k_base", "models": [ "gpt-4o", "gpt-4o-mini", "gpt-4.1" ], "characters": 33, "words": 6, "bytes": 47 }, "meta": { "note": "Counted with OpenAI's vocabulary for the encoding, treating special tokens as text. Chat requests add a few tokens per message on top." } } ``` ## Detect the language `GET /v1/text/language`, also `POST` Language and script, with a confidence. Covers about 80 languages including Hindi, Bengali, Marathi, Gujarati, Punjabi, Tamil, Telugu, Kannada, Malayalam, Odia and Urdu. Romanised Indian text (Hinglish, Tanglish) is flagged as such. POST body: The text. Send it as `text/plain`, or as JSON `{"text": "..."}` with the other options beside it. What you send is never written to the log, and the answer is not cached. Parameters: - `text` (query): The text (or POST it). Example: https://api.dharun.dev/v1/text/language?text=%E0%AE%85%E0%AE%95%E0%AE%B0+%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2+%E0%AE%8E%E0%AE%B4%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AF%86%E0%AE%B2%E0%AF%8D%E0%AE%B2%E0%AE%BE%E0%AE%AE%E0%AF%8D+%E0%AE%86%E0%AE%A4%E0%AE%BF+%E0%AE%AA%E0%AE%95%E0%AE%B5%E0%AE%A9%E0%AF%8D+%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B1%E0%AF%8D%E0%AE%B1%E0%AF%87+%E0%AE%89%E0%AE%B2%E0%AE%95%E0%AF%81 Response: ```json { "data": { "code": "tam", "code2": "ta", "name": "Tamil", "script": "Tamil", "confidence": 1, "reliable": true }, "meta": { "note": "About 80 languages from their letters. Short texts are uncertain; Romanised Indian languages are flagged but not identified." } } ``` ## Guides - [Remove Aadhaar, PAN and phone numbers before sending text to an LLM](https://api.dharun.dev/guides/redact-before-llm.md): Mask Indian personal identifiers in text before it reaches a language model or a log, with check-digit validation so ordinary numbers are left alone. --- # Transliteration API > Rewrite text between Indian scripts and Roman letters. Converts by rule between Devanagari, Bengali, Gurmukhi, Gujarati, Odia, Tamil, Telugu, Kannada and Malayalam, and to ISO 15919, IAST or plain ASCII. ISO 15919 and IAST can also be turned back into any of the scripts. The spelling changes, not the language: this is not translation. Casual Roman typing (vanakkam) cannot be converted by rule and is not accepted as input. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Transliterate text `GET /v1/transliterate`, also `POST` POST body: The text. Send it as `text/plain`, or as JSON `{"text": "..."}` with the other options beside it. What you send is never written to the log, and the answer is not cached. Parameters: - `text` (query): The text (or POST it). Letters of other scripts pass through unchanged. - `to` (query, required): A script (devanagari, bengali, gurmukhi, gujarati, odia, tamil, telugu, kannada, malayalam), a language code such as ta or hi, or iso15919, iast, ascii. - `from` (query): auto (default: the script of the text), a script, or iso15919 or iast for romanised input. Example: https://api.dharun.dev/v1/transliterate?to=tamil&text=%E0%A4%A8%E0%A4%AE%E0%A4%B8%E0%A5%8D%E0%A4%A4%E0%A5%87+%E0%A4%AD%E0%A4%BE%E0%A4%B0%E0%A4%A4 Response: ```json { "data": { "text": "நமஸ்தே பாரத", "from": "devanagari", "to": "tamil" }, "meta": { "note": "Converted by rule, letter by letter: the spelling changes, not the language. Letters a script lacks become the nearest one it has." } } ``` --- # Tamil legacy encodings API > Old Tamil text that shows as accented Latin letters, to Unicode and back. Before Unicode, Tamil was stored in 8-bit encodings that only looked like Tamil in one particular font; anywhere else the same text shows as characters like ¾Á¢ú. This converts such text to Unicode and Unicode back to it, moving the vowel signs that those encodings write before the consonant. TSCII 1.7 is offered now; TAB, TAM and Bamini are planned. The tables are written from the published standard. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Convert Tamil text `GET /v1/tamil-font/convert`, also `POST` Give the text as it looks without its font (the Windows-1252 characters), or POST the raw bytes as application/octet-stream. Converting to an 8-bit encoding answers with the same kind of text, and with the bytes in base64. Bytes the encoding does not assign are counted in undefined; characters it has no code for are listed in unmapped. POST body: The text, or with Content-Type application/octet-stream the raw bytes. Send it as `text/plain`, or as JSON `{"text": "..."}` with the other options beside it. What you send is never written to the log, and the answer is not cached. Parameters: - `text` (query): The text (or POST it). - `from` (query, required): What the text is in. One of: unicode, tscii. - `to` (query): What to convert to. Default unicode; one of from and to must be unicode. One of: unicode, tscii. Example: https://api.dharun.dev/v1/tamil-font/convert?from=tscii&text=%C2%BE%C3%81%C2%A2%C3%BA+%C3%85%C2%BD%C3%AC%C2%B8%C3%B5 Response: ```json { "data": { "from": "tscii", "to": "unicode", "text": "தமிழ் வணக்கம்" }, "meta": {} } ``` ## Encodings offered `GET /v1/tamil-font/encodings` The encodings that can be converted, with fonts that use each, to help recognise what a text is in. Example: https://api.dharun.dev/v1/tamil-font/encodings Response, with lists and long text shortened: ```json { "data": [ { "id": "tscii", "name": "TSCII 1.7", "about": "Tamil Script Code for Information Interchange: most Tamil web pages and mail from 1997 to the mid-2000s, and the Project Madurai library.", "fonts": [ "TSCu_Paranar", "TSCu_InaimathiTSC", "TSC_Avarangal" ] } ], "meta": { "note": "Convert with /v1/tamil-font/convert, from or to any of these and unicode." } } ``` --- # IP address location API > IP address to country, state, city and network. Country, region (the state, for Indian addresses), city and network operator of a public IPv4 or IPv6 address, from DB-IP's free databases, refreshed monthly. Addresses are never written to the request log. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Location of an IP address `GET /v1/ip/{address}` What you send is never written to the log, and the answer is not cached. Parameters: - `address` (path, required): IPv4 or IPv6 address. Example: https://api.dharun.dev/v1/ip/49.204.0.1 Response: ```json { "data": { "ip": "49.204.0.1", "version": 4, "country": { "code": "IN", "name": "India" }, "continent": "AS", "region": "Telangana", "stateCode": "TS", "city": "Hyderabad (NBT Nagar)", "latitude": 17.4089, "longitude": 78.4346, "asn": { "number": 55577, "organization": "Atria Convergence Technologies Pvt. Ltd." } }, "meta": { "source": { "name": "DB-IP Lite: IP to City and IP to ASN", "url": "https://db-ip.com/db/lite.php", "licence": "CC BY 4.0", "version": "2026-10", "retrieved": "2026-10-14T13:16:38Z", "attribution": "IP Geolocation by DB-IP (https://db-ip.com), licensed under CC BY 4.0." }, "note": "The position is that of a city or district for the address range, not of a device or a person." } } ``` ## Location of your own address `GET /v1/ip` What you send is never written to the log, and the answer is not cached. Example: https://api.dharun.dev/v1/ip ## Data source - [DB-IP Lite: IP to City and IP to ASN](https://db-ip.com/db/lite.php), 2026-10, retrieved 2026-10-14T13:16:38Z. Licence: CC BY 4.0. IP Geolocation by DB-IP (https://db-ip.com), licensed under CC BY 4.0. --- # Email checks API > Is an email address well formed, throwaway, and able to receive mail. Checks the form of an address, whether its domain hands out throwaway mailboxes, whether it is a free provider or a role account such as support@, and whether the domain has mail servers. No mail server is contacted and no mailbox is tried. Addresses are never written to the request log. Counts as 10 requests against the rate limit. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Check an email address `GET /v1/email/{address}` What you send is never written to the log, and the answer is not cached. Parameters: - `address` (path, required): The email address. Example: https://api.dharun.dev/v1/email/someone@mailinator.com ## Data source - [Disposable email domains](https://github.com/disposable-email-domains/disposable-email-domains), bf235abe3d82, retrieved 2026-10-13. Licence: CC0 1.0. Disposable domain list from the disposable-email-domains project (CC0). --- # DNS check API > A domain's DNS records at four public resolvers at once. Asks Cloudflare, Google, Quad9 and OpenDNS for the same record and says whether they agree: useful when a change is still spreading. Counts as 10 requests against the rate limit. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Look up DNS records `GET /v1/dns/{name}` Parameters: - `name` (path, required): Domain name (Indian-script names are accepted), or an IP address for PTR. - `type` (query): Record type. Default A. One of: A, AAAA, CNAME, MX, NS, TXT, CAA, SOA, SRV, PTR. Example: https://api.dharun.dev/v1/dns/dharun.dev?type=MX --- # Phone numbers API > Check and format an Indian phone number, and see whose series it is. Validates an Indian number, tells mobile from toll-free and fixed lines, formats it (E.164 and national), and names the operator and telecom circle a mobile number's series was first given to. With number portability the current operator can differ. Numbers are never written to the request log. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Check a phone number `GET /v1/phone/{number}` What you send is never written to the log, and the answer is not cached. Parameters: - `number` (path, required): The number, with or without +91, 91 or 0; spaces and dashes are ignored. Example: https://api.dharun.dev/v1/phone/+91%2095001%2012345 Response, with lists and long text shortened: ```json { "data": { "valid": true, "type": "mobile", "e164": "+919500112345", "national": "95001 12345", "series": "9500", "originalOperator": { "code": "AT", "name": "Airtel India" }, "circle": { "code": "TN", "name": "Tamil Nadu", "category": "A", "area": "State of Tamil Nadu, Puducherry district and Karaikal district" } }, "meta": { "source": { "name": "Mobile telephone numbering in India", "url": "https://en.wikipedia.org/w/index.php?title=Mobile_telephone_numbering_in_India&oldid=1376522760", "licence": "CC BY-SA 4.0", "version": "revision 1376522760", "retrieved": "2026-10-13", "attribution": "Mobile number series adapted from the Wikipedia article \"Mobile telephone numbering in India\", licensed CC BY-SA 4.0. This dataset is shared under the same lice…" }, "note": "Checks the number's form and names who its series was first given to. With number portability the current operator can differ, and whether the number is in use …" } } ``` ## Data source - [Mobile telephone numbering in India](https://en.wikipedia.org/w/index.php?title=Mobile_telephone_numbering_in_India&oldid=1376522760), revision 1376522760, retrieved 2026-10-13. Licence: CC BY-SA 4.0. Mobile number series adapted from the Wikipedia article "Mobile telephone numbering in India", licensed CC BY-SA 4.0. This dataset is shared under the same licence. --- # Traceroute from India API > The network path from a server in India to any host, with loss and latency per hop. An MTR-style trace from the server's own connection in India: each hop is probed several times, and every hop comes back with its address, name, network (AS) and country, packet loss and round-trip times. Useful to see how Jio, Airtel, BSNL and the rest reach a site, and where along the way delay or loss starts. Only public addresses can be traced. Hops inside private or shared address space are shown without their address. A trace takes several seconds and counts as 20 requests against the rate limit. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Trace the route to a host `GET /v1/mtr/{host}` Lists hops up to the one where the host answered, or one past the last router that answered. A hop with 100% loss is common: many routers forward traffic without answering probes. otherAddresses lists further routers seen at the same hop, where traffic is balanced over several paths. Parameters: - `host` (path, required): Domain name or public IP address. - `rounds` (query): Probes per hop, 1 to 10. Default 5; a trace takes about a second per round. - `v` (query): IP version for a domain name. Default 4. One of: 4, 6. Example: https://api.dharun.dev/v1/mtr/1.1.1.1 ## Data source - [DB-IP Lite: IP to City and IP to ASN](https://db-ip.com/db/lite.php), 2026-10, retrieved 2026-10-14T13:16:38Z. Licence: CC BY 4.0. IP Geolocation by DB-IP (https://db-ip.com), licensed under CC BY 4.0. --- # Regex tester API > Run a regular expression against a text and see every match, explained. Tests a pattern in JavaScript or RE2 (Go) syntax: every match with its groups and their character offsets, an optional replacement, and the pattern taken apart token by token in plain words. JavaScript patterns run under a one-second limit, since nested quantifiers can take exponentially long; RE2 cannot. Patterns and texts are not logged or kept. Each request counts as 10 against the rate limit. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Test a regular expression `GET /v1/regex`, also `POST` An invalid pattern answers 422 with code invalid_pattern and the engine's message; a JavaScript pattern that runs out of time answers 422 with code timeout. A group that took no part in a match has a null text, which is different from an empty one. POST body: The text to test the pattern on (pattern and options in the query), or JSON {"pattern": ..., "text": ...} with the options beside them. Send it as `text/plain`, or as JSON `{"text": "..."}` with the other options beside it. What you send is never written to the log, and the answer is not cached. Parameters: - `pattern` (query, required): The regular expression, without slashes. Up to 4096 bytes. - `text` (query): The text to test it on (or POST it). - `flavor` (query): js (default): JavaScript syntax, with lookaround and backreferences. re2: Go's syntax, linear time. One of: js, re2. - `flags` (query): Any of i (ignore case), m (^ and $ at line breaks), s (. matches line breaks). Every match is always listed, so g is not needed. - `replace` (query): Replace every match with this: $1, $, $& and $$ in js; ${1}, ${name} and $$ in re2. - `limit` (query): Matches listed, 1 to 1000. Default 100; count goes on to the end of the text. Example: https://api.dharun.dev/v1/regex?flags=i&pattern=%28%3F%3Cstate%3E%5BA-Z%5D%7B2%7D%29%5B+-%5D%3F%28%5Cd%7B2%7D%29&text=Cars+TN+37%2C+ka-05+and+MH12 Response, with lists and long text shortened: ```json { "data": { "flavor": "js", "pattern": "(?[A-Z]{2})[ -]?(\\d{2})", "flags": "i", "groups": [ { "index": 1, "name": "state" }, { "index": 2 } ], "count": 3, "truncated": false, "matches": [ { "text": "TN 37", "start": 5, "end": 10, "groups": [ { "index": 1, "name": "state", "text": "TN", "start": 5, "end": 7 }, { "index": 2, "text": "37", "start": 8, "end": 10 } ] }, { "text": "ka-05", "start": 12, "end": 17, "groups": [ { "index": 1, "name": "state", "text": "ka", "start": 12, "end": 14 }, { "index": 2, "text": "05", "start": 15, "end": 17 } ] }, { "text": "MH12", "start": 22, "end": 26, "groups": [ { "index": 1, "name": "state", "text": "MH", "start": 22, "end": 24 }, { "index": 2, "text": "12", "start": 24, "end": 26 } ] } ], "explanation": [ { "token": "(?", "depth": 0, "meaning": "Start of capturing group 1, named \"state\"." }, { "token": "[A-Z]", "depth": 1, "meaning": "One character: “A” to “Z”." }, { "token": "{2}", "depth": 1, "meaning": "Repeats the item before it exactly 2 times." } ] }, "meta": { "note": "JavaScript syntax, run by regexp2 in ECMAScript mode. It agrees with browsers and Node.js in nearly every case; a backreference such as \\1 in a pattern that mix…" } } ``` --- # Fake test data API > Made-up Indian people, companies and addresses for testing apps. Realistic test records that pass format checks: names from nine language regions, addresses at real pincodes with the right district and state, phone numbers, PANs and GSTINs with a correct check character. Every record is marked fake and none describes a real person or business. Give a seed to get the same records every time. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Generate fake records `GET /v1/fake/{kind}` people have a name, gender, birth date, email (on example domains), phone, PAN and address; companies a name, PAN, GSTIN, email, phone and address. Parameters: - `kind` (path, required): What to generate. One of: people, companies, addresses. - `count` (query): How many, 1 to 100. Default 10. - `state` (query): State code or name, for example TN or Tamil Nadu. - `seed` (query): The same seed gives the same records. Without one, each request differs. Example: https://api.dharun.dev/v1/fake/people?count=3&state=TN&seed=42 Response, with lists and long text shortened: ```json { "data": [ { "fake": true, "name": "Swetha Velusamy", "firstName": "Swetha", "lastName": "Velusamy", "gender": "female", "birthDate": "1989-02-16", "email": "swetha.velusamy68@example.net", "phone": "+91 78585 85475", "pan": "IBHPV7917Y", "address": { "line1": "No. 234, Nehru Street", "line2": "Ambedkar Colony", "city": "Bayamariyanendal", "district": "Pudukkottai", "stateCode": "TN", "state": "Tamil Nadu", "pincode": "614619" } }, { "fake": true, "name": "Saravanan Perumal", "firstName": "Saravanan", "lastName": "Perumal", "gender": "male", "birthDate": "2000-05-23", "email": "saravanan.perumal77@example.net", "phone": "+91 65125 54058", "pan": "PPBPP7146Z", "address": { "line1": "No. 141, Main Road", "line2": "Lakshmi Nagar", "city": "Odugampatti", "district": "Pudukkottai", "stateCode": "TN", "state": "Tamil Nadu", "pincode": "622502" } }, { "fake": true, "name": "Dinesh Krishnan", "firstName": "Dinesh", "lastName": "Krishnan", "gender": "male", "birthDate": "1949-12-01", "email": "dinesh.krishnan51@example.org", "phone": "+91 64882 31759", "pan": "UPRPK3338U", "address": { "line1": "No. 192, Temple Street", "line2": "Bharathi Nagar", "city": "Veluganandal", "district": "Tiruvannamalai", "stateCode": "TN", "state": "Tamil Nadu", "pincode": "606802" } } ], "meta": { "total": 3, "source": { "name": "All India Pincode Directory", "url": "https://www.data.gov.in/resource/all-india-pincode-directory-till-last-month", "licence": "Government Open Data License - India (GODL)", "version": "23760720 bytes", "retrieved": "2026-10-13", "attribution": "Contains data from the All India Pincode Directory, Department of Posts, published on data.gov.in under the Government Open Data License - India." }, "note": "Made-up test data: no record describes a real person or business. Pincodes, districts and states are real and belong together; everything else is invented. Phon…" } } ``` ## Data source - [All India Pincode Directory](https://www.data.gov.in/resource/all-india-pincode-directory-till-last-month), 23760720 bytes, retrieved 2026-10-13. Licence: Government Open Data License - India (GODL). Contains data from the All India Pincode Directory, Department of Posts, published on data.gov.in under the Government Open Data License - India. --- # Generated images API > Social preview images and code screenshots from a URL. Pictures made from text, with no browser involved: link-preview (Open Graph) cards and syntax-coloured code images. Latin, Devanagari, Bengali, Gurmukhi, Gujarati, Odia, Tamil, Telugu, Kannada and Malayalam are shaped properly (conjuncts, vowel signs) and can be mixed in one line; other scripts come out as empty boxes. PNG by default; format=svg gives the same picture as an SVG whose text is drawn as outlines, so it needs no fonts where it is shown. Text and colours only: no images are fetched from anywhere. Each request counts as 10 against the rate limit. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Social preview image `GET /v1/og-image` A 1200 by 630 card for og:image and twitter:image: a title (set as large as fits in three lines, cut with an ellipsis beyond that), an optional subtitle of up to two lines, and a site name and tag along the bottom. The same URL always gives the same picture, so it can be used directly in a meta tag. Parameters: - `title` (query, required): Up to 200 characters, in any script. - `subtitle` (query): Up to 300 characters; two lines are shown. - `site` (query): Site name, bottom left. - `tag` (query): Short label, bottom right. - `theme` (query): Default dark. One of: dark, light. - `bg` (query): Background colour, hex. - `fg` (query): Title colour, hex. - `accent` (query): Accent colour, hex. - `format` (query): Default png. One of: png, svg. Example: https://api.dharun.dev/v1/og-image?title=Free%20APIs%20for%20Indian%20developers&subtitle=Pincodes%2C%20IFSC%2C%20holidays%20and%20more&site=api.dharun.dev (returns the image itself) ## Code as an image `GET /v1/code-image`, also `POST` A code snippet as a window with syntax colouring. Up to 150 lines of 140 characters. PNGs are drawn at twice the pixel density for sharp text (very large ones at single). The language is guessed from the title's file extension or the code when not given, and reported in the X-Code-Language header. POST body: The code. Send it as `text/plain`, or as JSON `{"text": "..."}` with the other options beside it. What you send is never written to the log, and the answer is not cached. Parameters: - `code` (query): The code (or POST it). - `language` (query): Language name or file extension, such as go, python, js, sql. - `title` (query): File name shown in the title bar. - `theme` (query): Default dark. One of: dark, light. - `lineNumbers` (query): Show line numbers. One of: true. - `format` (query): Default png. One of: png, svg. Example: https://api.dharun.dev/v1/code-image?language=go&title=main.go&code=package+main%0A%0Aimport+%22fmt%22%0A%0Afunc+main%28%29+%7B%0A%09fmt.Println%28%22%E0%AE%B5%E0%AE%A3%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%AE%E0%AF%8D%22%29%0A%7D (returns the image itself) --- # Satellite passes API > When the ISS and amateur radio satellites pass over you, and where they are now. Pass predictions for the space stations (ISS, Tiangong) and about ninety amateur radio satellites, from any Indian pincode or any latitude and longitude: when each rises, how high it gets and where, when it sets, and whether it can be seen with the eye. Computed with SGP4 from CelesTrak's orbit elements, refreshed a few times a day; the elements themselves are not published here. Pass predictions count as 10 requests against the rate limit. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Passes over a place `GET /v1/sat-pass` Passes from now for the next days, soonest first. Directions are compass points and azimuths in degrees from true north; elevations are degrees above the horizon. A satellite can be named by catalogue number, by name, by the designation in its name's brackets (SO-50, AO-7), or as ISS, CSS or QO-100. Parameters: - `sat` (query): Catalogue number or name. Default ISS (25544). - `pincode` (query): Indian pincode of the observer. - `lat` (query): Latitude, if no pincode. Default New Delhi. - `lng` (query): Longitude, if no pincode. - `days` (query): How far ahead, 1 to 10. Default 3. - `minElevation` (query): Lowest peak elevation listed, in degrees. Default 10; 0 lists every pass. - `visible` (query): true lists only passes that can be seen with the eye. One of: true, false. - `tz` (query): IANA time zone for the times. Default Asia/Kolkata. Example: https://api.dharun.dev/v1/sat-pass?sat=ISS&pincode=600001 Response, with lists and long text shortened: ```json { "data": { "satellite": { "number": 25544, "name": "ISS (ZARYA)", "groups": [ "space stations", "amateur radio" ], "periodMinutes": 92.98, "inclination": 51.633, "elementsEpoch": "2026-10-13T19:43:22Z" }, "elementsAgeDays": 0.92, "place": { "latitude": 13.0949, "longitude": 80.287, "timeZone": "Asia/Kolkata", "pincode": "600001", "name": "Chennai" }, "from": "2026-10-14T23:22:00+05:30", "until": "2026-10-17T23:22:00+05:30", "minElevation": 10, "passes": [ { "rise": { "time": "2026-10-15T03:31:20+05:30", "azimuth": 210.4, "direction": "SSW", "elevation": 0, "rangeKm": 2349 }, "culmination": { "time": "2026-10-15T03:36:44+05:30", "azimuth": 127.5, "direction": "SE", "elevation": 60.1, "rangeKm": 482 }, "set": { "time": "2026-10-15T03:42:11+05:30", "azimuth": 41.9, "direction": "NE", "elevation": -0, "rangeKm": 2365 }, "durationSeconds": 650, "visible": { "from": "2026-10-15T03:42:00+05:30", "until": "2026-10-15T03:42:10+05:30" } }, { "rise": { "time": "2026-10-15T13:25:42+05:30", "azimuth": 341.7, "direction": "NNW", "elevation": 0, "rangeKm": 2358 }, "culmination": { "time": "2026-10-15T13:30:46+05:30", "azimuth": 50.2, "direction": "NE", "elevation": 21.2, "rangeKm": 993 }, "set": { "time": "2026-10-15T13:35:49+05:30", "azimuth": 118.8, "direction": "ESE", "elevation": -0, "rangeKm": 2355 }, "durationSeconds": 606, "visible": null }, { "rise": { "time": "2026-10-15T15:02:43+05:30", "azimuth": 295, "direction": "WNW", "elevation": 0, "rangeKm": 2355 }, "culmination": { "time": "2026-10-15T15:07:22+05:30", "azimuth": 236, "direction": "SW", "elevation": 13.5, "rangeKm": 1294 }, "set": { "time": "2026-10-15T15:12:00+05:30", "azimuth": 176.6, "direction": "S", "elevation": -0, "rangeKm": 2349 }, "durationSeconds": 556, "visible": null } ] }, "meta": { "total": 10, "source": { "name": "CelesTrak current GP element sets", "url": "https://celestrak.org/NORAD/elements/", "licence": "None stated by CelesTrak. USSPACECOM allows redistribution of basic space situational awareness data with credit; only results computed from it are published he…", "version": "fde424564d41", "retrieved": "2026-10-14T13:16:38Z", "attribution": "Orbit elements from CelesTrak (celestrak.org), based on US Space Force data from Space-Track.org." }, "note": "Passes from now, computed with SGP4 from the satellite's latest orbit elements. Rise and set are when it crosses the horizon (elevation 0°, no refraction); a pa…" } } ``` ## Where a satellite is now `GET /v1/satellites/{id}` The point on Earth below the satellite at the moment of the request, its altitude and speed, whether it is in sunlight, and how old its orbit elements are. Parameters: - `id` (path, required): Catalogue number or name. Example: https://api.dharun.dev/v1/satellites/ISS Response, with lists and long text shortened: ```json { "data": { "number": 25544, "name": "ISS (ZARYA)", "groups": [ "space stations", "amateur radio" ], "periodMinutes": 92.98, "inclination": 51.633, "elementsEpoch": "2026-10-13T19:43:22Z", "at": "2026-10-14T17:52:28Z", "latitude": 47.6603, "longitude": -102.7327, "altitudeKm": 429.2, "speedKmPerSecond": 7.658, "sunlit": true, "elementsAgeDays": 0.92 }, "meta": { "source": { "name": "CelesTrak current GP element sets", "url": "https://celestrak.org/NORAD/elements/", "licence": "None stated by CelesTrak. USSPACECOM allows redistribution of basic space situational awareness data with credit; only results computed from it are published he…", "version": "fde424564d41", "retrieved": "2026-10-14T13:16:38Z", "attribution": "Orbit elements from CelesTrak (celestrak.org), based on US Space Force data from Space-Track.org." }, "note": "Where the satellite is at the moment of the request, over the WGS 84 ellipsoid." } } ``` ## Tracked satellites `GET /v1/satellites` Every tracked satellite with its catalogue number, groups, orbital period and inclination. Parameters: - `q` (query): Part of a name, or a catalogue number. - `group` (query): Limit to one group. One of: stations, amateur. Example: https://api.dharun.dev/v1/satellites?group=stations Response, with lists and long text shortened: ```json { "data": [ { "number": 25544, "name": "ISS (ZARYA)", "groups": [ "space stations", "amateur radio" ], "periodMinutes": 92.98, "inclination": 51.633, "elementsEpoch": "2026-10-13T19:43:22Z" }, { "number": 36086, "name": "POISK", "groups": [ "space stations" ], "periodMinutes": 92.98, "inclination": 51.633, "elementsEpoch": "2026-10-13T19:43:22Z" }, { "number": 48274, "name": "CSS (TIANHE)", "groups": [ "space stations" ], "periodMinutes": 92.31, "inclination": 41.47, "elementsEpoch": "2026-10-14T06:49:21Z" } ], "meta": { "total": 18, "source": { "name": "CelesTrak current GP element sets", "url": "https://celestrak.org/NORAD/elements/", "licence": "None stated by CelesTrak. USSPACECOM allows redistribution of basic space situational awareness data with credit; only results computed from it are published he…", "version": "fde424564d41", "retrieved": "2026-10-14T13:16:38Z", "attribution": "Orbit elements from CelesTrak (celestrak.org), based on US Space Force data from Space-Track.org." } } } ``` ## Data source - [CelesTrak current GP element sets](https://celestrak.org/NORAD/elements/), fde424564d41, retrieved 2026-10-14T13:16:38Z. Licence: None stated by CelesTrak. USSPACECOM allows redistribution of basic space situational awareness data with credit; only results computed from it are published here. Orbit elements from CelesTrak (celestrak.org), based on US Space Force data from Space-Track.org. --- # HF propagation API > Space weather and a rough rating of shortwave radio bands, day and night. The numbers amateur radio operators check before getting on the air, from NOAA's Space Weather Prediction Center and refreshed every hour: 10.7 cm solar flux, sunspot number, the planetary K and A indices, the X-ray class and latest flare, solar wind speed and NOAA's radio blackout, radiation and geomagnetic storm scales. From those, each band group gets a good, fair or poor rating for day and for night. The ratings are a rule of thumb, and the rules are returned with them. Base URL `https://api.dharun.dev`. No API key. Answers are JSON, `{ "data": ..., "meta": { ... } }`, and errors are `{ "error": { "code", "message" } }` with a matching HTTP status. Rate limit: 600 requests a minute per client. ## Space weather and band conditions `GET /v1/propagation` Rules behind the band ratings: 80m-40m: fair by day (D-layer absorption), good at night. 30m-20m: good by day; at night good from a solar flux of 120, fair from 80, else poor. 17m-15m: by day good from a solar flux of 110, fair from 80, else poor; at night fair from 150, else poor. 12m-10m: by day good from a solar flux of 150, fair from 110, else poor; at night fair from 200, else poor. A K-index of 4 lowers every night rating one step; 5 or more lowers every rating one step, and 7 or more two. An M-class X-ray flux lowers the day rating of 80m-40m and 30m-20m one step; X-class makes every day rating poor. Readings NOAA did not publish at the last fetch are null. Example: https://api.dharun.dev/v1/propagation Response, with lists and long text shortened: ```json { "data": { "solarFlux": { "value": 136, "observed": "2026-10-13T20:00:00Z" }, "sunspotNumber": { "value": 102, "date": "2026-10-13" }, "kIndex": { "value": 2, "level": "quiet", "observed": "2026-10-14T12:00:00Z" }, "aIndex": { "value": 13, "date": "2026-10-13" }, "xray": { "class": "B6.4", "flux": 6.4e-7, "observed": "2026-10-14T17:36:00Z" }, "latestFlare": { "class": "C2.2", "peak": "2026-10-14T15:57:00Z" }, "solarWindSpeed": { "value": 538, "observed": "2026-10-14T17:30:00Z" }, "noaaScales": { "radioBlackout": "R0", "solarRadiation": "S0", "geomagneticStorm": "G0", "observed": "2026-10-14T17:38:00Z" }, "kHistory": [ { "start": "2026-10-13T15:00:00Z", "kp": 2.33 }, { "start": "2026-10-13T18:00:00Z", "kp": 3 }, { "start": "2026-10-13T21:00:00Z", "kp": 1.33 } ], "bands": [ { "band": "80m-40m", "day": "fair", "night": "good" }, { "band": "30m-20m", "day": "good", "night": "good" }, { "band": "17m-15m", "day": "good", "night": "poor" } ], "rules": [ "80m-40m: fair by day (D-layer absorption), good at night.", "30m-20m: good by day; at night good from a solar flux of 120, fair from 80, else poor.", "17m-15m: by day good from a solar flux of 110, fair from 80, else poor; at night fair from 150, else poor." ] }, "meta": { "source": { "name": "Space weather data", "url": "https://www.swpc.noaa.gov/", "licence": "Public domain (work of the US government)", "version": "6 of 6 files", "retrieved": "2026-10-14T17:39:57Z", "attribution": "Space weather data from the NOAA Space Weather Prediction Center." }, "note": "Indices from NOAA SWPC, fetched every hour (meta.source.retrieved says when). The band ratings are a rule of thumb from the solar flux, the K-index and the X-ra…" } } ``` ## Data source - [Space weather data](https://www.swpc.noaa.gov/), 6 of 6 files, retrieved 2026-10-14T17:39:57Z. Licence: Public domain (work of the US government). Space weather data from the NOAA Space Weather Prediction Center. --- # Guide: Bank holidays, working days and T+1 settlement dates > Find whether a date is a bank holiday in a state, the next working day, N working days ahead, and NSE settlement dates, in Python. Bank holidays in India differ by state, and some Saturdays are working days while others are not. The working-days endpoint knows the Reserve Bank's holiday list for each state, the second and fourth Saturday rule, and NSE's trading and clearing holidays. ## Is a date a working day? ```sh curl "https://api.dharun.dev/v1/working-days/2026-01-26?calendar=bank&state=TN" ``` ```json { "data": { "date": "2026-01-26", "weekday": "Monday", "calendar": "bank", "state": "TN", "working": false, "reasons": ["Republic Day"], "previousWorkingDay": "2026-01-23", "nextWorkingDay": "2026-01-27" } } ``` `calendar` is one of `bank` (needs `state`), `market` (NSE trading days), `settlement` (NSE clearing days) or `central` (central government offices). ## N working days from a date Add `add=N` (negative to go back) and read `shifted`. A T+1 trade settles one settlement day later: ```sh curl "https://api.dharun.dev/v1/working-days/2026-01-16?calendar=settlement&add=1" ``` ```json { "data": { "date": "2026-01-16", "working": true, "add": 1, "shifted": "2026-01-19" } } ``` ## In Python ```python import requests API = "https://api.dharun.dev/v1" def working_day(date: str, calendar: str = "bank", state: str | None = None, add: int = 0) -> dict: params = {"calendar": calendar} if state: params["state"] = state if add: params["add"] = add response = requests.get(f"{API}/working-days/{date}", params=params, timeout=10) body = response.json() if not response.ok: raise RuntimeError(body["error"]["message"]) return body["data"] day = working_day("2026-01-26", state="TN") if not day["working"]: print(f"Closed for {', '.join(day['reasons'])}; next open {day['nextWorkingDay']}") due = working_day("2026-01-16", calendar="bank", state="TN", add=3)["shifted"] print(f"Three bank working days later: {due}") ``` ## Count working days in a period ```sh curl "https://api.dharun.dev/v1/working-days?from=2026-01-01&to=2026-01-31&calendar=market" ``` The answer has the count and each day off with its reason. A period can be up to 366 days long. ## The holiday list itself ```sh curl "https://api.dharun.dev/v1/holidays/2026?type=bank&state=TN" ``` Only years whose lists have been published are answered, so a request for a year too far ahead returns an error rather than a guess. Festival dates that depend on the moon can move; the lists follow the issuing authority's latest notice. The code in this guide is MIT-0: copy it into anything, no credit needed. --- # Guide: Check a GSTIN or PAN before you save it > Catch typing mistakes in GSTINs and PANs with the check character, and read the state and PAN out of a GSTIN, in JavaScript. A GSTIN has fifteen characters: a two-digit state code, the holder's PAN, an entity number, the letter Z and a check character computed from the other fourteen. One wrong character makes the check fail, so a format check catches nearly every typing mistake without asking any government system. ## The request ```sh curl https://api.dharun.dev/v1/validate/gstin/27AAPFU0939F1ZV ``` ```json { "data": { "kind": "gstin", "normalized": "27AAPFU0939F1ZV", "valid": true, "parts": { "entityNumber": "1", "holderType": "Firm or Limited Liability Partnership", "pan": "AAPFU0939F", "state": "Maharashtra", "stateCode": "27" } }, "meta": { "note": "This checks the format only. It does not confirm that the identifier was ever issued." } } ``` A wrong character still answers `200`, with `valid: false` and the reason: ```sh curl https://api.dharun.dev/v1/validate/gstin/27AAPFU0939F1ZX ``` ```json { "data": { "kind": "gstin", "normalized": "27AAPFU0939F1ZX", "valid": false, "reason": "The check character does not match; one of the characters is wrong." } } ``` ## In a form ```js async function checkGstin(value) { const response = await fetch( `https://api.dharun.dev/v1/validate/gstin/${encodeURIComponent(value.trim())}` ); const { data } = await response.json(); if (!data.valid) return { ok: false, message: data.reason }; return { ok: true, gstin: data.normalized, // upper case, spaces removed: store this one state: data.parts.state, pan: data.parts.pan, }; } const result = await checkGstin("27aapfu0939f1zv"); console.log(result.ok ? `${result.gstin} is from ${result.state}` : result.message); ``` Compare `state` with the billing address's state: a GSTIN registered in another state is a common source of wrong tax on an invoice. ## PAN The fourth letter of a PAN says what kind of holder it belongs to: P for a person, C for a company, F for a firm and so on. ```sh curl https://api.dharun.dev/v1/validate/pan/ABCPK1234F ``` ```json { "data": { "kind": "pan", "normalized": "ABCPK1234F", "valid": true, "parts": { "holderType": "Individual" } } } ``` ## What it cannot tell you These checks are structural. A well-formed GSTIN may never have been issued, or may have been cancelled; only the GST portal knows that. Values sent to the format checks are never written to the request log. The code in this guide is MIT-0: copy it into anything, no credit needed. --- # Guide: Fill city and state from a pincode in a web form > Look up the district and state as soon as someone types a six-digit pincode, with plain JavaScript and no API key. Indian address forms ask for a pincode, a city and a state. The pincode alone tells you the district and the state, so you can fill those fields for the person typing. ## The request `GET /v1/pincode/{pincode}` returns the district, the state and every post office that uses the pincode: ```sh curl https://api.dharun.dev/v1/pincode/637001 ``` ```json { "data": { "pincode": "637001", "district": "Namakkal", "stateCode": "TN", "state": "Tamil Nadu", "offices": [ { "name": "Namakkal H.O", "type": "Head Office", "delivery": true, "district": "Namakkal" }, { "name": "Namakkal Bazaar S.O", "type": "Post Office", "delivery": false, "district": "Namakkal" } ] }, "meta": { "source": { "name": "...", "licence": "..." } } } ``` The real answer has a few more fields on each office (division, region, latitude and longitude). A pincode that does not exist answers `404` with `{ "error": { "code": "not_found", "message": "..." } }`. ## The form No key is needed and CORS is open, so the browser can call the API directly: ```html ``` ## Good to know - Keep the fields editable. A few pincodes reach into two districts; each office in `offices` carries its own `district`, so use the chosen office's district when it must be exact. - `stateCode` is the two-letter code that every other endpoint accepts in its `state` filter. [`/v1/states/TN`](https://api.dharun.dev/v1/states/TN) gives the state's GST code and vehicle prefixes. - To find a pincode from a place name instead, search: [`/v1/pincode?q=namakkal&state=TN`](https://api.dharun.dev/v1/pincode?q=namakkal&state=TN). - Pincodes change rarely. Cache answers for a day or more if you look up the same ones often. The code in this guide is MIT-0: copy it into anything, no credit needed. --- # Guide: Make a UPI payment QR code for an amount > Generate a QR code that any UPI app can scan to pay a set amount to your UPI ID, or a upi://pay link for a button on mobile. A UPI QR code is a `upi://pay` link drawn as a QR code. Any UPI app (Google Pay, PhonePe, Paytm, BHIM and the banks' own apps) can scan it and fill in the payee, the amount and a note. ## The QR code The endpoint returns the image, so it goes straight into an `` tag: ```html Scan to pay ₹250 to Sri Murugan Stores ``` | Parameter | Meaning | |---|---| | `pa` | Your UPI ID (required) | | `pn` | The name the payer's app shows | | `am` | The amount in rupees; leave it out to let the payer type it | | `tn` | A note, such as an order number | | `tr` | Your own reference for the payment | Add `format=png&size=512` for a PNG, which most printing tools prefer. ## A pay button on mobile On a phone, scanning your own screen is impossible, so offer the link itself. `format=json` returns it: ```sh curl "https://api.dharun.dev/v1/upi-qr?pa=shop@okaxis&pn=Sri%20Murugan%20Stores&am=250&tn=Order%2042&format=json" ``` ```json { "data": { "link": "upi://pay?pa=shop@okaxis&pn=Sri%20Murugan%20Stores&am=250.00&cu=INR&tn=Order%2042", "payeeAddress": "shop@okaxis", "payeeName": "Sri Murugan Stores", "amount": "250.00" } } ``` ```html Pay ₹250 with UPI ``` ## Good to know - Nothing is checked with a bank. A mistyped UPI ID still makes a QR code; the payer's app finds out when it tries to pay. Test with a small amount first. - A QR code does not tell you that someone paid. Confirm payments in your bank or payment gateway, using `tr` or `tn` to match them. - Payment details you send are never logged, and the images are marked so shared caches do not keep them. The code in this guide is MIT-0: copy it into anything, no credit needed. --- # Guide: Remove Aadhaar, PAN and phone numbers before sending text to an LLM > Mask Indian personal identifiers in text before it reaches a language model or a log, with check-digit validation so ordinary numbers are left alone. Support tickets, chat messages and documents often carry Aadhaar numbers, PANs, phone numbers and bank card numbers. Masking them before the text goes to a language model, a vector store or a log keeps them out of places they should not be. The redaction endpoint finds Indian identifiers by their structure and, where they have one, their check digit (Verhoeff for Aadhaar, Luhn for cards, the GSTIN check character), so a 12-digit order number is not mistaken for an Aadhaar number. ## The request Send the text as the POST body: ```sh curl -X POST https://api.dharun.dev/v1/text/redact \ -H "Content-Type: text/plain" \ --data "Call 98765 43210, PAN ABCPK1234F" ``` ```json { "data": { "text": "Call [PHONE], PAN [PAN]", "findings": [ { "type": "phone", "start": 5, "end": 16 }, { "type": "pan", "start": 22, "end": 32 } ], "counts": { "pan": 1, "phone": 1 } }, "meta": { "note": "Finds identifiers by their structure and check digits. Names and street addresses are not detected." } } ``` Short text can also go in the query: [`/v1/text/redact?text=Call%2098765%2043210`](https://api.dharun.dev/v1/text/redact?text=Call%2098765%2043210). The original values are never returned, and nothing you send is logged or kept. ## Before calling a model, in Python ```python import requests def redact(text: str) -> str: response = requests.post( "https://api.dharun.dev/v1/text/redact", data=text.encode("utf-8"), headers={"Content-Type": "text/plain; charset=utf-8"}, timeout=10, ) body = response.json() if not response.ok: raise RuntimeError(body["error"]["message"]) return body["data"]["text"] ticket = "Refund to my card please. PAN ABCPK1234F, call me on 98765 43210." safe = redact(ticket) # "Refund to my card please. PAN [PAN], call me on [PHONE]." # Now send `safe` to the model instead of `ticket`. ``` ## Options - `style=partial` keeps the last characters, as a bank statement does: `XXXXX XXX10`. - `types=aadhaar,pan,phone` limits what is masked. The kinds are `email`, `upi`, `gstin`, `card`, `aadhaar`, `pan`, `phone`, `vehicle`, `voter_id`, `passport` and `ip`. - With JSON, put the options beside the text: `{"text": "...", "style": "partial"}`. ## What it does not catch Names and street addresses have no fixed shape, so they are not detected. Treat redaction as one layer: still send models only the text a task needs. To see how many tokens the redacted text will cost, [`/v1/text/tokens`](https://api.dharun.dev/v1/text/tokens?model=gpt-4o&text=Call%20%5BPHONE%5D) counts them with OpenAI's tokenizers. The code in this guide is MIT-0: copy it into anything, no credit needed. --- # Guide: Show NSE and BSE company logos in your app > Put a listed company's logo in an img tag by ticker or ISIN, as SVG or sized PNG, with an initials tile when no logo exists. A watchlist or portfolio screen reads much faster with logos. The logo endpoint returns the image itself, so the URL goes straight into an `` tag. ## By ticker ```html TCS ``` A symbol can be a bare ticker (`TCS`, NSE is preferred), an exchange-qualified ticker (`NSE:TCS`), a Yahoo Finance symbol (`TCS.NS`) or an ISIN (`INE467B01029`). ## PNG at a set size SVG is the default. For PNG, give `format=png` and a `size` from 16 to 512 pixels: ```html TCS ``` Asking for twice the size you display keeps it sharp on high-density screens. ## When there is no logo An unknown symbol answers `404`, which shows as a broken image. With `fallback=monogram` it answers with a tile of the company's initials instead, and sets the `X-Logo-Fallback` header so you can tell: ```html NewCo ``` ## A React component ```jsx export function CompanyLogo({ symbol, size = 32 }) { const src = `https://api.dharun.dev/v1/logos/${encodeURIComponent(symbol)}?format=png&size=${size * 2}&fallback=monogram`; return {symbol}; } ``` ## Details and search `/v1/companies/{symbol}` returns the name, sector, industry, ISIN, market capitalisation, index memberships and the logo URLs: ```sh curl https://api.dharun.dev/v1/companies/RELIANCE curl "https://api.dharun.dev/v1/companies?q=tata&limit=5" ``` Logos are trademarks of their companies. Use them to identify the company, as a stock app does, not to suggest endorsement. The code in this guide is MIT-0: copy it into anything, no credit needed. --- # Guide: Show the bank and branch for an IFSC code > Turn an IFSC into a bank name, branch and address, and check that the branch takes NEFT, RTGS, IMPS or UPI before you send money there. When someone adds a bank account for a payout, showing "State Bank of India, Kolkata Main" under the IFSC they typed catches most mistakes before any money moves. ## Look up the branch ```sh curl https://api.dharun.dev/v1/ifsc/SBIN0000001 ``` ```json { "data": { "ifsc": "SBIN0000001", "bank": { "code": "SBIN", "name": "State Bank of India" }, "branch": "KOLKATA MAIN", "address": "SAMRIDDHI BHAWAN, 1 STRAND ROAD, KOLKATA 700 001", "city": "Kolkata", "district": "Kolkata", "stateCode": "WB", "state": "West Bengal", "micr": "700002021", "imps": true, "neft": true, "rtgs": true, "upi": true }, "meta": { "source": { "name": "IFSC dataset", "licence": "..." } } } ``` An IFSC that is not in the Reserve Bank's lists answers `404`. ## In Python ```python from functools import lru_cache import requests API = "https://api.dharun.dev/v1" @lru_cache(maxsize=4096) def branch(ifsc: str) -> dict | None: """The branch for an IFSC, or None if no branch has that code.""" response = requests.get(f"{API}/ifsc/{ifsc.strip().upper()}", timeout=10) if response.status_code == 404: return None response.raise_for_status() return response.json()["data"] found = branch("SBIN0000001") if found is None: print("No branch has this IFSC. Check it again.") elif not found["neft"]: print(f"{found['bank']['name']}, {found['branch']} does not take NEFT.") else: print(f"{found['bank']['name']}, {found['branch']}, {found['city']}") ``` ## Check the format first If you only want to know whether a code is shaped like an IFSC (four letters, a zero, six letters or digits), use the format check. It answers from the rules alone and never says 404: ```sh curl https://api.dharun.dev/v1/validate/ifsc/SBIN0000001 ``` ## Find a bank's code or its branches - Banks by name: [`/v1/banks?q=gramin`](https://api.dharun.dev/v1/banks?q=gramin) - One bank's branches in a state, filtered by text: [`/v1/ifsc?bank=SBIN&state=TN&q=namakkal`](https://api.dharun.dev/v1/ifsc?bank=SBIN&state=TN&q=namakkal) The data comes from the Reserve Bank's NEFT and RTGS lists through the open razorpay/ifsc dataset, and the server refreshes it every week. The code in this guide is MIT-0: copy it into anything, no credit needed. --- # Guide: Write rupee amounts in words for invoices and cheques > Spell an amount the Indian way, with lakh and crore, rupees and paise, in English, Hindi or Tamil. Invoices, receipts and cheques print the amount in words, and in India that means lakh and crore, not hundred thousand and million. ## The request ```sh curl "https://api.dharun.dev/v1/words/1,25,000.50?style=currency" ``` ```json { "data": { "input": "1,25,000.50", "number": "125000.50", "language": "en", "style": "currency", "words": "one lakh twenty-five thousand rupees and fifty paise only" } } ``` Commas, spaces and underscores in the number are ignored, so `125000.50` and `1,25,000.50` give the same answer. Without `style=currency` you get the plain number: "one lakh twenty-five thousand point five zero". ## Hindi and Tamil ```sh curl "https://api.dharun.dev/v1/words/1,25,000.50?style=currency&lang=hi" # एक लाख पच्चीस हज़ार रुपये और पचास पैसे मात्र curl "https://api.dharun.dev/v1/words/250?style=currency&lang=ta" ``` ## On an invoice ```js async function amountInWords(amount, lang = "en") { const response = await fetch( `https://api.dharun.dev/v1/words/${amount.toFixed(2)}?style=currency&lang=${lang}` ); const body = await response.json(); if (!response.ok) throw new Error(body.error.message); return body.data.words; } const words = await amountInWords(125000.5); // "one lakh twenty-five thousand rupees and fifty paise only" document.querySelector("#total-in-words").textContent = words.charAt(0).toUpperCase() + words.slice(1); ``` Pass the amount with two decimals (`toFixed(2)`), so that 0.5 rupees is read as fifty paise. The code in this guide is MIT-0: copy it into anything, no credit needed. --- # Use India API from your AI assistant > Connect the MCP server and your assistant can look up pincodes, IFSC codes, holidays and more by itself. No key, no sign-up, nothing to install. MCP server: `https://api.dharun.dev/mcp` (Streamable HTTP, stateless, no authentication). Each of the 44 tools returns exactly what the matching REST endpoint returns. ## Claude Code Add the server, or install the plugin, which brings the skill as well. ``` claude mcp add --transport http india-api https://api.dharun.dev/mcp # or the plugin (skill and MCP server together) /plugin marketplace add dharunashokkumar/api.dharun.dev /plugin install india-api@dharun-dev ``` ## Claude (claude.ai and Claude Desktop) Settings, Connectors, Add custom connector. Name it India API and paste the address. No authentication is needed. ``` https://api.dharun.dev/mcp ``` ## ChatGPT Where your plan allows custom connectors: turn on developer mode in Settings, then create a connector with this address and no authentication. ``` https://api.dharun.dev/mcp ``` ## VS Code (GitHub Copilot) Use the button, or add this to .vscode/mcp.json. ``` { "servers": { "india-api": { "type": "http", "url": "https://api.dharun.dev/mcp" } } } ``` Install in VS Code: https://vscode.dev/redirect/mcp/install?name=india-api&config=%7B%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fapi.dharun.dev%2Fmcp%22%7D ## Cursor Use the button, or add this to ~/.cursor/mcp.json. ``` { "mcpServers": { "india-api": { "url": "https://api.dharun.dev/mcp" } } } ``` Install in Cursor: https://cursor.com/en/install-mcp?name=india-api&config=eyJ1cmwiOiJodHRwczovL2FwaS5kaGFydW4uZGV2L21jcCJ9 ## Windsurf Add this to ~/.codeium/windsurf/mcp_config.json. ``` { "mcpServers": { "india-api": { "serverUrl": "https://api.dharun.dev/mcp" } } } ``` ## Gemini CLI Add this to ~/.gemini/settings.json. ``` { "mcpServers": { "india-api": { "httpUrl": "https://api.dharun.dev/mcp" } } } ``` ## OpenAI Codex Add this to ~/.codex/config.toml. ``` [mcp_servers.india-api] url = "https://api.dharun.dev/mcp" ``` ## Teach your coding agent the API The Agent Skill tells Claude Code, Codex, Copilot, Cursor, Gemini CLI and other agents when to use this API and how to call it. ``` npx skills add dharunashokkumar/api.dharun.dev ``` Or download https://api.dharun.dev/skills/india-api.zip and upload it where your assistant takes skills. Read it at https://api.dharun.dev/.well-known/agent-skills/india-api/SKILL.md. The skill is MIT-0. ## Tools - `get_company_logo`: Get the logo URLs (SVG and PNG) and details of a company listed on India's NSE or BSE. Accepts a ticker (TCS), exchange-qualified ticker (NSE:TCS), Yahoo symbol (TCS.NS) or ISIN. - `search_companies`: Search Indian listed companies by ticker, name, sector, industry, ISIN or index name (for example 'Nifty 50'). Returns details with logo URLs. - `lookup_pincode`: Look up an Indian pincode: its district, state and every post office that uses it. - `search_post_offices`: Find Indian post offices and their pincodes by the start of the office name, optionally within a state or district. - `lookup_ifsc`: Look up an Indian bank branch by its IFSC: bank, branch, address, MICR and supported payment systems. - `search_bank_branches`: Find branches of one Indian bank by state, city or text in the branch name or address. Needs the four-letter bank code; use search_banks to find it. - `search_banks`: Find Indian banks and their four-letter codes by name. - `lookup_rto`: Find which Regional Transport Office an Indian vehicle registration belongs to. Accepts a code (TN-28) or a full number plate (TN28AB1234). - `list_holidays`: List Indian holidays for a year: bank holidays, central government holidays, and stock market trading and clearing holidays. Filter by type, state or month. - `number_to_words`: Spell a number or rupee amount in words using the Indian system (lakh, crore), in English, Hindi or Tamil. - `validate_identifier`: Check the format of an Indian GSTIN, PAN or IFSC. Format only: it does not confirm the identifier was issued. - `lookup_airport`: Look up an airport by IATA code (MAA) or ICAO code (VOMM): name, city, state, country, coordinates and whether it has scheduled flights. - `search_airports`: Search airports by name or city, worldwide (those with IATA codes) and every Indian airfield and heliport. Filter by country (ISO code) or Indian state. - `make_upi_payment_link`: Build a UPI payment link (upi://pay) for an Indian UPI ID, with optional payee name, amount and note, plus the URL of a QR code image for it. Generate only; nothing is checked with a bank. - `find_constituency`: Find the assembly (MLA) and parliamentary (MP, Lok Sabha) constituency of a place in India, by pincode or by latitude and longitude. - `check_dns`: Look up a domain's DNS records (A, AAAA, MX, TXT, NS, CNAME, CAA, SOA, SRV, or PTR for an IP) at Cloudflare, Google, Quad9 and OpenDNS at once, and say whether they agree. - `check_email_address`: Check an email address without contacting its mail server: valid form, disposable (throwaway) domain, free provider, role account, and whether the domain has mail servers. - `make_fake_indian_data`: Generate made-up Indian test data for building apps: people (name, gender, birth date, email, phone, PAN, address) or companies (name, PAN, GSTIN with a valid check character, address) or addresses, at real pincodes. Never real people. - `lookup_hsn_code`: Look up an Indian HSN code (goods) or SAC code (services) used in GST invoices: its description, the chapter and heading above it, and the codes below it. No GST rates. - `search_hsn_codes`: Find Indian HSN (goods) or SAC (services) codes by words of their description, such as 'green tea' or 'construction'. - `lookup_ip_address`: Find the country, region (Indian state), city and network operator of a public IPv4 or IPv6 address. - `traceroute_from_india`: Trace the network path from a server in India to a host, MTR style: every hop with its address, name, network (AS) and country, packet loss and round-trip times. Shows how Indian networks reach a site. - `get_mutual_fund_nav`: Get the latest NAV of an Indian mutual fund scheme by AMFI scheme code or ISIN, with its fund house, category, plan and option. - `search_mutual_funds`: Search Indian mutual fund schemes by name words, fund house or category, filtered by direct/regular plan and growth/IDCW option, with their latest NAVs. - `get_panchang`: Hindu almanac (panchang) for a date and place: tithi, nakshatra, yoga, karana with their end times, sunrise, sunset, moonrise, moonset, Rahu kalam, Yamagandam, Gulika kalam, Abhijit muhurta, Tamil month and day, lunar month, Shaka and Vikram years. - `check_indian_phone_number`: Check an Indian phone number's form and type (mobile, toll-free, fixed line), format it, and name the operator and telecom circle its series was originally given to. - `get_hf_propagation`: Current space weather from NOAA (solar flux, sunspot number, K and A indices, X-ray class, NOAA R/S/G scales) and a rule of thumb good/fair/poor rating of HF amateur radio bands by day and night. - `test_regex`: Run a regular expression (JavaScript or RE2/Go syntax) against a text: every match with its groups and character offsets, an optional replacement, and a token by token explanation of the pattern. - `get_satellite_passes`: When the ISS, the Chinese space station or an amateur radio satellite passes over a place in the next days: rise, highest point and set times with compass directions and elevations, and when the pass can be seen with the eye. - `find_satellites`: List or search the tracked space stations and amateur radio satellites, with catalogue numbers, orbital periods and inclinations. - `where_is_satellite`: Where a tracked satellite such as the ISS is right now: the point on Earth below it, its altitude and speed, and whether it is in sunlight. - `lookup_railway_station`: Look up an Indian Railways station by its code (MAS, NDLS): name, state, railway zone and elevation. - `search_railway_stations`: Find Indian railway stations and their codes by name, state or railway zone. - `get_sun_and_moon`: Sunrise, sunset, solar noon, day length, civil, nautical and astronomical twilight, moonrise, moonset, moon phase, illumination, age and the next new, first quarter, full and last quarter moons, for a date at an Indian pincode or any latitude and longitude. - `count_tokens`: Count the tokens a text uses for an OpenAI model or encoding (o200k_base for GPT-4o and later, cl100k_base for GPT-4). - `redact_indian_identifiers`: Mask Aadhaar, PAN, GSTIN, card, phone, email, UPI ID, vehicle, voter ID, passport and IP numbers in a text, checking check digits where they exist. - `detect_language`: Detect the language and script of a text, including Indian languages. - `get_thirukkural`: Get a Thirukkural couplet by number (1-1330) in Tamil, with transliteration, English translations by G.U. Pope and by Drew and Lazarus, and its chapter. - `search_thirukkural`: Search the Thirukkural in Tamil or English, or list a chapter (1-133) or a paal (1 virtue, 2 wealth, 3 love). - `transliterate_indian_text`: Rewrite text from one Indian script in another (Devanagari, Bengali, Gurmukhi, Gujarati, Odia, Tamil, Telugu, Kannada, Malayalam), or in Roman letters (ISO 15919, IAST, plain ASCII), or from ISO 15919 / IAST into a script. Spelling only, not translation. - `check_working_day`: Check whether a date is a working day in India for banks in a state, NSE trading, NSE settlement or central government offices; get the previous and next working days, or the date N working days away (T+1 settlement: calendar settlement, add 1). - `count_working_days`: Count Indian working days between two dates (both included) for a calendar, and list each day off with its reason. - `indian_market_status`: Is the Indian stock market (NSE equities) open now or at a given moment: session, reason if closed, and when it next opens. - `find_post_offices_near`: Find Indian post offices and their pincodes near a latitude and longitude, nearest first. ## For other programs - OpenAPI 3.1: https://api.dharun.dev/openapi.json - llms.txt: https://api.dharun.dev/llms.txt, and everything in one file: https://api.dharun.dev/llms-full.txt - MCP server card: https://api.dharun.dev/mcp/server-card - AI catalog: https://api.dharun.dev/.well-known/ai-catalog.json - API catalog: https://api.dharun.dev/.well-known/api-catalog - Every page is also Markdown: add `.md` to its address or send `Accept: text/markdown`. --- # Privacy India API is built to know as little about you as possible. ## What is logged One line per request: the time, the method, the path with its query, the status, how long it took, the country of the request, the browser or program name (user agent) and the referring page. This is used to find faults and abuse. Logs are deleted on a rolling basis. ## What is never logged - **Your IP address.** It is held in memory for up to a minute to count requests against the rate limit, and never written anywhere. - **Personal values.** For these endpoints the path and query are replaced by `(redacted)` in the log, and the answer is marked `private, no-store` so no shared cache keeps it: `/v1/qr`, `/v1/upi-qr`, `/v1/barcode/{type}`, `/v1/ip/{address}`, `/v1/ip`, `/v1/email/{address}`, `/v1/phone/{number}`, `/v1/text/chunk`, `/v1/text/redact`, `/v1/text/tokens`, `/v1/text/language`, `/v1/regex`, `/v1/transliterate`, `/v1/tamil-font/convert`, `/v1/code-image`, `/v1/validate/{kind}/{value}`. The same holds for the matching MCP tools. - **Request bodies.** Text you POST is processed in memory and dropped once the answer is sent. ## Cookies and tracking None. The site sets no cookies and loads no analytics, advertising or third-party scripts. The documentation remembers which code language you picked in your own browser's storage; it is never sent anywhere. ## Others who see requests Requests pass through Cloudflare, which protects the site and sees them on the way, under its own privacy policy. The DNS check and the email check send the domain you give to public DNS resolvers, and the traceroute sends probes along the network path to the host you give. ## The data in answers Answers are public reference data: post offices, bank branches, holidays, codes. The fake data endpoint makes up people and companies; none of them is real. ## Questions Write to [me@dharun.dev](mailto:me@dharun.dev) or open an issue on [GitHub](https://github.com/dharunashokkumar/api.dharun.dev/issues). --- # Security How to report a problem, what the service does to limit harm, and how to check what it runs. ## Report a vulnerability Report it privately through [GitHub's vulnerability form](https://github.com/dharunashokkumar/api.dharun.dev/security/advisories/new), or by email to [me@dharun.dev](mailto:me@dharun.dev) or [dharun.dak@gmail.com](mailto:dharun.dak@gmail.com). Please do not open a public issue, do not test by overloading the service, and give time for a fix before you publish. The same policy is in [security.txt](https://api.dharun.dev/.well-known/security.txt) and [SECURITY.md](https://github.com/dharunashokkumar/api.dharun.dev/blob/main/SECURITY.md). ## How the service limits harm - No accounts, no keys and no stored user data, so there is nothing of yours to leak. - Datasets are opened read-only; no request can change them. - Every client has a rate limit (600 requests a minute), request bodies are capped at 256 KB, and heavy work runs in a fixed number of slots, so a burst waits in line instead of exhausting the server. - The network tools refuse private and reserved addresses, so they cannot be used to reach inside a network. - The image endpoints draw from text alone and never fetch anything from an address you give. - Personal values are kept out of logs and shared caches (see [privacy](https://api.dharun.dev/privacy)). ## Check the code All of it is open source on [GitHub](https://github.com/dharunashokkumar/api.dharun.dev). Every change runs the tests, Go's race detector, `govulncheck` against the Go vulnerability database and `shellcheck` before it can be released. [OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/dharunashokkumar/api.dharun.dev) grades the repository's security practices every week, and Dependabot proposes dependency updates. ## Verify a release Each release is built by GitHub Actions from a public commit and carries a signed build provenance attestation. To check a downloaded bundle: ``` gh attestation verify dharun-api-linux-amd64.tar.gz --repo dharunashokkumar/api.dharun.dev sha256sum -c dharun-api-linux-amd64.tar.gz.sha256 ``` ## Using it safely - Treat it like any outside service: set a timeout, handle errors, and cache answers you reuse. - Format checks (GSTIN, PAN, IFSC) confirm the structure, not that the identifier was ever issued. - Send only the personal data a task needs. --- # About India API puts the reference data that Indian apps need behind one free, consistent API. It is built and run by [Dharun Ashokkumar](https://dharun.dev). Requests for new APIs and reports of wrong data are welcome as [GitHub issues](https://github.com/dharunashokkumar/api.dharun.dev/issues). ## Licences - **Calling the API** puts no licence on your app. - **The code** is free software under the [GNU AGPL-3.0](https://github.com/dharunashokkumar/api.dharun.dev/blob/main/LICENSE). You may run, study and change it; if you run a changed copy as a service for others, you must offer them your changes. - **Code examples** in the documentation and the guides, the Agent Skill and the Claude Code plugin are MIT-0: use them anywhere, no credit needed. - **Data** keeps the licence of its source, listed below and named in every response under `meta.source`. - **Company logos** are trademarks of their owners and are shown to identify the companies. ## Data sources | Source | Licence | Retrieved | |---|---|---| | [Indian listed company logos](https://github.com/dharunashokkumar/api.dharun.dev) | Logos are trademarks of the companies they identify | 2026-04-29 | | [All India Pincode Directory](https://www.data.gov.in/resource/all-india-pincode-directory-till-last-month) | Government Open Data License - India (GODL) | 2026-10-13 | | [IFSC dataset](https://github.com/razorpay/ifsc/releases/tag/v2.0.62) | Public domain (dataset), as stated by the publisher | 2026-10-13 | | [List of Regional Transport Office districts in India](https://en.wikipedia.org/w/index.php?title=List_of_Regional_Transport_Office_districts_in_India&oldid=1377425763) | CC BY-SA 4.0 | 2026-10-13 | | [Bank holidays in India](https://www.rbi.org.in/Scripts/HolidayMatrixDisplay.aspx) | Official publication | 2026-10-13 | | [Central government holidays](https://dopt.gov.in/) | Official publication | 2026-10-13 | | [Trading and clearing holidays, NSE equities](https://www.nseindia.com/resources/exchange-communication-holidays) | Official publication | 2026-10-13 | | [HSN and SAC codes](https://tutorial.gst.gov.in/downloads/HSN_SAC.xlsx) | Statute and gazette notification; reproduction permitted by section 52(1)(q) of the Copyright Act, 1957 | 2026-10-13 | | [Net asset values of mutual fund schemes](https://www.amfiindia.com/net-asset-value) | Published by AMFI under SEBI's disclosure rules | 2026-10-14T17:39:57Z | | [DB-IP Lite: IP to City and IP to ASN](https://db-ip.com/db/lite.php) | CC BY 4.0 | 2026-10-14T13:16:38Z | | [Disposable email domains](https://github.com/disposable-email-domains/disposable-email-domains) | CC0 1.0 | 2026-10-13 | | [List of railway stations in India](https://en.wikipedia.org/w/index.php?title=List_of_railway_stations_in_India&oldid=1371613797) | CC BY-SA 4.0 | 2026-10-13 | | [Mobile telephone numbering in India](https://en.wikipedia.org/w/index.php?title=Mobile_telephone_numbering_in_India&oldid=1376522760) | CC BY-SA 4.0 | 2026-10-13 | | [Maps of assembly and parliamentary constituencies](https://github.com/datameet/maps/tree/b3fbbde595310b397a55d718e0958ce249a4fa1f) | Assembly boundaries CC BY 2.5 India; parliamentary boundaries (simplified, 2019) CC0 | 2026-10-13 | | [OurAirports](https://ourairports.com/data/) | Public domain | 2026-10-13 | | [Thirukkural](https://github.com/tk120404/thirukkural/tree/cf3ff6c5a73c23b4092913156830457caab65fd4) | Public domain text and translations; the compilation is Apache-2.0 | 2026-10-13 | | [CelesTrak current GP element sets](https://celestrak.org/NORAD/elements/) | None stated by CelesTrak. USSPACECOM allows redistribution of basic space situational awareness data with credit; only results computed from it are published here | 2026-10-14T13:16:38Z | | [Space weather data](https://www.swpc.noaa.gov/) | Public domain (work of the US government) | 2026-10-14T17:39:57Z |