cirql

A composable pipeline language for JSON

Pipe any JSON source — APIs, files, stdin — through composable transforms.

cq
> http "https://api.github.com/repos/golang/go/contributors"
  | filter .contributions > 500
  | map { who: .login, commits: .contributions }
  | sort .commits desc
  | limit 3

[
  { "who": "rsc", "commits": 7241 },
  { "who": "bradfitz", "commits": 3852 },
  { "who": "griesemer", "commits": 3116 }
]

Construct Variables. Chain APIs. Merge Results.

Query one API, reshape its response, and feed it as variables into the next — GraphQL, REST, or anything that speaks JSON. Fork parallel calls and merge them into a single payload.

REST → Transform → GraphQL

Fetch users from a REST API, extract their logins, then query a GraphQL API using each login as a variable — automatically.

cq
-- Fetch users from REST, reshape, feed to GraphQL
http "https://api.example.com/users"
| map { login: .username, id: .id }
| query {
    user(login: $login) {
      bio
      followers { totalCount }
      repos(first: 5) { nodes { name stargazerCount } }
    }
  }
| map {
    login: $login,
    bio: .user.bio,
    followers: .user.followers.totalCount,
    top_repo: .user.repos.nodes[0].name
  }
| sort .followers desc

[
  { "login": "ada", "bio": "...", "followers": 2841, "top_repo": "lovelace" },
  { "login": "linus", "bio": "...", "followers": 1902, "top_repo": "kernel" }
]

Fork & Merge Multiple APIs

Pull data from multiple sources in parallel, reshape each result, and merge them into a unified payload sent downstream.

cq
-- Fetch from two APIs, combine into one result
http "https://api.example.com/orgs"
| map { org: .login, url: .repos_url }
| http $url
| flatMap { org: $org, repo: .name, stars: .stargazers_count }
| sort .stars desc
| limit 10

[
  { "org": "golang", "repo": "go", "stars": 124000, ... },
  { "org": "rust-lang", "repo": "rust", "stars": 98000, ... }
]

Build & POST Constructed Payloads

Transform query results into a request body and POST it to another API — variable interpolation works in URLs, headers, and bodies.

cq
-- Query GitHub, build payload, POST to webhook
query {
    repository(owner: "golang", name: "go") {
      issues(states: OPEN, first: 5) {
        nodes { title number labels { nodes { name } } }
      }
    }
  }
| flatMap { title: .nodes[].title, num: .nodes[].number }
| map { text: "Issue #" + $num + ": " + $title }
| http "https://hooks.slack.com/services/T00/B00/xxx" (
    method: "POST",
    body: $text
  )

What is cirql?

cirql pipes JSON from any source — GraphQL, REST APIs, local files, stdin — through composable transform stages. Think jq meets curl — chain data sources, transform results, propagate variables, and aggregate data in a single expression.

Pipeline Composition

Chain any JSON source with | operators. Feed results from one stage into the next. Filter, map, reduce, sort — all inline.

http "https://api.example.com/users"
| filter .active == true
| map { name: .name, role: .role }
| sort .name asc

Pluggable Sources

Start a pipeline from GraphQL, REST, a local file, or stdin. The pipeline stages don't care where the JSON came from.

http "https://api.example.com/users"
| filter .active == true

file "data/products.json"
| sort .price asc

cat events.json | cq 'stdin
| reduce count'

Variable Propagation

Extract fields from one stage and inject them as variables into subsequent queries. Cross-source chaining becomes trivial.

http "https://api.example.com/users"
| map { login: .username }
| query {
    user(login: $login) { bio followers }
  }

Interactive REPL

Explore APIs interactively with cq. Schema-aware autocomplete for GraphQL, persistent history, multi-line pipelines.

> .set endpoint https://api.github.com/graphql
Connected. 142 types found.
> query { viewer { login } }
{ "viewer": { "login": "you" } }

Smart Optimization

The planner fuses sequential queries, batches list arguments, deduplicates sub-queries, and parallelizes fan-out operations.

-- cirql batches this automatically
query { users { id } }
| query { repos(owners: $id) { name } }
-- → single batched request

Multiple Output Formats

Pretty JSON by default. Compact JSON, ASCII tables, CSV, and TSV for scripting and piping to other tools.

$ cq -t 'http "https://api.example.com/users"'
┌──────────┬─────────┐
│ name     │ role    │
├──────────┼─────────┤
│ Ada      │ admin   │
│ Linus    │ dev     │
└──────────┴─────────┘

Hosted Service

api.cirql.io provides a hosted pipeline execution engine. Save pipelines, manage endpoints, collaborate with your team.

$ curl -X POST https://api.cirql.io/v1/execute \
    -d '{"pipeline": "http \"https://api.example.com/users\" | filter .active == true | reduce count"}'

Get Started

Install cq

go install github.com/nicerobot/cirql/cmd/cq@latest

Or use the API

curl https://api.cirql.io/v1/execute \
  -H "Content-Type: application/json" \
  -d '{"pipeline": "http \"https://your-api.com/users\" | filter .active == true | reduce count"}'