Campaign .update
Pause a Campaign, or change its budget or end date, in one call.
- Action class
spend- Approval
- Asks above your rule
- Emits
Campaign.updated- Sites
- 10 sites
- Price
- Free
POST https: //api.sb/ {your-domain}/ campaigns/ update
Pauses a Campaign, or changes its budget, bid or end date on your ad account, inside your standing approval. This Verb is a sketch on the hub’s Campaign Noun.
Inputs
| Name | Type | Default | Meaning |
|---|---|---|---|
campaign | Campaign | Required | The Campaign to change. |
state | 'live' | 'paused' | 'ended' | null | paused stops delivery and keeps every Ad; ended closes it for good. Unset: unchanged. |
budget | money | null | The new total for its whole window, never per day. Unset: unchanged. |
endsAt | datetime | null | The new end. Unset: unchanged. |
targeting | Targeting | null | New targeting, in the same account-neutral fields Campaign.create takes. Unset: unchanged. |
keywords | string[] | null | For a search ad account: the full new list of searches. Unset: unchanged. |
negatives | string[] | null | For a search ad account: searches to stop showing on, added to the ones it has, such as those that spent with no signup. Unset: unchanged. |
stopRule | string | null | A new stop rule. Unset: unchanged. |
reason | string | null | Why, in one sentence. It is kept on the Action and shown in the Play’s readout. |
Outputs
| Field | Type | What null means |
|---|---|---|
campaign | Campaign | Never null. |
campaign.state | string | Never null: the state after the change. |
campaign.budget | money, in USD | Never null: the budget after the change. |
campaign.endsAt | datetime | Never null: the end after the change. |
bill | Bill | Null unless the budget went up: then the Bill for the difference, owed for the ad spend. |
Effects
- Action class
spend: an approval rule onspendcan make it wait for your OK- Modes
try: Validates the change on the ad account and returns the Campaign as it would stand; nothing changes.send: Returns a pending Action;Campaign.updatedfires when the ad account confirms the change.do: Waits for the ad account to confirm and returns the changed Campaign.
- Idempotency
Only with a key: the same
Idempotency-Keyand input return the first Action, and the same key with other input returns409. A pause or a cut is safe to repeat: a Campaign already in that state returns unchanged.- Saved or shared
Each change is a new Version of the Campaign, with its reason. A cut lowers the open Bill; a raise books a Bill for the difference.
- Emits
Campaign.updatedwith{ campaign,changed, bill, reason } - Performed by
- Price
Free on your own account. The spend is billed by the site directly: Google, LinkedIn, Meta, Microsoft, Reddit, TikTok, X.
- Standing approval
It asks you first above its seat rule, unless a standing approval covers it: a
Mandateyou grant once withMandate.authorize.
On each Venue
| Site | Fields | Formats |
|---|---|---|
| Google Search and Google Display and YouTube | objective, budget, keywords, negatives | 2 |
objective, budget, endsAt, state, targeting | 3 | |
| Facebook and Instagram | objective, budget, state | 5 |
| Bing | objective, budget, state, negatives, bid | 1 |
objective, budget, endsAt, state, bid | 3 | |
| TikTok | objective, budget, endsAt, state | 2 |
| X | objective, budget, endsAt, state, bid | 2 |
Google Search and Google Display and YouTube
Through Google Ads.
| Our field | Google Ads’s field |
|---|---|
Campaign.objective | campaign.advertising_channel_type (With a conversion goal; leads runs a SEARCH campaign bidding toward your signup conversion) |
Campaign.budget | campaign_budget.amount_micros (A daily amount in millionths: $40 is 40000000) |
Campaign.keywords | ad_group_criterion.keyword (match_type EXACT for a test) |
Campaign.negatives | campaign_criterion.negative (With the wasted search term as its keyword) |
- A day’s spend. Google may spend up to twice the daily budget on one day and holds the month to about 30.4 days of it, so your standing approval’s cap is set on the month.
- Spend. Your standing approval holds the cap; a budget change past it waits with
over-mandate.
Through LinkedIn Ads.
| Our field | LinkedIn Ads’s field |
|---|---|
Campaign.objective | adCampaign.objectiveType (leads is LEAD_GENERATION with LinkedIn’s lead form, traffic WEBSITE_VISIT, conversions WEBSITE_CONVERSION) |
Campaign.budget | adCampaign.dailyBudget or adCampaign.totalBudget ({ amount,, the amount as a decimal string; a lifetime budget runs on lifetime pacing, which LinkedIn recommends) |
Campaign.endsAt | adCampaign.runSchedule.end |
Campaign.state | adCampaign.status (draft is DRAFT, live ACTIVE, paused PAUSED) |
Campaign.targeting | adCampaign.targetingCriteria (Job titles, industries, staff count ranges and locations, each a LinkedIn targeting facet) |
- Spend. Your standing approval holds the daily and total cap; a change past it waits with
over-mandate.
Facebook and Instagram
Through Meta Ads.
| Our field | Meta Ads’s field |
|---|---|
Campaign.objective | campaign.objective (leads is OUTCOME_LEADS, traffic OUTCOME_TRAFFIC, conversions OUTCOME_SALES) |
Campaign.budget | adset.daily_budget or adset.lifetime_budget (In the account currency’s smallest unit: $40.00 is 4000) |
Campaign.state | campaign.status (live is ACTIVE, paused is PAUSED) |
- Spend. Your standing approval holds the daily and total cap; a change past it waits with
over-mandate.
Bing
Through Microsoft Ads.
| Our field | Microsoft Ads’s field |
|---|---|
Campaign.objective | campaign goal (Set in Microsoft Ads’ own screens; leads bids toward the signup conversion the import brings over) |
Campaign.budget | campaign daily budget |
Campaign.state | campaign status (live is Active, paused Paused) |
Campaign.negatives | campaign negative keywords |
Campaign.bid | ad group default bid, (lowest-cost is maximize clicks; a costPer cap is a manual CPC bid) |
- Spend. Your standing approval holds the cap; a budget change past it waits with
over-mandate.
Through Reddit Ads.
| Our field | Reddit Ads’s field |
|---|---|
Campaign.objective | campaign objective (Picked in Ads Manager: traffic sends readers to your page; leads bids toward your signup event) |
Campaign.budget | ad group budget |
Campaign.endsAt | ad group end date and time |
Campaign.state | campaign and ad group status (live is active, paused paused) |
Campaign.bid | ad group bid strategy (lowest-cost is automatic bidding; a costPer cap is a cost cap on clicks or conversions) |
- Comments on a promoted post. Stay open; each one reaches you as a Message, and your agent drafts the answer.
- Spend. Your standing approval holds the cap; a change past it waits with
over-mandate.
TikTok
Through TikTok Ads.
| Our field | TikTok Ads’s field |
|---|---|
Campaign.objective | campaign objective_type (traffic is TRAFFIC; leads is LEAD_GENERATION with TikTok’s instant form; conversions is WEB_CONVERSIONS on your pixel) |
Campaign.budget | adgroup budget with budget_mode BUDGET_MODE_DAY (Over $20; the campaign budget stays unset unless you ask, and then it is over $50) |
Campaign.endsAt | adgroup schedule_end_time (Set with schedule_type SCHEDULE_START_END) |
Campaign.state | adgroup operation_status (live is ENABLE, paused DISABLE) |
- Spend. Your standing approval holds the cap; a change past it waits with
over-mandate.
X
Through X Ads.
| Our field | X Ads’s field |
|---|---|
Campaign.objective | campaign objective (Picked in X Ads: traffic is website traffic; engagement is post engagement) |
Campaign.budget | campaign total and daily budget |
Campaign.endsAt | ad group end time |
Campaign.state | campaign status (live is active, paused paused) |
Campaign.bid | ad group bid strategy (lowest-cost is autobid; a costPer cap is a target cost) |
- Spend. Your standing approval holds the cap; a change past it waits with
over-mandate.
What try does
| Account | What try does |
|---|---|
| Google Ads | Sends every change with validate_only set: Google Ads checks the whole build and returns any error, and creates nothing. |
| LinkedIn Ads | Reads your ad account, the matched count of each audience and the targeting facets, and checks the campaign against LinkedIn’s budget minimums; LinkedIn has no validate-only call, so nothing is sent to it and nothing is created. |
| Meta Ads | Sends the whole build with Meta’s validate_only execution option: Meta runs every check and creates nothing, and the response names any field it would reject. |
| Microsoft Ads | Returns what the import would bring over, term by term with the budget it would set, and the steps the browser agent would take; no session opens and nothing changes. |
| Reddit Ads | Returns the campaign and the promoted post as Ads Manager will hold them, with the steps the browser agent would take; no session opens and nothing is created. |
| TikTok Ads | Returns the Spark Ad and its ad group as Ads Manager will hold them, checked against TikTok’s budget floors, with the steps the browser agent would take; nothing is created. |
| X Ads | Returns the promotion as X Ads will hold it, with the steps the browser agent would take; no session opens and nothing is promoted. |
Refuses when
| Check | Error | Fix | Then call |
|---|---|---|---|
| A landing page fails its status or Price check | landing | Fix what the reason names, then turn the Play back on. | Campaign.update |
Every call through an account can also meet the shared account refusals: grant-missing, needs-reauth, account-not-connected, over-mandate, quota-reached, venue-rejected.
The landing payload
{
"type": "https://startupbuilder.dev/errors/landing" ,
"title": "Landing",
"status": 422,
"detail": "A landing Page fails its status or Price check.",
"fix": "Fix what the reason names, then turn the Play back on." ,
"next": {
"verb": "Campaign.update",
"input": {}
},
"instance": "https://api.sb/leaseline.app/actions/action_1"
}When it waits
| Fact | Value |
|---|---|
send returns | A pending Action until the ad account confirms the change; a raise over your approval rule waits for an Approval first. |
| Delivered by | Campaign.updated |
Example
Pause the LinkedIn test: it has spent $61.20 for one lead, over the $40
stop rule.To retry, send the same Idempotency-Key: the retry returns the first answer for $0. A new key reads again.
Test values
A sk_test_ key answers these the same way every time, at $0 (every test value).
| Test value | Always returns | What it is for |
|---|---|---|
campaign_test_linkedin | Refuses with over-mandate | A raise to $999,999 is over the Limit of every test standing approval, so it refuses and the test Campaign keeps its budget. |
maxCost: | Refuses with max-cost | Any priced call with a maxCost of 0.0001 is refused before it spends: the price is above the cap. |
rate-limited.test | Refuses with rate-limited | Any call naming this hostname answers 429 with Retry-After, so your retry logic runs. |
sources-busy.test | Refuses with sources-busy | Any call naming this hostname answers 503 as if every route were busy, and nothing is spent. |
Used by
- Jobs: Run ads
- Integrations: Google Ads · LinkedIn Ads · Meta Ads · Microsoft Ads · Reddit Ads · TikTok Ads · X Ads