Form to CSV: get every answer as a spreadsheet file

Updated 2026-10-30

I want my answers in a spreadsheet. One request gives me a CSV file. The dashboard has a CSV button too.

One line

You need your API key and form id. See the quickstart.

bash
export AIFORMAPI_KEY="afk_your_key_here"

curl -sS "https://aiformapi.com/v1/forms/FORM_ID/responses?format=csv" \
  -H "Authorization: Bearer $AIFORMAPI_KEY" \
  -o responses.csv

Swap FORM_ID for your form's id.

JavaScript

Needs Node 18 or newer.

javascript
import { writeFile } from "node:fs/promises";

const key = process.env.AIFORMAPI_KEY;
const formId = process.env.AIFORMAPI_FORM_ID;

const res = await fetch(
  `https://aiformapi.com/v1/forms/${formId}/responses?format=csv`,
  { headers: { Authorization: `Bearer ${key}` } }
);

if (!res.ok) {
  const body = await res.json();
  throw new Error(`${res.status} ${body.error.code}: ${body.error.message}`);
}

await writeFile("responses.csv", await res.text());
console.log("Saved responses.csv");

Python

python
import os
import requests

key = os.environ["AIFORMAPI_KEY"]
form_id = os.environ["AIFORMAPI_FORM_ID"]

res = requests.get(
    f"https://aiformapi.com/v1/forms/{form_id}/responses",
    params={"format": "csv"},
    headers={"Authorization": f"Bearer {key}"},
    timeout=30,
)

if not res.ok:
    error = res.json()["error"]
    raise SystemExit(f"{res.status_code} {error['code']}: {error['message']}")

with open("responses.csv", "wb") as f:
    f.write(res.content)
print("Saved responses.csv")

Errors come back as JSON: {"error": {"code", "message"}}. See errors.

Only new answers

Add since with a UTC ISO 8601 time. Save the time of each pull. Use it on the next one.

bash
curl -sS "https://aiformapi.com/v1/forms/FORM_ID/responses?format=csv&since=2026-10-01T00:00:00Z" \
  -H "Authorization: Bearer $AIFORMAPI_KEY" \
  -o october.csv

Many rows

limit sets rows per call. A CSV holds up to 10,000 rows. Use cursor to go on. See the responses guide.

What is in the file

ColumnWhat it holds
One per field idThe answer. The header is the field id
response_idThe id of the stored response
sourcehuman, paste, agent_api or agent_mcp. See agent-fillable forms
submitted_atWhen it was stored
csv
full_name,attending,guests,response_id,source,submitted_at
Ada Lovelace,Yes,1,RESPONSE_ID_1,human,2026-10-30T09:14:02Z
Grace Hopper,Maybe,0,RESPONSE_ID_2,paste,2026-10-30T09:20:41Z

Open the file

Excel. File, Open, then pick Text Files. Or Data, From Text/CSV, then Load. See form to Excel.

Google Sheets. File, Import, pick the file. See form to Google Sheets.

Numbers. Drag the file onto the Numbers icon.

Careful with strangers' answers. A cell can start with =, +, - or @. A spreadsheet may read it as a formula. Our CSV puts an apostrophe in front, so it stays text.

A browser bar and IMPORTDATA(url) cannot send the Authorization header. They get 401 unauthorized. Never put your key in a link. For a sheet that fills itself, use the Apps Script on form to Google Sheets.

Limits

Free plan: 30 requests a minute, 1,000 a day per key. See rate limits. Want a push? Add a webhook. More: forms API.

Sources, read 2026-10-30: Microsoft, Google Sheets, IMPORTDATA, Apple.

Questions

How do I export form responses to CSV?

GET /v1/forms/{id}/responses with format=csv and your API key in the Authorization header. Save the body as a .csv file. The dashboard has a CSV button too.

Can I get only the new responses?

Yes. Add since with a UTC ISO 8601 time. You get the responses after that time. Save the time of each pull and use it next time.

Why does my browser link or IMPORTDATA formula fail?

The API reads your key from the Authorization header. A browser bar and IMPORTDATA send only a URL, so you get 401 unauthorized. Use curl, a script or the dashboard.