JSONSheet API Documentation
Convert any public Excel or Google‑Sheet link into clean JSON.
Perfect for dashboards, automation workflows and backend jobs.
Overview
JSONSheet is a stateless, open-source web API. It streams an .xlsx
file from a public URL, parses every worksheet and returns typed JSON. No temp storage, no spreadsheet SDKs, no vendor lock-in.
Key Features
- Latency < 200 ms for small workbooks
- AI-assisted cleanup (headers, dates, currency)
- Blank-row & duplicate-row removal
- Per-IP rate-limiting + HSTS (edge-terminated)
- Runs anywhere via Docker
How It Works
- Upload Excel to Google Drive, Dropbox.
- Create a public-view link.
POST
that link to JSONSheet.- Receive structured JSON instantly.
Base URL
https://jsonsheet.com
Endpoints
Method | Path | Description |
---|---|---|
GET | /api/v1/jsonsheet/version | Health-check – returns semantic version + UTC time |
POST | /api/v1/jsonsheet/converter | Parse workbook → JSON (no cleanup, fastest) |
/api/v1/jsonsheet/converter?cleanup=true | Parse + normalise headers, dates, currency | |
/api/v1/jsonsheet/converter?cleanup=true&removeBlankRows=true&removeDuplicateRows=true | Full cleanup + blank / duplicate-row filters |
Request Payload
Content-Type: application/json
{
"url": "https://docs.google.com/spreadsheets/d/<FILE_ID>/export?format=xlsx"
}
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
cleanup | bool | false | Enable AI cleanup pipeline |
fixHeaders | bool | true | Snake-case, trim & deduplicate header row |
normDates | bool | true | Convert 60+ date formats → ISO 8601 |
normCurrency | bool | true | Strip currency symbols & thousand seps |
removeBlankRows | bool | false | Drop rows where all cells are empty |
removeDuplicateRows | bool | false | Hash-compare rows; remove dupes |
Typical Response
{
"tables": [
{
"sheetName": "Sample",
"rows": [
{ "id": "1", "name": "Alice" },
{ "id": "2", "name": "Bob" }
]
}
]
}
Supported Source Links
- Google Sheets export (
…/export?format=xlsx
) - Google Drive file links (public)
- Dropbox (
?dl=0
or?raw=1
) - Any HTTPS URL (e.g. S3 presigned link)
- OneDrive – planned Q3 2025
Rate Limits
- 100 requests / minute / IP (free tier)
- 5 000 requests / day / IP
- Higher throughput? Contact us
Error Responses
Status | Message | Reason & Resolution |
---|---|---|
400 | Invalid or missing URL | Body must include a public .xlsx link |
413 | File too large (10 MB) | Split workbook or compress content |
429 | Too Many Requests | Rate-limit exceeded – retry ≤ 60 s |
500 | Could not parse file | Password protected or malformed workbook |
Quick-Start Code Snippets
Shell (cURL)
curl -X POST \
https://api.jsonsheet.com/api/v1/jsonsheet/converter?cleanup=true \
-H "Content-Type: application/json" \
-d '{"url":"https://docs.google.com/spreadsheets/d/FILE_ID/export?format=xlsx"}'
JavaScript (Fetch API)
fetch("https://api.jsonsheet.com/api/v1/jsonsheet/converter?cleanup=true", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({ url: excelLink })
}).then(r => r.json()).then(console.log);
Next.js (API Route)
// pages/api/convert.js
export default async function handler(req, res) {
const response = await fetch(
"https://api.jsonsheet.com/api/v1/jsonsheet/converter?cleanup=true",
{
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({ url: req.body.url })
});
res.status(200).json(await response.json());
}
Python (requests)
import requests, json, pprint
payload = {"url":
"https://docs.google.com/spreadsheets/d/FILE_ID/export?format=xlsx"}
r = requests.post(
"https://api.jsonsheet.com/api/v1/jsonsheet/converter?cleanup=true",
json=payload, timeout=30)
pprint.pprint(r.json())
ASP.NET (C# HttpClient)
using var client = new HttpClient();
var body = new StringContent(
JsonSerializer.Serialize(new { url = link }),
Encoding.UTF8, "application/json");
var resp = await client.PostAsync(
"https://api.jsonsheet.com/api/v1/jsonsheet/converter?cleanup=true",
body);
var json = await resp.Content.ReadAsStringAsync();
Java 17 (HttpClient)
HttpClient http = HttpClient.newHttpClient();
String json = """
{ "url": "https://docs..." }""";
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.jsonsheet.com/api/v1/jsonsheet/converter?cleanup=true"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
String out = http.send(req, BodyHandlers.ofString()).body();
Go
payload := map[string]string{"url":"https://docs..."}
buf, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST",
"https://api.jsonsheet.com/api/v1/jsonsheet/converter?cleanup=true",
bytes.NewReader(buf))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
res, _ := client.Do(req)
Integration Scenarios
Frontend — Angular 16 +
// app.component.html
<form [formGroup]="fg" (ngSubmit)="submit()" class="row gap-2 align-items-center">
<input class="form-control flex-grow-1"
formControlName="url"
placeholder="Public Excel link (.xlsx or G-Sheets export)"
required />
<button class="btn btn-primary" type="submit">Fetch JSON</button>
</form>
// app.component.ts
export class AppComponent {
fg = this.fb.group({ url: [''] });
constructor(private fb: FormBuilder,
private http: HttpClient) {}
submit() {
if (this.fg.invalid) return;
const body = { url: this.fg.value.url };
this.http.post(
'https://api.jsonsheet.com/api/v1/jsonsheet/converter?cleanup=true&removeBlankRows=true',
body
).subscribe(console.log);
}
}
Frontend — React 18 +
import { useState } from 'react';
export default function Converter() {
const [url, setUrl] = useState('');
const [result, setResult] = useState(null);
async function handleSubmit(e) {
e.preventDefault();
const res = await fetch(
'https://api.jsonsheet.com/api/v1/jsonsheet/converter?cleanup=true',
{
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ url })
}
);
setResult(await res.json());
}
return (
<>
<form onSubmit={handleSubmit}>
<input value={url}
onChange={e => setUrl(e.target.value)}
placeholder="Excel link" required />
<button>Fetch</button>
</form>
<pre>{result && JSON.stringify(result, null, 2)}</pre>
</>
);
}
No-Code Automation (Zapier)
- Trigger • file uploaded to Dropbox.
- Zapier Webhook →
…/converter?cleanup=true
. - Parse JSON → Airtable / Google Sheets / email.
FAQ
- Production-ready? Yes, the API is stateless and containerised.
- Do you store data? No. Files are streamed, parsed, then deleted.
- Max workbook size? 10 MB on free tier (higher on request).
- Cold start? After 15 min idle the first request may take ≈ 50 s.
Roadmap 2025
v1.0 delivers sheet-to-JSON conversion with optional AI cleanup.
Upcoming: Data-viz dashboards, scheduled PDF/CSV export, webhook push notifications.