π§ Find an idea the data can carry
Where the fleet's ideas came from, plus a 20-minute vet that proves the data exists for your place, is allowed, and supports the features you want.
You'll leave with
- Three ideas grounded in data that actually exists
- A 20-minute vetting checklist run on your best one
- A pivot plan for when the data you wanted isn't published
Most app ideas die because the data behind them was imaginary. Five of the apps in my fleet (the live apps I run at traqqit.com) started as public data (records a government or company publishes for anyone) that existed but was miserable to use. In this course an app is a website that does something useful, opened in a browser. The order never changes: data first, then the idea, never the idea and then hope. I'm a data person, not a 10Γ engineer, and I have built on data that turned out not to exist; this is the check I run now, before any code.
Where the fleet's ideas came from
A product people loved that died
Acento, my Argentine Spanish trainer, started from the feel of an accent-training website that had shut down. A product that died still proves people wanted it. I rebuilt only its core loop (the one thing learners did again and again), for one dialect, Buenos Aires (porteΓ±o) Spanish and its slang, so my content could go deeper than a big app's. Later, once accent scoring could run cheaply in the browser, Acento added the feature the original was known for.
To find your own, list shut-down apps in an area you care about, read old reviews for what users loved, and pick one loop you can rebuild with no server (an always-on computer you rent) and no machine learning (software trained on examples, which usually needs a big server). What you can't build yet goes on your SKIPPED list (from The laziest thing that works).
β οΈ Borrow the idea and the feel, never the name, logo or look. That invites trademark trouble (a trademark is a name or logo the law reserves for its owner) and reads as impersonation.
Public data nobody made usable
Habooby (Phoenix dust and air quality), Ticket Heat (traffic tickets), Who Owns Phoenix (which companies own the homes), The List (an official New York City tax roll) and my medical price tool all started from a dataset someone had already published and nobody had made usable.
What are a dataset, rows and columns?
A dataset is one published collection of records, usually a table: each row is one record (one ticket), each column one fact about it (date, place, amount). It often comes as a CSV file, a table saved as plain text, one row per line.
Most data apps take one of four shapes: searchable (a records set with no search box: add one), mappable (anything with an address or coordinates, a place's latitude and longitude, wants to be a map), personal (what does this mean for my street, my bill?) or legible (a raw file turned into a chart a person understands).
Problems you see up close
First Bites (a baby's first foods and allergens) and Baby Signs (signs to share with a baby) are small, focused tools for parents of babies. Neither started from a dataset; both run mostly on content I made and on what parents log each day. A daily habit is data too.
Narrow, scored and yours
Narrow beats broad for a solo maker: one city, one dialect, one sport. My price tool started with Phoenix hospitals only, and widened to all of Arizona only after that worked, with no code change: more hospitals in a settings file, then loading the data again. Five more states came later, the same way (Big public data on a small server, late in the course, shows that layout).
Score every candidate 0 (no), 1 (maybe) or 2 (yes):
| Question | A yes looks like |
|---|---|
| Does the data exist? | You've opened it and seen rows. A 0 here ends the idea. |
| Who exactly is it for? | One line: "renters checking who owns their building". |
| Could the smallest version ship in a week? | One page, one dataset, one thing to do. |
| Would you use it yourself? | You'd open it next week, unprompted. |
"Phoenix evictions" is a topic. An address that hands back rows is a source. If you can't name the source, you don't have a project yet.
What are Claude Code, VS Code and NOTES.md?
Claude Code is Anthropic's AI assistant. It works in your project folder inside VS Code, a free code editor: you describe a job in plain English, and it reads files, searches the web and runs commands, asking you first. NOTES.md is that folder's notes file, which Claude reads every session (Work with Claude Code sets it up).
Put the winner's one-sentence pitch at the top of NOTES.md: "This makes ___ data searchable / mappable / personal / legible for ___."
One clever join is the product
A data app is worth sharing when it reveals something the raw data hides, and that's usually one join away.
What's a join?
Connecting records that share a value. Below, every home whose tax bill goes to the same mailing address is grouped as one owner, whatever owner name each record shows.
On Who Owns Phoenix (as of its data date), matching one big landlord's brand name found a few hundred homes, while grouping owners by a cleaned-up mailing address found thousands under many shell LLC names. That gap is the app's headline.
What's a shell LLC?
An LLC (limited liability company) is a cheap legal wrapper for a business. A shell exists mainly to hold property, so one company can own homes under many names.
Corporate landlords often register homes under many names, but the tax bills go to the same few offices. Cleaning makes one address always look the same: uppercase, no punctuation, one spelling each for SUITE/STE, STREET/ST and PO BOX.
1234 Main Street, Suite 100 -> 1234 MAIN ST STE 100
1234 MAIN ST. STE 100 -> 1234 MAIN ST STE 100
Group by the cleaned address, and each office's homes come together. A short hand-made list merges one brand's several offices, and a plain "how it works" note lets readers check the method.
β οΈ Check the biggest groups by hand. A law firm or property manager can collect tax bills for hundreds of unrelated owners: a shared mailbox, not a landlord.
For your idea, ask Claude Code: "Here are my dataset's columns. What could one join reveal that the raw rows hide? Give me three, and how I'd check the top results by hand."
Does it exist for YOUR place?
"Global" APIs often have regional holes. Habooby taught me this the slow way: a weather API's pollen data returned real numbers for London and nothing but nulls for Phoenix, because its pollen forecast covers Europe only. Time went into building on it before I noticed.
What are an API, JSON and null?
An API is a web address that returns data instead of a page, usually as JSON: plain text like {"pm10": 25.4} that people and programs can both read. A dataset's page often has an API or Export button. null is JSON's word for "no value at all".
See the same kind of hole yourself. These links ask a free air-quality API, Open-Meteo, for grass pollen and pm10 (dust) at two places; the latitude and longitude ride in the address. Open each in a new tab:
Near the end of each answer, on one long line or laid out neatly depending on your browser:
Your numbers will differ. London's 0.0 is a real answer: zero grass pollen that hour (in season you'll see counts). Phoenix's null is no data at all, though its dust reading works. The docs say why, in one line: pollen is "only available in Europe during pollen season".
β οΈ Never show null as 0. "No pollen today" and "we don't know" are different claims. Hide the feature, or say "not available here".
So query your place next to a place the docs show working. Then write down, for every source: coverage (your place? how far back?), update frequency, whether it needs a key, CORS, rate limits (how many requests it answers per minute, hour or day; a request is one ask for data) and terms.
What are an API key and CORS?
An API key is a code a provider gives you to identify your app; treat it as a secret unless the provider says it's public. CORS is the browser rule that lets your page read another site's API only if that site allows it. It matters only if your page asks live; data you download ahead into your own file doesn't care.
Keyless APIs change too. The US Census data API started requiring a key, and now redirects keyless calls (sends them to another address) to a page titled "Missing Key", so code expecting data gets a web page. The fix: a free key, or another free copy of the same data that needs none.
And check the columns before you design: no coordinates means no map, and no dollar amounts means no totals.
Find the official source first
Before scraping (writing a program that pulls data out of web pages), look for what the publisher already provides.
A required index file
Some publishers must post an index at a fixed address. US hospitals must post /cms-hpt.txt on their main website, listing each location's name and the link to its price file, in blocks like this (example values):
location-name: Example General Hospital
source-page-url: https://www.hospital.example.org/price-transparency
mrf-url: https://www.hospital.example.org/files/example-general_standardcharges.csv
contact-name: PRICE TRANSPARENCY CONTACT
contact-email: prices@hospital.example.org
Adding one state to a private variant of my price tool meant finding 118 hospital price files. The /cms-hpt.txt files turned that into a quick job for a small program instead of days of research: 35 hospital websites served one; hospitals without one were researched by hand. Before you trust a link, have Claude check that it answers (without downloading the file): some carry a temporary access code and die weeks later, so re-read the index for a fresh one.
A county map service
County assessor (property-tax) and GIS (mapping) offices often run a public ArcGIS REST service. Who Owns Phoenix is built on one free layer: owner, mailing address, property-use code, value and outline for about 681k single-family homes (of 1.76M parcels in all), with no key, 1,000 rows a page.
What's an ArcGIS REST service?
ArcGIS is mapping software many governments use. Its REST service is the public address behind their maps, where each layer (parcels, ZIP codes) answers questions with data. A parcel is one piece of land with its own tax record.
Search for YOUR COUNTY parcels arcgis rest services, then click through the folders to a layer (its address ends in MapServer/ or FeatureServer/ and a number). Its page lists the fields (columns) and its MaxRecordCount, the most rows one answer holds. To get 20 rows, copy the ending below, click your browser's address bar, press the right-arrow key to jump to the end of the layer's address, paste, and press Enter:
/query?where=1=1&outFields=*&returnGeometry=false&resultRecordCount=20&f=json
where=1=1 means any row, outFields=* every column, returnGeometry=false skips the outlines, and f=json asks for data instead of a page: you should see "features": and 20 records. For all of them, ask Claude to fetch 1,000 rows a page (resultOffset=0, 1000, 2000β¦) until the answer no longer says "exceededTransferLimit":true.
The feed behind the official map
No download, but an official map shows the data? Its code fetches it from somewhere. In Chrome or Edge on a computer, open the map, press Ctrl+Shift+I (Mac: Cmd+Option+I) for DevTools, click Network, then Fetch/XHR, and reload. Click a row whose name looks like data (often containing json or query): its Response tab shows the data, its Headers tab the address, and that address is the feed. (Safari hides DevTools until you switch them on; phones can't do this.) Habooby's county rain gauges come from a feed like this.
What are DevTools?
Tools built into desktop browsers that show what a page is doing underneath: every file it loads, every error. Looking can't break anything.
π‘ Be gentle with small servers: that feed was built for one map's visitors. Fetch it from your own script (a small program you run yourself), a second or two between requests, save a copy, and let your visitors load your copy (Build static-first shows how). Never point thousands of browsers at a county server.
Are you allowed to use it?
Data you can reach isn't always data you may use. Check the site's robots.txt and its terms of use.
What's robots.txt?
A text file at the top of a website (yoursite.com/robots.txt) telling crawlers, programs that visit pages automatically, what they may fetch. Each User-agent line names a program (* means all of them, yours included), and the Disallow lines under it list what's off-limits.
User-agent: *
Disallow: /admin/
User-agent: ClaudeBot
Disallow: /
Here every program may read everything except /admin/, and Claude's crawler may read nothing. Some sites block AI tools by name (ClaudeBot, Claude-Web, GPTBot). That's the owner opting out, and it's a no: don't fetch, and don't route around it with another tool. Ask the owner instead, and credit them.
π On one of my side projects, a nonprofit's robots.txt allows crawling except its admin area, so its pages are read a second or two apart and saved for days. A popular community forum's robots.txt blocks Claude's crawler by name, so it's never scraped. For full coverage, the plan is a credited data partnership with the nonprofit, not more scraping.
One wrinkle: robots.txt speaks to crawlers. An official API's published terms are the rules for calling it, which is why Open-Meteo's API address can disallow every crawler while its terms invite programs in, within limits. That's no loophole: if a website's pages block you, you're blocked.
Pages, not databases
Reading the public pages a site serves (or the API its own pages call) is different from taking its whole database. That nonprofit's map loads from a deliberately disguised link to its raw data store. I left it alone, and the project reads records one at a time from public pages. If someone hid it, it isn't for you.
Open data, closed media
"Open dataset" doesn't mean usable media. Researching sign-language video for Baby Signs, I found one well-known sign database licensed CC BY-NC but excluding its videos, another dataset for academic use only, and a large research set with no posted license at all. So Baby Signs draws its own signs, and hiring a Deaf signer is the respectful path to video later.
What's a license (and CC BY-NC)?
A license is the owner's written permission, with conditions. Creative Commons licenses are common ready-made ones: BY means credit the creator, NC means no commercial use. "Academic use only" rules out commercial use too, even a free app with a paid tier.
For each source, write down, with links: does the license cover the media files, allow commercial use, allow offline copies? If nothing fits: your own artwork, a paid creator, or plain links out.
Say whose it is
If your app borrows from a community (a language, a culture, a craft), say so in the product and point people to that community's own teachers. Baby Signs says plainly that ASL (American Sign Language) is a full language belonging to the Deaf community, and points to Deaf teachers in its footer and at the end of its how-to guide. Record that stance in NOTES.md under Decisions (don't undo), so a redesign can't quietly strip it out.
Pivot honestly
Ticket Heat began as a brief for a parking-ticket map. But the city publishes no parking-citation data at all. The only citation data is police traffic citations, so the product became traffic tickets. Later, detailed violation types turned out not to exist anywhere either, so a second dataset went in instead: police calls for crashes, DUIs (driving drunk or high) and racing, labeled "dispatched calls, not citations".
Label every layer with what it counts. "Calls to police" and "tickets written" are different things, and readers notice a blur. Put the unit in the legend (the map's key) and in every popup (the box that opens when you tap a dot): "police calls", not "crashes".
For your own idea, search your city's open-data portal (its website of public datasets, each with a page, a column list and usually an Export or API button) for the exact dataset, and read its columns: location? amount? type? If it isn't there, rename and rescope before you build, not after a reader notices.
Your pivot plan is four lines: what you wanted, the closest real data (with a link), what it can honestly claim (unit included), and the new name and scope. Nothing close? Find a regional source, make it yourself (Baby Signs' drawings), ask the owner for access with credit, or move the feature to SKIPPED.
The 20-minute vet
All of the above as one checklist. Run it on your best idea, for your own place, before any code. Each step asks one of three questions: complete for my place, fresh enough, allowed? One strike is usually fatal, so any no means pivot now. Killing an idea now is free; killing it after you've built it is not.
| Step | Minutes | In the pollen example |
|---|---|---|
| 1. Find the official source | 5 | Open-Meteo's air-quality API and its docs |
| 2. Fetch 20 rows for your place and 20 for a place the docs show working | 5 | Phoenix and London |
| 3. Check the columns you need exist: coordinates for a map, amounts for totals | 3 | Dust: yes. Pollen: null in Phoenix |
| 4. Read robots.txt and the terms | 4 | Free tier non-commercial, with limits; credit required |
| 5. Write coverage, update frequency, key, CORS, rate limits and license into NOTES.md | 3 | Dust: go. Pollen: pivot |
While you're in the rows, note what one row is (one ticket, one call, one building, one hour at one spot): the next lesson leans on it.
Do it with Claude: the prompts
Now your own idea. Open your project folder in VS Code (no project yet? an empty folder called myapp will do) and start Claude Code as in Set up your workshop. The examples follow one made-up project, a pollen and dust map for Phoenix; swap in your topic and place.
Before Claude searches the web, opens a page or runs a command such as curl (which fetches a web address and shows the raw answer), it shows you exactly what and asks; the wording changes between versions. The web requests here only read public pages, and the only files written are in your project folder. Choose the plain Yes while you learn, so you see every address.
Ten ideas, then three survivors
Send the first message, pick your three favorites, then send the second.
EXAMPLE β YOU ASK CLAUDE CODE
What's happening underneath: Claude answers from its training here, without searching, so a dataset it names may be outdated or invented: a lead, not a fact. Before an idea makes your three, open its data and see rows. Score the three with the four questions, and put the winner's pitch in NOTES.md.
You should see ten numbered ideas, then a critique of your three. An "I'm not sure" is a gift: it tells you what to test first.
Find the official source (5 minutes)
EXAMPLE β YOU ASK CLAUDE CODE
What's happening underneath: Claude searches and reads pages for you, asking first. For the CORS line it adds an Origin header, as a web page would; without one, this server sends no CORS header. Claude can mix up two datasets or quote a license from the wrong page, so open every link it gives you: no link you've opened, no source. If it didn't mention them, ask about a required index file, the city's open-data portal or a county ArcGIS service.
You should land on a docs or dataset page with a description, a field list, and an API or Export button.
Fetch 20 rows, twice (8 minutes)
EXAMPLE β YOU ASK CLAUDE CODE
What's happening underneath: the same request twice, only the place changed, with the raw answers kept so you can check Claude's summary. Open both files from VS Code's file list on the left and press Ctrl+F (Mac: Cmd+F) for null: nulls in yours but not in theirs are a hole. Check the columns your features need, too.
Read the rules yourself (4 minutes)
EXAMPLE β YOU ASK CLAUDE CODE
What's happening underneath: curl shows robots.txt exactly, but Claude reads the terms through its web tool, which can hand it a summary rather than the page, and it can misread a license. So open each page, press Ctrl+F (Mac: Cmd+F) and paste a few words of each quote. Found word for word? Good. Not found? Ask for the exact sentence. The quoted words decide, never the summary.
Write it down, or pivot (3 minutes)
EXAMPLE β YOU ASK CLAUDE CODE
What's happening underneath: one edit to one file. Read NOTES.md against your samples and the quotes you checked: a wrong line here gets repeated, confidently, in every later session. What this lesson adds should look like this (keep your other sections; use your own values):
# myapp
Pitch: This makes Phoenix dust data mappable for people with asthma.
## Ideas (0-2 each: data exists / who it's for / ships in a week / I'd use it)
1. Pollen and dust map: 7/8. Data: https://open-meteo.com/en/docs/air-quality-api
2. Symptom diary: 6/8. Input: what I log each day
3. THIRD IDEA: SCORE/8. Data: LINK
## Data sources
### Open-Meteo air-quality API (vetted DATE)
- Link: https://open-meteo.com/en/docs/air-quality-api
- Coverage: Phoenix dust (pm10) yes. Pollen no: null here, Europe only
- Updates: every 12 hours outside Europe (docs table)
- Key: none
- CORS: yes (access-control-allow-origin: *)
- Rate limit: "Less than 10'000 API calls per day, 5'000 per hour and 600 per minute."
- Terms: "You may only use the free API services for non-commercial purposes." Subscriptions or ads count as commercial.
- License: "API data are offered under Attribution 4.0 International (CC BY 4.0)". Credit with a link.
- Columns I need: pm10 yes. grass_pollen null in Phoenix
- One row is: one hour at one spot
- Verdict: GO for dust, while the app stays free of ads and subscriptions. PIVOT for pollen.
## Pivot plan: pollen
- Wanted: daily pollen levels for Phoenix
- Closest real data: UNCONFIRMED (look for a regional source)
- Can honestly claim: nothing about pollen yet
- New scope: a dust map. Pollen goes on SKIPPED.
Any no means pivot now: vet the closest real data, under its new name, before you build.
Your turn
- Get ten ideas from Claude, argue against your top three, and keep three whose data you've opened. Done when
NOTES.mdlists three, each scored out of 8, with a link that loads rows (or, for a daily habit, its input). - Write your winner's pitch at the top of
NOTES.md. Done when it fits "This makes ___ data ___ for ___." - Find
nullin the Phoenix answer and a number in London's, then compare your own place with one the docs show working. Done when you've seen your place's real values yourself. - Run the 20-minute vet on your winner. Done when its Data sources entry has every line filled in or marked UNCONFIRMED, plus a verdict.
- Find every license quote word for word on the real page with Ctrl+F. Done when each one turns up.
- Write a pivot plan, even if the verdict is go. Done when it names what you wanted, the closest real data, what it can honestly claim, and the new name.
Next, Numbers you can defend: what one row of your data really means, and how to make every number your app shows true before a reader checks it.