update_campaign_status
Pause, resume, or remove a campaign. Supports Google Ads and Meta Ads today; TikTok mutations aren’t yet implemented.
When preview=true, this returns the before/after diff without calling the platform API. When preview=false, it mutates the live campaign and automatically writes a DecisionLogEntry with entry_type="edit", created_via="tool", and a short fingerprint of the calling API key in metadata. This is what closes the causal loop for get_impact_analysis.
If the campaign is already in the target status, the call is a no-op: changed: false, no platform call, no decision logged.
Parameters#
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
ad_account_id | string | yes | Ad account id | |
campaign_id | string | yes | Platform campaign id (from list_campaigns) | |
status | string | yes | One of "enabled", "paused", or "removed" (canonical, translated per platform) | |
preview | boolean | no | false | When true, compute the local diff only; don’t mutate the platform |
Platform status mapping#
| Canonical | Meta | |
|---|---|---|
enabled | ACTIVE | ENABLED |
paused | PAUSED | PAUSED |
removed | delete | remove |
Returns#
json
{
"ad_account_id": "ad_acct_abc",
"campaign_id": "c1",
"campaign_name": "Retargeting - Core",
"platform": "meta_ads",
"preview": false,
"changed": true,
"applied": true,
"diff": { "status": { "before": "enabled", "after": "paused" } },
"decision_id": "decentry_TBcROKMXAp3AZcbPxTwQaFVB",
"platform_response": { "id": "c1", "status": "PAUSED" },
"source": "adlyse.ads_writes@v1"
}| Field | Description |
|---|---|
preview | true = no platform call was made; false = live mutation |
changed | false if the campaign was already in the target status — no-op |
applied | true only when a platform call succeeded and a decision was logged |
diff.status.before | Campaign’s status as of the latest sync |
decision_id | Id of the auto-logged DecisionLogEntry; null on preview or no-op |
platform_response | Raw response from the platform’s mutation API |
Errors#
error_type | When |
|---|---|
auth_error | Missing / invalid API key |
validation_error | status not in {enabled, paused, removed} |
not_found | Ad account doesn’t belong to your org, or campaign isn’t synced under this account |
unsupported_for_platform | Ad account is on TikTok |
credentials_missing | Ad account has no linked OAuth credentials; reconnect it |
platform_error | Platform API rejected the mutation; no decision is logged on failure |
Example: preview then apply#
Preview request:
json
{
"ad_account_id": "ad_acct_abc",
"campaign_id": "c1",
"status": "paused",
"preview": true
}Preview response:
json
{
"campaign_id": "c1",
"platform": "meta_ads",
"preview": true,
"changed": true,
"applied": false,
"diff": { "status": { "before": "enabled", "after": "paused" } },
"decision_id": null,
"source": "adlyse.ads_writes@v1"
}Apply request:
json
{
"ad_account_id": "ad_acct_abc",
"campaign_id": "c1",
"status": "paused",
"preview": false
}Apply response:
json
{
"campaign_id": "c1",
"platform": "meta_ads",
"preview": false,
"changed": true,
"applied": true,
"diff": { "status": { "before": "enabled", "after": "paused" } },
"decision_id": "decentry_TBcROKMXAp3AZcbPxTwQaFVB",
"platform_response": { "id": "c1", "status": "PAUSED" },
"source": "adlyse.ads_writes@v1"
}See also#
update_campaign_budget— change daily budget- Decision Log — how these entries feed impact analysis