catalogue / tools / Documents / XLSX to JSON

Convert XLSX to JSON

To convert XLSX to JSON, send one POST to /v1/xlsx-to-json with the XLSX source. Each call costs $0.005 in USDC on Base via x402, with no account and no API key. The source file can be up to 25 MB.

Endpoint
POST /v1/xlsx-to-json
Price
$0.005 per call

01Limits

LimitValue
Largest source file25 MB (26,214,400 bytes)
Timeout40 s
Source formatsXLSX
Output formatsJSON
Option header_rowdefault 1
Option max_rowsdefault 1000

02Example

A real XLSX to JSON run of xlsx-to-json.

Request
POST /v1/xlsx-to-json
content-type: application/json
payment-signature: <base64 x402 payload>

{
  "url": "https://grist.tools/samples/documents/garden-inventory.xlsx",
  "header_row": 1,
  "max_rows": 1000
}
Response
200 OK
payment-response: <base64 settlement receipt>

{
  "source_url": "https://grist.tools/samples/documents/garden-inventory.xlsx",
  "sheet_count": 2,
  "sheets": [
    {
      "name": "Seeds",
      "columns": [
        "Variety",
        "Crop",
        "Packets",
        "Sown On",
        "Organic"
      ],
      "rows": [
        {
          "Variety": "Early Scarlet",
          "Crop": "Radish",
          "Packets": 4,
          "Sown On": "2026-03-14T00:00:00.000Z",
          "Organic": true
        },
        {
          "Variety": "Green Arrow",
          "Crop": "Pea",
          "Packets": 6,
          "Sown On": "2026-03-21T00:00:00.000Z",
          "Organic": true
        },
        {
          "Variety": "Golden Cherry",
          "Crop": "Tomato",
          "Packets": 2,
          "Sown On": "2026-04-11T00:00:00.000Z",
          "Organic": false
        }
      ],
      "row_count": 3,
      "truncated": false
    },
    {
      "name": "Tools",
      "columns": [
        "Tool",
        "Count",
        "Location"
      ],
      "rows": [
        {
          "Tool": "Spade",
          "Count": 3,
          "Location": "Shed"
        },
        {
          "Tool": "Watering can",
          "Count": 5,
          "Location": "Rain barrels"
        }
      ],
      "row_count": 2,
      "truncated": false
    }
  ]
}

Source file: documents/garden-inventory.xlsx, 6.7 KB (6,816 bytes). Two-sheet Excel workbook of garden stock: Seeds (text, counts, sowing dates, a boolean) and Tools, written by exceljs with pinned document and zip dates. The request sets header_row to 1 and max_rows to 1000. The recorded run returned 639 bytes of JSON, 9% of the source size, with 2 sheets.

03Format notes

XLSX as a source

An XLSX workbook is an OOXML ZIP archive, so the first gate only confirms the PK 03 04 signature; exceljs is what establishes that the archive is a workbook and fails otherwise. Before exceljs reads anything, the inflated size and the entry count of the archive are bounded, because the download cap cannot stop a ZIP bomb. The number of worksheets is bounded too, and max_rows is applied to each sheet separately, marking a cut sheet as truncated. The header_row option names the row holding column names, or selects positional arrays instead; blank headings become generated names and duplicates get suffixes. Error cells become null, dates become ISO-8601 strings and formulas contribute their cached results. A sheet name that is not in the workbook is refused with the list of available names.

JSON as a target

The JSON that Grist returns keeps different value types depending on the reader. csv-to-json leaves every cell a string and returns header-keyed objects, or positional arrays when header is false, together with the delimiter, the column list, a row count and a truncated flag. xlsx-to-json keeps numbers and booleans as typed values, turns dates into ISO-8601 strings, uses the cached result of a formula, and reduces rich text and hyperlinks to their text; error cells become null. It returns every worksheet, or a single sheet selected by exact name. A delimited source therefore produces JSON that needs type conversion by the caller, while a workbook source produces typed values straight away. Blank and duplicate headings are made unique by both readers before they become object keys.

04Errors

CodeHTTP
invalid_input400
blocked_target403
unreachable_target424
upstream_timeout424
unsupported_content_type415
too_large413
unprocessable422
internal500

When each is raised, and what it means for payment: /docs/xlsx-to-json.

05Questions

What does it cost to convert XLSX to JSON?
$0.005 per call, paid in USDC on Base via x402.
How large can the XLSX file be?
Up to 25 MB (26,214,400 bytes). Past a limit the call answers too_large (413).
What happens if the conversion fails?
The tool answers with a typed JSON error from the errors table. Payment is settled only after the tool has produced its result; a call that fails inside the tool is never settled.

06Related