AskCSV answers questions about a CSV file in plain English. It writes a DuckDB SQL query, runs it in your browser, draws a chart and writes a short answer.
Your file is never uploaded. The model sees a summary of the table and the rows a query returns, not the file.
Every number in the answer is checked in code against the query result. The check proves the number is in the result, not that the sentence around it is right, so read the SQL for anything important.
It is free to use, with an hourly question limit.
Drop a CSV or pick a sample. DuckDB-WASM, a SQL engine compiled to WebAssembly and loaded from the jsDelivr CDN, reads the file into one table inside this browser tab. It then profiles the table with SUMMARIZE and takes 5 random sample rows.
Your question and the table profile go to the AskCSV server, which asks an OpenAI model for a typed plan: a one line intent, one DuckDB query and a chart spec.
The server rejects anything that is not a single SELECT or WITH statement, any write or DDL keyword, PRAGMA, SET, ATTACH, INSTALL, and functions that reach outside the table such as read_csv, read_parquet or glob. The browser runs the same check again right before executing, including SQL you edit by hand.
The query runs in DuckDB in your tab. If it errors, is blocked or returns no rows, the SQL and the error go back to the model for a fix, up to 3 attempts in total. Every attempt is listed under "How I got this".
The chart spec is checked against the columns the query actually returned. Unknown or non-numeric columns are dropped, scatter plots need a numeric x axis, and a chart with too many points falls back to a table.
Up to 200 result rows go to the model, which writes one to three sentences. Every number in the answer is matched against the result cells, allowing for rounding such as 38.2k. If a number is not found, the server asks once more. The browser repeats the check and shows a warning naming any number it could not find.
Models: GPT-5.4 mini by default, or GPT-5.5. You pick one in the menu at the top of the app.
The CSV file itself never leaves your device. These parts of it do, through the AskCSV server to OpenAI:
The AskCSV server does not save any of this. It only records when each IP address asked, to enforce the hourly limit. What OpenAI keeps is set by its API data policy, not by this app. Your conversations, including up to 200 result rows per answer, stay in this browser's local storage until you delete them. Uploaded files are not kept, so you drop the file again to continue an old conversation.
On the SaaS subscriptions sample, the question "What is active MRR by plan?" leads to a query like this one. The model writes its own SQL each time, so yours may differ.
SELECT plan, ROUND(SUM(mrr_usd), 2) AS active_mrr FROM subscriptions WHERE status = 'active' GROUP BY plan ORDER BY active_mrr DESC
| plan | active_mrr |
|---|---|
| Enterprise | 419479.65 |
| Scale | 247350.75 |
| Growth | 126749.21 |
| Starter | 44160.99 |
The model is told to chart a few categories like these as bars.
Plans, seats, MRR and churn for a B2B tool, 2024 to 2025.
3,200 rows
A year of trips with stations, rider type, bike type and weather.
4,200 rows
Order lines from three stores, January to September 2025.
4,800 rows