jq Helper – transform JSON with jq avatar

jq Helper – transform JSON with jq

Pricing

from $0.01 / successful conversion

Go to Apify Store
jq Helper – transform JSON with jq

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.

R.L.

Maintained by Community

Actor 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 jq install, 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

  1. Choose your data source: paste JSON into jsonInput, or set datasetId to an existing dataset (e.g. an upstream scraper's run).
  2. Write your transformation in the filter field using jq syntax.
  3. Pick an applyMode (perItem or wholeInput).
  4. 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:

ModeWhat the filter receivesReach a field with
perItem (default)each array element, one at a time, as a single object.websiteUrl
wholeInputthe 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

FieldTypeDescription
filterstring (required)The jq program. jq 1.8 syntax. May emit 0, 1, or many values per input — each becomes one output item.
applyModeperItem | wholeInputperItem (default): run on each element. wholeInput: feed the whole array as a single value.
datasetIdstringApify 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.
jsonInputstringRaw JSON (object/array/scalar) or JSONL (one value per line). Free — for prototyping.
wrapKeystringNon-object outputs are wrapped as { <wrapKey>: value } (dataset items must be objects). Default value.
failOnErrorbooleantrue 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):

  1. Open the upstream Actor's run config → Integrations tab → Connect Actor or Task.
  2. Choose jq Helper to run on success (event ACTOR.RUN.SUCCEEDED).
  3. In jq Helper's input, set the datasetId field to the upstream run's dataset using the variable:
    {{resource.defaultDatasetId}}
    Leave jsonInput empty (the two sources are mutually exclusive), then set your filter and applyMode.

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 datasetId path, so each chained run is a paid $0.01 conversion. Inline jsonInput stays 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.txt
apify 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.