Export Google Sheets Data as CSV via API
Use the SheetsAPI format=csv query parameter to get a Google Sheet as a downloadable CSV file — with examples in curl, fetch, and a Next.js download button.
One parameter, CSV output
GKit SheetsAPI returns JSON by default. Add ?format=csv to any list endpoint and you get back a plain-text CSV file with a header row — ready to open in Excel, import into another tool, or stream to the browser as a download.
GET /api/spreadsheets/{userKey}/{sheetName}?format=csv
The response has Content-Type: text/csv and the first row is the column header from your sheet.
curl
The simplest way to test it:
curl -o contacts.csv \
-H "Authorization: Bearer sk_..." \
"https://sheetsapi.gkit.mreshank.com/api/spreadsheets/uk_abc123/Contacts?format=csv"-o contacts.csv writes the response body straight to a file. Open it in any spreadsheet app.
To inspect it inline without saving:
curl -s \
-H "Authorization: Bearer sk_..." \
"https://sheetsapi.gkit.mreshank.com/api/spreadsheets/uk_abc123/Contacts?format=csv"Output:
name,email,plan
Ada Lovelace,ada@example.com,pro
Grace Hopper,grace@example.com,free
fetch in JavaScript
async function fetchCsv(userKey, sheetName) {
const res = await fetch(
`https://sheetsapi.gkit.mreshank.com/api/spreadsheets/${userKey}/${sheetName}?format=csv`,
{
headers: { Authorization: `Bearer ${process.env.GKIT_API_KEY}` },
}
);
if (!res.ok) throw new Error(`Failed: ${res.status}`);
return res.text(); // plain CSV string
}
const csv = await fetchCsv("uk_abc123", "Contacts");
console.log(csv);
// name,email,plan
// Ada Lovelace,ada@example.com,proFrom there you can parse it with any CSV library (papaparse, csv-parse) or send it straight to the user.
Next.js download button
The pattern below fetches the CSV on the client, wraps it in a Blob, creates a temporary object URL, clicks it programmatically, then immediately revokes the URL — the browser's native download dialog appears with no server route required.
"use client";
import { useState } from "react";
interface DownloadCsvButtonProps {
userKey: string;
sheetName: string;
fileName?: string;
}
export function DownloadCsvButton({
userKey,
sheetName,
fileName = `${sheetName}.csv`,
}: DownloadCsvButtonProps) {
const [loading, setLoading] = useState(false);
async function handleDownload() {
setLoading(true);
try {
const res = await fetch(
`/api/sheets-csv?userKey=${userKey}&sheet=${sheetName}`
);
if (!res.ok) throw new Error("Export failed");
const csv = await res.text();
const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = fileName;
a.click();
URL.revokeObjectURL(url);
} finally {
setLoading(false);
}
}
return (
<button onClick={handleDownload} disabled={loading}>
{loading ? "Exporting…" : "Download CSV"}
</button>
);
}The component calls a thin Next.js route handler (/api/sheets-csv) that proxies the request server-side so your API key never reaches the browser:
// app/api/sheets-csv/route.ts
import { NextRequest, NextResponse } from "next/server";
export async function GET(req: NextRequest) {
const { searchParams } = req.nextUrl;
const userKey = searchParams.get("userKey");
const sheet = searchParams.get("sheet");
if (!userKey || !sheet) {
return NextResponse.json({ error: "Missing params" }, { status: 400 });
}
const upstream = await fetch(
`https://sheetsapi.gkit.mreshank.com/api/spreadsheets/${userKey}/${sheet}?format=csv`,
{
headers: { Authorization: `Bearer ${process.env.GKIT_API_KEY}` },
}
);
if (!upstream.ok) {
return NextResponse.json({ error: "Upstream failed" }, { status: 502 });
}
const csv = await upstream.text();
return new NextResponse(csv, {
headers: {
"Content-Type": "text/csv",
"Content-Disposition": `attachment; filename="${sheet}.csv"`,
},
});
}Drop <DownloadCsvButton userKey="uk_abc123" sheetName="Contacts" /> anywhere in your app and users get a one-click export of live sheet data.
Combining with pagination parameters
?format=csv works alongside limit and offset if you only want a slice of the sheet:
# First 50 rows as CSV
curl "https://sheetsapi.gkit.mreshank.com/api/spreadsheets/uk_abc123/Orders?format=csv&limit=50&offset=0"For a full export, omit limit — the default returns all rows.