Ads
Audiences, Campaigns and Ads on your own Meta, Google, Bing, LinkedIn, Reddit, X and TikTok ad accounts, spent only under a standing approval.
- System
- Ads
- Nouns
- 4
- Verbs
- 6
- Events
- 6
You, to your agent
Add the third ad to the LinkedIn test: the renewal-notice angle, with the checklist image.
curl -X POST "https: //api.sb/ leaseline.app/ ads/ create? mode= try" \
-H "Authorization: Bearer $SB_TOKEN" \
-H "Content-Type: application/ json" \
-d '{"campaign": "campaign_Li4tX9pQ2w", "format": "image", "headline": "Every renewal notice, 60 days out, for every owner", "body": "Leaseline tracks rent and lease renewals for property managers with 20 to 400 units. $149 a month per portfolio.", "media": ["file_Rn6cK2vT8m"], "landingUrl": "https: //leaseline.app/ renewals", "cta": "learn-more", "variant": "renewal-notice"}'
npx startup-builder do Ad.create --try --data '{"campaign": "campaign_Li4tX9pQ2w", "format": "image", "headline": "Every renewal notice, 60 days out, for every owner", "body": "Leaseline tracks rent and lease renewals for property managers with 20 to 400 units. $149 a month per portfolio.", "media": ["file_Rn6cK2vT8m"], "landingUrl": "https: //leaseline.app/ renewals", "cta": "learn-more", "variant": "renewal-notice"}'
{
"name": "do",
"arguments": {
"mode": "try",
"code": "return await $.Ad.create({ campaign: 'campaign_Li4tX9pQ2w', format: 'image', headline: 'Every renewal notice, 60 days out, for every owner', body: 'Leaseline tracks rent and lease renewals for property managers with 20 to 400 units. $149 a month per portfolio.', media: ['file_Rn6cK2vT8m'], landingUrl: 'https: //leaseline.app/ renewals', cta: 'learn-more', variant: 'renewal-notice' })"
}
}
import { $ } from 'startup-builder'
const result = await $.try.Ad.create({ campaign: 'campaign_Li4tX9pQ2w', format: 'image', headline: 'Every renewal notice, 60 days out, for every owner', body: 'Leaseline tracks rent and lease renewals for property managers with 20 to 400 units. $149 a month per portfolio.', media: ['file_Rn6cK2vT8m'], landingUrl: 'https: //leaseline.app/ renewals', cta: 'learn-more', variant: 'renewal-notice' })
Response
{
"api": "https: //api.sb/ leaseline.app",
"ad": {
"$type": "Ad",
"campaign": "https: //api.sb/ leaseline.app/ campaigns/ campaign_Li4tX9pQ2w",
"format": "image",
"variant": "renewal-notice",
"state": "inReview",
"landingUrl": "https: //leaseline.app/ renewals? utm_source= linkedin& utm_medium= paid& utm_campaign= campaign_Li4tX9pQ2w& utm_content= renewal-notice",
"spend": null,
"outside": null
},
"action": {
"operation": "Ad.create",
"mode": "try",
"status": "done"
}
}
Try mode reads, stores nothing and spends nothingAPI referenceIts Nouns
Nouns
| Noun | What it is |
|---|---|
| Campaign | A Campaign is a bounded effort toward a Goal, with a budget, a window, and the Ads or Messages it sends to Audiences. |
| Ad | An Ad is one paid or house placement promoting an offer to an Audience, in a format such as search, display, or video. |
| Audience | An Audience is a saved query over Visitors, leads, Prospects, or customers, used to target Ads and Messages. |
| Demand Budget | A Demand Budget is the money a founder commits each month to demand Plays, recorded as a Decision with a target and a stop rule. |
Properties
The hub defines each Noun’s core Properties; Ads adds the ones a sale needs.
Campaign
| Property | Type | What it holds | Defined by |
|---|---|---|---|
budget | money | What it may spend. | The hub |
startsAt | datetime | When it starts. | The hub |
endsAt | datetime | When it ends. | The hub |
venue | VenueId | Where it runs, such as facebook or linkedin. | Ads |
state | 'draft' | 'live' | 'paused' | 'ended' | Where it stands on the ad account. | Ads |
stopRule | string | The reading that pauses it, read each day from your own results. | Ads |
bill | Bill | The budget, booked as a Bill you owe the site. | Ads |
Ad
| Property | Type | What it holds | Defined by |
|---|---|---|---|
format | string | One of search, display, image, or video. | The hub |
spend | money | What it has cost so far. | The hub |
review | 'pending' | 'approved' | 'rejected' | The site’s review; a rejected Ad comes back with the site’s reason. | Ads |
headline | string | At the site’s length, such as 27 characters on a Meta feed ad. | Ads |
landingUrl | string | The page it sends clicks to; it must answer before the Ad is created. | Ads |
Audience
| Property | Type | What it holds | Defined by |
|---|---|---|---|
size | integer | How many people match. | The hub |
matched | integer | How many members the ad account matched, as it reports. | Ads |
Demand Budget
| Property | Type | What it holds | Defined by |
|---|---|---|---|
amount | money | The monthly spend it funds; zero is the default. | The hub |
tier | string | One of $0, $100, $1k, $10k or $100k: the highest tier at or below the amount, whose Play mix it buys. | The hub |
target | string | The Metric value the spend must reach, such as cost per first Order under $40. | The hub |
stopRule | string | The reading that closes the budget, such as acquisition cost above margin for two weeks. | The hub |
until | date | The last day the budget runs before its Decision is read. | The hub |
status | string | One of Open, Stopped or Closed. A closed budget is kept with its Evidence. | The hub |
Lifecycle
Every move names the Verb that makes it, or the Event it waits on.
Campaign
| State | What it means | Moves to |
|---|---|---|
draft | On the ad account, not serving: its first Ad has not passed review. | live on Ad.updated; ended by Campaign.update |
live | Serving and spending inside its budget and your standing approval. | paused by Campaign.update; ended by Campaign.update |
paused | Stopped by its stop rule or by you; its spend so far is booked. | live by Campaign.update; ended by Campaign.update |
ended | Past its end date, or closed; its results stay readable. | None: it ends here. |
Verbs
| Verb | What it does | Approval | On each site | Limits |
|---|---|---|---|---|
Campaign.create | Opens a Campaign on your connected ad account, with its budget, window and stop rule, and books the budget as a Bill. | Asks you first above its seat rule | Google Search, Google Display, YouTube, LinkedIn, Facebook, Instagram, Bing, Reddit, TikTok, X | The budget is booked as a Bill; over your approval rule it asks first unless a standing approval covers it. |
Campaign.update | Pauses a Campaign, or changes its budget, bid or end date on your ad account, inside your standing approval. | Asks you first above its seat rule | Google Search, Google Display, YouTube, LinkedIn, Facebook, Instagram, Bing, Reddit, TikTok, X | A raise past your standing approval waits with over-mandate. |
Ad.create | Builds one ad in a Campaign on your connected ad account; it runs once the site’s review passes. | Goes out on its own | Google Search, Google Display, YouTube, LinkedIn, Facebook, Instagram, Bing, Reddit, TikTok | Every new Ad passes the site’s own review before it serves. |
Audience.create | Matches a list from your records, such as your waitlist, to an Audience on your ad account, every email hashed first. | Runs on its own | Google Search, Google Display, YouTube, LinkedIn, Facebook, Instagram | None. |
Mandate.spend | Pays an outside party with a single-use card, inside your standing approval. | Asks you first above its seat rule | None. | None. |
Ad.update | Changes an Ad’s copy, creative or status; a changed Ad goes back through the site’s review. | Runs on its own | None. | None. |
A Verb that asks you first runs on its own inside a standing approval: a Mandate you grant once with Mandate.authorize.
Events
| Event | Emitted by |
|---|---|
Campaign.created | Campaign.create |
Campaign.updated | Campaign.update |
Ad.created | Ad.create |
Ad.updated | Ad.update |
Audience.created | Audience.create |
Mandate.spent | Mandate.spend |
A Trigger can start a Workflow on any of them, and a Watch delivers each to your endpoint, signed (Events and webhooks).
Who operates it
| Part | Ads |
|---|---|
| Accountable | Paid Media Manager |
| Also calls its Verbs | Marketing lead |
| Seat | An agent holds each seat until you seat a person in it. |
| Asks you first | Campaign.create, Campaign.update, Mandate.spend, unless a standing approval covers it |
Integrations
Meta Ads · Google Ads · Microsoft Ads · LinkedIn Ads · Reddit Ads · X Ads · TikTok Ads
Import and export
| Direction | What | How |
|---|---|---|
| Import | Campaigns already on your ad account | Integration.sync reads them in as Campaigns and Ads, with their spend to date |
| Export | Spend and results by Ad and day | Metric.query, or Collection.export to your warehouse |
Example
A $100 test that pauses its own losers.
Campaign.createopens a one-week Campaign on Meta with $100 and a stop rule: pause an Ad past $15 with no trial.Ad.createadds four Ads, one per angle; Meta rejects one for implying a guaranteed result, and it is rewritten.- On day 3, two Ads pass $15 with no trial.
Campaign.updatepauses them and moves their $39 to the leaders. Metric.queryreads trials per dollar from your own account each day until the winner rule names one.