How AskCSV works

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.

Try it with a sample

From question to answer

  1. Load the data in your tab

    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.

  2. Plan a query

    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.

  3. Check the SQL is read-only

    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.

  4. Run it, and repair if needed

    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".

  5. Draw the chart

    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.

  6. Write and check the answer

    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.

What runs where

In your browser

  • Reading the CSV and storing it as a table
  • Profiling columns and picking sample rows
  • Running every SQL query
  • The second read-only check
  • Drawing the chart as SVG
  • The second number check on the answer
  • Conversation history, in local storage

On the server

  • The hourly question limit, counted per IP address
  • Calls to the OpenAI Responses API with structured output
  • The first read-only check on the model's SQL
  • The first number check on the answer, with one retry

Models: GPT-5.4 mini by default, or GPT-5.5. You pick one in the menu at the top of the app.

What the model sees

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.

An example

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
Result of the example query
planactive_mrr
Enterprise419479.65
Scale247350.75
Growth126749.21
Starter44160.99

The model is told to chart a few categories like these as bars.

Sample datasets

Limits