# Storage Editor (`josef.prochazka/storage-editor`) Actor

Browse, search, edit, duplicate, rename, and delete your Apify datasets, key-value stores, and request queues in a web UI. Clean up a dataset by dropping fields and rows and saving the result as a new dataset. Standby Actor: always ready, no run to start.

- **URL**: https://apify.com/josef.prochazka/storage-editor.md
- **Developed by:** [Josef Procházka](https://apify.com/josef.prochazka) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Storage Editor for Apify datasets, key-value stores and request queues

Storage Editor is a web-based editor for the three Apify storage types: **datasets, key-value
stores and request queues**. It lets you browse, search, create, rename, duplicate and delete
storages, edit their contents, and, most importantly, **edit a dataset** by dropping fields and
rows and saving the result as a new dataset. Datasets have no edit API on the Apify platform, so
this is the practical way to clean one up without writing a script.

The Actor runs only as a [Standby Actor](https://docs.apify.com/platform/actors/running/standby):
it behaves like an always-on web app at a stable URL, starts in about a second when first opened,
and costs nothing while idle. You never start it as a run; a run started by hand only prints these
instructions and finishes. It is written in Go, ships as a 7.5 MB Docker image and runs in the
smallest 128 MB memory slot.

### What you can do with it

- **Clean up a scraped dataset** before handing it over: remove test rows, drop internal fields
  such as debug URLs or raw HTML, and save a tidy copy under a new name.
- **Split or trim data**: keep only rows matching a search term (a domain, a status, a category)
  and save them as a separate dataset.
- **Fix a request queue**: change the URL, method, `userData` or `handledAt` of individual
  requests, add missing ones, or delete stale ones.
- **Manage key-value records**: read, write and delete records of any content type, including
  images and other binary files, with a preview for images.
- **Organise storages**: find a storage by name or ID among thousands, rename it, duplicate it,
  or delete it. Duplicating copies everything, including binary records and request metadata.

### Features

- Three tabs, one per storage type, each with paging, an "include unnamed" switch and a search
  box that scans your whole account (up to 20 000 storages) by name or ID, optionally case sensitive.
- **Custom view** for any storage: shows every top-level field as a checkbox to drop or keep,
  offers a row search with "remove matching", "keep only matching" and per-row remove, and saves
  the result as a new storage or replaces the original in place.
- **Datasets of any size**: the dataset view previews only the first 100 rows (or 1 000, or
  10 000). You pick fields and search rules on the preview, and saving applies them to every row
  on the server, streamed in the background. A dataset with 50 000 or 5 million rows is edited the
  same way within the 128 MB memory slot. A dataset that fits in the preview is edited row by row
  exactly as you see it.
- **Dataset editor**: paged item viewer with a text filter and a push-items box.
- **Key-value store editor**: key list with prefix filter, record editor with content type, base64
  handling and file upload for binary records, image preview.
- **Request queue editor**: request list with filter, a field-by-field form for URL, method,
  unique key, `userData`, `headers`, `payload`, `retryCount`, `noRetry` and `handledAt`, and a
  raw-JSON escape hatch for anything else. Only changed fields are written.
- **Duplicate** any storage under a new name; refuses to write into a storage that already exists.
- **Closes itself when unused**: the run shuts down ten seconds after the last tab is closed, or
  after three minutes without any activity in an open tab, with a 30-second countdown first. Any
  click or key press keeps it alive, and reopening the page starts a fresh run in a few seconds.
- Built-in diagnostics: the header shows the build, run and whether your token can see account
  storages, and 403 responses explain what to fix.

### How to use the web UI

1. Open the Actor in Apify Console and go to the **Endpoints** tab. Copy the Standby URL.
2. Open it in your browser with your API token appended once:

   ```text
   https://<your-username>--storage-editor.apify.actor/?token=<YOUR_APIFY_TOKEN>
   ```

   The page removes the token from the address bar, keeps it in the browser tab and sends it
   with every request. The platform authenticates each request and routes it to a Standby run
   owned by your account, and the Actor uses the same token to call the Apify API for you.
3. Pick a tab, find a storage, and use **Open** to edit contents, **View** to build a filtered
   copy, or the row actions to rename, duplicate or delete.

Editing a dataset, step by step:

1. Open the dataset and click **Custom view**. The first 100 rows load; a bigger preview can be
   picked in the **Preview** panel.
2. In **Fields**, tick the fields to drop (or switch to "keep only the checked fields"). Fields
   that do not appear in the preview rows can be added by name.
3. In **Rows**, type a search term and click **Remove matching** or **Keep only matching**. Each
   click adds a rule, listed below the search box, that applies to every row of the dataset. The
   search looks at the whole original row as JSON, so you can filter on a field and hide it
   afterwards, or match an exact value such as `"status":"error"`. The cross next to a row removes
   just that row.
4. Enter a name and click **Save as new dataset**, or **Save and replace original** to keep the
   old name. The server copies the dataset through your rules in the background and the page shows
   the progress; the run stays alive until the copy finishes even if you close the tab. Replacing
   writes to a temporary name and deletes the original only after every row is written, then
   renames the copy.

### Permissions

The Actor runs with **Limited permissions**. A Limited run token only reaches the run's own
default storages, so the editor does not use it for your data: every storage call is made with
the API token you opened the page with, for that request only. The token is kept in memory for
the life of the run and is never logged or stored.

This means the editor can reach exactly what your token can reach. Use a scoped token limited to
some storages and the editor sees only those. Because the Actor does not need Full permissions,
accounts that may not run Full-permission Actors owned by other users, such as Apify admin
accounts, can use it.

The header of the web UI shows "full access" when your token can list the account's storages,
and "(run token)" if your token did not reach the Actor and the run's own token was used.

The editor needs an API token in the URL. If the Standby endpoint is set to Console login
instead, the browser has no token to send, and the editor can reach only the run's own storages.

### Limits

| Limit | Value | Reason |
| --- | --- | --- |
| Dataset size for a custom view | no limit | the preview holds up to 10 000 rows; saving streams every row on the server |
| Rows loaded into a key-value store or request queue view | 10 000 | browser memory; the page warns when a storage is larger |
| Items per dataset push | as many as fit in 5 MB | Apify API payload limit; bigger pastes are split automatically |
| Storages scanned per search | 20 000 | the API has no name filter, so pages are scanned |
| Record or item body per request | 10 MB | server-side cap |
| Time per request | 5 minutes | Standby platform limit; affects duplicating very large storages |
| Field filtering | top-level fields | nested keys are shown inside their parent value |
| Idle shutdown | 3 minutes unused, or 10 s after the last tab closes | the run closes when nobody uses the editor; a countdown warns 30 s ahead |

### Troubleshooting and FAQ

**The page shows "403" and "LIMITED access" in the header.** The token you opened the page with
cannot list the account's storages, usually because it is a scoped token. Open the Standby URL
again with a token that has access to the storages you want to edit. If the header also says
"(run token)", the token did not reach the Actor; report it as a bug.

**I rebuilt the Actor but see the old UI.** Standby runs outlive builds. Abort them or wait for
the idle timeout. The header shows the build number of the run you are talking to.

**Duplicate says the name already exists.** The Actor refuses to merge into an existing storage.
Choose a new name, or delete the old storage first.

**The preview says "about N rows" but the saved dataset has a different count.** The number is
estimated from the preview. The rules run on every row when saving, and the final toast shows the
exact count.

**Why did the cross remove only one row?** A cross removes that exact preview row. To remove all
rows like it across the whole dataset, search for something they share and use
**Remove matching**.

**Pressing Start does nothing useful.** That is by design: a normal run only prints instructions,
sets its status message accordingly and finishes. Use the Endpoints tab instead.

**The page says the editor closed.** Nobody used it for a while, so the run stopped to save
compute. Open the Standby URL again with your token; a new run starts in a few seconds and
everything is where you left it, because all data lives in your storages, not in the run.

**Can I use a scoped token?** Yes for authentication, but a scoped token that restricts the Actor
scope narrows the run's access and the editor will get 403s. Use a token without that restriction.

Found a bug or missing a feature? Open a report in the **Issues** tab of this Actor with the
storage type, the action you took and the message from the toast or the header.

### How it works, in short

The editor is a small web application served by the Actor itself. Everything it does is an
ordinary Apify API call made with the run's own token, so it can only ever touch the storages of
the account that opened it, and nothing is stored anywhere except in your storages. No data passes
through third-party services.

# Actor input Schema

## Actor input object example

```json
{}
```

# Actor output Schema

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("josef.prochazka/storage-editor").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("josef.prochazka/storage-editor").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 '{}' |
apify call josef.prochazka/storage-editor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,josef.prochazka/storage-editor"
        }
    }
}
```

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/nv3cyr3h5DMcJdAEP/builds/D3eu9m1yNjf64xAaW/openapi.json
