FlatData API — Project Description
FlatData is a lightweight HTTP API for converting structured JSON data into downloadable CSV files. It’s ideal for quickly exporting tabular data from frontends, scripts, and integrations without managing CSV formatting edge cases yourself.
- Base URL (via RapidAPI):
https://flatdata.p.rapidapi.com - Host header:
X-RapidAPI-Host: flatdata.p.rapidapi.com - Auth header:
X-RapidAPI-Key: <your-rapidapi-key>
What you can do
- Convert a JSON array of objects to a CSV file with consistent column order.
- Control the output filename via a query parameter.
- Health-check the service for monitoring and readiness.
How it works (high level)
- You POST a JSON payload containing an array of “rows” (objects) to the conversion endpoint.
- The service determines the CSV columns by the order in which keys appear across your rows (first-seen order). This ensures stable column ordering even when rows have different keys.
- Values are stringified with sensible rules (see “CSV generation rules”).
- The API returns a
text/csvresponse with aContent-Dispositionheader so browsers download it as a file.
Endpoints
1) Convert JSON to CSV
- Method:
POST - Path:
/convert/csv - Full URL:
https://flatdata.p.rapidapi.com/convert/csv - Query parameters:
filename(optional): Base filename without extension. Defaults toconverted. The API ensures a.csvextension.
- Request body (JSON):
rows: An array of objects. Each object is one CSV row; keys are column names.
- Success response:
200 OK- Content-Type:
text/csv; charset=utf-8 - Body: CSV content (string/bytes)
- Headers:
Content-Disposition: attachment; filename="<name>.csv"
- Error responses:
400 Bad Request— malformed or invalid input401 Unauthorized— missing or invalid RapidAPI key
Example request body:
{
"rows": [
{ "name": "alice", "age": 30 },
{ "name": "bob", "city": "NYC" }
]
}
Resulting CSV (columns in first-seen order: name,age,city):
name,age,city
alice,30,
bob,,NYC
2) Health check
- Method:
GET - Path:
/health - Full URL:
https://flatdata.p.rapidapi.com/health - Response:
200 OK- Body (JSON):
{ "status": "ok" }
- Body (JSON):
CSV generation rules
- Column order: Determined by the first time a key is seen as the rows are scanned from top to bottom. New keys encountered later are appended to the end of the header.
- Missing keys: Render as empty fields in that row.
- Value stringification:
nullor missing → empty string- boolean →
true/false - number → numeric string (no extra quotes)
- string → output as-is (CSV writer will quote as needed)
- arrays/objects → compact JSON string (e.g.,
{"k":1}or[1,2])
- Headers: Included when there is at least one column.
Authentication (RapidAPI)
Include these headers in every request:
X-RapidAPI-Host: flatdata.p.rapidapi.comX-RapidAPI-Key: <your-rapidapi-key>
If the key is missing or invalid you’ll receive 401 Unauthorized.
Usage examples
curl
curl -X POST "https://flatdata.p.rapidapi.com/convert/csv?filename=users" \
-H "Content-Type: application/json" \
-H "X-RapidAPI-Host: flatdata.p.rapidapi.com" \
-H "X-RapidAPI-Key: $RAPIDAPI_KEY" \
--data '{
"rows": [
{ "name": "alice", "age": 30 },
{ "name": "bob", "city": "NYC" }
]
}' \
-o users.csv
JavaScript (fetch)
const res = await fetch("https://flatdata.p.rapidapi.com/convert/csv?filename=report", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-RapidAPI-Host": "flatdata.p.rapidapi.com",
"X-RapidAPI-Key": process.env.RAPIDAPI_KEY
},
body: JSON.stringify({
rows: [
{ id: 1, name: "Widget", price: 9.99 },
{ id: 2, name: "Gadget", stock: 12 }
]
})
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const blob = await res.blob();
// download in browser
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "report.csv"; // server also sets Content-Disposition
a.click();
URL.revokeObjectURL(url);
Python (requests)
import requests
url = "https://flatdata.p.rapidapi.com/convert/csv"
params = {"filename": "inventory"}
headers = {
"Content-Type": "application/json",
"X-RapidAPI-Host": "flatdata.p.rapidapi.com",
"X-RapidAPI-Key": "<your-rapidapi-key>"
}
payload = {
"rows": [
{"sku": "A1", "qty": 3},
{"sku": "B2", "loc": "DC-1"}
]
}
r = requests.post(url, params=params, json=payload, headers=headers)
r.raise_for_status()
with open("inventory.csv", "wb") as f:
f.write(r.content)
Input validation and errors
400 Bad Requesttypically indicates:- Missing
rowsfield rowsis not an array of objects- Non-serializable values (should be rare; complex types are JSON-stringified)
- Missing
401 Unauthorizedmeans your RapidAPI key is missing or invalid.
The error body includes a brief message, e.g. "failed to convert to CSV: <reason>".
File naming behavior
- If
filenameis omitted or blank, the service defaults toconverted.csv. - If you pass
filenamewithout.csv, the API appends.csv. - If you pass
filenameending with.csv(any casing), it’s used as-is.
Performance and limits
- Column detection is single pass over your rows, suitable for typical client-side exports.
- Very large payloads may be limited by gateway or RapidAPI plan limits; consider batching if needed.
- Arrays/objects within fields are compact JSON strings, which can increase CSV size. If size is critical, flatten these values before sending.
FAQ
- Why are some cells empty? Because not all rows have all keys; missing keys become empty fields.
- Why is my array/object quoted JSON in the CSV? Non-primitive values are JSON-stringified to keep CSV valid and lossless.
- Can I control column order? Implicitly by ordering keys in early rows. The first time a key appears determines its position.