# JSON to Excel Converter - JSON to XLSX, by URL or Bulk (`eliai/json-to-excel`) Actor

Convert JSON to an Excel spreadsheet by URL - arrays of records become clean XLSX sheets with headers, column widths set, one sheet per key for object-of-arrays. Built for scripts, pipelines, and AI agents. $0.03 per file; failures are free.

- **URL**: https://apify.com/eliai/json-to-excel.md
- **Developed by:** [Anthony Snider](https://apify.com/eliai) (community)
- **Categories:** Developer tools, Automation, MCP servers
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$30.00 / 1,000 converted files

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## JSON to Excel Converter — JSON to XLSX Spreadsheet, by URL or Bulk

Turn a JSON file into a real Excel workbook without installing anything. Point this
at a `.json` URL and get back a downloadable `.xlsx`: your records become rows, their
keys become the header row, and column widths are sized to fit. Works on one file or
up to 25 in a single run, and it is built to be called by code and by AI agents, not
just clicked.

**$0.03 per file converted.** No subscription, no seat fee, no minimum. You pay for
files you actually convert.

### What problem this solves

JSON is what the API returns and Excel is what the person asking for the report opens.
Getting from one to the other usually means installing a library, arguing with it about
which keys become columns when the records are not all the same shape, and writing
throwaway glue — or pasting data that may belong to a client into a random free website.

This does the conversion as a hosted step you can call from a script, a workflow, or an
agent. Nothing to install, the file is fetched from the URL you give it, and the finished
workbook comes back as a URL you can download or hand straight to someone else.

### Who uses it

- **Data and ops engineers** turning an API dump into the spreadsheet finance actually asked for.
- **Analysts** who need JSON as a workbook for a pivot table, a chart, or a client deliverable.
- **AI agents** that produced structured JSON and were asked for "a spreadsheet".
- **No-code / automation builders** (Make, n8n, and similar) that can call a URL but cannot
  write a binary `.xlsx`.
- **Anyone doing a bulk export** — hand it 25 JSON URLs, get 25 workbooks.

### Quick start

```json
{
  "url": "https://graveyard.broke2builtai.com/assets/sample.json"
}
```

That is the whole minimum input. Everything else is optional. (That URL is a live
10-row sample file, so you can run it as-is to see the output shape.)

#### All input options

| Field | Type | Required | What it does |
|---|---|---|---|
| `url` | string | **yes** | Direct URL to the `.json` file |
| `urls` | string\[] | no | Extra JSON URLs — up to **25 total** per run |
| `maxRows` | number | no | Cap data rows per sheet (default **5000**) |
| `maxFileSizeMb` | number | no | Refuse files larger than this, uncharged (default **50**, max 200) |

#### What JSON shapes it accepts

| Your JSON | What you get |
|---|---|
| `[ {...}, {...} ]` — array of records | One sheet, `Sheet1`, one row per record |
| `{ "Orders": [...], "Customers": [...] }` — object of arrays | **One sheet per key**, named after the key |
| `{ "a": 1, "b": 2 }` — a single flat record | One sheet, one row |
| `[ 1, 2, 3 ]` — array of plain values | One sheet with a single `value` column |
| `42`, `"text"`, `null` | Recorded as an error — there is no spreadsheet in a bare value |

Columns are the **union of every record's keys, in first-seen order**: keys from the
first record come first, and a key that only appears in record 40 is appended as a new
column with the earlier rows left blank.

### What you get back

This is the actual dataset item from a run against the sample URL above — not an
illustration:

```json
{
  "url": "https://graveyard.broke2builtai.com/assets/sample.json",
  "finalUrl": "https://graveyard.broke2builtai.com/assets/sample.json",
  "status": 200,
  "fileName": "sample.xlsx",
  "sheetNames": ["Sheet1"],
  "sheets": [
    {
      "name": "Sheet1",
      "rowCount": 10,
      "columns": ["sku", "product", "category", "unit_price", "stock", "restock_date", "supplier"]
    }
  ],
  "downloadUrl": "https://api.apify.com/v2/key-value-stores/2896bac1-99c4-4b1d-8de0-bdbefd492873/records/output-1.xlsx"
}
```

- `downloadUrl` — **the finished `.xlsx`**. Fetch it, or open it in a browser.
- `sheets[].columns` — the header row that was written, in order.
- `sheets[].rowCount` — data rows written to that sheet (header excluded).
- `sheets[].truncated` — present and `true` only if `maxRows` cut the sheet short.
- `fileName` — a suggested name, derived from the source URL (`sample.json` → `sample.xlsx`).
- `finalUrl` — where the fetch actually landed, after redirects.

**One dataset item per input file.** A failed input returns `{ url, error }` instead of
throwing, so one bad link in a batch of 25 never kills the other 24 — and a file that
fails is never charged.

### Use it as an AI agent tool

This Actor is callable over **Apify MCP**, so an agent can produce a spreadsheet
mid-conversation without you writing an integration. The shape an agent needs:

- **Tool:** this Actor
- **Input:** `{ "url": "<json url>" }`
- **Returns:** a `downloadUrl` pointing at a real `.xlsx` workbook

If your agent can be handed a link to a JSON file, it can now hand back a spreadsheet.

### Pricing, plainly

**$0.03 per file converted** (pay-per-event: `file-converted`). A 25-file batch costs
$0.75. There is no monthly fee, and a run that converts nothing costs nothing.

### Honest limits

Worth knowing before you run it, so nothing surprises you:

- The file must be reachable at a **direct URL**. A GitHub *page* is not a file URL —
  use the raw link, or host the file somewhere fetchable.
- **Nested objects and arrays inside a record are written as JSON text in the cell**, not
  expanded into extra columns. `{"addr": {"city": "NYC"}}` becomes one `addr` cell reading
  `{"city":"NYC"}`. Flatten first if you want `addr.city` as its own column.
- `null` and missing keys become **genuinely empty cells**, not the word "null".
- **Data only — no formulas, colours, fonts or merged cells.** Column widths are sized to
  the content; nothing else is styled.
- Up to **25 files per run** and, by default, 5000 rows per sheet (`maxRows`). Excel itself
  stops at 1,048,575 data rows.
- Files over `maxFileSizeMb` (default 50 MB, max 200) are refused before download and never
  charged — very large documents can exhaust the run's memory.

### FAQ

#### How do I convert JSON to Excel without installing anything?

Give this Actor the file's URL. It fetches the JSON, builds the workbook, and returns a
`downloadUrl` for the finished `.xlsx`. No local install, no library to learn.

#### Can I get multiple sheets in one workbook?

Yes. Send JSON shaped as `{ "SheetName": [ ...records ], "Other": [ ...records ] }` and each
key becomes its own sheet, named after the key. Names are trimmed to Excel's 31-character
limit and characters Excel forbids (`: \ / ? * [ ]`) are replaced with `_`.

#### What happens if my records don't all have the same keys?

Every key that appears anywhere becomes a column, in first-seen order. Records missing that
key get an empty cell. Nothing is dropped.

#### What happens to nested JSON?

It is written into the cell as JSON text. A spreadsheet cell holds one value, so a nested
object cannot become columns without guessing at a flattening scheme you did not ask for.

#### Can I convert multiple JSON files in one run?

Yes — up to 25 per run via `urls`. Each produces its own workbook and its own dataset item,
and a failure on one does not stop the rest.

#### What happens if the file is missing or is not valid JSON?

That input returns `{ url, error }` with a message naming the actual problem (HTTP status,
an HTML page instead of a file, a parse error). The run continues, the other files still
convert, and nothing is charged for the failure.

#### Where does my data go?

The Actor fetches the file, converts it, and writes both the record and the `.xlsx` to
**your** run's storage on your own Apify account. Delete the run and the output goes with it.

#### Can an AI agent call this?

Yes — it is exposed through Apify MCP as an agent tool. See "Use it as an AI agent tool".

#### I need the opposite direction.

Excel to JSON is a separate Actor by the same author.

### Who made this

[Broke to Built](https://broke2builtai.com) — a company of machines, building things
it gives away. This is one of them; the rest are free too.

### For AI agents

This Actor is built to be called by software, not just by people.

- **Mount it directly as an MCP tool** — no Store search, no ranking, just this one tool:
  `https://mcp.apify.com/?actors=eliai/json-to-excel`
- **Or call it over HTTP** and get the results in the same request:
  `POST https://api.apify.com/v2/acts/eliai~json-to-excel/run-sync-get-dataset-items`
- **Pay with x402, without an Apify account.** This Actor is whitelisted for agentic payments, so an agent holding USDC on Base can buy a prepaid token and spend it here. The minimum purchase is $1, the token balance is an absolute spending cap, and it expires 14 days after purchase.
- **Costs are predictable before you call.** Pricing is pay-per-event (see Pricing above), so an agent can budget a run in advance instead of discovering the bill afterwards.
- **Send only the field you mean.** If you pass the bulk field, it is used on its own; the single-value field is a fallback, never merged into your request. You are charged for the items you sent and nothing else.

# Actor input Schema

## `url` (type: `string`):

Direct URL to a .json file. An array of records becomes one sheet; an object of { sheetName: \[records] } becomes one sheet per key.

## `urls` (type: `array`):

Optional list of additional JSON file URLs to convert in one run (max 25 total).

## `maxRows` (type: `integer`):

Cap the number of data rows written per sheet (header row excluded). Excel itself stops at 1,048,575 data rows.

## `maxFileSizeMb` (type: `integer`):

Files larger than this are recorded as failed (never charged) instead of being downloaded. Very large documents can exhaust run memory, so raise this only with a higher memory setting.

## Actor input object example

```json
{
  "url": "https://graveyard.broke2builtai.com/assets/sample.json",
  "urls": [],
  "maxRows": 5000,
  "maxFileSizeMb": 50
}
```

# Actor output Schema

## `results` (type: `string`):

Every item this run produced, including a downloadUrl per workbook, as JSON.

## `resultsCsv` (type: `string`):

The same items as a spreadsheet-ready CSV.

## `workbooks` (type: `string`):

The key-value store holding every .xlsx workbook this run produced.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "url": "https://graveyard.broke2builtai.com/assets/sample.json",
    "urls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("eliai/json-to-excel").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "url": "https://graveyard.broke2builtai.com/assets/sample.json",
    "urls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("eliai/json-to-excel").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "url": "https://graveyard.broke2builtai.com/assets/sample.json",
  "urls": []
}' |
apify call eliai/json-to-excel --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,eliai/json-to-excel"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/qNMD9lauBLcDQQg1m/builds/OYJ24DtHUiiHbM2L3/openapi.json
