The campaign creation wizard is split into 4 steps , each backed by its own
PATCH endpoint. You can update any step independently — the draft always saves,
and the response tells you about any validation issues.
Step Endpoint What you edit 1 PATCH /api/v1/campaigns/drafts/{id}/campaign-settingsBudget, bidding, targeting, schedule 2 PATCH /api/v1/campaigns/drafts/{id}/ad-groupsAd groups and their keywords 3 PATCH /api/v1/campaigns/drafts/{id}/adsResponsive Search Ads (headlines, descriptions) 4 PATCH /api/v1/campaigns/drafts/{id}/extensionsSitelinks, callouts, phone, snippets
All four endpoints share the same response format — the full refreshed draft
plus a warnings array for the current step. Data always saves even when
warnings are present; warnings are informational only.
Authentication
Every request requires a valid Bearer token from an approved user who has
access to the draft.
Authorization: Bearer < access_toke n >
All step endpoints return DraftStepResponseSchema:
draft
CampaignDraftSchema
required
The full campaign draft after the update, with all related objects (ad groups,
keywords, RSAs, extensions) prefetched.
Validation warnings for this step. Each warning contains: Show Warning object fields
JSON path to the problematic field (e.g. "daily_budget_micros").
Machine-readable error code (e.g. "REQUIRED", "INVALID_RANGE").
Human-readable description of the issue.
Step 1 — Campaign Settings
PATCH /api/v1/campaigns/drafts/{draft_id}/campaign-settings
Update campaign-level settings. Only provided fields are changed — omitted
fields stay untouched.
Request fields
Internal draft name (1–128 characters).
The campaign name visible in Google Ads.
Daily budget in micros (1 000 000 micros = 1 currency unit).
Bidding strategy configuration.
Default keyword match type ("BROAD", "PHRASE", "EXACT").
Google Ads language criterion IDs.
Search / Display network toggles.
Day-of-week and hour bid adjustments.
Campaign start date (YYYY-MM-DD).
Campaign end date (YYYY-MM-DD).
Conversion goal configurations.
Example
curl -X PATCH https://dev-api.cattix.com/api/v1/campaigns/drafts/42/campaign-settings \
-H "Authorization: Bearer $TOKEN " \
-H "Content-Type: application/json" \
-d '{
"campaign_name": "Summer Sale 2026",
"daily_budget_micros": 5000000,
"start_date": "2026-06-01",
"end_date": "2026-08-31"
}'
{
"draft" : {
"id" : 42 ,
"name" : "CATTIX | 2026-02-10 | car" ,
"campaign_name" : "Summer Sale 2026" ,
"daily_budget_micros" : 5000000 ,
"start_date" : "2026-06-01" ,
"end_date" : "2026-08-31" ,
"..." : "..."
},
"warnings" : [
{
"field" : "bidding_strategy" ,
"code" : "REQUIRED" ,
"message" : "Bidding strategy is required"
}
]
}
Step 2 — Ad Groups
PATCH /api/v1/campaigns/drafts/{draft_id}/ad-groups
Bulk-patch ad groups and their nested keywords in one request. Each item
identifies the ad group by id.
Request fields
ad_groups
PatchAdGroupItem[]
required
Array of ad group patches. Show Ad group item fields
ID of the ad group to update.
Default CPC bid in micros.
Nested keyword patches for this ad group. ID of the keyword to update.
"BROAD", "PHRASE", or "EXACT".
Keyword-level CPC bid in micros (overrides ad group bid).
Landing page URL for this keyword.
Example
curl -X PATCH https://dev-api.cattix.com/api/v1/campaigns/drafts/42/ad-groups \
-H "Authorization: Bearer $TOKEN " \
-H "Content-Type: application/json" \
-d '{
"ad_groups": [
{
"id": 988,
"name": "Brand Terms",
"cpc_bid_micros": 750000,
"keywords": [
{ "id": 27467, "text": "cattix crm", "match_type": "PHRASE" },
{ "id": 27468, "cpc_bid_micros": 1000000 }
]
}
]
}'
{
"draft" : { "id" : 42 , "..." : "..." },
"warnings" : [
{
"field" : "ad_groups[fa8820c2-d5fd-4ba6-9f78-0f4804df94a9].keywords" ,
"code" : "REQUIRED" ,
"message" : "Ad group 'Brand Terms' must have at least one keyword"
}
]
}
If a referenced ad group or keyword ID does not belong to the draft, the
endpoint returns 404 with details about which IDs are missing.
Step 3 — Ads
PATCH /api/v1/campaigns/drafts/{draft_id}/ads
Bulk-patch Responsive Search Ads (RSAs). Each item identifies the RSA by id.
Request fields
Array of RSA patches. Array of headline objects with text and optional pinned_field.
Array of description objects with text and optional pinned_field.
Mobile-specific landing page URL.
First display path segment (max 15 chars).
Second display path segment (max 15 chars).
Tracking URL template with {lpurl} placeholder.
Example
curl -X PATCH https://dev-api.cattix.com/api/v1/campaigns/drafts/42/ads \
-H "Authorization: Bearer $TOKEN " \
-H "Content-Type: application/json" \
-d '{
"responsive_search_ads": [
{
"id": 3315,
"headlines": [
{ "text": "CATTIX" },
{ "text": "Source Inventory Smarter" },
{ "text": "Get Started for Free" }
],
"final_url": "https://cattix.com/research-pro"
}
]
}'
{
"draft" : { "id" : 42 , "..." : "..." },
"warnings" : [
{
"field" : "rsas.final_url" ,
"code" : "REQUIRED" ,
"message" : "2 RSA(s) are missing final_url. Please set landing page URLs."
}
]
}
Step 4 — Extensions
PATCH /api/v1/campaigns/drafts/{draft_id}/extensions
Update the draft’s ad extensions (sitelinks, callouts, phone, structured
snippets).
Request fields
Extensions configuration object. 2–20 sitelink extensions, each with link_text, final_url, and optional
description_1 / description_2.
Up to 20 callout extensions, each with callout_text.
Phone extension with country_code and phone_number.
Structured snippet extensions with header and values.
Example
curl -X PATCH https://dev-api.cattix.com/api/v1/campaigns/drafts/42/extensions \
-H "Authorization: Bearer $TOKEN " \
-H "Content-Type: application/json" \
-d '{
"extensions": {
"sitelinks": [
{ "link_text": "Pricing", "final_url": "https://example.com/pricing" },
{ "link_text": "Contact Us", "final_url": "https://example.com/contact" }
],
"callouts": [
{ "callout_text": "Free Trial" },
{ "callout_text": "24/7 Support" }
]
}
}'
{
"draft" : { "id" : 42 , "..." : "..." },
"warnings" : []
}
How warnings work
Every step endpoint runs its own set of validators after saving. This means:
Your changes are always persisted , even if warnings appear.
Warnings highlight issues that would block campaign submission (e.g. missing
budget, too few keywords).
You can safely save incomplete data and come back later — the wizard is
designed for iterative editing.
Typical warnings
Warning object
Step Field Code Message Campaign Settings bidding_strategyREQUIREDBidding strategy is required Campaign Settings daily_budget_microsREQUIREDDaily budget is required Campaign Settings end_dateINVALID_RANGEEnd date must be after start date Ad Groups ad_groups[{temp_id}].keywordsREQUIREDAd group '' must have at least one keyword Ads rsasREQUIREDAt least one completed RSA is required Ads rsas.final_urlREQUIRED RSA(s) are missing final_url. Please set landing page URLs. Extensions extensions.sitelinksMIN_COUNTAt least 2 sitelinks are required when sitelinks are provided
{
"field" : "bidding_strategy" ,
"code" : "REQUIRED" ,
"message" : "Bidding strategy is required"
}
Warnings do not prevent saving. Treat them as a checklist the user should
resolve before submitting the campaign for review.