---
title: "Results & exports · Scrape.ly Docs"
description: "View, export, download, and share run results, and how long they are kept."
url: https://scrape.ly/docs/results
markdown: https://scrape.ly/docs/results.md
---

# Results & exports

> View, export, download, and share run results, and how long they are kept.

Every run stores its results in Scrape.ly storage. Most Actors write result items to the run's default **dataset**, and some also write files or a summary to its default **key-value store**. This page shows how to view those results in the dashboard, export them in different formats, download them over the API, and how long they are kept.

## Where a run's results live

Each run gets its own default storages, created when the run starts:

| Storage | Holds | Run field |
| --- | --- | --- |
| Dataset | The result items, one JSON object per item | `defaultDatasetId` |
| Key-value store | The run's `INPUT`, plus any records the Actor writes, such as `OUTPUT`, screenshots, or HTML | `defaultKeyValueStoreId` |
| Request queue | The URLs a crawler has visited or still plans to visit | `defaultRequestQueueId` |

The Actor's README usually says which of these holds its results. See [Storage](https://scrape.ly/docs/storage.md) for how the storages work.

## View results in the dashboard

Open the run, then the **Storage** tab, and choose **Dataset**, **Key-value store**, or **Request queue**. The dataset has four views:

- **Overview**: the item count and the number of fields.
- **All fields**: every field name found in the items.
- **Table**: the items as a sortable table.
- **JSON**: the raw items.

If the Actor defines an output schema, the run also has an **Output** tab with links to its main results.

All your storages, including those of older runs, are under **Storage** in the side menu, in the **Datasets**, **Key-value stores**, and **Request queues** tabs. From a storage's page you can **Export** (datasets), **Download** records (key-value stores), **Rename**, or **Delete** it.

## Export a dataset

Click **Export** on the run page or the dataset page to open **Export dataset**:

| Option | What it does | API parameter |
| --- | --- | --- |
| **Format** | JSON, CSV, XML, Excel, HTML Table, RSS, JSONL, or PDF | `format` |
| **Select fields** | Keep only the fields you pick | `fields` |
| **Omit fields** | Drop the fields you pick | `omit` |
| **Unwind fields** (advanced) | Expand array or object fields into separate items | `unwind` |
| **Offset**, **Limit** (advanced) | Skip items, cap the item count | `offset`, `limit` |
| **Clean items** (advanced) | Skip empty items and hidden `#` fields | `clean` |
| **Reverse order** (advanced) | Newest items first | `desc` |

**Select fields**, **Omit fields**, and **Unwind fields** are multi-select lists of the dataset's top-level fields, found by sampling its first and last 100 items. Type to filter the list. To use a field the sample missed, type its name and press **Enter** or **,**. **Unwind fields** lists the fields that hold arrays or objects.

**Download** saves the file. **View in new tab** opens the result in the browser, limited to the first 1,000 items unless you set a limit.

### PDF exports

A PDF is a printable report of the items, with the same field options as the other formats.

| Part | Behavior |
| --- | --- |
| Heading | Dataset name (or the Actor, for unnamed datasets), dataset ID, run ID, row count, and when it was generated |
| Up to 6 columns | Portrait table, one column per field |
| 7 to 16 columns | Landscape table |
| More than 16 columns | Landscape, one key/value block per item |
| Every page | Column header and `Page X of Y` |
| Nested values | Written inline: `a, b` for arrays, `key: value` for objects |
| Long text | Wrapped, then cut with `…` |
| Items | The first 2,000 selected items. The PDF says when items were left out; use `offset` for the next part. |
| Rows | Up to 5,000, counted after `unwind` |
| Text | About 3 million characters; past that the PDF stops with a note |

Pick fields with **Select fields** to keep wide datasets in table form. For complete exports of large datasets, use CSV, Excel, or JSON.

## Download with the API

```
GET /v2/datasets/{datasetId}/items
GET /v2/actor-runs/{runId}/dataset/items
GET /v2/actors/{actorId}/runs/last/dataset/items
GET /v2/actor-tasks/{taskId}/runs/last/dataset/items
```

The first form takes a dataset ID or `username~dataset-name`. The other three are shortcuts to a run's default dataset: a specific run, your latest run of an Actor, or your latest run of a task. The `runs/last` forms accept `status=SUCCEEDED` to skip runs that are still going or failed.

```bash
curl "https://api.scrape.ly/v2/datasets/<datasetId>/items?format=csv&fields=title,url,price&clean=true" \
  -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  -o results.csv
```

```api-test
{ "method": "GET", "path": "/v2/datasets/{datasetId}/items?format=json&limit=10&clean=true" }
```

### Item parameters

| Parameter | Effect |
| --- | --- |
| `format` | `json` (default), `jsonl`, `csv`, `xlsx`, `xml`, `html`, `rss`, or `pdf` |
| `offset`, `limit` | Paging. Without a `limit`, all items are returned. |
| `desc` | `true` or `1` returns newest items first |
| `fields` | Comma-separated list of fields to include |
| `omit` | Comma-separated list of fields to drop |
| `unwind` | Comma-separated fields to expand: an array becomes one item per element, an object is merged into the item |
| `flatten` | Comma-separated fields to flatten into `field.subfield` keys |
| `clean` | `true` is the same as `skipEmpty=true&skipHidden=true` |
| `skipEmpty` | Skip empty items |
| `skipHidden` | Drop fields whose names start with `#` |
| `skipFailedPages` | Skip items that contain an `errorInfo` field |
| `attachment` | `true` makes the response a file download. PDFs are named after the dataset and open in the browser without it. |
| `delimiter` | CSV delimiter; default `,` |
| `skipHeaderRow` | Omit the CSV header row |
| `bom` | CSV byte-order mark; on by default, `bom=false` turns it off |
| `escapeFormulas` | CSV values that start with `=`, `+`, `-`, or `@` get a leading `'` so spreadsheets don't run them as formulas; on by default, `escapeFormulas=false` turns it off |
| `xmlRoot`, `xmlRow` | XML element names; defaults `items` and `item` |

Responses include the headers `X-Apify-Pagination-Offset`, `-Limit`, `-Count`, `-Total`, and `-Desc`, so you can page through large datasets. Very large downloads are streamed. If you start too many large downloads at once, you get `429` with a `Retry-After` header.

With the clients, use `client.dataset(id).listItems()` in JavaScript or `client.dataset(id).list_items()` in Python. See the [Datasets API reference](https://scrape.ly/docs/api-datasets.md#get-dataset-items) for the full response format.

> [!NOTE]
> Downloading results is billed: dataset reads count as storage operations, and the bytes you download count as data transfer. See [What a run costs](https://scrape.ly/docs/use-actors.md#what-a-run-costs).

## OUTPUT and other key-value records

Many Actors write a summary or a single result to the `OUTPUT` record of their default key-value store. Others save files there, such as screenshots, PDFs, or HTML.

```
GET /v2/key-value-stores/{storeId}/keys
GET /v2/key-value-stores/{storeId}/records/{key}
GET /v2/actor-runs/{runId}/key-value-store/records/{key}
GET /v2/key-value-stores/{storeId}/records
```

- `keys` lists the record keys. It accepts `prefix`, `exclusiveStartKey`, and `limit` (up to 1000).
- `records/{key}` returns the record with its original content type. Add `attachment=true` to download it as a file.
- `records` (without a key) downloads all records as a ZIP file. Filter it with `prefix`.
- The `actor-runs/{runId}/key-value-store/...` form reads the run's default store without looking up its ID.

```api-test
{ "method": "GET", "path": "/v2/key-value-stores/{storeId}/records/OUTPUT" }
```

`POST /v2/actors/{actorId}/run-sync` starts a run and returns its `OUTPUT` record in one call. See [Run synchronously](https://scrape.ly/docs/run-actors.md#run-synchronously).

The run's own input is the `INPUT` record, also available at `GET /v2/actor-runs/{runId}/input`.

## Retention

| What | Kept for |
| --- | --- |
| Unnamed storages (every run's defaults) | 2 days (48 hours) on the free plan, 31, 60 or 90 days on the Starter, Scale or Business plan, then deleted |
| Named storages | Until you delete them |
| Runs and their logs | As long as their results: 2 days on the free plan, 31, 60 or 90 days on the Starter, Scale or Business plan |
| Your latest 10 runs on the free plan | Kept with their results and logs until you delete them. When a newer run pushes one out, it is deleted with its results about 2 days later |

To keep a run's results past the retention window, export them, or copy the items into a named dataset that you create under **Storage** or with `POST /v2/datasets?name=<name>`. Renaming a run's default storage does not change its expiry date. Named storages are permanent, but they still count toward storage costs.

Storage is billed by the hour while it exists. If your balance drops to zero, unnamed storages are deleted 3 days later and named storages after a longer grace period. See [Storage retention](https://scrape.ly/docs/storage.md#retention).

## Share results

Storages are private to your account: without your token, `GET /v2/datasets/{id}/items` returns `404`. To share results without sharing your token, create a signed URL. Signed URLs always expire.

```js
import { ScrapelyClient } from 'scrapely-client';

const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN, baseUrl: 'https://api.scrape.ly' });

// Valid for 24 hours; defaults to 1 hour
const url = await client.dataset('<datasetId>').createItemsPublicUrl({
    clean: true,
    expiresInSecs: 24 * 60 * 60,
});
```

Anyone with the URL can download the items until it expires, without a token. They can add item parameters such as `&format=csv` to it. Signed URLs can only be created for storages you own.

For pipelines, the usual alternative is a webhook that fires when the run succeeds and fetches the items with your token. See [Integrations](https://scrape.ly/docs/integrations.md#webhooks).

## What's next

- [Integrations](https://scrape.ly/docs/integrations.md): get notified and chain runs
- [Storage](https://scrape.ly/docs/storage.md): datasets, key-value stores, and request queues in depth
- [Datasets API](https://scrape.ly/docs/api-datasets.md) and [Key-value stores API](https://scrape.ly/docs/api-key-value-stores.md)

---

- Previous: [AI chat](https://scrape.ly/docs/ai-chat.md)
- Next: [Automations](https://scrape.ly/docs/automations.md)
- All docs: [Docs index](https://scrape.ly/docs.md), [llms.txt](https://scrape.ly/llms.txt)
