Add & Edit Campaign Elements — Native / Channel-First (N×N×N)
add_and_edit_native_campaign_elementsAdd elements to, and edit campaign-level fields of, an existing Channel-First / Native (N×N×N) campaign — the one built with create_native_structure_campaign (channel.structureType=NATIVE, WizNativeAdContainer). This is the NATIVE counterpart of add_and_edit_campaign_elements: that tool edits Precision (1×1×1 / METADATA) campaigns; THIS tool edits Native (N×N×N) campaigns.
CRITICAL: PICK THE TOOL BY THE CAMPAIGN'S STRUCTURE (not by user phrasing):
• Native / Channel-First / Platform-First / N×N×N campaign → THIS tool (`add_and_edit_native_campaign_elements`).
• Precision Optimization / 1×1×1 / METADATA campaign → `add_and_edit_campaign_elements`.
Both tools guard: call THIS tool on a Precision/METADATA campaign and it returns an error telling you to use `add_and_edit_campaign_elements`, and vice-versa. So if you guess wrong, the error tells you the right one — no silent mis-write. If you don't know the structure, check the campaign first (its channels' structureType) or just try and follow the redirect.
WHAT THIS TOOL DOES:
- EDIT campaign-level fields: name, budgetGroup, startDate, endDate (same smart/partial semantics as the flat tool — only pushed when different / supplied).
- ADD new containers: each channel's `containers[]` APPENDS new WizNativeAdContainers (one audience × an `ad_offers` list of {ad, offer} pairs each, same shape as `create_native_structure_campaign`). Existing containers are PRESERVED — the channel's current container list is re-POSTed with the new ones appended.
- ADD bare target groups: each channel's optional `target_groups[]` (names) attaches targeting groups to the native channel without a full container (places targetingGroupId on a reused/appended ad-less container).
- ATTACH negative keyword lists (Google Ads / Microsoft Ads only): the search channel block's optional `negative_keyword_lists[]` (names of EXISTING lists) attaches them channel-wide — valid with or without new containers. Names inside `containers[].negative_keyword_lists` are unioned in and applied at the same channel level. A name that doesn't resolve on the channel is reported in `errors[]`, never silently skipped.
- EDIT existing containers (PER CONTAINER): each channel's optional `modify_containers[]` targets an existing container by `name` and, within it, deletes specific Ad—Offer rows (`remove_ads`), clears an offer from one ad while keeping it on the OTHER ads (`clear_offers_on_ads`), removes this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience`), or deletes the whole container (`delete_container`). This is the surgical counterpart to the channel-wide remove_* tools — use it when an audience/offer/ad is shared across containers and you only want to touch one. Removing a group clears it on that one container; a group reused by other containers stays alive for them.
WHAT THIS TOOL DOES NOT DO:
- It does not switch a campaign's structure (that's fixed at creation).
- For a change that spans ALL ads (remove an offer/ad everywhere it appears on the channel), use the channel-wide removal tools (remove_offers_from_campaign / remove_ad_from_campaign / remove_audiences_from_campaign / remove_target_groups_from_campaign / remove_keywords_from_campaign); `modify_containers` is only for a specific container/row.
CONTAINER RULES (same as create_native_structure_campaign):
- Each container is one audience × a LIST of (ad, offer) pairs (`ad_offers`, 1+). Group several ads/offers under one audience by adding pairs — e.g. 3 ads on the same offer = 3 pairs that repeat the same `offer` id. Send two containers only to run the audience as two separate ad-sets.
- `audience` / `exclude_audience` / `target_group` are NAMES (resolved server-side); the `ad` / `offer` inside each `ad_offers` pair are integer IDs.
- Audience names are resolved BEFORE anything is created: a container whose `audience` cannot be resolved is dropped with an error in `errors[]` that states whether retrying can help ("may still be matching") or not ("not available on this channel"); no keyword group or other element is left behind for a dropped container.
- `audience` is REQUIRED for LinkedIn/Facebook/Instagram/Reddit; OPTIONAL for Google/Microsoft search containers (keyword-only is valid — provide `keywords`/`keyword_ids` instead).
- Offer–channel lock still applies: a Lead Gen offer must be locked to the container's channel (LinkedIn→LINKEDIN, etc.); Google takes Landing Page offers only; Landing Page offers are universal.
RESPONSE: same top-level shape as `add_and_edit_campaign_elements` (success, campaign_id, changes {renamed, budget_group_reassigned, schedule_updated}, added_summary per channel {containers, target_groups, negative_keyword_lists, and — when modify_containers is used — ads_removed, offers_cleared, containers_deleted, audiences_removed, target_groups_removed, keywords_removed, excludes_removed}, optimization_group, campaign_url, full_response). On partial failures, success=false plus `errors[]`; the rest of the edit still proceeds.
EXAMPLE (append a LinkedIn container + rename):
add_and_edit_native_campaign_elements(campaign_data={
"campaignId": 159490,
"name": "Q3_ABM_Native_v2",
"linkedin": {"containers": [
{"name": "VPs > Demo > Form", "audience": "VPs - NA", "ad_offers": [{"ad": 156502, "offer": 57538}]}
]}
})
EXAMPLE (append a Google keyword-only container + bare target group):
add_and_edit_native_campaign_elements(campaign_data={
"campaignId": 159490,
"google": {
"containers": [
{"name": "Incident Response", "ad_offers": [{"ad": 210804, "offer": 67269}],
"keywords": ["incident response platform"], "negative_keyword_lists": ["Competitor Brands"]}
],
"target_groups": ["Tech Decision Makers"]
}
})
EXAMPLE (ROW-LEVEL: drop the offer from ONE ad in a container, keep it on the other ads):
add_and_edit_native_campaign_elements(campaign_data={
"campaignId": 159490,
"facebook": {"modify_containers": [
{"container": "ICP > 3 creatives > TOF offer",
"clear_offers_on_ads": ["Ungated-AI-in-Finance-v2-vert_FB"]}
]}
})
EXAMPLE (PER-CONTAINER: delete one Ad—Offer row in one container; delete a whole other container):
add_and_edit_native_campaign_elements(campaign_data={
"campaignId": 159490,
"linkedin": {"modify_containers": [
{"container": "VPs > Demo > Form", "remove_ads": ["Old Creative A"]},
{"container": "Retired ad-set", "delete_container": True}
]}
})
EXAMPLE (PER-CONTAINER: drop a reused audience from ONE container, keep it on the others):
add_and_edit_native_campaign_elements(campaign_data={
"campaignId": 159490,
"facebook": {"modify_containers": [
{"container": "ICP - A2", "remove_audience": True}
]}
})Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_data | Yes | Native (N×N×N) campaign edit payload: campaignId + optional campaign-level fields + per-channel `containers[]` (append) and optional `target_groups[]`. |