Skip to content

Code Dataset Runner

Try for free

Run a short JavaScript or Python snippet on every row of a dataset, JSON or CSV file, or once as a plain script. Map, filter, split, enrich and total rows in a secure sandbox with no network access. Results go to a new dataset; console output to a LOGS record.

🧑‍💻 Code Dataset Runner

Run a short JavaScript or Python snippet on every row of your data: datasets from earlier runs, JSON or CSV links, or rows you paste. Map, filter, split, enrich and total rows in a few lines of code, or run a snippet once as a plain script. The code runs in a locked-down sandbox with no network, and the result is a new dataset you can export to JSON, CSV or Excel. $0.0042 per 1,000 saved rows plus $0.000185 per second of code time and $0.0015 per run on the Free plan (less on higher plans), with platform usage included.

✨ Why use Code Dataset Runner?

  • ✍️ Your own logic in a few lines — anything a formula or a field mapping cannot do: rename and reshape fields, compute prices, clean text, parse dates, split one row into several, merge fields from nested objects.
  • 🐍 JavaScript or Python — modern JavaScript (with await) or Python 3.11 with its standard library (re, json, datetime, statistics, collections ...).
  • 🔁 Every row or once — run the code per row with an optional finish() for totals, or once over all rows to sort, group or build a report.
  • 🔒 Secure sandbox — the code runs in a separate process with no network, no file writes, no other programs and none of the run's credentials; a self-check proves this before your code starts.
  • 🧯 Errors don't sink the run — a failing row is skipped, kept with an _error field, or stops the run (you choose), and every error is listed with its row number and line.
  • ⚡ Fast — thousands of rows per second for simple code; rows are read page by page and saved as they are ready.

🎯 Use cases

  • 🧹 Clean scraped data — trim and normalise text, fix number formats, drop empty or test rows before they reach your sheet or database.
  • 💶 Compute fields — add prices with VAT, currency conversions, discounts, score columns or slugs to product, listing or lead datasets.
  • 🔀 Reshape for an import — rename fields, flatten nested objects or split a list field into one row per entry for a CRM, shop or BI tool.
  • 📊 Quick totals — count rows per category, average a price, or find the top 10 with a finish() function or Run once.
  • 🔄 Automations — start it after a scraper run with that run's dataset, so each result is cleaned the same way before it moves on.
  • 🧪 Try a snippet — run a few lines of JavaScript or Python once and read the result and console output, without setting anything up.

🚀 How to use

  1. Write your code in JavaScript code or Python code (fill in one of them). The code is the body of a function that gets item (one row), index (its position in your data) and params.
  2. Pick the Datasets to process, add JSON or CSV links, or paste rows in Items (JSON).
  3. Optional: set Variables (params) your code reads, the Time limit per row, what happens When the code fails on a row, or a Range of rows.
  4. Click Start. The rows your code returned are in the dataset; counts and errors are in the OUTPUT record and console output in the LOGS record.
  5. Download the dataset as JSON, CSV, Excel or XML, or read it through the API.

📥 Input

FieldWhat it does
jsCodeJavaScript: the body of function (item, index, params), or your own function transform(item, index, params) plus an optional function finish()
pythonCodePython: the body of def transform(item, index, params), or your own def transform(item) plus an optional def finish()
modeperRow (every row) or once; empty = every row when you give data, otherwise once
datasetIdsDatasets to process, in this order
dataUrlsPublic JSON, JSON Lines or CSV links, read after the datasets
itemsRows pasted as a JSON array, read last
paramsA JSON object your code reads as params
codeTimeoutSecsTime limit for one call of your code (per row, or the whole Run once call); default 10, 0 = no limit
onErrorskip (default), keep (save the row with _error) or stop
offset, limitSkip the first rows and stop after a number of rows, counted across all sources

What your code returns decides what is saved:

Return valueSaved
the item (changed or not), or nothingthe item as it is now
an object (dict)that object as the row
a listone row per entry (an empty list drops the row)
false or null (JavaScript), False (Python)nothing: the row is dropped
any other valuea row {"value": ...}

code (with language: javascript or python) is accepted too, in place of jsCode / pythonCode.

{
  "datasetIds": ["<dataset ID of a scraper run>"],
  "jsCode": "if (!item.price) return false;\nitem.priceWithVat = Math.round(item.price * (1 + params.vatRate) * 100) / 100;\nreturn item;",
  "params": {"vatRate": 0.2},
  "onError": "keep"
}

The same in Python, with a total per category saved after the last row:

from collections import Counter
counts = Counter()

def transform(item):
    if not item.get("price"):
        return False
    counts[item["category"]] += 1
    item["priceWithVat"] = round(item["price"] * 1.2, 2)
    return item

def finish():
    return [{"category": c, "rows": n} for c, n in counts.items()]

📤 Output

The dataset gets the rows your code returned, with your own fields. The example input (five product rows, one without a price) saves four rows:

[
  {"title": "Desk lamp", "price": 29.9, "category": "Lighting", "url": "https://shop.example.com/p/desk-lamp", "priceWithVat": 35.88, "slug": "desk-lamp"},
  {"title": "Office chair", "price": 149, "category": "Furniture", "url": "https://shop.example.com/p/office-chair", "priceWithVat": 178.8, "slug": "office-chair"}
]

A Run once call that returns a plain value (or nothing) saves one row with the value and the console output:

[{"result": 42, "logs": ["Hello world!"]}]

Every run also stores:

RecordContent
OUTPUTrowsRead, rowsSaved, rowsDropped, rowsWithError, errors (row number and message, the first 100), codeSeconds, sources and the sandbox self-check
LOGSconsole.log / print output, each line prefixed with its row number (the first 10,000 lines)

💰 Pricing

Pay per event, platform usage included:

EventFree / StarterScaleBusiness
Row saved$0.0042 per 1,000$0.0038 per 1,000$0.0034 per 1,000
Code time, per started second$0.000185$0.00015$0.00012
Run start$0.0015$0.0015$0.0015

Code time is the time the sandbox spends running your code (counted together for the whole run and rounded up to whole seconds). Example on the Free plan: cleaning 1,000 rows with a short snippet takes about one second of code time, so it costs about $0.0015 + $0.000185 + $0.0042 ≈ $0.0059. Dropped rows and rows that fail are not charged as saved rows (unless you keep failed rows with Keep the row with an _error field).

❓ FAQ

Is my code safe to run here, and is my data private? The code runs in its own process inside your run, with no network access, a read-only file system, no other programs and an empty environment (no tokens or passwords). Only you see the run, its dataset and its records.

Can my code call an API or download a page? No. The sandbox has no network on purpose. Use a scraper actor to fetch the data first, then run your code on its dataset.

Can I use npm or pip packages? No package installs. JavaScript has the full language (JSON, Math, Date, RegExp, Intl, Map/Set, async/await); Python has the full standard library.

How many rows can it process? As many as your sources hold: rows are read page by page and saved as they are ready, so memory stays flat. Run once loads all rows into memory, so use Every row (with finish() for totals) for very large data.

What if my code throws on some rows? With the default Skip the row the run goes on and lists each error (row number, message and the line in your code) in the OUTPUT record. If the code fails on each of the first 20 rows, the run stops early so a broken snippet does not run over all your data.

Can I schedule it or use the API? Yes. Start it from an automation after a scraper finishes with {"datasetIds": ["{{resource.defaultDatasetId}}"]}, schedule it, or call it through the API with the same input.

⚠️ Limits

  • No network, no file writes and no other programs inside the code: it can only compute on the rows it gets.
  • No npm or pip installs; only the language itself (JavaScript) or the Python standard library.
  • One call of your code may run for the Time limit per row (default 10 s); a row that runs longer is stopped and counted as an error. If a row is stopped or uses too much memory, the sandbox is restarted and global variables your code kept are reset.
  • Runs use 512 MB by default and at most 1,024 MB. Memory for the code is part of it: about 45% for JavaScript and 65% for Python (230 MB and 330 MB at 512 MB).
  • Run once passes all rows to your code at once, so they must fit in that memory.
  • Each call keeps up to 200 log lines of up to 2,000 characters; the LOGS record keeps the first 10,000 lines of the run (a record has a size limit).
//From the blog\\

Latest articles

All articles

The internet is full of data.
Start owning yours.

Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes.

No credit card. No setup calls.