# Recommendations

Read Google's optimization recommendations for a Google Ads account with their estimated impact, apply them with Google's suggested values or your own, and dismiss the ones you do not want.

By the end of this page, you can read Google's optimization recommendations for an ad account (budgets, bidding targets, keywords, assets).

You see what each one is expected to change, apply the ones you want and dismiss the rest.

## Before you start

You need a `googleads` [account](/platforms/google-ads#connect). Every call takes `accountId`. Add `adAccountId` (the customer id) when the connection has several Google customers.

## Read recommendations

[`GET /v1/ads/recommendations`](/ad-campaigns/list-google-recommendations) lists the account's recommendations. Narrow it with:

- `campaignId`: Google's numeric campaign id.
- `types`: a comma-separated list of Google `RecommendationType` values, such as `CAMPAIGN_BUDGET,KEYWORD,SET_TARGET_CPA`. An unknown type returns `400`.

```bash
curl "https://zernio.com/api/v1/ads/recommendations?accountId=66b2e19d8c3f5a7e9d0b1c2d&adAccountId=1234567890&types=FORECASTING_SET_TARGET_CPA,CAMPAIGN_BUDGET" \
  -H "Authorization: Bearer $ZERNIO_API_KEY"
```

Response (`200`), trimmed to one recommendation:

```json
{
  "adAccountId": "1234567890",
  "recommendations": [
    {
      "resourceName": "customers/1234567890/recommendations/NjgzMzAxODc4NS0yNDItMTc5MDQzODQxMDc1NC0rMjQxOTE1ODU2NzEtMA",
      "id": "NjgzMzAxODc4NS0yNDItMTc5MDQzODQxMDc1NC0rMjQxOTE1ODU2NzEtMA",
      "type": "FORECASTING_SET_TARGET_CPA",
      "dismissed": false,
      "campaignId": "21874563210",
      "campaignIds": ["21874563210"],
      "adGroupId": null,
      "campaignBudgetId": null,
      "impact": {
        "base": { "impressions": 2790, "clicks": 87, "cost": 420, "conversions": 3.96, "conversionsValue": 0, "videoViews": 0 },
        "potential": { "impressions": 5909, "clicks": 185, "cost": 889.58, "conversions": 8.39, "conversionsValue": 0, "videoViews": 0 }
      },
      "details": {
        "recommendedTargetCpaMicros": "105420000",
        "campaignBudget": { "currentAmountMicros": "60000000", "recommendedNewAmountMicros": "140000000", "newStartDate": "2026-10-01" }
      }
    }
  ],
  "cachedAt": null,
  "stale": false
}
```

- `resourceName` is what you pass to apply or dismiss; the bare `id` works too.
- `campaignId` is the campaign the recommendation targets. `campaignIds` lists every campaign it touches (several for account-level types).
- `adGroupId` and `campaignBudgetId` are set when the recommendation targets one.
- `impact` is Google's estimate over its own window. `base` is what the target does today, and `potential` what Google expects after applying.
  - `cost` is in account currency units, not micros.
  - `impact` is `null` when Google gives no estimate for the type.
- `details` is the type-specific payload exactly as Google returns it, camelCase and with amounts in micros (divide by 1,000,000). Its fields depend on `type`, so read them against Google's `Recommendation` reference.

The list is cached for 10 minutes per customer and filter. Applying or dismissing clears it, so the next read is live.

When Google's quota runs out, the last successful copy is served with `stale: true`. Check `cachedAt` before treating it as current.

## Apply recommendations

[`POST /v1/ads/recommendations/apply`](/ad-campaigns/apply-google-recommendations) applies up to 100 recommendations in one call.

Without `parameters`, Google applies its own suggested values.

To override them, `parameters` takes exactly one key named for the recommendation type, in Google's `ApplyRecommendationOperation` shape (amounts in micros):

```bash
curl -X POST "https://zernio.com/api/v1/ads/recommendations/apply" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "66b2e19d8c3f5a7e9d0b1c2d",
    "adAccountId": "1234567890",
    "recommendations": [
      { "resourceName": "customers/1234567890/recommendations/NjgzMzAxODc4NS0yNDEtMTc5MDQ3NTQyNjU5Ni0rMjM1MjA5NjcxNjctMA" },
      {
        "resourceName": "NjgzMzAxODc4NS0yMjgtMTc5MDQyNDE5NjUwNS0rMTU3NjMyNzU3ODk",
        "parameters": { "campaignBudget": { "newBudgetAmountMicros": "150000000" } }
      }
    ]
  }'
```

Response (`200`):

```json
{
  "adAccountId": "1234567890",
  "results": [
    { "resourceName": "customers/1234567890/recommendations/NjgzMzAxODc4NS0yNDEtMTc5MDQ3NTQyNjU5Ni0rMjM1MjA5NjcxNjctMA", "status": "applied" },
    { "resourceName": "customers/1234567890/recommendations/NjgzMzAxODc4NS0yMjgtMTc5MDQyNDE5NjUwNS0rMTU3NjMyNzU3ODk", "status": "failed", "error": "The recommendation is no longer valid." }
  ]
}
```

The accepted `parameters` keys:

- Budget: `campaignBudget`, `moveUnusedBudget`
- Keywords: `keyword`, `useBroadMatchKeyword`
- Ads: `textAd`, `responsiveSearchAd`, `responsiveSearchAdAsset`, `responsiveSearchAdImproveAdStrength`
- Assets: `callAsset`, `calloutAsset`, `sitelinkAsset`, `leadFormAsset`
- Bidding: `targetCpaOptIn`, `targetRoasOptIn`, `raiseTargetCpa`, `lowerTargetRoas`, `setTargetCpa`, `setTargetRoas`, `forecastingSetTargetCpa`, `forecastingSetTargetRoas`, `raiseTargetCpaBidTooLow`, `raiseTargetCpaPerformanceBidTooLow`, `lowerTargetRoasPerformanceBidTooLow`
- Extensions: `calloutExtension`, `callExtension`, `sitelinkExtension`

Sending two keys, or one not on this list, returns `400`.

<Callout type="warn">
Applying changes the account (budgets, bidding strategies, keywords, assets) and cannot be undone through this endpoint. It is not idempotent, and Google offers no validate-only mode for it, so apply only what you have read and chosen.
</Callout>

Items run in partial-failure mode. Each one gets its own `status`: `applied`, or `failed` with Google's message in `error`.

A stale or invalid recommendation does not block the others. The call answers `200` even when some items fail, so check every result.

Every `resourceName` must belong to the customer in the call. One under another customer returns `400`.

## Dismiss recommendations

[`POST /v1/ads/recommendations/dismiss`](/ad-campaigns/dismiss-google-recommendations) dismisses up to 100 recommendations, so Google stops suggesting them. `resourceNames` takes resource names or bare ids:

```bash
curl -X POST "https://zernio.com/api/v1/ads/recommendations/dismiss" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "66b2e19d8c3f5a7e9d0b1c2d",
    "adAccountId": "1234567890",
    "resourceNames": ["NjgzMzAxODc4NS0yNDItMTc5MDQzODQxMDc1NC0rMjQxOTE1ODU2NzEtMA"]
  }'
```

Response (`200`):

```json
{ "adAccountId": "1234567890", "results": [{ "resourceName": "customers/1234567890/recommendations/NjgzMzAxODc4NS0yNDItMTc5MDQzODQxMDc1NC0rMjQxOTE1ODU2NzEtMA", "status": "dismissed" }] }
```

Dismissing runs in the same partial-failure mode as apply.

## If it fails

| Status | Cause | Fix |
|---|---|---|
| `400` | An unknown `types` value, a malformed or foreign `resourceName`, more than 100 items, or `parameters` with other than one known key | Fix the named field. |
| `404` | The `accountId` is not visible to your API key | Check the id against [List accounts](/accounts/list-accounts). |
| `422` | No Google Ads customer on the connection, or it needs reconnecting | Reconnect the account ([Connect](/platforms/google-ads#connect)). |
| `429` | The per-user burst limit or Google's quota ([quotas](/platforms/google-ads/reference#quotas-and-the-ops-budget)) | Retry after the window or `details.resetsAt`. |
| `501` | The account is not a Google Ads connection | Recommendations are Google-only; use a `googleads` account. |

A `failed` item inside a `200` is Google refusing that one recommendation. Usually it has expired, or the account changed since it was generated.

Read the list again and act on the current set.

## Related

- [Conversions](/platforms/google-ads/conversions#conversion-goals): the goals that bidding recommendations optimize toward.
- [Limits and errors](/platforms/google-ads/reference): quotas and what the API cannot do.
- [List Google Ads recommendations](/ad-campaigns/list-google-recommendations), [Apply Google Ads recommendations](/ad-campaigns/apply-google-recommendations) and [Dismiss Google Ads recommendations](/ad-campaigns/dismiss-google-recommendations): every field.