jq Helper – transform JSON with jq
Pricing
from $0.01 / successful conversion
jq Helper – transform JSON with jq
Run jq programs over inline JSON or a linked Apify dataset. Built for chaining into data-processing and enrichment workflows.
Pricing
from $0.01 / successful conversion
Rating
0.0
(0)
Developer
R.L.
Maintained by CommunityActor stats
0
Bookmarked
7
Total users
3
Monthly active users
a month ago
Last modified
Categories
Share
jq Helper – Transform & Filter JSON with jq (no code)
Run any jq program over your JSON and get clean, structured results back. Reshape, filter, flatten, enrich, and aggregate JSON — from a pasted snippet or straight from another Apify Actor's dataset. The fast, no-code way to add a JSON transformation step to any scraping or data pipeline.
Map · filter · select · flatten · rename keys · merge fields · group & aggregate — all with battle-tested jq 1.8 syntax.
🧩 What is jq Helper?
jq Helper is a tiny, blazing-fast Apify Actor that puts the full power of jq — the most popular command-line JSON processor — into a hosted, chainable step. Instead of writing a throwaway script every time a scraper returns messy JSON, drop in a jq filter and let this Actor do the transformation in the cloud.
It's built to slot directly into the Apify ecosystem: point it at the output dataset of any scraper and use it as a JSON post-processing, cleanup, and enrichment stage in your automation.
✨ Key features
- Full jq 1.8 support — the complete language:
select,map,group_by,reduce,sort_by,unique, string ops, math, conditionals, and more. - Two input sources — paste inline JSON / JSONL, or read items from a linked Apify dataset by ID (perfect for chaining Actors).
- Two apply modes — transform each item independently (mapping/filtering/enrichment) or process the whole array at once (aggregations, grouping, dedupe).
- Pipeline-ready — writes results to its own dataset so the next Actor or integration (Zapier, Make, Google Sheets, webhooks…) can pick them up.
- Robust by default — errors on a single bad record are skipped and logged (or fail-fast if you prefer), and results are pushed in efficient batches.
- Zero setup — no servers, no
jqinstall, no dependencies to manage.
🚀 Use cases
- Clean up scraped data — drop nulls, rename fields, normalize values, flatten nested objects.
- Filter datasets — keep only the records that match your criteria (
select(.price < 100)). - Reshape for export — turn a verbose API response into a tidy, flat table for CSV/Excel/Sheets.
- Enrich records — derive new fields (domains from emails, full location strings, computed flags).
- Aggregate & summarize — group by a field, count, average, sum across an entire dataset.
- Glue Actors together — sit between a scraper and your destination as a no-code transformation step.
🔧 How to use
- Choose your data source: paste JSON into
jsonInput, or setdatasetIdto an existing dataset (e.g. an upstream scraper's run). - Write your transformation in the
filterfield using jq syntax. - Pick an
applyMode(perItemorwholeInput). - Run it — transformed records land in the Actor's default dataset, ready to export or pass downstream.
⚠️ Per-item vs. whole-input (read this first)
This is the one thing to get right:
| Mode | What the filter receives | Reach a field with |
|---|---|---|
perItem (default) | each array element, one at a time, as a single object | .websiteUrl ✅ |
wholeInput | the entire array as one value | .[].websiteUrl ✅ |
In per-item mode the array is iterated for you, so don't prefix with .[] — .[].websiteUrl will fail with "Cannot index string with string". Use a leading .[] only in whole-input mode.
📥 Input
| Field | Type | Description |
|---|---|---|
filter | string (required) | The jq program. jq 1.8 syntax. May emit 0, 1, or many values per input — each becomes one output item. |
applyMode | perItem | wholeInput | perItem (default): run on each element. wholeInput: feed the whole array as a single value. |
datasetId | string | Apify dataset to read items from (provide either this or jsonInput, not both). Map this field to chain Actors in an integration. Paid: $0.01 per successful run. |
jsonInput | string | Raw JSON (object/array/scalar) or JSONL (one value per line). Free — for prototyping. |
wrapKey | string | Non-object outputs are wrapped as { <wrapKey>: value } (dataset items must be objects). Default value. |
failOnError | boolean | true aborts on any jq runtime error; default false skips + logs the bad record. |
📤 Output
Each value emitted by your filter becomes one item in the Actor's default dataset. Object outputs are stored as-is (their keys become columns); scalars and arrays are wrapped under wrapKey. Export the dataset as JSON, CSV, Excel, HTML, or RSS, or hand it to the next step in your workflow.
💡 Examples
Reshape & build a location string (per-item):
{fullName, currentEmployer, location: ([.city, .state, .country] | map(select(.)) | join(", "))}
Keep only verified records (per-item):
select(.clearVerified == true)
Pull one field as a clean column (per-item):
{websiteUrl}
Group and summarize the whole dataset (whole-input):
group_by(.state) | map({state: .[0].state, count: length}) | .[]
Deduplicate by a key (whole-input):
unique_by(.profileUrl) | .[]
🔗 Chaining after another Actor (integrations)
Run jq Helper automatically whenever an upstream scraper finishes, and pass it that run's dataset.
In the Console (no code):
- Open the upstream Actor's run config → Integrations tab → Connect Actor or Task.
- Choose jq Helper to run on success (event
ACTOR.RUN.SUCCEEDED). - In jq Helper's input, set the
datasetIdfield to the upstream run's dataset using the variable:
Leave{{resource.defaultDatasetId}}jsonInputempty (the two sources are mutually exclusive), then set yourfilterandapplyMode.
The transformed items land in jq Helper's own dataset — ready for the next Actor, a webhook, or an export to Sheets/Make/Zapier.
Other variables from the same run you can drop into string fields:
{{resource.id}}(run ID),{{resource.actId}},{{resource.defaultKeyValueStoreId}},{{resource.status}}.
In code (parent orchestrator):
run = await Actor.call(actor_id='you/scraper', run_input={...})await Actor.call(actor_id='rl1987/jq-helper',run_input={'filter': '.websiteUrl','applyMode': 'perItem','datasetId': run.default_dataset_id,},)
Chaining always uses the
datasetIdpath, so each chained run is a paid $0.01 conversion. InlinejsonInputstays free for prototyping.
❓ FAQ
Do I need to install jq? No. The jq engine is bundled — just write filters.
Which jq version? jq 1.8, the full language.
My filter returns a string/number — why is it {"value": ...}? Dataset items must be JSON objects, so scalars and arrays are wrapped. Set wrapKey to rename the key, or emit an object (e.g. {websiteUrl}) for named columns.
How do I aggregate across all records? Use applyMode: wholeInput and reach elements with .[].
What if one record is malformed? By default it's skipped and logged; set failOnError: true to stop the run instead.
🛠️ Local development
pip install -r requirements.txtapify run # reads storage/key_value_stores/default/INPUT.json
Built with the Apify SDK for Python and the jq bindings (bundles libjq — no system jq required).
Disclaimer: This is an independent, unofficial project. It is not affiliated with, endorsed by, or otherwise associated with the jq project or any of its developers. "jq" is used here only to describe the JSON-processing language this Actor runs; all rights to jq belong to its respective authors.
