> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cattix.com/llms.txt
> Use this file to discover all available pages before exploring further.

# RSA Auto-Regeneration

> How Responsive Search Ads are automatically regenerated when ad groups or keywords change

<Note>
  Ця сторінка також доступна [українською](/guides/rsa-auto-regeneration-uk).
</Note>

When a user edits ad groups or keywords in the campaign draft wizard, the
backend can automatically regenerate Responsive Search Ads (RSAs) so they stay
aligned with the current ad group content. This happens via **background tasks**
— the API returns immediately and RSAs are generated asynchronously.

## How it works

Every ad group and keyword mutation endpoint accepts an optional query parameter:

```
?regenerate_rsas=true   (default)
?regenerate_rsas=false  (opt out)
```

When `regenerate_rsas=true` (the default) **and** the mutation affects
RSA-relevant fields, the backend:

1. Resolves the company name and description from the linked `AssistantKnowledgeItem`
2. Collects the active (non-deleted) keywords for each affected ad group
3. Enqueues a background `generate_rsas_for_ad_group` task per affected ad group
4. Returns the normal response immediately — RSA generation happens asynchronously

<Note>
  If no company is linked to the draft's Google Ads customer, RSA regeneration is
  silently skipped. This can happen for newly connected accounts that don't have a
  company entity yet.
</Note>

***

## Which endpoints trigger it

### Endpoints with auto-regeneration

| Endpoint                                             | Method   | Triggers RSA regen when...                             |
| ---------------------------------------------------- | -------- | ------------------------------------------------------ |
| `.../drafts/{id}/ad-groups`                          | `PATCH`  | Ad group **name** changes, or keyword **text** changes |
| `.../drafts/{id}/ad-groups`                          | `POST`   | New ad group is created **with at least one keyword**  |
| `.../drafts/{id}/ad-groups/{ag_id}`                  | `PUT`    | Ad group **name** changes                              |
| `.../drafts/{id}/ad-groups/{ag_id}/keywords`         | `POST`   | Always (new keyword added)                             |
| `.../drafts/{id}/ad-groups/{ag_id}/keywords/{kw_id}` | `PUT`    | Keyword **text** changes                               |
| `.../drafts/{id}/ad-groups/{ag_id}/keywords/{kw_id}` | `DELETE` | Always (keyword removed)                               |

### What does NOT trigger regeneration

These changes are **not** considered RSA-relevant:

* Changing `cpc_bid_micros` on an ad group or keyword
* Changing a keyword's `match_type`
* Changing a keyword's `final_url`
* Creating an ad group **without** keywords

<Tip>
  The rule of thumb: RSAs are regenerated when the **content** that goes into ad
  copy changes (ad group name, keyword text, keyword presence). Bid and targeting
  changes don't affect ad copy.
</Tip>

***

## Opting out

Pass `?regenerate_rsas=false` on any of the above endpoints to skip automatic
regeneration. Use this when:

* The user is making rapid batch edits and you plan to trigger regeneration
  manually at the end
* You're only updating bids or metadata and want to guarantee no background
  tasks fire
* The user has manually edited RSA copy and doesn't want it overwritten

<CodeGroup>
  ```bash cURL theme={null}
  # Rename an ad group without regenerating RSAs
  curl -X PATCH "https://dev-api.cattix.com/api/v1/campaigns/drafts/42/ad-groups?regenerate_rsas=false" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "ad_groups": [
        { "id": 988, "name": "Updated Brand Terms" }
      ]
    }'
  ```

  ```typescript TypeScript theme={null}
  // Rename an ad group without regenerating RSAs
  const resp = await fetch(
    `${API_BASE}/api/v1/campaigns/drafts/42/ad-groups?regenerate_rsas=false`,
    {
      method: "PATCH",
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        ad_groups: [{ id: 988, name: "Updated Brand Terms" }],
      }),
    }
  );
  ```
</CodeGroup>

***

## Manual regeneration endpoints

You can also trigger RSA generation explicitly, regardless of the
`regenerate_rsas` flag:

| Endpoint                                              | What it does                                     |
| ----------------------------------------------------- | ------------------------------------------------ |
| `POST .../drafts/{id}/ad-groups/{ag_id}/rsa/generate` | Generate RSAs for a single ad group              |
| `POST .../drafts/{id}/rsas/generate-all`              | Generate RSAs for **all** ad groups in the draft |

Both endpoints require **no request body** — company name, description, and
landing page URL are auto-resolved from the draft's linked company and
`AssistantKnowledgeItem`. Both return a `task_id` for polling. RSAs are created
asynchronously by the background worker.

<Note>
  If no company is linked to the draft's Google Ads customer, these endpoints
  return **400** with an error message. This differs from auto-regeneration (which
  silently skips).
</Note>

***

## Quick reference: decision flowchart

```
Mutation request arrives
  │
  ├─ regenerate_rsas=false? ──► Skip. Done.
  │
  ├─ Was an RSA-relevant field changed?
  │    │
  │    ├─ Ad group name changed?        ──► Yes ──► Regenerate for that ad group
  │    ├─ Keyword text changed?         ──► Yes ──► Regenerate for parent ad group
  │    ├─ Keyword created?              ──► Yes ──► Regenerate for parent ad group
  │    ├─ Keyword deleted?              ──► Yes ──► Regenerate for parent ad group
  │    ├─ Ad group created w/ keywords? ──► Yes ──► Regenerate for new ad group
  │    └─ Only bids/match_type/url?     ──► No  ──► Skip
  │
  └─ Enqueue background task(s)
       └─ Response returned immediately
```

<Warning>
  Auto-regeneration **replaces** existing RSAs for the affected ad groups. If the
  user has manually edited RSA headlines or descriptions, those edits will be
  overwritten. Use `?regenerate_rsas=false` to preserve manual edits.
</Warning>
