The Google Analytics Data API v1 lets you generate funnel reports.
Funnel exploration lets you visualize the steps your users take to complete a
task and quickly see how well they are succeeding or failing at each step.

> [!NOTE]
> **Note:** Funnel reporting feature is only available in the [v1alpha version](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.md.txt) of the Google Analytics Data API. While we will try to notify you of upcoming changes, you should expect to encounter breaking changes before this feature is publicly released. For official Google Analytics API announcements, subscribe to the [Google Analytics API
> Notify Group](https://groups.google.com/forum/#!forum/google-analytics-api-notify).

## Shared features with core reports

Funnel reporting requests have the same semantics with Core report requests for
many shared features. For example pagination, Dimension Filters and User
Properties behave the same in Funnel Reports as Core Reports. This
guide focuses on funnel reporting features. To familiarize yourself with the
Core Reporting functionality of the Data API v1, read the [reporting basics guide](https://developers.google.com/analytics/devguides/reporting/data/v1/basics.md.txt),
as well as [advanced use cases](https://developers.google.com/analytics/devguides/reporting/data/v1/advanced.md.txt) guide.

## Funnel reporting method

The Data API v1 supports funnel reporting capabilities in the [`runFunnelReport`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt)
method. This method returns a customized funnel report of your Google Analytics
event data.

### Selectin a reporting entity

All methods of the Data API v1 require the [Google Analytics property identifier](https://developers.google.com/analytics/devguides/reporting/data/v1/property-id.md.txt)
to be specified inside a URL request path in the form of
`properties/GA_PROPERTY_ID`, such as:

```console
  POST  https://analyticsdata.googleapis.com/v1alpha/properties/GA_PROPERTY_ID:runFunnelReport
```

The resulting report will be generated based on the Google Analytics event data
collected in the specified Google Analytics property.

If you are using one of the [Data API client libraries](https://developers.google.com/analytics/devguides/reporting/data/v1/client-libraries.md.txt), there
is no need to manipulate the request URL path manually. Most API clients
provide a `property` parameter that expects a string in the form of
`properties/GA_PROPERTY_ID`. See [Quick start guide](https://developers.google.com/analytics/devguides/reporting/data/v1/quickstart.md.txt)
for examples of using the client libraries.

### Funnel report request

To request a funnel report, you can construct a [`RunFunnelReportRequest`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#request-body)
object. We recommend starting with these request parameters:

- A valid entry in the [`dateRanges`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#body.request_body.FIELDS.date_ranges)
  field.

- A valid funnel specification in the [`funnel`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#body.request_body.FIELDS.funnel)
  field.

#### Funnel specification

A funnel specification in the [`funnel`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#funnel)
field of a [`RunFunnelReportRequest`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#request-body)
object defines the user journey you want to measure by describing [`steps`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#Funnel.FIELDS.steps)
of this funnel.

Funnel steps contain one or more conditions that your users must meet to be
included in that step of the funnel journey. Conditions for inclusion into each
step can be described in the
[`filterExpression`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelStep.FIELDS.filter_expression)
field of each step.

Each funnel filter expression is a combination of two types of filters:

- [`funnelFieldFilter`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelFilterExpression.FIELDS.funnel_field_filter)
  creates a filter for a dimension or metric.

- [`funnelEventFilter`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelFilterExpression.FIELDS.funnel_event_filter)
  creates a filter that matches events of a single event name. If an optional
  [`funnelParameterFilterExpression`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelEventFilter.FIELDS.funnel_parameter_filter_expression)
  field is specified, only the subset of events that match both the single event
  name and the parameter filter expressions match this event filter.

Filters can be combined using [`AND`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelFilterExpression.FIELDS.and_group),
[OR](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelFilterExpression.FIELDS.or_group)
groups, as well as negated using a [`NOT` expression](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelFilterExpression.FIELDS.not_expression).

Report results for each funnel step will be broken down based on the dimension
and specified in the
[`funnelBreakdown`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#body.request_body.FIELDS.funnel_breakdown)
field.

#### Funnel report example

The following example uses the Google Analytics Data API v1 to reproduce the default funnel
report provided in the [Funnel
exploration](https://support.google.com/analytics/answer/9327974) template of the
Google Analytics web interface:

![Sample funnel report UI](https://developers.google.com/static/analytics/devguides/reporting/data/v1/images/funnels-funnel-table-ui-edit-steps.png)

#### Funnel steps

The preceding funnel configuration contains the following steps:

| # | Step name | Condition |
|---|---|---|
| 1 | First open/visit | Event name is `first_open` or `first_visit`. |
| 2 | Organic visitors | `firstUserMedium` dimension contains the term "organic". |
| 3 | Session start | Event name is `session_start`. |
| 4 | Screen/Page view | Event name is `screen_view` or `page_view`. |
| 5 | Purchase | Event name is `purchase` or `in_app_purchase`. |

**Step 1** (First open/visit) of the funnel includes all users after their first
interaction with a website or application, such as users who triggered
`first_open` or `first_visit` events.

To implement this behavior, the following snippet specifies a [`FunnelStep`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelStep) object with a
`filterExpression` field.

The filter expression field is a [`FunnelFilterExpression`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelFilterExpression) object
constructed by combining two
[`FunnelEventFilter`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelEventFilter)
entities using an [OR
group](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport#FunnelFilterExpression.FIELDS.or_group).

```json
  {
    "name": "Purchase",
    "filterExpression": {
      "orGroup": {
        "expressions": [
          {
            "funnelEventFilter": {
              "eventName": "first_open"
            }
          },
          {
            "funnelEventFilter": {
              "eventName": "first_visit"
            }
          }
        ]
      }
    }
  }
```

**Step 2** (Organic visitors) of the funnel includes users whose first [medium](https://support.google.com/analytics/answer/9143382#attribution)
includes the term "organic". In the following snippet, the [`fieldName`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelFieldFilter.FIELDS.field_name)
field of [`FunnelFieldFilter`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelFieldFilter)
instructs the filter to match the `firstUserMedium` dimension.
The [`stringFilter`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelFieldFilter.FIELDS.string_filter)
field contains a condition to include only the values of
the dimension that contain the term "organic".

```json
  {
    "name": "Organic visitors",
    "filterExpression": {
      "funnelFieldFilter": {
        "fieldName": "firstUserMedium",
        "stringFilter": {
          "matchType": "CONTAINS",
          "caseSensitive": false,
          "value": "organic"
        }
      }
    }
  }
```

The remaining funnel steps can be specified in a similar fashion.

##### Breakdown dimension

An optional breakdown dimension (`deviceCategory` in this example) can be
specified using a [`FunnelBreakdown`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelBreakdown)
object:

```json
  "funnelBreakdown": {
    "breakdownDimension": {
      "name": "deviceCategory"
    }
  }
```

By default, only the first 5 distinct values of the breakdown dimension are
included in the report. You can use the [`limit`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelBreakdown.FIELDS.limit)
field of the `FunnelBreakdown` object to override this behavior.

##### Complete funnel report query

Here is a complete query that generates a funnel report:

### HTTP

```console
POST https://analyticsdata.googleapis.com/v1alpha/properties/GA_PROPERTY_ID:runFunnelReport
{
  "dateRanges": [
    {
      "startDate": "30daysAgo",
      "endDate": "today"
    }
  ],
  "funnelBreakdown": {
    "breakdownDimension": {
      "name": "deviceCategory"
    }
  },
  "funnel": {
    "steps": [
      {
        "name": "First open/visit",
        "filterExpression": {
          "orGroup": {
            "expressions": [
              {
                "funnelEventFilter": {
                  "eventName": "first_open"
                }
              },
              {
                "funnelEventFilter": {
                  "eventName": "first_visit"
                }
              }
            ]
          }
        }
      },
      {
        "name": "Organic visitors",
        "filterExpression": {
          "funnelFieldFilter": {
            "fieldName": "firstUserMedium",
            "stringFilter": {
              "matchType": "CONTAINS",
              "caseSensitive": false,
              "value": "organic"
            }
          }
        }
      },
      {
        "name": "Session start",
        "filterExpression": {
          "funnelEventFilter": {
            "eventName": "session_start"
          }
        }
      },
      {
        "name": "Screen/Page view",
        "filterExpression": {
          "orGroup": {
            "expressions": [
              {
                "funnelEventFilter": {
                  "eventName": "screen_view"
                }
              },
              {
                "funnelEventFilter": {
                  "eventName": "page_view"
                }
              }
            ]
          }
        }
      },
      {
        "name": "Purchase",
        "filterExpression": {
          "orGroup": {
            "expressions": [
              {
                "funnelEventFilter": {
                  "eventName": "purchase"
                }
              },
              {
                "funnelEventFilter": {
                  "eventName": "in_app_purchase"
                }
              }
            ]
          }
        }
      }
    ]
  }
}
```

### Report response

The [Funnel Report Response](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#response-body)
of a funnel report API request consists of the two main parts, both returned
as a [`FunnelSubReport`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelSubReport)
object: *Funnel Visualization* and *Funnel Table*.

> [!NOTE]
> **Note:** Funnel reports can be sampled, which is indicated by the presence of [`SamplingMetadata`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/SamplingMetadata.md.txt) in the response.

#### Funnel visualization

Funnel Visualization, returned in the [`funnelVisualization`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#body.RunFunnelReportResponse.FIELDS.funnel_visualization)
field of the [Funnel Report Response](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#response-body),
contains a high level overview of the funnel report. This is useful, as the
name implies, for a quick visualization of the generated funnel report.

Each row of the Funnel visualization table contains some or all of the
following fields:

- Funnel step name (`funnelStepName` dimension).

- Active users count (`activeUsers` metric).

- Segment (`segment` dimension). Present only if [`Segment`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#Segment)
  is specified in the funnel query.

- Date (`date` dimension). Present only if the [`TRENDED_FUNNEL`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelVisualizationType.ENUM_VALUES.TRENDED_FUNNEL)
  visualization type was specified in the query.

- Next action dimension (`funnelStepNextAction` dimension). Present only if the
  [`FunnelNextAction`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#FunnelNextAction)
  is specified in the funnel query.

Here's how the Google Analytics web interface would display the Funnel
visualization section of this guide's example report:

![Funnel report headers: sample](https://developers.google.com/static/analytics/devguides/reporting/data/v1/images/funnels-funnel-table-headers.png)

#### Funnel table

Funnel Table, returned in the [`funnelTable`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#body.RunFunnelReportResponse.FIELDS.funnel_table)
field of the [Funnel Report Response](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#response-body),
represents the main part of the report. Each row of the table
contains some or all of the following fields:

- Funnel step name (`funnelStepName` dimension).

- Breakdown dimension.

- Active users count (`activeUsers` metric).

- Step completion rate (`funnelStepCompletionRate` metric).

- Step abandonments count (`funnelStepAbandonments` metric).

- Step abandonments rate (`funnelStepAbandonmentRate` metric).

- Segment name (`segment` dimension). Present only if [`Segment`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport.md.txt#Segment)
  is specified in the funnel query.

Total values are returned in a
separate row having `RESERVED_TOTAL` as a breakdown dimension value.

Here's an example of the Funnel Table displayed in the Google Analytics web
interface:

![Funnel report table: sample](https://developers.google.com/static/analytics/devguides/reporting/data/v1/images/funnels-funnel-table.png)

#### Raw response

The following snippet demonstrates an example of raw data returned in response
to the `runFunnelReport` query.

Depending on the data collected by your property, the example report would
return the following report showing the number of active users included into
each funnel step.

```json
{
  "funnelTable": {
    "dimensionHeaders": [
      {
        "name": "funnelStepName"
      },
      {
        "name": "deviceCategory"
      }
    ],
    "metricHeaders": [
      {
        "name": "activeUsers",
        "type": "TYPE_INTEGER"
      },
      {
        "name": "funnelStepCompletionRate",
        "type": "TYPE_INTEGER"
      },
      {
        "name": "funnelStepAbandonments",
        "type": "TYPE_INTEGER"
      },
      {
        "name": "funnelStepAbandonmentRate",
        "type": "TYPE_INTEGER"
      }
    ],
    "rows": [
      {
        "dimensionValues": [
          {
            "value": "1. First open/visit"
          },
          {
            "value": "RESERVED_TOTAL"
          }
        ],
        "metricValues": [
          {
            "value": "4621565"
          },
          {
            "value": "0.27780178359495106"
          },
          {
            "value": "3337686"
          },
          {
            "value": "0.72219821640504889"
          }
        ]
      },
      {
        "dimensionValues": [
          {
            "value": "1. First open/visit"
          },
          {
            "value": "desktop"
          }
        ],
        "metricValues": [
          {
            "value": "4015959"
          },
          {
            "value": "0.27425279989163237"
          },
          {
            "value": "2914571"
          },
          {
            "value": "0.72574720010836768"
          }
        ]
      },
      {
        "dimensionValues": [
          {
            "value": "1. First open/visit"
          },
          {
            "value": "mobile"
          }
        ],
        "metricValues": [
          {
            "value": "595760"
          },
          {
            "value": "0.29156035987646034"
          },
          {
            "value": "422060"
          },
          {
            "value": "0.70843964012353966"
          }
        ]
      },
      {
        "dimensionValues": [
          {
            "value": "1. First open/visit"
          },
          {
            "value": "tablet"
          }
        ],
        "metricValues": [
          {
            "value": "33638"
          },
          {
            "value": "0.205571080325822"
          },
          {
            "value": "26723"
          },
          {
            "value": "0.79442891967417806"
          }
        ]
      },

...

    ],
    "metadata": {
      "samplingMetadatas": [
        {
          "samplesReadCount": "9917254",
          "samplingSpaceSize": "1162365416"
        }
      ]
    }
  },

  "funnelVisualization": {
    "dimensionHeaders": [
      {
        "name": "funnelStepName"
      }
    ],
    "metricHeaders": [
      {
        "name": "activeUsers",
        "type": "TYPE_INTEGER"
      }
    ],
    "rows": [
      {
        "dimensionValues": [
          {
            "value": "1. First open/visit"
          }
        ],
        "metricValues": [
          {
            "value": "4621565"
          }
        ]
      },

...

    ],
    "metadata": {
      "samplingMetadatas": [
        {
          "samplesReadCount": "9917254",
          "samplingSpaceSize": "1162365416"
        }
      ]
    }
  },
  "kind": "analyticsData#runFunnelReport"
}
```

### Client libraries

See the [Quick start guide](https://developers.google.com/analytics/devguides/reporting/data/v1/quickstart.md.txt) for an explanation on
how to install and configure [client libraries](https://developers.google.com/analytics/devguides/reporting/data/v1/client-libraries.md.txt).

Here are examples using client libraries that run a funnel query and print the
response.

### Java

[google-analytics-data/src/main/java/com/google/analytics/data/samples/RunFunnelReportSample.java](https://github.com/googleanalytics/java-docs-samples/blob/main/google-analytics-data/src/main/java/com/google/analytics/data/samples/RunFunnelReportSample.java) [Open in Cloud Shell](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleanalytics/java-docs-samples&page=editor&open_in_editor=google-analytics-data/src/main/java/com/google/analytics/data/samples/RunFunnelReportSample.java "Open this sample or repository in the Google Cloud Shell Editor") [View on GitHub](https://github.com/googleanalytics/java-docs-samples/blob/main/google-analytics-data/src/main/java/com/google/analytics/data/samples/RunFunnelReportSample.java)

```java
import com.google.analytics.data.v1alpha.AlphaAnalyticsDataClient;
import com.google.analytics.data.v1alpha.DateRange;
import com.google.analytics.data.v1alpha.Dimension;
import com.google.analytics.data.v1alpha.DimensionHeader;
import com.google.analytics.data.v1alpha.FunnelBreakdown;
import com.google.analytics.data.v1alpha.FunnelEventFilter;
import com.google.analytics.data.v1alpha.FunnelFieldFilter;
import com.google.analytics.data.v1alpha.FunnelFilterExpression;
import com.google.analytics.data.v1alpha.FunnelFilterExpressionList;
import com.google.analytics.data.v1alpha.FunnelStep;
import com.google.analytics.data.v1alpha.FunnelSubReport;
import com.google.analytics.data.v1alpha.MetricHeader;
import com.google.analytics.data.v1alpha.Row;
import com.google.analytics.data.v1alpha.RunFunnelReportRequest;
import com.google.analytics.data.v1alpha.RunFunnelReportResponse;
import com.google.analytics.data.v1alpha.SamplingMetadata;
import com.google.analytics.data.v1alpha.StringFilter;
import com.google.analytics.data.v1alpha.StringFilter.MatchType;

/**
 * Google Analytics Data API sample application demonstrating the creation of a funnel report.
 *
 * <p>See
 * https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport
 * for more information.
 *
 * <p>Before you start the application, please review the comments starting with "TODO(developer)"
 * and update the code to use correct values.
 *
 * <p>To run this sample using Maven:
 *
 * <pre>{@code
 * cd google-analytics-data
 * mvn compile exec:java -Dexec.mainClass="com.google.analytics.data.samples.RunFunnelReportSample"
 * }</pre>
 */
public class RunFunnelReportSample {

  public static void main(String... args) throws Exception {
    /**
     * TODO(developer): Replace this variable with your Google Analytics 4 property ID before
     * running the sample.
     */
    String propertyId = "YOUR-GA4-PROPERTY-ID";
    sampleRunFunnelReport(propertyId);
  }

  /**
   * Runs a funnel query to build a report with 5 funnel steps.
   *
   * <ol>
   *   <li>First open/visit (event name is `first_open` or `first_visit`).
   *   <li>Organic visitors (`firstUserMedium` dimension contains the term "organic").
   *   <li>Session start (event name is `session_start`).
   *   <li>Screen/Page view (event name is `screen_view` or `page_view`).
   *   <li>Purchase (event name is `purchase` or `in_app_purchase`).
   * </ol>
   *
   * The report configuration reproduces the default funnel report provided in the Funnel
   * Exploration template of the Google Analytics UI. See more at
   * https://support.google.com/analytics/answer/9327974
   */
  static void sampleRunFunnelReport(String propertyId) throws Exception {

    // Using a default constructor instructs the client to use the credentials
    // specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
    try (AlphaAnalyticsDataClient analyticsData = AlphaAnalyticsDataClient.create()) {
      RunFunnelReportRequest.Builder requestBuilder =
          RunFunnelReportRequest.newBuilder()
              .setProperty("properties/" + propertyId)
              .addDateRanges(DateRange.newBuilder().setStartDate("30daysAgo").setEndDate("today"))
              .setFunnelBreakdown(
                  FunnelBreakdown.newBuilder()
                      .setBreakdownDimension(Dimension.newBuilder().setName("deviceCategory")));

      // Adds each step of the funnel.
      requestBuilder
          .getFunnelBuilder()
          .addSteps(
              FunnelStep.newBuilder()
                  .setName("First open/visit")
                  .setFilterExpression(
                      FunnelFilterExpression.newBuilder()
                          .setOrGroup(
                              FunnelFilterExpressionList.newBuilder()
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("first_open")))
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("first_visit"))))));
      requestBuilder
          .getFunnelBuilder()
          .addSteps(
              FunnelStep.newBuilder()
                  .setName("Organic visitors")
                  .setFilterExpression(
                      FunnelFilterExpression.newBuilder()
                          .setFunnelFieldFilter(
                              FunnelFieldFilter.newBuilder()
                                  .setFieldName("firstUserMedium")
                                  .setStringFilter(
                                      StringFilter.newBuilder()
                                          .setMatchType(MatchType.CONTAINS)
                                          .setCaseSensitive(false)
                                          .setValue("organic")))));
      requestBuilder
          .getFunnelBuilder()
          .addSteps(
              FunnelStep.newBuilder()
                  .setName("Session start")
                  .setFilterExpression(
                      FunnelFilterExpression.newBuilder()
                          .setFunnelEventFilter(
                              FunnelEventFilter.newBuilder().setEventName("session_start"))));

      requestBuilder
          .getFunnelBuilder()
          .addSteps(
              FunnelStep.newBuilder()
                  .setName("Screen/Page view")
                  .setFilterExpression(
                      FunnelFilterExpression.newBuilder()
                          .setOrGroup(
                              FunnelFilterExpressionList.newBuilder()
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("screen_view")))
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("page_view"))))));
      requestBuilder
          .getFunnelBuilder()
          .addSteps(
              FunnelStep.newBuilder()
                  .setName("Purchase")
                  .setFilterExpression(
                      FunnelFilterExpression.newBuilder()
                          .setOrGroup(
                              FunnelFilterExpressionList.newBuilder()
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("purchase")))
                                  .addExpressions(
                                      FunnelFilterExpression.newBuilder()
                                          .setFunnelEventFilter(
                                              FunnelEventFilter.newBuilder()
                                                  .setEventName("in_app_purchase"))))));

      // Make the request.
      RunFunnelReportResponse response = analyticsData.runFunnelReport(requestBuilder.build());
      printRunFunnelReportResponse(response);
    }
  }

  /** Prints results of a runFunnelReport call. */
  static void printRunFunnelReportResponse(RunFunnelReportResponse response) {
    System.out.println("Report result:");
    System.out.println("=== FUNNEL VISUALIZATION ===");
    printFunnelSubReport(response.getFunnelVisualization());

    System.out.println("=== FUNNEL TABLE ===");
    printFunnelSubReport(response.getFunnelTable());
  }

  /** Prints the contents of a FunnelSubReport object. */
  private static void printFunnelSubReport(FunnelSubReport funnelSubReport) {
    System.out.println("Dimension headers:");
    for (DimensionHeader dimensionHeader : funnelSubReport.getDimensionHeadersList()) {
      System.out.println(dimensionHeader.getName());
    }
    System.out.println();

    System.out.println("Metric headers:");
    for (MetricHeader metricHeader : funnelSubReport.getMetricHeadersList()) {
      System.out.println(metricHeader.getName());
    }
    System.out.println();

    System.out.println("Dimension and metric values for each row in the report:");
    for (int rowIndex = 0; rowIndex < funnelSubReport.getRowsCount(); rowIndex++) {
      Row row = funnelSubReport.getRows(rowIndex);
      for (int fieldIndex = 0; fieldIndex < row.getDimensionValuesCount(); fieldIndex++) {
        System.out.printf(
            "%s: '%s'%n",
            funnelSubReport.getDimensionHeaders(fieldIndex).getName(),
            row.getDimensionValues(fieldIndex).getValue());
      }
      for (int fieldIndex = 0; fieldIndex < row.getMetricValuesCount(); fieldIndex++) {
        System.out.printf(
            "%s: '%s'%n",
            funnelSubReport.getMetricHeaders(fieldIndex).getName(),
            row.getMetricValues(fieldIndex).getValue());
      }
    }
    System.out.println();

    System.out.println("Sampling metadata for each date range:");
    for (int metadataIndex = 0;
        metadataIndex < funnelSubReport.getMetadata().getSamplingMetadatasCount();
        metadataIndex++) {
      SamplingMetadata samplingMetadata =
          funnelSubReport.getMetadata().getSamplingMetadatas(metadataIndex);
      System.out.printf(
          "Sampling metadata for date range #%d: samplesReadCount=%d, samplingSpaceSize=%d%n",
          metadataIndex,
          samplingMetadata.getSamplesReadCount(),
          samplingMetadata.getSamplingSpaceSize());
    }
  }
}
```

### PHP

[google-analytics-data/src/run_funnel_report.php](https://github.com/googleanalytics/php-docs-samples/blob/main/google-analytics-data/src/run_funnel_report.php) [Open in Cloud Shell](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleanalytics/php-docs-samples&page=editor&open_in_editor=google-analytics-data/src/run_funnel_report.php "Open this sample or repository in the Google Cloud Shell Editor") [View on GitHub](https://github.com/googleanalytics/php-docs-samples/blob/main/google-analytics-data/src/run_funnel_report.php)

```php
use Google\Analytics\Data\V1alpha\Client\AlphaAnalyticsDataClient;
use Google\Analytics\Data\V1alpha\DateRange;
use Google\Analytics\Data\V1alpha\Dimension;
use Google\Analytics\Data\V1alpha\FunnelBreakdown;
use Google\Analytics\Data\V1alpha\FunnelEventFilter;
use Google\Analytics\Data\V1alpha\FunnelFieldFilter;
use Google\Analytics\Data\V1alpha\FunnelFilterExpression;
use Google\Analytics\Data\V1alpha\FunnelFilterExpressionList;
use Google\Analytics\Data\V1alpha\FunnelStep;
use Google\Analytics\Data\V1alpha\Funnel;
use Google\Analytics\Data\V1alpha\FunnelSubReport;
use Google\Analytics\Data\V1alpha\RunFunnelReportRequest;
use Google\Analytics\Data\V1alpha\RunFunnelReportResponse;
use Google\Analytics\Data\V1alpha\StringFilter;
use Google\Analytics\Data\V1alpha\StringFilter\MatchType;

/**
 * Runs a funnel query to build a report with 5 funnel steps.
 *
 * Step 1: First open/visit (event name is `first_open` or `first_visit`).
 * Step 2: Organic visitors (`firstUserMedium` dimension contains the term "organic").
 * Step 3: Session start (event name is `session_start`).
 * Step 4: Screen/Page view (event name is `screen_view` or `page_view`).
 * Step 5: Purchase (event name is `purchase` or `in_app_purchase`).
 *
 * The report configuration reproduces the default funnel report provided in the Funnel
 * Exploration template of the Google Analytics UI. See more at
 * https://support.google.com/analytics/answer/9327974
 *
 * @param string $propertyId Your GA-4 Property ID
 */
function run_funnel_report(string $propertyId)
{
    // Create an instance of the Google Analytics Data API client library.
    $client = new AlphaAnalyticsDataClient();

    // Create the funnel report request.
    $request = (new RunFunnelReportRequest())
        ->setProperty('properties/' . $propertyId)
        ->setDateRanges([
            new DateRange([
                'start_date' => '30daysAgo',
                'end_date' => 'today',
            ]),
        ])
        ->setFunnelBreakdown(
            new FunnelBreakdown([
                'breakdown_dimension' =>
                    new Dimension([
                        'name' => 'deviceCategory'
                    ])
            ])
        )
        ->setFunnel(new Funnel());

    // Add funnel steps to the funnel.

    // 1. Add first open/visit step.
    $request->getFunnel()->getSteps()[] = new FunnelStep([
        'name' => 'First open/visit',
        'filter_expression' => new FunnelFilterExpression([
            'or_group' => new FunnelFilterExpressionList([
                'expressions' => [
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'first_open',
                        ])
                    ]),
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'first_visit'
                        ])
                    ])
                ]
            ])
        ])
    ]);

    // 2. Add organic visitors step.
    $request->getFunnel()->getSteps()[] = new FunnelStep([
        'name' => 'Organic visitors',
        'filter_expression' => new FunnelFilterExpression([
            'funnel_field_filter' => new FunnelFieldFilter([
                'field_name' => 'firstUserMedium',
                'string_filter' => new StringFilter([
                    'match_type' => MatchType::CONTAINS,
                    'case_sensitive' => false,
                    'value' => 'organic',
                ])
            ])
        ])
    ]);

    // 3. Add session start step.
    $request->getFunnel()->getSteps()[] = new FunnelStep([
        'name' => 'Session start',
        'filter_expression' => new FunnelFilterExpression([
            'funnel_event_filter' => new FunnelEventFilter([
                'event_name' => 'session_start',
            ])
        ])
    ]);

    // 4. Add screen/page view step.
    $request->getFunnel()->getSteps()[] = new FunnelStep([
        'name' => 'Screen/Page view',
        'filter_expression' => new FunnelFilterExpression([
            'or_group' => new FunnelFilterExpressionList([
                'expressions' => [
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'screen_view',
                        ])
                    ]),
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'page_view'
                        ])
                    ])
                ]
            ])
        ])
    ]);

    // 5. Add purchase step.
    $request->getFunnel()->getSteps()[] = new FunnelStep([
        'name' => 'Purchase',
        'filter_expression' => new FunnelFilterExpression([
            'or_group' => new FunnelFilterExpressionList([
                'expressions' => [
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'purchase',
                        ])
                    ]),
                    new FunnelFilterExpression([
                        'funnel_event_filter' => new FunnelEventFilter([
                            'event_name' => 'in_app_purchase'
                        ])
                    ])
                ]
            ])
        ])
    ]);

    // Make an API call.
    $response = $client->runFunnelReport($request);

    printRunFunnelReportResponse($response);
}

/**
 * Print results of a runFunnelReport call.
 * @param RunFunnelReportResponse $response
 */
function printRunFunnelReportResponse(RunFunnelReportResponse $response)
{
    print 'Report result: ' . PHP_EOL;
    print '=== FUNNEL VISUALIZATION ===' . PHP_EOL;
    printFunnelSubReport($response->getFunnelVisualization());

    print '=== FUNNEL TABLE ===' . PHP_EOL;
    printFunnelSubReport($response->getFunnelTable());
}

/**
 * Print the contents of a FunnelSubReport object.
 * @param FunnelSubReport $subReport
 */
function printFunnelSubReport(FunnelSubReport $subReport)
{
    print 'Dimension headers:' . PHP_EOL;
    foreach ($subReport->getDimensionHeaders() as $dimensionHeader) {
        print $dimensionHeader->getName() . PHP_EOL;
    }

    print PHP_EOL . 'Metric headers:' . PHP_EOL;
    foreach ($subReport->getMetricHeaders() as $metricHeader) {
        print $metricHeader->getName() . PHP_EOL;
    }

    print PHP_EOL . 'Dimension and metric values for each row in the report:';
    foreach ($subReport->getRows() as $rowIndex => $row) {
        print PHP_EOL . 'Row #' . $rowIndex . PHP_EOL;
        foreach ($row->getDimensionValues() as $dimIndex => $dimValue) {
            $dimName = $subReport->getDimensionHeaders()[$dimIndex]->getName();
            print $dimName . ": '" . $dimValue->getValue() . "'" . PHP_EOL;
        }
        foreach ($row->getMetricValues() as $metricIndex => $metricValue) {
            $metricName = $subReport->getMetricHeaders()[$metricIndex]->getName();
            print $metricName . ": '" . $metricValue->getValue() . "'" . PHP_EOL;
        }
    }

    print PHP_EOL . 'Sampling metadata for each date range:' . PHP_EOL;
    foreach ($subReport->getMetadata()->getSamplingMetadatas() as $metadataIndex => $metadata) {
        printf('Sampling metadata for date range #%d: samplesReadCount=%d' .
            'samplingSpaceSize=%d%s',
            $metadataIndex, $metadata->getSamplesReadCount(), $metadata->getSamplingSpaceSize(), PHP_EOL);
    }
}
```

### Python

[google-analytics-data/run_funnel_report.py](https://github.com/googleanalytics/python-docs-samples/blob/main/google-analytics-data/run_funnel_report.py) [Open in Cloud Shell](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleanalytics/python-docs-samples&page=editor&open_in_editor=google-analytics-data/run_funnel_report.py "Open this sample or repository in the Google Cloud Shell Editor") [View on GitHub](https://github.com/googleanalytics/python-docs-samples/blob/main/google-analytics-data/run_funnel_report.py)

```python
from google.analytics.data_v1alpha import AlphaAnalyticsDataClient
from google.analytics.data_v1alpha.types import (
    DateRange,
    Dimension,
    Funnel,
    FunnelBreakdown,
    FunnelEventFilter,
    FunnelFieldFilter,
    FunnelFilterExpression,
    FunnelFilterExpressionList,
    FunnelStep,
    RunFunnelReportRequest,
    StringFilter,
)


def run_sample():
    """Runs the sample."""
    # TODO(developer): Replace this variable with your Google Analytics 4
    #  property ID before running the sample.
    property_id = "YOUR-GA4-PROPERTY-ID"
    run_funnel_report(property_id)


def run_funnel_report(property_id="YOUR-GA4-PROPERTY-ID"):
    """Runs a funnel query to build a report with 5 funnel steps.
      Step 1: First open/visit (event name is `first_open` or `first_visit`).
      Step 2: Organic visitors (`firstUserMedium` dimension contains the term
      "organic").
      Step 3: Session start (event name is `session_start`).
      Step 4: Screen/Page view (event name is `screen_view` or `page_view`).
      Step 5: Purchase (event name is `purchase` or `in_app_purchase`).

    The report configuration reproduces the default funnel report provided in
    the Funnel Exploration template of the Google Analytics UI.
    See more at https://support.google.com/analytics/answer/9327974
    """
    client = AlphaAnalyticsDataClient()

    request = RunFunnelReportRequest(
        property=f"properties/{property_id}",
        date_ranges=[DateRange(start_date="30daysAgo", end_date="today")],
        funnel_breakdown=FunnelBreakdown(
            breakdown_dimension=Dimension(name="deviceCategory")
        ),
        funnel=Funnel(
            steps=[
                FunnelStep(
                    name="First open/visit",
                    filter_expression=FunnelFilterExpression(
                        or_group=FunnelFilterExpressionList(
                            expressions=[
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="first_open"
                                    )
                                ),
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="first_visit"
                                    )
                                ),
                            ]
                        )
                    ),
                ),
                FunnelStep(
                    name="Organic visitors",
                    filter_expression=FunnelFilterExpression(
                        funnel_field_filter=FunnelFieldFilter(
                            field_name="firstUserMedium",
                            string_filter=StringFilter(
                                match_type=StringFilter.MatchType.CONTAINS,
                                case_sensitive=False,
                                value="organic",
                            ),
                        )
                    ),
                ),
                FunnelStep(
                    name="Session start",
                    filter_expression=FunnelFilterExpression(
                        funnel_event_filter=FunnelEventFilter(
                            event_name="session_start"
                        )
                    ),
                ),
                FunnelStep(
                    name="Screen/Page view",
                    filter_expression=FunnelFilterExpression(
                        or_group=FunnelFilterExpressionList(
                            expressions=[
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="screen_view"
                                    )
                                ),
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="page_view"
                                    )
                                ),
                            ]
                        )
                    ),
                ),
                FunnelStep(
                    name="Purchase",
                    filter_expression=FunnelFilterExpression(
                        or_group=FunnelFilterExpressionList(
                            expressions=[
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="purchase"
                                    )
                                ),
                                FunnelFilterExpression(
                                    funnel_event_filter=FunnelEventFilter(
                                        event_name="in_app_purchase"
                                    )
                                ),
                            ]
                        )
                    ),
                ),
            ]
        ),
    )
    response = client.run_funnel_report(request)
    print_run_funnel_report_response(response)


def print_funnel_sub_report(funnel_sub_report):
    """Prints the contents of a FunnelSubReport object."""
    print("Dimension headers:")
    for dimension_header in funnel_sub_report.dimension_headers:
        print(dimension_header.name)

    print("\nMetric headers:")
    for metric_header in funnel_sub_report.metric_headers:
        print(metric_header.name)

    print("\nDimensions and metric values for each row in the report:")
    for row_idx, row in enumerate(funnel_sub_report.rows):
        print("\nRow #{}".format(row_idx))
        for field_idx, dimension_value in enumerate(row.dimension_values):
            dimension_name = funnel_sub_report.dimension_headers[field_idx].name
            print("{}: '{}'".format(dimension_name, dimension_value.value))

        for field_idx, metric_value in enumerate(row.metric_values):
            metric_name = funnel_sub_report.metric_headers[field_idx].name
            print("{}: '{}'".format(metric_name, metric_value.value))

    print("\nSampling metadata for each date range:")
    for metadata_idx, metadata in enumerate(
        funnel_sub_report.metadata.sampling_metadatas
    ):
        print(
            "Sampling metadata for date range #{}: samplesReadCount={}, "
            "samplingSpaceSize={}".format(
                metadata_idx, metadata.samples_read_count, metadata.sampling_space_size
            )
        )


def print_run_funnel_report_response(response):
    """Prints results of a runFunnelReport call."""
    print("Report result:")
    print("=== FUNNEL VISUALIZATION ===")
    print_funnel_sub_report(response.funnel_visualization)

    print("=== FUNNEL TABLE ===")
    print_funnel_sub_report(response.funnel_table)



```