Thinking global, living local

How to use fuel-retail-outlets: see where India's petrol pumps are, state by state

October 25, 2026

A crawl of 104,945 petrol-pump records from a public API, plus extractors and gap-analysis maps. This post shows the one cleaning step you must do first, and the state-by-state coverage it gives you.

Open-Source Tools · How-To · Energy & fuels models

How to use fuel-retail-outlets: see where India's petrol pumps are, state by state

Skip to article content
Text Size

Revised · v1.0.0 · what changed

104,945unique ids in the 16 Oct 2026 crawl
82,602outlets after removing duplicate rows
22,343duplicate rows removed (21%)
2.7 vs 11.5pumps per 100,000 people: Bihar vs Punjab

Code: github.com/herrrickshaw/fuel-retail-outlets

Watch the walkthrough

Watch on YouTube: youtu.be/_4NBKi2NCGI

Why it is useful

  • Who benefits: fuel-retail, CNG and EV-charging planners, consultants and students who need a pump-level list of India with location, company and fuel type.
  • What it replaces: collecting listings from each oil company's locator one by one.
  • Evidence from the run: counted naively, Delhi appears to have 21,939 pumps; after removing duplicate rows it has 419. The raw file also holds 22,343 duplicate rows (21.3%). If you skip the cleaning step, every state count is wrong.
  • After cleaning, the per-capita view shows a clear spread: Bihar 2.7, West Bengal 2.8 and Jharkhand 3.4 pumps per 100,000 people, against Punjab 11.5 and Haryana 11.3.

What it is for

This repo collects Indian petrol, diesel and CNG outlet listings from public sources (the SSRI petrol-pump API, the BPCL dealership locator and CashAtPOS), with two small web apps for the map and a coverage gap-analysis heatmap.

The data is indicative, for planning and visualisation. It is not an official registry. Outlet records are public business listings.

Who it is for

  • Energy and mobility analysts sizing pump or charger networks
  • Students working on India fuel-retail geography
  • Anyone who needs a raw outlet list to join with district or population data
Not for.
  • Regulatory or legal use; it is not an official registry (PPAC publishes the official totals)
  • Using raw counts without removing duplicates first
  • Real-time prices; the prices in the crawl are a snapshot

What you need

RequirementWhyHow to get it
git and a terminalTo clone the repoTerminal on macOS/Linux, WSL/Git Bash on Windows; or GitHub Codespaces
Python 3 (standard library only for the steps shown)The sample reads a gzipped JSON-lines filepython.org, or brew install python
Internet only if you re-crawlcrawl_ssri.py calls the public API (about 6 minutes, per the repo notes). Not needed for the sample.pip install requests, then python api-data-integration/crawl_ssri.py
API keys, accounts, licencesNone needed for the steps shownNothing to sign up for; the sample commands read files already in the repo

Get the code and an AI assistant

You do not have to be a programmer. Get the repository, give it to an AI assistant, and ask in plain language. Any of these routes works:

ToolWhat you needBest for
GitHubFree account to fork or star; git to clone, or the green Code button, then Download ZIP, or open in CodespacesGetting the code and keeping up with updates
Claude CodeClaude subscription or API key; run claude inside the cloned folderLetting the AI read and run the whole repo
Gemini CLIGoogle account; run gemini inside the cloned folderThe same hands-on workflow with Gemini
Claude.ai, Gemini or ChatGPT in the browserA chat account; upload README.md and the files you care about (or paste the output of git ls-files)Understanding the project and asking questions without installing anything
Other tools (Copilot Chat, Cursor, Codex CLI)Open the cloned folder in the tool and point it at README.md firstEditing and extending the code
git clone https://github.com/herrrickshaw/fuel-retail-outlets.git
cd fuel-retail-outlets
claude      # or: gemini

Install

  1. Clone the repository (needs git)
    git clone https://github.com/herrrickshaw/fuel-retail-outlets.git
    cd fuel-retail-outlets
  2. Nothing to install for the sample below. For the web apps, serve a folder with Python
    cd fuel-station-gap-analysis && python3 -m http.server 8001

Quick start: commands and what you should see

Load the committed crawl and deduplicate it the way the repo's notes describe

python3 -I - <<'E'
import gzip,json,collections
p='api-data-integration/outlet_data_ssri_complete/ssri_pumps_raw_20261016.jsonl.gz'
rows=[json.loads(l) for l in gzip.open(p,'rt') if l.strip()]
k={}
for r in rows:
    key=(r['name'],r['address'],r['company'],r['latitude'],r['longitude'])
    if key not in k or r['id']>k[key]['id']: k[key]=r
u=list(k.values())
print(len(rows),len(u),len(rows)-len(u))
print(collections.Counter(r['company'] for r in u).most_common(5))
E

104945 82602 22343, then the company counts: BPCL 25,795, HPCL 23,543, IOCL 19,446, Nayara 9,007, Unknown 2,504.

Open the gap-analysis heatmap

cd fuel-station-gap-analysis && python3 -m http.server 8001

Visit http://localhost:8001 to see the state-level heatmap. The page loads its map tiles from the internet. I did not open it in this run.

Sample outputs

Real output from a run on the date shown in the sources line; trimmed to fit.

Why you must deduplicate: Delhi, raw versus cleaned

raw rows with state == 'Delhi'  : 21,939
  of which district 'New Delhi' : 21,572, all IOCL-heavy
  sitting on only 57 distinct coordinates (3,986 identical rows on each of several points)
after dedup (name+address+company+lat+lon): 419

The repo's own notes (SSRI_REEXTRACTION_20260712.md) document this; the 16 Oct 2026 file is still raw, so you have to apply the step yourself. My dedup gives 82,602; the note's earlier snapshot gave 82,609.

Pumps per 100,000 people by state (cleaned; state populations from the repo's gap-analysis data.js)

state             pumps   per 100k people   per 1000 km2
Uttar Pradesh      8,915        4.5              37.0
Maharashtra        7,317        6.5              23.8
Tamil Nadu         5,812        8.1              44.7
Madhya Pradesh     5,320        7.3              17.3
Karnataka          5,268        8.6              27.5
-- lowest (states with 100+ pumps) --
Delhi                419        2.5             282.5
Bihar              2,779        2.7              29.5
West Bengal        2,522        2.8              28.4
Jharkhand          1,109        3.4              13.9
Assam              1,108        3.6              14.1
-- highest --
Arunachal Pradesh    201       14.6              2.4
Punjab             3,204       11.5              63.6
Haryana            2,855       11.3              64.6
Telangana          3,609       10.3              32.2

Delhi's low per-capita number reflects a dense city counted against its whole population and is not a real gap; read the table as a starting screen, not a verdict.

Data-quality check on state names

state values in the raw file: 53 spellings
unmatched to the 35 states in data.js after dedup: 10,532 of 82,602 outlets
  'unknown' (all Nayara): 9,007
  'Jharkand': 593, 'Jammu And Kashmir': 333, 'Jammu & Kashmir': 230 ...
matched: 72,070

Only the matched outlets feed the table above, so the table understates states with spelling variants (I mapped Jharkand, Uttrakhand and Jammu variants) and cannot place Nayara's 9,007 outlets by state at all.

Ways to use it

MethodHow it works
Python / pandasRead the .jsonl.gz, deduplicate, then group by state, district or company.
Web mapsServe fuel-pump-locations-map or fuel-station-gap-analysis with python3 -m http.server.
Re-crawlRun api-data-integration/crawl_ssri.py for a fresh snapshot (not run here).
Through an AI assistantOpen the folder in Claude Code or Gemini CLI and ask it to deduplicate the crawl and rank states; or upload README.md and REBUILD_NOTE.md to a chat assistant.

Sample prompts for your AI assistant

Copy, paste and edit the parts in [brackets].

  • Claude: Read REBUILD_NOTE.md and SSRI_REEXTRACTION_20260712.md, then write a script that deduplicates the crawl and prints pumps per state.
  • Gemini: Using the crawl, find the ten districts with the most CNG pumps and explain how you handled spelling variants of state names.
  • ChatGPT: Here is a table of pumps per 100,000 people by state. Which states look under-served and which numbers are probably artefacts?
  • GitHub (Copilot Chat or Codespaces): Write a function that normalises the 53 state spellings in the crawl to one canonical name per state or UT.
  • Claude: Compare the deduplicated total with the PPAC baseline described in PPAC_RETAIL_OUTLETS_MAY2026.md and explain the gap.
  • Any assistant: Suggest how to join this outlet list with district population to find gaps for EV charging.

Limits and honest caveats

  • Raw data contains about 21% duplicate rows; always deduplicate. In the 16 Oct 2026 file Delhi shows 21,939 rows before cleaning and 419 after.
  • Even after cleaning, 82,602 outlets compares with a PPAC official baseline of 103,450 (May 2026) in the repo's notes, so coverage is roughly 80%.
  • State names are inconsistent (53 spellings) and all 9,007 Nayara outlets have state 'unknown', so state tables miss them unless you geocode by coordinates.
  • Population figures in the gap-analysis data.js are older census-based numbers; per-capita values are indicative.
  • Not an official registry. Prices and timings are a snapshot.
  • The README refers to files removed in the LFS-free rebuild (derived maps and unified DB); they must be regenerated by the scripts. I did not run the extractors, web apps or any network call; only the committed crawl was read.

Sources: Read the committed crawl api-data-integration/outlet_data_ssri_complete/ssri_pumps_raw_20261016.jsonl.gz and fuel-station-gap-analysis/data.js from github.com/herrrickshaw/fuel-retail-outlets (commit 266995b) with the Python standard library on 19 October 2026. Outlet names and addresses were not reproduced; only aggregates are shown. Extractors, web apps and network crawl not run.

Revision history.
  • v1.0.0 — 29 October 2026 — first published.

About this article: Researched, written and edited by Umashankar Triplicane Dwarakanathan, with AI research assistance; every figure is meant to trace to the primary source cited. See the Editorial Policy for how sourcing, AI use and corrections work.

Umashankar Triplicane Dwarakanathan
Contact Us
Umashankar Triplicane Dwarakanathan
Investment Promotion & Energy-Sector Leader · Chennai, Tamil Nadu, India
LinkedIn → GitHub → Email +91 78273 81696
How this site works

Data-led analysis of India's trade, currency and industrial policy. Every article is built from primary official sources, and every figure links back to the release, table or filing it came from.

Sources. DGCI&S TradeStat (imports/exports, HSN-wise) · PIB (government press releases, January 2017 to today, refreshed daily) · RBI (circulars, balance of payments) · MoSPI (CPI/WPI, IIP) · PARIVESH (environmental clearances) · CCIL (bond yields) · BIS (policy rates) · SEBI, NSE/BSE and SEC filings for company data.

Interpretation. Figures carry their vintage and retrieval date; estimates and press-reported numbers are labelled as such; where sources disagree, both are shown. Corrections are made visibly, never silently. Articles are written with AI assistance from the cited sources — AI-generated text can misstate figures even when working from real material, so verify any number that matters to a decision against the linked primary source.

footer

Browse all articles by topic

Every piece on this blog, grouped. Or read the full index.

Agriculture & FertilisersAI ToolsChemicalsClimate & CarbonEnergy & FuelsGas & LNGImport SubstitutionIndustrial PolicyMarkets & FinanceMobility & EVPrices & InflationTextilesTrade & Tariffs

Each topic is a live archive page that updates itself as pieces are labelled. It replaces a hand-kept list that had fallen 18 articles behind.