September 12, 2026
FROM A DATA REQUEST TO A PRODUCT DECISION

You can now find data in the ByeBuy Data directory, separate model knowledge from retrieved facts, and sort every fact as static, live, private, or user-provided. One gap remains — the most visible beginner mistake in the API economy: displaying raw JSON as if it were a product.
JSON is a delivery format, not a decision.
JSON is not the product
Fetch a filing from SEC EDGAR, a series from FRED, or a forecast from Open-Meteo and you get an honest, messy, provider-shaped response: nested objects, provider field names, mixed units, provider timezones, pagination. Paste that into the interface and you have handed the user your supply chain instead of their answer.
A product must translate: pick the fields that matter, rename them into the user's language, align dates and units, apply a rule, and render the result with its evidence.
The six-step flow
Every data feature in this course follows the same pipeline — Classes 19 through 23 each deepen one stage:
Question → source → retrieval → normalization → product rule → useful output
1. Question. One sentence the user actually asked: "Is this company growing while the economy weakens?" 2. Source. The owner that can answer it: EDGAR for reported facts, FRED for macro context, Open-Meteo for forecasts, your database for saved work. 3. Retrieval. The call or query that fetches the slice: one company, concept, and period; one series and window; one location and date range — permission-checked first. 4. Normalization. Equivalent records get consistent names, types, dates, units, and IDs — defined fully below. 5. Product rule. The judgment: threshold, comparison, score, filter, or ranking that turns records into a recommendation. 6. Useful output. A dashboard, alert, report, recommendation, or automation the user can act on — with source links attached.
Skip normalization and the rule misfires: quarterly mixed with annual, Celsius averaged with Fahrenheit, one company's "revenues" compared against another's "net sales" as if they matched.
Normalization: one language for equivalent facts
Normalization means converting provider-shaped responses into product-shaped records: consistent field names, data types, date formats, units, currencies, geographies, and stable IDs. The provider optimizes for its own system; you optimize for your user's question.
Concretely, normalizing a filing fact means mapping us-gaap:Revenues in USD for CIK 0000320193 ending 2024-09-28 to company_id=apple, metric=revenue, period=FY2024, value_usd=391035000000. Normalizing a forecast means converting all timestamps to the trip's timezone and labeling every temperature with its unit. Same questions, one vocabulary — no matter how many providers contributed.
Normalization also decides what to *keep*: the original URL, owner, retrieval time, and period travel with the record forever. A number without its coordinates is decoration.
Sonariq: filings and notes become a research product
Watch the pipeline carry Sonariq, the financial-research system from Lesson 18.1:
EDGAR filing JSON + FRED series + analyst Markdown notes
→ retrieval (one company, chosen concepts and periods; one macro window)
→ normalization (company record, dated series, shared units and IDs)
→ product pieces:
company record — CIK, sector, fiscal calendar
evidence list — each claim linked to filing URL + accession number
financial series — revenue and margins by period
scoring inputs — growth, consistency, macro-context features
readable report — narrative drafted from the normalized records
The product value is the workflow and judgment *around* the source — which concept counts as revenue, which periods compare fairly, what the macro backdrop was — not the raw SEC response. Two apps can call the same EDGAR endpoint; the one with the better normalization and rules gives the better answer.
Five outputs from the same data
One normalized record set can serve five different products. Name which one you are building, because each needs a different rule and interface:
| Output | What the user gets | Example on Sonariq data |
|---|---|---|
| Dashboard | Current state at a glance | Revenue trend with FRED backdrop, each point linked to its filing |
| Alert | A nudge only when something crosses a line | "Revenue fell 8% year-over-year in the latest 10-K" |
| Report | A readable narrative with evidence | Quarterly brief: figures, comparisons, every claim cited |
| Recommendation | A suggested action with reasons | "Worth deeper review," plus the supporting series |
| Automation | An action taken under permission | File the brief to the research queue after the filing lands |
A dashboard without thresholds overwhelms; an alert without a threshold spams; a report without citations persuades without proof. The data is shared — the rule and the rendering are the product.
Provenance: keep the receipt
Every normalized record must carry its receipt — provenance: the original source URL, the owner name, the retrieval timestamp, and the date or period the fact describes. A filing figure keeps its filing URL, accession number, concept, period end, and filed date. A FRED observation keeps its series ID, observation date, and release. A forecast value keeps its coordinates, timestamp, timezone, and units. Keep the ByeBuy Data directory listing and owner docs page where you found it, too.
Provenance answers the only question a skeptical user should ever need to ask: "says who, from when, retrieved when?" It also makes debugging possible — stale cache versus changed provider versus wrong rule — and it grounds the citations Class 23 demands. Never strip it to "save space."
Practical exercise: five fields, one source, one decision
Take one public JSON response — an EDGAR company-facts slice, a FRED series, or an Open-Meteo forecast. Create a half-page note called NORMALIZE-ONE.md with: (1) five fields the user needs in product names, not provider field names, (2) the source URL to retain plus owner, retrieval time, and period coverage, and (3) one decision or view the app produces.
Worked mini-example: Brussels trip filter + support boundary (same pipeline, two rules)
Raw (provider-shaped, from Open-Meteo): latitude, longitude, timezone, hourly.time[], hourly.temperature_2m[], hourly.precipitation_probability[] — nested, UTC-shifted, no decision.
Normalized (product-shaped — keep these five, drop the rest):
| Product field | From provider field | Example value |
|---|---|---|
place | latitude 50.85, longitude 4.35 → "Brussels" | Brussels |
slot_local | hourly.time + timezone=Europe/Brussels | 2026-09-12T12:00 |
temp_c | temperature_2m + unit °C | 14.2 °C |
rain_pct | precipitation_probability | 65% |
retrieved_at | request time you add | 2026-09-11T08:00Z |
Provenance to retain: source URL https://api.open-meteo.com/v1/forecast?latitude=50.85&longitude=4.35&hourly=temperature_2m,precipitation_probability&timezone=Europe%2FBrussels, owner Open-Meteo, retrieved_at=2026-09-11T08:00Z, period covered 2026-09-12 to 2026-09-13.
Decision/output (one rule, reusable — trip filter with support boundary):
Do this now (20 minutes)
1. Fetch or copy one real JSON slice (Open-Meteo Brussels URL above, one EDGAR CIK, or one FRED series) into the top of NORMALIZE-ONE.md as "Raw." 2. Below it, write a 5-row map: product name | provider field | type/unit/timezone — rename everything into user language, convert all times to one timezone. 3. Add a provenance line: source URL + owner + retrieved_at (now) + period covered. If any piece is missing, you are not done. 4. Write one decision in two sentences starting with IF/THEN plus threshold (rain >50%, revenue drop >8%, ticket age >48h) and name its output type: dashboard card, alert, report paragraph, recommendation, or automation. 5. Save NORMALIZE-ONE.md next to DATA-SORT.md — this is your Class 19 input for judging source fitness.
Finish line: a half-page note with five user-named fields, the retained source URL with owner/time/period, and one decision or view in two sentences.
Verify: hand your five fields to a friend. Can they make the decision without the raw JSON? If not, normalization is incomplete.
Common beginner mistake + what to do instead: renaming fields without aligning meaning — e.g. comparing a forecast precipitation_probability against an observed rainfall total, or quarterly revenue against annual revenue, then firing the alert. Instead, add a kind column (forecast vs observation, Q vs FY) during normalization and block the rule when kinds do not match.
Check your understanding
1. Why is displaying raw JSON not a product? What is missing? 2. Recite the six-step flow and name what happens at each step. 3. Define normalization and give one example for a filing fact or a forecast. 4. What four pieces of provenance must travel with every normalized record, and why?
ARTICLE DISCUSSION
JOIN THE
CONVERSATION.
Got a question, a take, or a better way to do this? Log in and leave a comment.
