Field masks

  • Field masks in the Google Ads API specify which fields to update in an API request, ignoring any fields not listed.

  • The recommended way to generate field masks is using the FieldMaskUtil class, specifically FieldMasks.AllSetFieldsOf for new objects and FieldMasks.FromChanges for existing objects.

  • To clear a field, you must manually include it in the field mask without setting the field value in the object, as setting it to a default value won't clear it.

In the Google Ads API, a field mask is used to provide a list of fields that an API request should update. Any field that is not specified in the field mask is ignored, even if sent to the server.

FieldMasks class

The recommended way to generate field masks in the .NET client library is to use the built-in FieldMasks utility class, which lets you generate field masks from a modified object instead of building them from scratch.

Here's an example for updating a campaign that uses the FieldMasks.AllSetFieldsOf method to produce a field mask enumerating all set fields. You can then pass the generated field mask directly to the update call:

// Update campaign by setting its status to paused, and "Search network" to
// false.
Campaign campaignToUpdate = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
    Status = CampaignStatus.Paused,
    NetworkSettings = new NetworkSettings()
    {
        TargetSearchNetwork = false
    }
};

// Create the operation.
CampaignOperation operation = new CampaignOperation()
{
    Update = campaignToUpdate,
    UpdateMask = FieldMasks.AllSetFieldsOf(campaignToUpdate)
};

// Update the campaign.
MutateCampaignsResponse response = campaignService.MutateCampaigns(
    customerId.ToString(), new CampaignOperation[] { operation });

Sometimes, you may need to work with an existing object and update a few fields. In such cases, use the FieldMasks.FromChanges method instead. This method generates a field mask that represents the difference between two objects:

Campaign existingCampaign;

// Obtain existingCampaign from an earlier API call.

// Create a new campaign based on the existing campaign for update.
Campaign campaignToUpdate = new Campaign(existingCampaign);

// Update campaign by setting its status to paused, and "Search network" to
// false.
campaignToUpdate.Status = CampaignStatus.Paused;
campaignToUpdate.NetworkSettings = new NetworkSettings()
{
    TargetSearchNetwork = false
};

// Create the operation.
CampaignOperation operation = new CampaignOperation()
{
    Update = campaignToUpdate,
    UpdateMask = FieldMasks.FromChanges(existingCampaign, campaignToUpdate)
};

Handle FieldMaskError.FIELD_HAS_SUBFIELDS errors

On rare occasions, you may need to set a message field without updating any of its subfields. Consider the following example:

// Creates a campaign with the proper resource name and an empty
// MaximizeConversions field.
Campaign campaign = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
    MaximizeConversions = new MaximizeConversions()
};

CampaignOperation operation = new CampaignOperation()
{
    Update = campaign,
    UpdateMask = FieldMasks.AllSetFieldsOf(campaign)
};

MutateCampaignsResponse response = campaignService.MutateCampaigns(
    customerId.ToString(), new CampaignOperation[] { operation });

This API call fails with a FieldMaskError.FIELD_HAS_SUBFIELDS error. Since MaximizeConversions has subfields, the Google Ads API server expects field masks for the mutable subfields to be present in the request. However, FieldMasks cannot generate subfield masks automatically in this situation because the request does not set any subfields.

In such cases, you can manually add paths to fieldMask.Paths (which is a RepeatedField<string>):

// Creates a Campaign object with the proper resource name.
Campaign campaign = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
};

FieldMask fieldMask = FieldMasks.AllSetFieldsOf(campaign);
// Only include 'maximize_conversions.target_cpa_micros' in the field mask
// as it is the only mutable subfield on MaximizeConversions when used as a
// standard bidding strategy.
//
// Learn more about standard and portfolio bidding strategies at:
// https://developers.google.com/google-ads/api/docs/campaigns/bidding/assign-strategies
fieldMask.Paths.Add("maximize_conversions.target_cpa_micros");

// Creates an operation to update the campaign with the specified fields.
CampaignOperation operation = new CampaignOperation()
{
    Update = campaign,
    UpdateMask = fieldMask
};

Clear fields

The Google Ads API supports clearing some field values. To clear a field, you must manually include that field in the field mask while leaving the field unset on the resource object. Setting a field to its default value (such as 0 for an int64 field) doesn't clear the field.

The following code example shows how to clear the target_cpa_micros field of a MaximizeConversions bidding strategy:

Correct code

The following code clears the target_cpa_micros field because it adds maximize_conversions.target_cpa_micros to the field mask without setting the campaign.MaximizeConversions.TargetCpaMicros property:

// Creates a Campaign object with the proper resource name.
Campaign campaign = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
};

// Constructs a field mask from the existing campaign and adds the
// 'maximize_conversions.target_cpa_micros' field to the field mask, which
// clears this field from the bidding strategy without impacting any other
// fields on the bidding strategy.
FieldMask fieldMask = FieldMasks.AllSetFieldsOf(campaign);
fieldMask.Paths.Add("maximize_conversions.target_cpa_micros");

// Creates an operation to update the campaign with the specified field.
CampaignOperation operation = new CampaignOperation()
{
    Update = campaign,
    UpdateMask = fieldMask
};

Incorrect code

The following code doesn't clear the target_cpa_micros field, because it sets the field to 0. Both the FieldMasks utility and the Google Ads API server ignore this value when TargetCpaMicros is 0 or when the path is omitted from the mask, and the server does not return an error:

// Creates a campaign with the proper resource name and a
// MaximizeConversions object. Attempts to clear the target_cpa_micros
// field by setting it to 0.
Campaign campaign = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
    MaximizeConversions = new MaximizeConversions()
    {
        TargetCpaMicros = 0
    }
};

// Constructs an operation using FieldMasks.AllSetFieldsOf to derive the
// update mask.
CampaignOperation operation = new CampaignOperation()
{
    Update = campaign,
    UpdateMask = FieldMasks.AllSetFieldsOf(campaign)
};

// Sends the operation in a mutate request that succeeds without clearing
// the previous 'target_cpa_micros' value cleanly.
MutateCampaignsResponse response = campaignService.MutateCampaigns(
    customerId.ToString(), new CampaignOperation[] { operation });