To evaluate how campaign changes and ad exposure affect performance, query
experiment and lift measurement reporting resources in the Google Ads API.

The Google Ads API supports two ways to report on standard A/B experiments:

- **Direct experiment reporting** : Query the [`experiment`](https://developers.google.com/google-ads/api/fields/v26/experiment.md.txt) resource for metrics. This option provides metrics for control and treatment arms in a single response, along with statistical comparison data such as uplift and p-values. Direct experiment reporting is the only way to report on **intra-campaign** experiments.
- **Campaign reporting** : Query the [`campaign`](https://developers.google.com/google-ads/api/fields/v26/campaign.md.txt) resource for metrics by using the `campaign.experiment_type` field to distinguish between base and experiment campaigns. This option is available only for experiments that use separate control and treatment campaigns, such as **system-managed** experiments.

For standard experiments, this guide focuses primarily on direct experiment
reporting, which supports all reportable experiment types. For lift measurement
studies, see the [Lift
reporting](https://developers.google.com/google-ads/api/docs/experiments/lift-reporting) guide or the summary
sections on this page for [Brand Lift](https://developers.google.com/google-ads/api/docs/experiments/reporting.md.txt#brand-lift-reporting), [Conversion
Lift](https://developers.google.com/google-ads/api/docs/experiments/reporting#conversion-lift-reporting) (including [A/B + Conversion
Lift](https://developers.google.com/google-ads/api/docs/experiments/reporting#ab-lift-reporting)), and [Search Lift](https://developers.google.com/google-ads/api/docs/experiments/reporting.md.txt#search-lift-reporting).

## Direct experiment reporting

To retrieve performance metrics and statistical comparisons between your control
and treatment arms in a single response across all supported Google Ads API versions
(v23 and later), query the `experiment` resource directly.

### Metrics and statistical significance

For core metrics such as clicks, impressions, cost, conversions, and conversion
value, the `experiment` resource provides both treatment metrics (for example,
`metrics.clicks`) and control metrics (for example, `metrics.control_clicks`) in
the same row.

The `experiment` resource also provides fields to help you evaluate the
statistical significance of any difference between the arms:

- `metrics.*_p_value`: The probability of observing results at least as extreme as the measured difference if the experiment has no actual effect on the metric. A lower p-value indicates higher statistical significance.
- `metrics.*_point_estimate`: The estimated percentage lift (positive or negative) in the given metric for the treatment arm compared to the control arm. Together with the `metrics.*_margin_of_error` field, this value defines a confidence interval with a prescribed confidence level for the estimated difference. The estimated quantity is `(treatment / control) - 1`, and the point estimate is the center of the confidence interval.
- `metrics.*_margin_of_error`: The radius of the confidence interval, which is centered at the `metrics.*_point_estimate` value. The API calculates this margin for a prescribed confidence level that depends on the experiment type.

The following core metric fields are supported on the `experiment` resource,
including a treatment group value, a control group value, and the stat fields
listed previously:

- `clicks`
- `impressions`
- `cost_micros`
- `conversions`
- `cost_per_conversion`
- `conversion_value`
- `conversion_value_per_cost`

For conversions, specifically, the statistical fields are available through the
following `absolute_change` fields, rather than as relative values:

- [`metrics.conversions_absolute_change_p_value`](https://developers.google.com/google-ads/api/fields/v26/experiment.md.txt#metrics.conversions_absolute_change_p_value): The p-value for the null hypothesis that the experiment has no effect on conversions absolute change. Ranges from 0 to 1.
- [`metrics.conversions_absolute_change_point_estimate`](https://developers.google.com/google-ads/api/fields/v26/experiment.md.txt#metrics.conversions_absolute_change_point_estimate): The point estimate when estimating the experiment's effect on conversions absolute change.
- [`metrics.conversions_absolute_change_margin_of_error`](https://developers.google.com/google-ads/api/fields/v26/experiment.md.txt#metrics.conversions_absolute_change_margin_of_error): The margin of error when estimating the experiment's effect on conversions absolute change.

For assistance constructing valid queries to the `experiment` resource, use the
[Google Ads Query Builder](https://developers.google.com/google-ads/api/fields/v26/experiment_query_builder.md.txt) tool.

### Example query

The following Google Ads Query Language (GAQL) query retrieves key metrics for an experiment:

```sql
SELECT
  experiment.experiment_id,
  experiment.name,
  experiment.type,
  metrics.clicks,
  metrics.control_clicks,
  metrics.clicks_point_estimate,
  metrics.clicks_margin_of_error,
  metrics.clicks_p_value,
  metrics.conversions,
  metrics.control_conversions,
  metrics.conversions_absolute_change_point_estimate,
  metrics.conversions_absolute_change_margin_of_error,
  metrics.conversions_absolute_change_p_value
FROM experiment
WHERE experiment.experiment_id = EXPERIMENT_ID
```

Replace the following:

- `EXPERIMENT_ID`: the integer ID of the experiment (`experiment.experiment_id`).

### Interpret results

Use the p-value, point estimate, and margin of error fields to determine whether
your experiment has yielded statistically significant results. For example, if
the `metrics.conversions_absolute_change_p_value` metric is less than your
chosen threshold (such as `0.05` for 95% confidence) and the
`metrics.conversions_absolute_change_point_estimate` metric minus the
`metrics.conversions_absolute_change_margin_of_error` metric is greater than
zero, the treatment arm is performing significantly better than the control arm
in terms of conversions.

The following code example demonstrates how to evaluate results based on p-value
and lift estimates:


### Java

```java
private void evaluateExperiment(
    GoogleAdsClient googleAdsClient, long customerId, GoogleAdsRow row) {
  Metrics metrics = row.getMetrics();
  String experimentResourceName = row.getExperiment().getResourceName();

  // 1. Evaluate conversion success as a primary success signal if available.
  // - Point Estimate: Represents the estimated average lift or difference in conversions.
  // - Margin of Error: Outlines the confidence interval bounds. Note that the margin_of_error
  //   provided by the API is calculated for a preset confidence level which is set based on the
  //   experiment type.
  // - Lower Bound: (Point Estimate - Margin of Error). If this value is above 0,
  //   we have statistical significance that performance has improved.
  double convPValue = metrics.getConversionsAbsoluteChangePValue();
  double convLift = metrics.getConversionsAbsoluteChangePointEstimate();
  double convError = metrics.getConversionsAbsoluteChangeMarginOfError();
  double convLowerBound = convLift - convError;

  if (convPValue <= P_VALUE_THRESHOLD) {
    if (convLowerBound > 0) {
      System.out.printf(
          "Significant Success: Conversions increased. Even at the lower bound, the lift is %.2f."
              + " Promoting changes.%n",
          convLowerBound);
      promoteExperiment(googleAdsClient, customerId, experimentResourceName);
      return;
    } else if ((convLift + convError) < 0) {
      System.out.printf(
          "Significant Decline: Even the upper bound (%.2f) is below zero. Ending experiment.%n",
          convLift + convError);
      endExperiment(googleAdsClient, customerId, experimentResourceName);
      return;
    }
  }

  // 2. Fall back to evaluating click metrics if conversions are inconclusive.
  double clickPValue = metrics.getClicksPValue();
  double clickLift = metrics.getClicksPointEstimate();
  double clickError = metrics.getClicksMarginOfError();
  double clickLowerBound = clickLift - clickError;

  if (clickPValue <= P_VALUE_THRESHOLD && clickLowerBound > 0) {
    System.out.printf("Click volume is significantly up (+%.1f%%).%n", clickLift * 100);

    // Graduation is only supported for separate campaign experiments, not
    // intra-campaign experiments where there is no separate treatment campaign.
    ExperimentType experimentType = row.getExperiment().getType();
    if (experimentType != ExperimentType.ADOPT_BROAD_MATCH_KEYWORDS
        && experimentType != ExperimentType.ADOPT_AI_MAX) {
      System.out.println("Graduating treatment campaign for further manual analysis.");
      graduateExperiment(googleAdsClient, customerId, experimentResourceName);
    } else {
      System.out.println(
          "Intra-campaign trial detected: graduation is not supported. Continuing to run the"
              + " experiment to gather more conversion data.");
    }
  } else {
    // 3. Print status if no action was taken.
    System.out.printf(
        "Inconclusive: No significant lift in Conversions (p=%.2f) or Clicks (p=%.2f). Current"
            + " estimated lift: %.2f +/- %.2f. Allowing the experiment to continue running.%n",
        convPValue, clickPValue, convLift, convError);
  }
}

      
```

### C#

```c#
private static void EvaluateExperiment(GoogleAdsClient client, long customerId, GoogleAdsRow row)
{
    // This function evaluates performance metrics and immediately takes action
    // to update the experiment's status (promote, end, or graduate) if
    // statistical significance thresholds are met.
    var metrics = row.Metrics;
    string experimentResourceName = row.Experiment.ResourceName;

    bool hasConvMetrics = metrics.HasConversionsAbsoluteChangePValue
        && metrics.HasConversionsAbsoluteChangePointEstimate
        && metrics.HasConversionsAbsoluteChangeMarginOfError;

    bool hasClickMetrics = metrics.HasClicksPValue
        && metrics.HasClicksPointEstimate
        && metrics.HasClicksMarginOfError;

    // 1. Evaluate conversion success as a primary success signal if available.
    // - Point Estimate: Represents the estimated average lift or difference in conversions.
    // - Margin of Error: Outlines the confidence interval bounds. Note that the margin_of_error
    //   provided by the API is calculated for a preset confidence level which is set based on
    //   the experiment type.
    // - Lower Bound: (Point Estimate - Margin of Error). If this value is above 0,
    //   we have statistical significance that performance has improved.
    if (hasConvMetrics)
    {
        double convPValue = metrics.ConversionsAbsoluteChangePValue;
        double convLift = metrics.ConversionsAbsoluteChangePointEstimate;
        double convError = metrics.ConversionsAbsoluteChangeMarginOfError;
        double convLowerBound = convLift - convError;

        if (convPValue <= P_VALUE_THRESHOLD)
        {
            if (convLowerBound > 0)
            {
                Console.WriteLine(
                    $"Significant Success: Conversions increased. Even at the lower" +
                    $" bound, the lift is {convLowerBound:F2}. Promoting changes.");
                PromoteExperiment(client, customerId, experimentResourceName);
                return;
            }
            else if ((convLift + convError) < 0)
            {
                Console.WriteLine(
                    $"Significant Decline: Even the upper bound ({convLift + convError:F2}) " +
                    $"is below zero. Ending experiment.");
                EndExperiment(client, customerId, experimentResourceName);
                return;
            }
        }
    }

    // 2. Evaluate click volume as a secondary signal.
    // This is helpful as an early indicator or for lower-volume accounts.
    if (hasClickMetrics)
    {
        double clickPValue = metrics.ClicksPValue;
        double clickLift = metrics.ClicksPointEstimate;
        double clickError = metrics.ClicksMarginOfError;
        double clickLowerBound = clickLift - clickError;

        if (clickPValue <= P_VALUE_THRESHOLD && clickLowerBound > 0)
        {
            // We have a directional winner: high confidence in more traffic,
            // but not enough data to confirm conversion impact yet.
            Console.WriteLine(
                $"Click volume is significantly up (+{clickLift * 100:F1}%).");

            // Graduation is only supported for separate campaign experiments, not
            // intra-campaign experiments where there is no separate treatment campaign.
            if (row.Experiment.Type != ExperimentType.AdoptBroadMatchKeywords
                && row.Experiment.Type != ExperimentType.AdoptAiMax)
            {
                Console.WriteLine("Graduating treatment campaign for further manual analysis.");
                GraduateExperiment(client, customerId, experimentResourceName);
            }
            else
            {
                Console.WriteLine(
                    "Intra-campaign trial detected: graduation is not supported. " +
                    "Continuing to run the experiment to gather more conversion data.");
            }
            return;
        }
    }

    // 3. Print status if no action was taken.
    if (hasConvMetrics || hasClickMetrics)
    {
        string convStatus = hasConvMetrics
            ? $"Conversions (p={metrics.ConversionsAbsoluteChangePValue:F2}, " +
              $"lift={metrics.ConversionsAbsoluteChangePointEstimate:F2} +/- " +
              $"{metrics.ConversionsAbsoluteChangeMarginOfError:F2})"
            : "Conversions (not populated)";

        string clickStatus = hasClickMetrics
            ? $"Clicks (p={metrics.ClicksPValue:F2}, " +
              $"lift={metrics.ClicksPointEstimate:F2} +/- " +
              $"{metrics.ClicksMarginOfError:F2})"
            : "Clicks (not populated)";

        Console.WriteLine(
            $"Inconclusive: No significant action taken. {convStatus}, {clickStatus}. " +
            "Allowing the experiment to continue running.");
    }
    else
    {
        Console.WriteLine(
            "Conversion and click performance metrics are not yet populated. " +
            "Allowing the experiment to continue running.");
    }
}
      
```

### PHP

```
This example is not yet available in PHP; you can take a look at the other languages.
    
```

### Python

```python
def evaluate_experiment(
    client: GoogleAdsClient, customer_id: str, row: GoogleAdsRow
) -> None:
    """Evaluates the performance of the experiment and updates it accordingly
    (for example, promotes, ends, or graduates).

    Checks conversion and click metrics against statistical significance thresholds
    to determine the appropriate action to take on the experiment.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID.
        row: a GoogleAdsRow containing the experiment and metrics.
    """
    # This function evaluates performance metrics and immediately takes action
    # to update the experiment's status (promote, end, or graduate) if
    # statistical significance thresholds are met.
    metrics = row.metrics
    experiment_resource_name = row.experiment.resource_name

    has_conv_metrics = (
        "conversions_absolute_change_p_value" in metrics
        and "conversions_absolute_change_point_estimate" in metrics
        and "conversions_absolute_change_margin_of_error" in metrics
    )
    has_click_metrics = (
        "clicks_p_value" in metrics
        and "clicks_point_estimate" in metrics
        and "clicks_margin_of_error" in metrics
    )

    # 1. Evaluate conversion success as a primary success signal if available.
    # - Point Estimate: Represents the estimated average lift or difference in conversions.
    # - Margin of Error: Outlines the confidence interval bounds. Note that the margin_of_error provided by the API is calculated for a preset confidence level which is set based on the experiment type.
    # - Lower Bound: (Point Estimate - Margin of Error). If this value is above 0,
    #   we have statistical significance that performance has improved.
    if has_conv_metrics:
        conv_p_value = metrics.conversions_absolute_change_p_value
        conv_lift = metrics.conversions_absolute_change_point_estimate
        conv_error = metrics.conversions_absolute_change_margin_of_error
        conv_lower_bound = conv_lift - conv_error

        if conv_p_value <= P_VALUE_THRESHOLD:
            if conv_lower_bound > 0:
                print(
                    "Significant Success: Conversions increased. Even at the lower"
                    f" bound, the lift is {conv_lower_bound:.2f}. Promoting"
                    " changes."
                )
                promote_experiment(
                    client, customer_id, experiment_resource_name
                )
                return
            elif (conv_lift + conv_error) < 0:
                print(
                    "Significant Decline: Even the upper bound"
                    f" ({conv_lift + conv_error:.2f}) is below zero. Ending"
                    " experiment."
                )
                end_experiment(client, customer_id, experiment_resource_name)
                return

        # 2. Evaluate click volume as a secondary signal.
        # This is helpful as an early indicator or for lower-volume accounts.
        click_p_value = metrics.clicks_p_value
        click_lift = metrics.clicks_point_estimate
        click_error = metrics.clicks_margin_of_error
        click_lower_bound = click_lift - click_error

        if click_p_value <= P_VALUE_THRESHOLD and click_lower_bound > 0:
            # We have a directional winner: high confidence in more traffic,
            # but not enough data to confirm conversion impact yet.
            print(f"Click volume is significantly up (+{click_lift*100:.1f}%).")

            # Graduation is only supported for separate campaign experiments, not
            # intra-campaign experiments where there is no separate treatment campaign.
            experiment_type_name = row.experiment.type_.name
            if (
                experiment_type_name != "ADOPT_BROAD_MATCH_KEYWORDS"
                and experiment_type_name != "ADOPT_AI_MAX"
            ):
                print(
                    "Graduating treatment campaign for further manual analysis."
                )
                graduate_experiment(
                    client, customer_id, experiment_resource_name
                )
            else:
                print(
                    "Intra-campaign trial detected: graduation is not supported. "
                    "Continuing to run the experiment to gather more conversion data."
                )
            return

    # 3. Print status if no action was taken.
    if has_conv_metrics or has_click_metrics:
        conv_status = (
            f"Conversions (p={metrics.conversions_absolute_change_p_value:.2f}, "
            f"lift={metrics.conversions_absolute_change_point_estimate:.2f} +/- "
            f"{metrics.conversions_absolute_change_margin_of_error:.2f})"
            if has_conv_metrics
            else "Conversions (not populated)"
        )
        click_status = (
            f"Clicks (p={metrics.clicks_p_value:.2f}, "
            f"lift={metrics.clicks_point_estimate:.2f} +/- "
            f"{metrics.clicks_margin_of_error:.2f})"
            if has_click_metrics
            else "Clicks (not populated)"
        )
        print(
            f"Inconclusive: No significant action taken. {conv_status}, {click_status}."
            " Allowing the experiment to continue running."
        )
    else:
        print(
            "Conversion and click performance metrics are not yet populated. "
            "Allowing the experiment to continue running."
        )
      
```

### Ruby

```ruby
def evaluate_experiment(client, customer_id, row)
  # This function evaluates performance metrics and immediately takes action
  # to update the experiment's status (promote, end, or graduate) if
  # statistical significance thresholds are met.
  metrics = row.metrics
  experiment_resource_name = row.experiment.resource_name

  has_conv_metrics = !metrics.nil? &&
                     metrics.has_conversions_absolute_change_p_value? &&
                     metrics.has_conversions_absolute_change_point_estimate? &&
                     metrics.has_conversions_absolute_change_margin_of_error?
  has_click_metrics = !metrics.nil? &&
                      metrics.has_clicks_p_value? &&
                      metrics.has_clicks_point_estimate? &&
                      metrics.has_clicks_margin_of_error?

  # 1. Evaluate conversion success as a primary success signal if available.
  # - Point Estimate: Represents the estimated average lift or difference in conversions.
  # - Margin of Error: Outlines the confidence interval bounds. Note that the margin_of_error
  #   provided by the API is calculated for a preset confidence level which is set based on the experiment type.
  # - Lower Bound: (Point Estimate - Margin of Error). If this value is above 0,
  #   we have statistical significance that performance has improved.
  if has_conv_metrics
    conv_p_value = metrics.conversions_absolute_change_p_value
    conv_lift = metrics.conversions_absolute_change_point_estimate
    conv_error = metrics.conversions_absolute_change_margin_of_error
    conv_lower_bound = conv_lift - conv_error

    if conv_p_value <= P_VALUE_THRESHOLD
      if conv_lower_bound > 0
        puts sprintf(
          "Significant Success: Conversions increased. Even at the lower " \
          "bound, the lift is %.2f. Promoting changes.",
          conv_lower_bound,
        )
        promote_experiment(client, customer_id, experiment_resource_name)
        return
      elsif (conv_lift + conv_error) < 0
        puts sprintf(
          "Significant Decline: Even the upper bound (%.2f) is below zero. " \
          "Ending experiment.",
          conv_lift + conv_error,
        )
        end_experiment(client, customer_id, experiment_resource_name)
        return
      end
    end
  end

  # 2. Evaluate click volume as a secondary signal.
  # This is helpful as an early indicator or for lower-volume accounts.
  if has_click_metrics
    click_p_value = metrics.clicks_p_value
    click_lift = metrics.clicks_point_estimate
    click_error = metrics.clicks_margin_of_error
    click_lower_bound = click_lift - click_error

    if click_p_value <= P_VALUE_THRESHOLD && click_lower_bound > 0
      # We have a directional winner: high confidence in more traffic,
      # but not enough data to confirm conversion impact yet.
      puts sprintf("Click volume is significantly up (+%.1f%%).", click_lift * 100)

      # Graduation is only supported for separate campaign experiments, not
      # intra-campaign experiments where there is no separate treatment campaign.
      experiment_type = row.experiment.type
      if experiment_type != :ADOPT_BROAD_MATCH_KEYWORDS && experiment_type != :ADOPT_AI_MAX
        puts "Graduating treatment campaign for further manual analysis."
        graduate_experiment(client, customer_id, experiment_resource_name)
      else
        puts "Intra-campaign trial detected: graduation is not supported. " \
             "Continuing to run the experiment to gather more conversion data."
      end
      return
    end
  end

  # 3. Print status if no action was taken.
  if has_conv_metrics || has_click_metrics
    conv_status = if has_conv_metrics
      sprintf(
        "Conversions (p=%.2f, lift=%.2f +/- %.2f)",
        metrics.conversions_absolute_change_p_value,
        metrics.conversions_absolute_change_point_estimate,
        metrics.conversions_absolute_change_margin_of_error,
      )
    else
      "Conversions (not populated)"
    end

    click_status = if has_click_metrics
      sprintf(
        "Clicks (p=%.2f, lift=%.2f +/- %.2f)",
        metrics.clicks_p_value,
        metrics.clicks_point_estimate,
        metrics.clicks_margin_of_error,
      )
    else
      "Clicks (not populated)"
    end

    puts "Inconclusive: No significant action taken. #{conv_status}, #{click_status}. " \
         "Allowing the experiment to continue running."
  else
    puts "Conversion and click performance metrics are not yet populated. " \
         "Allowing the experiment to continue running."
  end
end
      
```

### Perl

```
This example is not yet available in Perl; you can take a look at the other languages.
    
```

### curl

> [!NOTE]
> **Note:** While a direct REST code sample for this step isn't provided here, you can achieve this using a manual REST request.   
>
> Refer to the Google Ads API REST interface documentation and the method-specific reference pages. You will need to construct the JSON payload based on the proto definitions.   
>
> Key Resources:
>
> - [Using REST](https://developers.google.com/google-ads/api/rest/overview.md.txt)
> - [REST Interface Structure](https://developers.google.com/google-ads/api/rest/design/overview.md.txt)
> - [JSON Field Mappings](https://developers.google.com/google-ads/api/rest/design/json-mappings.md.txt)
> - Consult the [REST API Reference](https://developers.google.com/google-ads/api/reference/rpc/latest/overview) for the specific service and method.

<br />

### Benefits over campaign reporting

Direct experiment reporting offers several advantages over querying campaign
reports separately:

- **Centralized metrics**: Retrieves metrics for control and treatment arms in a single row.
- **Statistical confidence data**: Provides calculated p-values, point estimates, and margins of error.
- **Efficiency**: Eliminates the need to manually join or compare results from multiple reports.
- **Intra-campaign support**: Supports control-versus-treatment comparisons for intra-campaign experiments, where traffic splits within a single campaign.

## Campaign reporting

Across all supported Google Ads API versions (v23 and later), for experiments that
create separate treatment campaigns (for example, `SEARCH_CUSTOM`), you can
query the `campaign` resource and use the `campaign.experiment_type` field to
identify `BASE` (control) and `EXPERIMENT` (treatment) campaigns. This approach
is useful when you need to segment metrics at a more granular level (such as by
ad group or keyword) or view campaign metadata that is not available on the
`experiment` resource. However, campaign reporting requires you to perform
performance comparisons and statistical calculations manually.

You cannot use campaign-level reporting to compare arms for intra-campaign
experiments, because the traffic split happens internally within a single
campaign. Querying the `campaign` resource for an intra-campaign experiment
returns only aggregated totals.

## Brand Lift reporting

In Google Ads API v25 and later, evaluate how your ad campaigns influence brand
perception by querying the read-only (`OUTPUT_ONLY`)
[`LiftMeasurementFlight`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementFlight.md.txt), [`LiftMeasurementConfig`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementConfig.md.txt),
and Brand Lift breakdown resources ([`LiftMeasurementAgeRange`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementAgeRange.md.txt),
[`LiftMeasurementCampaign`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementCampaign.md.txt),
[`LiftMeasurementDevice`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementDevice.md.txt), [`LiftMeasurementGender`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementGender.md.txt),
and [`LiftMeasurementVideo`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementVideo.md.txt)). In Google Ads API v27 and later, you can
also select the `lift_guidance` field (`lift_guidance.outcome` and
`lift_guidance.guidance_message`) for row-level statistical interpretation.

For survey response reportability thresholds, empty-response (`results: []`)
diagnostics, outcome interpretation, and GAQL query examples, see [Brand Lift
reporting](https://developers.google.com/google-ads/api/docs/experiments/lift-reporting#brand-lift-reporting)
in the Lift reporting guide.

## Conversion Lift reporting

In Google Ads API v25 and later, Conversion Lift reporting measures the incremental
impact of your ads on conversions, conversion value, cost per incremental
conversion (iCPA), and incremental return on ad spend (iROAS) by comparing an
exposed group against an unexposed holdback group across daily cumulative
evaluation snapshots (`segments.conversion_lift_start_date` and
`segments.conversion_lift_end_date`) on the
[`LiftMeasurementConfig`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementConfig.md.txt) resource. In Google Ads API v26 and later, you
can also discover linked configurations and campaigns through the
[`campaign.lift_measurement_config`](https://developers.google.com/google-ads/api/reference/rpc/v26/Campaign.md.txt#lift_measurement_config) and
[`lift_measurement_config.campaigns`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementConfig.md.txt#campaigns%5B%5D) fields, and in
Google Ads API v27 and later, select `lift_measurement_config.lift_guidance` for
row-level statistical interpretation.

For study and flight discovery, cumulative snapshot date ranges, conversion
action scopes (`SELECTED` versus `ALL`), dimensional breakdowns, reportability
thresholds, and GAQL query examples, see [Conversion Lift
reporting](https://developers.google.com/google-ads/api/docs/experiments/lift-reporting#conversion-lift-reporting)
in the Lift reporting guide.

### A/B + Conversion Lift reporting

In Google Ads API v25 and later, A/B + Conversion Lift studies combine a two-arm
[`experiment`](https://developers.google.com/google-ads/api/fields/v26/experiment.md.txt) (discovered through the
[`ExperimentArm`](https://developers.google.com/google-ads/api/reference/rpc/v26/ExperimentArm.md.txt) resource and the
[`experiment.lift_measurement_config`](https://developers.google.com/google-ads/api/reference/rpc/v26/Experiment.md.txt#lift_measurement_config) field) with
holdback measurement on the [`LiftMeasurementConfig`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementConfig.md.txt) resource.
Include the [`segments.experiment_arm`](https://developers.google.com/google-ads/api/reference/rpc/v26/Segments.md.txt#experiment_arm) segment and the Bayesian
winner score metrics (`metrics.*_winner_score`) to evaluate per-arm causal lift
and head-to-head winner probabilities.

For experiment arm discovery, per-arm and combined-arm queries, winner score
interpretation, and multi-study batch queries, see [A/B + Conversion Lift
reporting](https://developers.google.com/google-ads/api/docs/experiments/lift-reporting#ab-lift-reporting) in
the Lift reporting guide.

## Search Lift reporting

In Google Ads API v26 and later, Search Lift reporting measures the incremental
increase in organic search query volume across Google Search and YouTube driven
by your ad campaigns. Query the
[`SearchLiftKeywordBundle`](https://developers.google.com/google-ads/api/reference/rpc/v26/SearchLiftKeywordBundle.md.txt) resource for configured
keyword bundles and the [`LiftMeasurementConfig`](https://developers.google.com/google-ads/api/reference/rpc/v26/LiftMeasurementConfig.md.txt) resource (with
`lift_measurement_config.lift_guidance` in Google Ads API v27 and later) for relative
and normalized incremental search metrics.

For Search Lift segmentation rules, metric definitions, and GAQL query examples,
see [Search Lift
reporting](https://developers.google.com/google-ads/api/docs/experiments/lift-reporting#search-lift-reporting)
in the Lift reporting guide.

## Best practices

The following best practices apply to standard A/B experiments (such as campaign
and intra-campaign experiments). Lift measurement studies (Brand Lift,
Conversion Lift, and Search Lift) use study-specific configurations and report
90% one-sided confidence bounds (`*_p90_lower_bound` and `*_p90_upper_bound`,
which together form an 80% two-sided confidence interval with `p_value <= 0.10`)
rather than a 95% confidence threshold. See the [Lift
reporting](https://developers.google.com/google-ads/api/docs/experiments/lift-reporting) guide for lift
study thresholds and interpretation.

- **Select an appropriate confidence level** : Setting a lower p-value threshold can provide directional guidance faster, especially with lower budgets or conversion volumes. A 95% confidence level (`p_value <= 0.05`) is the academic standard and provides higher precision over a longer timeframe.
- **Run experiments for long enough**: Run experiments for at least 4 weeks to account for weekly performance cycles, conversion delays, and learning periods.
- **Give time for ramp-up**: For campaigns that use automated bidding or test new features, disregard the first 1--2 weeks of data so that bidding models and traffic levels can recalibrate to the split.
- **Use 50/50 splits**: A 50/50 traffic split is generally the fastest way to achieve statistically significant results.
- **Schedule in advance**: Set your experiment start date 3--7 days in the future to allow time for ad review and approval processes.

> [!IMPORTANT]
> **Important:** You can only run one standard A/B experiment per campaign at any given time.