---
title: "Cascading Parameters"
meta:
    description: Learn how to query nodes across Pipes and pass parameters through the dependency chain.
---

# Cascading Parameters

## What you'll learn

In this tutorial, you'll learn how to:

- Reference a node from one Pipe inside another Pipe
- Pass query parameters through the Pipe dependency chain

## Prerequisites

- A Tinybird account. If you don't already have a Tinybird account, you can create one at [cloud.tinybird.co](https://cloud.tinybird.co/signup) -- it's free!
- Basic SQL knowledge
- Tinybird CLI and Tinybird Local container installed on your machine. [See Tinybird Forward installation](/forward/install-tinybird#install-tinybird-on-your-machine)

## Overview

In Tinybird, a Pipe can have multiple nodes. Each node contains a SQL `SELECT` statement that reads from a Data Source or from a previous node in the same Pipe.

You can also read from a node in a **different** Pipe. This lets you reuse query logic across multiple Endpoints without duplicating SQL.

When you reference another Pipe, its query parameters cascade: if both Pipes define a parameter with the same name, the value you pass to the Endpoint is forwarded to the dependency too.

{% steps %}

## Set up the project

Create a new directory and scaffold a Tinybird project:

```bash
mkdir cascading-params && cd cascading-params
```

```bash
tb init --type cli --dev-mode manual --folder . --cicd skip
```

## Create the helper Pipe

Create a Pipe that generates an hourly time series between a `start` and `end` timestamp. This Pipe is not an Endpoint — it's a helper that other Pipes can reference.

```tb {% title="pipes/hourly_time_range.pipe" %}
DESCRIPTION >
    Generate hourly timestamps between start and end.

NODE time_window
SQL >
    %
    SELECT
        _end,
        {\% if defined(start) %}
            toStartOfInterval(toDateTime({{DateTime(start)}}), INTERVAL 1 HOUR) AS _start
        {\% else %}
            _end - INTERVAL 24 HOUR AS _start
        {\% end %}
    FROM
    (
        SELECT
            {\% if defined(end) %}
                toStartOfInterval(toDateTime({{DateTime(end)}}), INTERVAL 1 HOUR) AS _end
            {\% else %}
                toStartOfInterval(now(), INTERVAL 1 HOUR) AS _end
            {\% end %}
    )

NODE time_series
SQL >
    SELECT
        _start + (number * 3600) AS time
    FROM time_window
    ARRAY JOIN range(dateDiff('hour', _start, _end)) AS number
```

This Pipe has two nodes:

- `time_window`: calculates the start and end of the range using the `start` and `end` query parameters.
- `time_series`: expands the range into one row per hour using `ARRAY JOIN`.

## Create the Endpoint that references the helper

Create a second Pipe that reads from `hourly_time_range` and publishes the result as an Endpoint.

```tb {% title="endpoints/time_series_endpoint.pipe" %}
DESCRIPTION >
    Return an hourly time series by referencing the helper pipe.

NODE time_series
SQL >
    %
    SELECT time
    FROM hourly_time_range

TYPE ENDPOINT
```

The `FROM hourly_time_range` clause references the helper Pipe by its name. Tinybird resolves this to the last node of `hourly_time_range.pipe` (the `time_series` node).

{% callout type="tip" %}
When you reference another Pipe by name, Tinybird reads from its **last node**. You don't need to specify the node name.
{% /callout %}

## Validate and build locally

Start Tinybird Local and build the project:

```bash
tb local start
```

```bash
tb build
```

If the build succeeds, both Pipes are deployed locally and the dependency between them is resolved.

## Test the Endpoint

Copy the local admin token and call the Endpoint, passing the `start` parameter:

```bash
tb token copy "admin local_testing@tinybird.co" && TB_LOCAL_TOKEN=$(pbpaste)

curl -s "http://localhost:7181/v0/pipes/time_series_endpoint.json?start=2026-02-17%2000:00:00&token=$TB_LOCAL_TOKEN"
```

Even though you're calling the `time_series_endpoint` Endpoint, the `start` parameter cascades to `hourly_time_range` because both Pipes use a parameter named `start`. The response contains hourly timestamps starting from the value you passed:

```json
{
    "data":
    [
        {"time": "2026-02-17 00:00:00"},
        {"time": "2026-02-17 01:00:00"},
        {"time": "2026-02-17 02:00:00"}
    ]
}
```

You can also pass the `end` parameter to control the upper bound:

```bash
curl -s "http://localhost:7181/v0/pipes/time_series_endpoint.json?start=2026-02-17%2000:00:00&end=2026-02-17%2006:00:00&token=$TB_LOCAL_TOKEN"
```

{% /steps %}

## How cascading works

Parameters with the same name in different Pipes are cascaded down the dependency chain. When you call an Endpoint with `start=2026-02-17`, the value is forwarded to every Pipe in the chain that defines a `start` parameter.

This means you can build reusable query logic in helper Pipes and expose it through multiple Endpoints, all sharing the same parameters.

## Common errors

If a Pipe references a node from another Pipe that doesn't exist or isn't deployed, you'll see an error like:

```
Node 'my_node' from pipe 'my_pipe' depends on 'other_pipe', but it is missing or not accessible in the deployment
```

To fix this, make sure the referenced Pipe is included in your project and is deployed. Run `tb build` locally to validate all dependencies before deploying.

## Next steps

- Learn more about [query parameters](/forward/work-with-data/query-parameters).
- Learn about [Pipe files](/forward/dev-reference/datafiles/pipe-files).
- Publish your Endpoints and learn about [Endpoints](/forward/work-with-data/publish-data/endpoints).
