# DuckDB Helper – SQL over CSV, JSON, Parquet, Excel, SQLite (`rl1987/duckdb-wrapper`) Actor

Run a DuckDB SQL query over remote or local input files (CSV, JSON/NDJSON, Parquet, Excel, Avro, SQLite, and more) and push the results to a dataset.

- **URL**: https://apify.com/rl1987/duckdb-wrapper.md
- **Developed by:** [R.L.](https://apify.com/rl1987) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 33.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.01 / query over input file(s) or a chained dataset

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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

## DuckDB Helper – Run SQL over CSV, JSON, Parquet, Excel & SQLite

**Turn any messy export into clean, structured data — no code, no database to set up.** Give DuckDB Helper a link to your file(s) (or another Actor's scrape results) and a SQL query, and get back tidy rows, ready to filter, download, or pipe into your next automation.

---

### What does DuckDB Helper do?

DuckDB Helper runs your SQL query over data files hosted anywhere on the web — CSV, JSON, Parquet, Excel, and more — using the [DuckDB](https://duckdb.org) engine, without you needing to install DuckDB, write a script, or manage a database. Point it at one or more files, write a query in plain SQL, and it does the rest: downloads the files, loads them, runs the query, and hands you the result as dataset rows or a single downloadable file.

It's also built to slot straight into the **Apify ecosystem** as a post-processing step: connect it to any scraper Actor and it can clean up, filter, deduplicate, or reshape that Actor's output automatically every time a run finishes.

### Why use DuckDB Helper?

- **Clean up scraper output** — dedupe rows, drop unwanted columns, filter out junk records, straight after a scrape finishes.
- **Combine multiple sources** — join a CSV price list against an Excel product catalog against a scraped dataset, all in one query.
- **Convert formats** — pull data out of Excel or SQLite and get back CSV, JSON, or Parquet (or the reverse).
- **Aggregate & summarize** — group, count, sum, and average across thousands of rows without opening a spreadsheet.
- **Skip the database setup** — no server, no connection strings, no install; just a query and a link to your data.

### How to use DuckDB Helper

DuckDB Helper has two explicit modes, chosen with the **Mode** field — there's no guessing which run is billable:

- **Free** (the default): try out SQL syntax against literals, a URL read directly inside the query itself, or data you paste straight into **Paste data**. `Input files` and `Dataset ID` are disabled in this mode. Never charged.
- **Paid**: load `Input files` and/or a chained `Dataset ID`. **$0.01** per successful run, regardless of data size.

1. Pick **Mode**. Leave it on `free` to experiment; switch to `paid` once you're ready to process real files or a dataset.
2. In free mode, either write literals or paste some CSV/JSON/TSV/NDJSON text into **Paste data** to test against real content, no cost, no URL needed. In paid mode, point it at your data: add file links under **Input files** (each gets a name you reference in your query), and/or set **Dataset ID** to pull in another Actor's scrape results.
3. Write your **SQL query** referencing those names, e.g. `SELECT * FROM sales WHERE amount > 100`.
4. Optionally cap the row count and choose whether you also want a single downloadable file (CSV, JSON, Parquet, or Excel).
5. Run it. Your results appear as dataset rows, a downloadable file, or both.

#### A quick example

Say you have a CSV of Titanic passengers hosted online and want everyone over 60:

- **Mode**: `paid`
- **Input files**: `{ "name": "titanic", "url": "https://.../titanic.csv" }`
- **SQL query**: `SELECT Name, Age FROM titanic WHERE Age > 60 ORDER BY Age`

Run it, and the matching passengers land in your dataset — no download, no spreadsheet, no script.

#### Try it for free with pasted data

No URL, no charge — just paste some data straight into the input:

- **Mode**: `free`
- **Paste data**: `name,age\nAlice,30\nBob,16`
- **SQL query**: `SELECT * FROM data WHERE age > 18`

### More examples

Every example below is a real, working input — copy it in and run it as-is.

**Filter a CSV**
- Input files: `{ "name": "titanic", "url": "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv" }`
- SQL query: `SELECT Name, Age FROM titanic WHERE Age > 60 ORDER BY Age`

**Query a JSON API response**
- Input files: `{ "name": "users", "url": "https://jsonplaceholder.typicode.com/users", "format": "json" }`
- SQL query: `SELECT name, email, company.name AS company FROM users`

**Read an NDJSON/JSONL file**
- Input files: `{ "name": "movies", "url": "https://raw.githubusercontent.com/duckdb/duckdb/main/data/json/example_rn.ndjson", "format": "ndjson" }`
- SQL query: `SELECT * FROM movies LIMIT 10`

**Aggregate a Parquet file**
- Input files: `{ "name": "people", "url": "https://raw.githubusercontent.com/duckdb/duckdb/main/data/parquet-testing/userdata1.parquet", "format": "parquet" }`
- SQL query: `SELECT first_name, last_name, salary FROM people ORDER BY salary DESC LIMIT 10`

**Pull rows out of an Excel workbook**
- Input files: `{ "name": "sales", "url": "https://go.microsoft.com/fwlink/?LinkID=521962", "format": "excel" }`
- SQL query: `SELECT Segment, Country, SUM(Profit) AS total_profit FROM sales GROUP BY Segment, Country ORDER BY total_profit DESC`

**Query a SQLite database**
- Input files: `{ "name": "chinook", "url": "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite", "format": "sqlite" }`
- SQL query: `SELECT Name, Composer FROM chinook.Track LIMIT 10` — note the `chinook.` prefix: SQLite sources attach as a database, so tables are reached as `<name>.<table>`, not through a single view.

**Read an Avro file**
- Input files: `{ "name": "weather", "url": "https://raw.githubusercontent.com/apache/avro/main/share/test/data/weather.avro", "format": "avro" }`
- SQL query: `SELECT * FROM weather LIMIT 10`

**Chain after another Actor and export a clean file**
- Dataset ID: `{{resource.defaultDatasetId}}` (set via Integrations, or a real dataset ID for a one-off test)
- SQL query: `SELECT * FROM dataset WHERE Age > 70 ORDER BY Age`
- Export result as: `excel`, with `skipDatasetPush` enabled — produces only a ready-to-download spreadsheet, no dataset rows.

### Input

| Field | What it's for |
|-------|----------------|
| **Mode** | `free` (default) — literals, pasted data, or a URL read directly in SQL; never charged. `paid` — process `Input files`/`Dataset ID`; $0.01/run. |
| **SQL query** | The query to run. Reference your pasted data/input files/dataset by name, or point it straight at a URL in the query itself. |
| **Paste data** | Free-mode only. Paste CSV/TSV/JSON/NDJSON text directly — no URL needed — to test against real content at no cost. |
| **Input files** | Paid mode only. The file(s) to load — each just needs a name and a link; the format (CSV, JSON, Parquet, Excel, Avro, SQLite) is detected automatically. |
| **Dataset ID** | Paid mode only. ID of an Apify dataset to load and query — this is what you map when chaining DuckDB Helper after another Actor. |
| **Max output rows** | Optional safety cap on how many rows come back. |
| **Also export result file** | Get the full result as one downloadable CSV, JSON, Parquet, or Excel file, in addition to (or instead of) dataset rows. |

Full field-level details, including advanced options like extra DuckDB extensions for Postgres/MySQL/Iceberg/Delta sources, are in the Input tab.

### Output

By default, every matching row becomes one item in the dataset, with your query's columns as fields:

```json
[
    { "Name": "Barkworth, Mr. Algernon Henry Wilson", "Age": 80 },
    { "Name": "Svensson, Mr. Johan", "Age": 74 }
]
````

Download the dataset as JSON, CSV, Excel, HTML, or RSS — or hand it straight to the next Actor in your workflow.

If you turned on **Also export result file**, you'll additionally get a direct download link (in the run log and in the run's Output) pointing straight to a single CSV/JSON/Parquet/Excel file — handy when you just want a file to save or share rather than dataset rows to page through.

### Post-processing another Actor's results

The most common way to use DuckDB Helper: run it automatically right after a scraper finishes, to clean up or filter that Actor's output.

1. Open your scraper Actor's run → **Integrations** tab → **Connect Actor or Task**.
2. Choose **DuckDB Helper**, set it to run on success.
3. In DuckDB Helper's input, set **Dataset ID** to the upstream run's dataset using the variable `{{resource.defaultDatasetId}}`.
4. Write your SQL query against the `dataset` view, e.g. `SELECT * FROM dataset WHERE price > 100`.

The cleaned-up results land in DuckDB Helper's own dataset, ready for the next step — a webhook, a Google Sheet, or another Actor.

### Pricing

**Mode** decides the price, explicitly — not what fields happen to be filled in. `free` mode (literals, pasted data, or a URL read directly inside the SQL) never charges, and disables `Input files`/`Dataset ID`. Switch to `paid` mode to load `Input files` and/or a chained `Dataset ID`; each successful run is then a flat **$0.01**, regardless of how much data it processes.

### FAQ

**Do I need to know DuckDB specifically?** No — if you know standard SQL, you're covered. DuckDB's syntax is very close to PostgreSQL.

**What file formats are supported?** CSV/TSV, JSON, NDJSON/JSONL, Parquet, Excel (.xlsx/.xls), Avro, and SQLite out of the box. Postgres, MySQL, Iceberg, and Delta sources are supported for advanced users via the Input tab's extensions option.

**My file didn't load — why?** Most often the URL isn't reachable, or its format couldn't be guessed from the link. Set the format explicitly in the Input files list to skip auto-detection.

**Can I query more than one file at once?** Yes — add each as its own entry under Input files (and/or set a Dataset ID), then join or union them in a single SQL query.

**A column in my output looks like garbled binary text (e.g. `b'\x01\x00...'`)** — this happens with non-JSON DuckDB types such as `GEOMETRY` or `BLOB` (e.g. from the `spatial` extension). Cast them to text before selecting, e.g. `ST_AsText(geom_column)`.

***

Built with the [Apify SDK for Python](https://docs.apify.com/sdk/python/) and [DuckDB](https://duckdb.org).

> **Disclaimer:** This is an independent, unofficial project. It is **not affiliated with, endorsed by, or otherwise associated with the [DuckDB project](https://duckdb.org) or any of its developers.** "DuckDB" is used here only to describe the SQL engine this Actor runs; all rights to DuckDB belong to its respective authors.

# Actor input Schema

## `mode` (type: `string`):

Free: try out your SQL against literals or a URL read directly inside the query (e.g. `read_csv('https://...')`) — no charge, but `inputFiles`/`datasetId` below are disabled. Paid: load `inputFiles` and/or a chained `datasetId` — $0.01 per successful run, regardless of data size.

## `sqlQuery` (type: `string`):

SQL to run in DuckDB (DuckDB SQL syntax). In free mode, use literals, paste data into `inlineData` below and query its view, or read a URL directly with a DuckDB table function (read\_csv, read\_json, read\_parquet, ...) — httpfs is preloaded so http(s):// URLs work inline. In paid mode, also reference the views defined in `inputFiles`/`datasetId` below by name.

## `inlineData` (type: `string`):

Paste CSV/TSV/JSON/NDJSON text directly to test your query against real data — no URL, no download, works in free mode. Loaded as a view named by `inlineViewName` (default `data`) in the format set by `inlineFormat`.

## `inlineFormat` (type: `string`):

Format of the text pasted into `inlineData`.

## `inlineViewName` (type: `string`):

View name to reference the pasted data by in `sqlQuery` (only used if `inlineData` is set).

## `inputFiles` (type: `array`):

Requires Mode = paid. Source files to download and load into DuckDB as queryable views. Each entry is an object with `name` (view name to use in `sqlQuery`), `url` (http(s):// URL to download, or a local file path), and optional `format` (one of auto, csv, tsv, json, ndjson, parquet, excel, avro, sqlite — 'auto' guesses from the extension/content-type). Supports every file format DuckDB reads natively: CSV/TSV, JSON, NDJSON/JSONL, Parquet, Excel (.xlsx/.xls), Avro, and SQLite.

## `datasetId` (type: `string`):

Requires Mode = paid. ID of an Apify dataset to load as a queryable view (e.g. the default dataset of an upstream scraper's run) — for post-processing another Actor's output straight from an integration. Loaded as the view named in `datasetViewName` (default `dataset`). Combine with `inputFiles` to join scraped data against a lookup file.

## `datasetViewName` (type: `string`):

View name to reference the loaded dataset by in `sqlQuery` (only used if `datasetId` is set).

## `extensions` (type: `array`):

Additional DuckDB extensions to INSTALL and LOAD before running the query (beyond httpfs/json/parquet/excel/sqlite/avro, which are always loaded). E.g. `iceberg`, `delta`, `postgres`, `mysql`, `spatial` — use their SQL functions (iceberg\_scan, delta\_scan, postgres\_attach, ...) directly in `sqlQuery`.

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

Safety cap on the number of result rows pushed to the dataset. Leave empty for no cap.

## `exportFormat` (type: `string`):

Save the full query result as a single file in the key-value store, in this format. The run log and OUTPUT record then include a direct public download URL — useful when the caller wants a plain file rather than (or in addition to) dataset rows.

## `skipDatasetPush` (type: `boolean`):

If enabled, result rows are not pushed to the Actor's dataset — only the `exportFormat` file is produced. Requires `exportFormat` to not be `none`. Useful when you only want a downloadable file (e.g. a full Excel/CSV export) and don't need dataset-per-row output.

## Actor input object example

```json
{
  "mode": "free",
  "sqlQuery": "SELECT * FROM data WHERE age >= 18",
  "inlineData": "name,age\nAlice,30\nBob,16",
  "inlineFormat": "csv",
  "inlineViewName": "data",
  "inputFiles": [],
  "datasetViewName": "dataset",
  "extensions": [],
  "exportFormat": "none",
  "skipDatasetPush": false
}
```

# 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 = {
    "sqlQuery": "SELECT * FROM data WHERE age >= 18",
    "inlineData": `name,age
Alice,30
Bob,16`,
    "extensions": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("rl1987/duckdb-wrapper").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 = {
    "sqlQuery": "SELECT * FROM data WHERE age >= 18",
    "inlineData": """name,age
Alice,30
Bob,16""",
    "extensions": [],
}

# Run the Actor and wait for it to finish
run = client.actor("rl1987/duckdb-wrapper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "sqlQuery": "SELECT * FROM data WHERE age >= 18",
  "inlineData": "name,age\\nAlice,30\\nBob,16",
  "extensions": []
}' |
apify call rl1987/duckdb-wrapper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=rl1987/duckdb-wrapper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "DuckDB Helper – SQL over CSV, JSON, Parquet, Excel, SQLite",
        "description": "Run a DuckDB SQL query over remote or local input files (CSV, JSON/NDJSON, Parquet, Excel, Avro, SQLite, and more) and push the results to a dataset.",
        "version": "0.1",
        "x-build-id": "l4dp2RCQhTu8z733D"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/rl1987~duckdb-wrapper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-rl1987-duckdb-wrapper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/rl1987~duckdb-wrapper/runs": {
            "post": {
                "operationId": "runs-sync-rl1987-duckdb-wrapper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/rl1987~duckdb-wrapper/run-sync": {
            "post": {
                "operationId": "run-sync-rl1987-duckdb-wrapper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "sqlQuery",
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "free",
                            "paid"
                        ],
                        "type": "string",
                        "description": "Free: try out your SQL against literals or a URL read directly inside the query (e.g. `read_csv('https://...')`) — no charge, but `inputFiles`/`datasetId` below are disabled. Paid: load `inputFiles` and/or a chained `datasetId` — $0.01 per successful run, regardless of data size.",
                        "default": "free"
                    },
                    "sqlQuery": {
                        "title": "SQL query",
                        "type": "string",
                        "description": "SQL to run in DuckDB (DuckDB SQL syntax). In free mode, use literals, paste data into `inlineData` below and query its view, or read a URL directly with a DuckDB table function (read_csv, read_json, read_parquet, ...) — httpfs is preloaded so http(s):// URLs work inline. In paid mode, also reference the views defined in `inputFiles`/`datasetId` below by name.",
                        "default": "SELECT * FROM data WHERE age >= 18"
                    },
                    "inlineData": {
                        "title": "Paste data",
                        "type": "string",
                        "description": "Paste CSV/TSV/JSON/NDJSON text directly to test your query against real data — no URL, no download, works in free mode. Loaded as a view named by `inlineViewName` (default `data`) in the format set by `inlineFormat`."
                    },
                    "inlineFormat": {
                        "title": "Pasted data format",
                        "enum": [
                            "csv",
                            "tsv",
                            "json",
                            "ndjson"
                        ],
                        "type": "string",
                        "description": "Format of the text pasted into `inlineData`.",
                        "default": "csv"
                    },
                    "inlineViewName": {
                        "title": "Pasted data view name",
                        "type": "string",
                        "description": "View name to reference the pasted data by in `sqlQuery` (only used if `inlineData` is set).",
                        "default": "data"
                    },
                    "inputFiles": {
                        "title": "Input files",
                        "type": "array",
                        "description": "Requires Mode = paid. Source files to download and load into DuckDB as queryable views. Each entry is an object with `name` (view name to use in `sqlQuery`), `url` (http(s):// URL to download, or a local file path), and optional `format` (one of auto, csv, tsv, json, ndjson, parquet, excel, avro, sqlite — 'auto' guesses from the extension/content-type). Supports every file format DuckDB reads natively: CSV/TSV, JSON, NDJSON/JSONL, Parquet, Excel (.xlsx/.xls), Avro, and SQLite.",
                        "items": {
                            "type": "object"
                        },
                        "default": []
                    },
                    "datasetId": {
                        "title": "Dataset ID",
                        "type": "string",
                        "description": "Requires Mode = paid. ID of an Apify dataset to load as a queryable view (e.g. the default dataset of an upstream scraper's run) — for post-processing another Actor's output straight from an integration. Loaded as the view named in `datasetViewName` (default `dataset`). Combine with `inputFiles` to join scraped data against a lookup file."
                    },
                    "datasetViewName": {
                        "title": "Dataset view name",
                        "type": "string",
                        "description": "View name to reference the loaded dataset by in `sqlQuery` (only used if `datasetId` is set).",
                        "default": "dataset"
                    },
                    "extensions": {
                        "title": "Extra DuckDB extensions",
                        "type": "array",
                        "description": "Additional DuckDB extensions to INSTALL and LOAD before running the query (beyond httpfs/json/parquet/excel/sqlite/avro, which are always loaded). E.g. `iceberg`, `delta`, `postgres`, `mysql`, `spatial` — use their SQL functions (iceberg_scan, delta_scan, postgres_attach, ...) directly in `sqlQuery`.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxRows": {
                        "title": "Max output rows",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Safety cap on the number of result rows pushed to the dataset. Leave empty for no cap."
                    },
                    "exportFormat": {
                        "title": "Export result as downloadable file",
                        "enum": [
                            "none",
                            "csv",
                            "json",
                            "parquet",
                            "excel"
                        ],
                        "type": "string",
                        "description": "Save the full query result as a single file in the key-value store, in this format. The run log and OUTPUT record then include a direct public download URL — useful when the caller wants a plain file rather than (or in addition to) dataset rows.",
                        "default": "none"
                    },
                    "skipDatasetPush": {
                        "title": "Skip pushing rows to the dataset",
                        "type": "boolean",
                        "description": "If enabled, result rows are not pushed to the Actor's dataset — only the `exportFormat` file is produced. Requires `exportFormat` to not be `none`. Useful when you only want a downloadable file (e.g. a full Excel/CSV export) and don't need dataset-per-row output.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
