JSON to Excel API reference
Base URL: https://api.justapi.tech (alias: https://xlsx.justapi.tech)
| Method | Path | Description | Modes |
|---|---|---|---|
POST |
/v1/xlsx/generate |
Generate a spreadsheet | sync, async (sync: 5,000 rows) |
Native payload
{
"sheets": [{
"name": "Report",
"columns": [
{ "header": "ID", "key": "id", "width": 32 },
{ "header": "Amount", "key": "amount", "format": "$#,##0.00", "type": "number" }
],
"rows": [{ "id": "f477...", "amount": 1520.5 }],
// SheetStyle is flat, not nested. Every field is optional; the first
// three default to true.
"style": {
"headerBold": true, "headerBackground": "#1F2937", "headerColor": "#FFFFFF",
"freezeHeader": true, "autofilter": true, "autofit": true
}
}],
"options": { "filename": "report-2026-03.xlsx", "creator": "My App", "allowFormulas": false }
}
filename is also accepted at the root as a convenience for the download name (options.filename
wins if both are present). Zebra striping ("zebra": true) is not implemented yet — it is silently
ignored rather than documented as if it worked.
Legacy payload (Excelerant-compatible, unchanged)
[{ "name": "This is a Test",
"cols": [{"header":"ID","id":"id"}],
"rows": [{"id":"f477...","first_name":"Cornelius"}] }]
Detected by shape (a root array of sheets with cols/rows) and normalized internally. The
adapter also tolerates, without losing data or failing: an unwrapped single sheet, an empty first
sheet, key/field instead of id, row tuples instead of objects, and a missing sheet name
(falls back to SheetN).
Sync vs async
mode defaults to "sync" here — the opposite of every other service — because the legacy array
payload has nowhere to put a mode field, and the already-integrated Bubble client expects its
200 with a URL. "mode": "async" gets you the 202 from the shared envelope once the balance is
reserved; a webhook is required with it (webhook without mode: "async" is a 400).
Row ceiling: 200,000 in both modes (MAX_SYNC_ROWS, a Worker CPU budget, not a memory one — see
docs/10-carga-xlsx.md). Over that, sync returns 400 sync_not_available and async 413 file_too_large. Format ceiling is 1,048,576 rows × 16,384 columns either way.
Example
curl https://api.justapi.tech/v1/xlsx/generate \
-H "Authorization: Bearer ak_live_..." \
-H "Content-Type: application/json" \
-d '{"sheets":[{"name":"Report","columns":[{"header":"ID","key":"id"}],"rows":[{"id":"1"}]}]}'
Full envelope, error catalog and billing rule are the same across every JustAPI service — see the API reference index and error codes.