SQL on CSV & Excel API
Query CSV, XLSX and JSON files with SQL: SELECT, WHERE, JOIN, GROUP BY with SUM / COUNT / AVG, HAVING, ORDER BY and LIMIT. Results as JSON or CSV.
Upload one or more tables as multipart files (CSV with any delimiter, XLSX, JSON array or JSON lines); each file becomes a table named after the file (orders.csv → orders) or after a custom field name. You can also send csv text (table t, or the name in table), data (JSON array) or tables {"name": rows | "csv text"}. Column types are inferred (numbers, booleans, text; empty cells are NULL; numbers with leading zeros such as phone numbers stay text).
Supported SQL: SELECT [DISTINCT] columns, *, t.*, expressions and aliases; FROM with [INNER] JOIN / LEFT JOIN … ON (equality joins use a hash join) and comma / CROSS JOIN; WHERE with AND / OR / NOT, comparisons, LIKE (case-insensitive, % and _), IN, BETWEEN, IS [NOT] NULL; GROUP BY with COUNT(*), COUNT(DISTINCT), SUM, AVG, MIN, MAX, TOTAL, GROUP_CONCAT; HAVING; ORDER BY columns, aliases or positions with ASC / DESC and NULLS FIRST / LAST; LIMIT / OFFSET; CASE, CAST and functions LOWER, UPPER, LENGTH, TRIM, SUBSTR, REPLACE, INSTR, CONCAT, ROUND, ABS, FLOOR, CEIL, COALESCE, IFNULL, NULLIF, DATE, YEAR, MONTH, DAY and UNACCENT (removes Vietnamese diacritics). Subqueries, UNION and window functions are not supported.
Output JSON (columns, rows, counts) or format=csv. Limits: 200,000 rows per table, 5,000,000 cells in total, 10,000 result rows (max_rows), 8 seconds per query; nothing is stored.
Parameters
| Name | In | Type | Required | Default | |
|---|---|---|---|---|---|
sql | body | string | yes | SELECT query (max 20,000 characters). | |
file | body | file | no | One or more multipart files (CSV, XLSX, JSON); the table name comes from the file name. | |
csv | body | string | no | CSV text for a single table named t (or table). | |
data | body | array | no | JSON array of objects (or arrays with a header row) for a single table. | |
tables | body | object | no | Several tables: {"orders": [...], "customers": "id,name\n1,An"}. | |
table | body | string | no | t | Table name for csv / data. |
sheet | body | string | no | XLSX sheet name or index (default: first visible sheet). | |
delimiter | body | string | no | auto | CSV delimiter (auto-detected by default). |
format | body|query | string | no | json | json or csv. |
max_rows | body|query | number | no | 10000 | Cap on returned rows (1-10,000). |
Example
curl -X POST "https://apibox.io.vn/v1/csv-query" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file1=@./my-file"const form = new FormData();
form.append('file1', fileInput.files[0]);
const res = await fetch('https://apibox.io.vn/v1/csv-query', {
method: 'POST',
headers: { Authorization: 'Bearer YOUR_API_KEY' },
body: form,
});
console.log(await res.json());import requests
res = requests.post(
"https://apibox.io.vn/v1/csv-query",
headers={"Authorization": "Bearer YOUR_API_KEY"},
files={"file1": open("my-file", "rb")},
timeout=30,
)
print(res.json())<?php
$ch = curl_init('https://apibox.io.vn/v1/csv-query');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY'],
CURLOPT_POSTFIELDS => ['file1' => new CURLFile('my-file')],
]);
$response = curl_exec($ch);
print_r(json_decode($response, true));Response
{
"columns": [
"name",
"orders",
"total"
],
"row_count": 3,
"total_rows": 3,
"truncated": false,
"rows": [
{
"name": "Trần Thị Bình",
"orders": 2,
"total": 600000
},
{
"name": "Lê Văn Cường",
"orders": 1,
"total": 450000
},
{
"name": "Nguyễn Văn An",
"orders": 1,
"total": 300000
}
],
"tables": {
"orders": {
"rows": 6,
"columns": [
"id",
"customer_id",
"product",
"qty",
"price",
"date",
"status"
]
},
"customers": {
"rows": 4,
"columns": [
"id",
"name",
"city",
"phone"
]
}
},
"ms": 3
}
Use cases
- Join an order export with a customer list and total revenue per customer
- Filter and aggregate a large Excel sheet without opening Excel
- Let no-code tools run reports on CSV exports from an e-commerce platform
- Check data quality: duplicates, NULLs and outliers with GROUP BY and HAVING
FAQ
How are tables named?
After the uploaded file name without extension (Đơn hàng.csv → Đơn_hàng), or after the multipart field name if it is not file / file1…; in JSON use the keys of tables. A single table can also be called t.
Does it support JOIN?
Yes: INNER JOIN and LEFT JOIN with any ON condition, plus comma / CROSS joins. Equality joins (a.id = b.id) are fast hash joins; other conditions compare row pairs up to 5 million.
Is LIKE case-sensitive?
No. LIKE ignores case for all letters, including Vietnamese (Áo matches áo%). Use UNACCENT() to also ignore diacritics: WHERE UNACCENT(name) LIKE '%nguyen%'.
Related APIs
JSON Validator
Check JSON syntax with exact line and column of errors, and validate data against a JSON Schema (draft 4, 7, 2019-09 or 2020-12).
{ }JSON Formatter
Pretty print JSON with 0-8 spaces or tabs, minify it, or sort object keys recursively. Syntax errors are reported with line and column.
CSVCSV to JSON
Convert CSV into an array of JSON objects using the header row, with delimiter auto-detection, number and boolean typing, and row-level errors.