> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kadoa.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Export data

> Download, fetch, or page through your extracted data whenever you need it.

Get your extracted data on demand. Download a file in the dashboard, fetch rows with the SDK or REST API, or ask your AI tool. To deliver every run to Amazon S3, Snowflake, or another destination automatically, see [Destinations](https://docs.kadoa.com/docs/destinations/overview.md).

## Before you begin

For the SDK and REST API, you need a team [API key](https://docs.kadoa.com/docs/api-keys.md).

## View data in the dashboard

All extracted data is available in your [Kadoa Dashboard](https://kadoa.com/dashboard).

1. Open your workflow.
2. Browse records in the table view.
3. Filter and sort to find specific items.

To query the data with SQL or a plain-English question, use the [Data Explorer](https://docs.kadoa.com/docs/ui/data-explorer.md).

## Download the latest run

**Dashboard**

1. Open your workflow in the [Kadoa Dashboard](https://kadoa.com/dashboard).
2. Select the download icon at the top right. The menu reads "Get data from the latest published run".
3. Select a format:
   * **CSV**: table rows for spreadsheets.
   * **JSON**: your data plus metadata (`workflowId`, `runId`, `executedAt`). See the [JSON download format](#json-download).

If the download icon is disabled, the first run has not finished or the run has no data. Hover over the icon to see which.

You can also download from the **Download** row in the **Deliver** tab of the **Pipeline** panel.

**SDK & API**

Add `format=csv` to receive a CSV file instead of JSON. All pagination and filter parameters apply.

```bash theme={null}
GET https://api.kadoa.com/v4/workflows/{workflowId}/data?format=csv
```

If a large CSV would exceed the response timeout, add `download=link`:

```bash theme={null}
GET https://api.kadoa.com/v4/workflows/{workflowId}/data?format=csv&download=link
```

Kadoa then materializes the file in object storage and returns a `downloadPath` that you fetch separately.

For typed columns, use a [Parquet file](#export-a-parquet-file).

**MCP**

Ask your AI tool, for example:

```text theme={null}
> Export the full 'Product Monitor' dataset and analyze price trends by category.
```

Your AI tool uses `export_data`. It returns a signed URL for the full dataset as CSV (default) or JSON. See [Fetching and exporting data](https://docs.kadoa.com/docs/sdk/mcp-tools.md#reading-data).

## Fetch data from code

**SDK & API**

Fetch the data of an existing workflow by its ID:

```typescript Node SDK theme={null}
// Simplest way to fetch workflow data
const data = await client.extraction.fetchData({
  workflowId: workflowId,
});
console.log(data.data);
```

```python Python SDK theme={null}
from kadoa_sdk import FetchDataOptions, KadoaClient, KadoaClientConfig

client = KadoaClient(KadoaClientConfig(api_key="YOUR_API_KEY"))

# Simplest way to fetch workflow data
data = client.extraction.fetch_data(
    FetchDataOptions(workflow_id="YOUR_WORKFLOW_ID")
)
print(data.data)
```

To choose the page and page size, pass more options:

```typescript Node SDK theme={null}
const data = await client.extraction.fetchData({
  workflowId: workflowId,
  page: 1,
  limit: 10,
});

console.log(data.data); // Array of extracted items
console.log(data.pagination); // { page, limit, totalCount, totalPages }
```

```python Python SDK theme={null}
from kadoa_sdk import FetchDataOptions, KadoaClient, KadoaClientConfig

client = KadoaClient(KadoaClientConfig(api_key="YOUR_API_KEY"))

data = client.extraction.fetch_data(
    FetchDataOptions(
        workflow_id="YOUR_WORKFLOW_ID",
        page=1,
        limit=10,
    )
)

print(data.data)
print(data.pagination)
```

If you create and run a workflow with `extraction.run`, the result already includes the data:

```typescript Node SDK theme={null}
const result = await client.extraction.run({
  urls: ["https://sandbox.kadoa.com/ecommerce"],
  name: "Product Extraction",
});

// Data is included in the result
console.log(result.data); // Array of extracted items
console.log(result.pagination); // { page, limit, totalCount, totalPages }
```

```python Python SDK theme={null}
from kadoa_sdk import ExtractionOptions, KadoaClient, KadoaClientConfig

client = KadoaClient(KadoaClientConfig(api_key="YOUR_API_KEY"))

result = client.extraction.run(
    ExtractionOptions(
        urls=["https://sandbox.kadoa.com/ecommerce"],
        name="Product Extraction",
    )
)

# Data is included in the result
print(result.data)  # Array of extracted items
print(result.pagination)  # { page, limit, totalCount, totalPages }
```

With the REST API, the data endpoint returns the most recent data of a workflow. See the [Get workflow data by ID reference](https://docs.kadoa.com/api-reference/workflows/get-workflow-data-by-id.md).

```bash theme={null}
GET https://api.kadoa.com/v4/workflows/{workflowId}/data
```

The [response format](#response-format) section shows what comes back.

**MCP**

Ask your AI tool, for example:

```text theme={null}
> Show me the first 20 rows of my 'Product Monitor' data.
```

Your AI tool uses `fetch_data`. It reads 50 rows per page by default, up to 500, with filters and sorting.

## Page through large runs

**SDK & API**

The SDK can iterate page by page or fetch every row at once:

```typescript Node SDK theme={null}
// Option 1: Iterate page by page
for await (const page of client.extraction.fetchDataPages({
  workflowId: workflowId,
})) {
  console.log("Page data:", page.data);
  console.log("Page number:", page.pagination.page);
}

// Option 2: Get everything at once
const allData = await client.extraction.fetchAllData({
  workflowId: workflowId,
});
console.log("All data:", allData);
```

```python Python SDK theme={null}
import asyncio

from kadoa_sdk import FetchDataOptions, KadoaClient, KadoaClientConfig

client = KadoaClient(KadoaClientConfig(api_key="YOUR_API_KEY"))
workflow_id = "YOUR_WORKFLOW_ID"

# Option 1: Iterate page by page
async def iterate_pages() -> None:
    async for page in client.extraction.fetch_data_pages(
        FetchDataOptions(workflow_id=workflow_id)
    ):
        print("Page data:", page.data)
        if page.pagination:
            print("Page number:", page.pagination.page)

asyncio.run(iterate_pages())

# Option 2: Get everything at once
all_data = client.extraction.fetch_all_data(FetchDataOptions(workflow_id=workflow_id))
print("All data:", all_data)
```

With the REST API, set `page` and `limit`:

```bash theme={null}
GET https://api.kadoa.com/v4/workflows/{workflowId}/data?page=1&limit=100
```

`limit` defaults to 25 rows. Set `limit=0` to stream all rows without paging.

The total row count is `pagination.totalCount`. The response has no `hasMore` flag. To check whether more pages exist, compare `pagination.page < pagination.totalPages`.

**MCP**

Ask your AI tool, for example:

```text theme={null}
> Get every row from my 'Product Monitor' workflow.
```

`fetch_data` returns a `pagination` object. While `hasMore` is true, your AI tool calls `fetch_data` again with `pagination.next`. Results over about 80 KB are cut at a whole row and marked `truncated: true`. For the full dataset in one file, your AI tool uses `export_data`.

## Get a specific run

**Dashboard**

1. Open your workflow.
2. Select the **History** tab, then **Runs**.
3. Select the run you want.
4. Select the download icon at the top right. The menu reads "Get data from the selected run".
5. Select **CSV** or **JSON**.

**SDK & API**

Add `runId` to the data endpoint to retrieve data from a specific historical run instead of the latest. The [Parquet export](#export-a-parquet-file) takes `runId` too.

**MCP**

Ask your AI tool, for example:

```text theme={null}
> Export the run of 'Product Monitor' that finished yesterday as CSV.
```

Your AI tool uses `list_workflow_runs` to find the run, then `export_data` with its `runId`. Without a `runId`, `export_data` uses the latest completed run.

## Filter and sort rows

**SDK & API**

Pass a URL-encoded JSON array to `filters`. Each entry specifies a field, an operator, and a value:

```bash theme={null}
GET https://api.kadoa.com/v4/workflows/{workflowId}/data?limit=50&filters=[{"field":"jobTitle","operator":"CONTAINS","value":"Manager"},{"field":"postedDate","operator":"AFTER","value":"2024-01-01"}]
```

Sort with `sortBy` and `order`. The [filter operators](#filter-operators) and [query parameters](#query-parameters) sections list every option.

**MCP**

Ask your AI tool, for example:

```text theme={null}
> Show me 'Product Monitor' rows where the title contains Manager, sorted by price.
```

`fetch_data` and `export_data` both take `filters`, `sortBy`, and `order`. `export_data` can also export only selected rows with `rowIds`, up to 1,000.

## Export a Parquet file

This task uses the REST API. Create a signed URL for workflow data as a typed Parquet file. See the [Create workflow data export reference](https://docs.kadoa.com/api-reference/workflows/create-workflow-data-export.md).

```bash theme={null}
GET https://api.kadoa.com/v4/workflows/{workflowId}/data/export?format=parquet
```

Use Parquet to load Kadoa output directly into analytical tools such as DuckDB, Spark, Polars, Snowflake, BigQuery, or pandas. The export endpoint materializes the requested result set and returns a signed `url`. Pass `runId` to export a specific historical run:

```bash theme={null}
curl "https://api.kadoa.com/v4/workflows/{workflowId}/data/export?format=parquet&runId={runId}" \
  -H "x-api-key: YOUR_API_KEY"
```

Filtering, sorting, and row selection use the same query parameters as CSV and JSON exports. To stream the complete run artifact directly, use `GET /v4/workflows/{workflowId}/data/parquet`.

The file keeps typed columns where the workflow schema provides native types. These include booleans, numbers, dates, timestamps, JSON-compatible objects, and arrays. Older runs may still reflect the type information available when that run was produced.

## See where data is delivered

This task uses the dashboard. If your team has [data destinations](https://docs.kadoa.com/docs/destinations/data-destinations.md), the download menu also lists the destinations that receive this workflow's results after every run, with provider and target.

![The download menu with CSV and JSON buttons, a Copy endpoint URL button, and two destinations, an S3 bucket and a Snowflake table, synced after every run](https://mintcdn.com/kadoa/tTSIGshtzEsVczM_/images/workflows/download-destinations.png?fit=max\&auto=format\&n=tTSIGshtzEsVczM_\&q=85\&s=0900d722cd057e105616b4e4d7496ae0)

The **Deliver** tab of the [Pipeline](https://docs.kadoa.com/docs/ui/workflows/pipeline.md) panel shows the same destinations with their file formats. Select **Add** there to request a new destination, such as Snowflake, Databricks, Amazon S3, Google Cloud Storage, or SFTP.

## Query parameters

These parameters apply to `GET /v4/workflows/{workflowId}/data`.

| Parameter | Type | Default | Description |
| - | - | - | - |
| `page` | integer | `1` | Page number |
| `limit` | integer | `25` | Rows per page. Set to `0` to stream all rows without paging |
| `sortBy` | string | None | Field name to sort by |
| `order` | string | `asc` | Sort order: `asc` or `desc` |
| `filters` | string | None | JSON-encoded array of filter objects. See [filter operators](#filter-operators). |
| `runId` | string | None | Retrieve data from a specific historical run instead of the latest |
| `format` | string | `json` | Response format: `json` or `csv` |

## Filter operators

| Operator | Description |
| - | - |
| `EQUALS` / `NOT_EQUALS` | Exact match |
| `CONTAINS` / `NOT_CONTAINS` | Substring match (case-insensitive) |
| `STARTS_WITH` / `ENDS_WITH` | Prefix / suffix match |
| `GREATER_THAN` / `LESS_THAN` / `GREATER_THAN_OR_EQUAL` / `LESS_THAN_OR_EQUAL` | Numeric or date comparison |
| `IN` / `NOT_IN` | Value must (or must not) be in an array: `"value": ["Sales","Marketing"]` |
| `IS_NULL` / `IS_NOT_NULL` | Field presence check |
| `IS_EMPTY` / `IS_NOT_EMPTY` | Null or empty string check |
| `BEFORE` / `AFTER` | Date field comparison |
| `WITHIN_LAST_DAYS` | Date field within the last N days: `"value": 7` |

## Response format

### REST API

The data endpoint returns JSON by default:

```json Response theme={null}
{
  "workflowId": "workflow-123",
  "runId": "run-456",
  "executedAt": "2024-01-15T10:30:00Z",
  "data": [
    {
      "id": "123",
      "title": "Product Name",
      "price": 99.99,
      "extractedAt": "2024-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "totalCount": 150,
    "page": 1,
    "totalPages": 6,
    "limit": 25
  }
}
```

If your workflow schema marks one or more fields as [key fields](https://docs.kadoa.com/docs/workflows/key-fields.md) (`isKey: true`), Kadoa deduplicates the results. You get at most one record per unique key combination. Key fields should be scalar `STRING`, `NUMBER`, or `LINK` fields. Kadoa treats records with a missing or empty key field as distinct and does not merge them.

### JSON download

A JSON file downloaded from the dashboard has this structure:

```json theme={null}
{
  "workflowId": "68e7fc4befac26b8f917755f",
  "runId": "68e7fc4cefac26b8f9177560",
  "executedAt": "2025-10-09T18:17:49.209Z",
  "data": [
    {
      "title": "Product Name",
      "price": "$99.99",
      "inStock": true,
      "extractedAt": "2024-01-15T10:30:00Z"
    }
  ]
}
```

### SDK

Data returned by the SDK follows this structure:

```json Node SDK theme={null}
{
  data: [
    {
      // Your extracted fields
      title: "Product Name",
      price: "$99.99",
      inStock: true
    }
  ],
  pagination: {
    page: 1,
    limit: 50,
    totalCount: 150,
    totalPages: 3
  }
}
```

```python Python SDK theme={null}
response_format = {
    "data": [
        {
            "title": "Product Name",
            "price": "$99.99",
            "inStock": True,
        }
    ],
    "pagination": {"page": 1, "limit": 50, "totalCount": 150, "totalPages": 3},
}
print(response_format)
```

## Status codes

| Code | Meaning | Action |
| - | - | - |
| 200 | Success | Process data normally |
| 400 | Bad Request | Check query parameters |
| 401 | Unauthorized | Verify API key |
| 404 | Not Found | Check workflow ID |
| 429 | Rate Limited | Wait and retry |
| 500 | Server Error | Contact support |

## Related

* [Get workflow data by ID API reference](https://docs.kadoa.com/api-reference/workflows/get-workflow-data-by-id.md)
* [API authentication](https://docs.kadoa.com/api-reference/introduction.md)
* [Destinations](https://docs.kadoa.com/docs/destinations/overview.md)
* [MCP tools](https://docs.kadoa.com/docs/sdk/mcp-tools.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.