Paid-media campaign lifecycle
Erdo can read a connected ad account in full — campaigns, spend, status, keywords — and it can also act on a campaign: pause it, enable it, or change its daily budget. The lifecycle endpoints expose exactly those three actions over/v1 (and the matching MCP tools), so an external product or script can
drive a decision the evidence argues for instead of someone performing it by
hand in the provider’s console.
Every lifecycle call goes through the same approval gate that governs
agent-proposed changes. There is one gated path into a customer’s ad account,
not two: the /v1 call files the very action an agent’s tool would file — same
action key, same input, same deduplication — and a caller with an API key is
never more trusted than an agent.
Supported providers: google_ads. Any other provider is rejected with an
unimplemented error rather than silently ignored.
The two outcomes
What happens depends on whether your organization has granted a standing always-approve policy for the action (the same standing grant you create by choosing “always allow” when deciding an agent’s approval):-
No standing policy — propose. The call does not touch the provider.
It files a pending approval request and returns
status: "pending_approval"with theapproval_request_id— accepted, not performed (202 semantics, expressed in the body). The approval appears in the activity feed and onGET /v1/approvals, stamped withsubject_resource_type: "paid_media_campaign"and the campaign’s external id so you can list everything awaiting decision about one campaign. When a human approves it — feed, CLI, orPOST /v1/approvals/{id}/decide— the exact stored action executes, under the approver’s identity. A rejection is terminal and nothing reaches the provider. -
Standing policy — execute. The call executes immediately through the same
integration handler an agent-run approval would execute, and returns
status: "executed"with the provider’s result.
Set campaign status
externalID(path) — the provider’s campaign id.provider—google_ads.customer_id— the provider account the campaign belongs to (campaign ids are only unique within an account). Required.status—pausedorenabled. Removal is deliberately not exposed: deleting a campaign is destructive, not lifecycle.reason(optional) — shown on the approval card as the why beside the what, so the approver reads the evidence, not just the action.
Set campaign daily budget
daily_budget_micros— the new daily budget in micros of the account currency (50000000= $50.00). Must be positive.
Response
Following up on a pending action
List what is awaiting decision about one campaign:always_org, with parameter constraints)
creates the standing policy that makes subsequent identical calls execute
immediately — see Approvals and Autonomy.
MCP tools
The same capability is available as MCP tools:erdo_set_paid_media_campaign_status— provider, customer id, campaign id,paused/enabled, optional reason.erdo_set_paid_media_campaign_budget— provider, customer id, campaign id, daily budget in micros, optional reason.

