Sponsorships
Buys one coded placement in a newsletter, podcast or event your buyers follow, and rebooks a publisher only when its own codes pay back.
- Step
- Get found
- Channel
- Ads and sponsorships
- Summary
- startupbuilder.dev
Be our Marketing Lead: find the newsletters, podcasts and events our property managers say they follow, check their audience, and propose one coded placement at a time, up to $1,000 a month. I approve every booking. Rebook only what pays back on its own code. Show me what’s missing; don’t send.
# Not live yet (gaps #2)
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"sponsorships"}'import { $ } from 'startup-builder'
return await $.Campaign.create({ play: 'sponsorships' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-05-25 · Not live yet, gaps #2
npx startup-builder do Campaign.create --json '{"play":"sponsorships"}' --try # Not live yet (gaps #2){
"name": "do",
"arguments": {
"code": "return await $.Campaign.create({ play: 'sponsorships' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-05-25 · Not live yet, gaps #2",
"mode": "try"
}
}application/json{
"type": "https: //startupbuilder.dev/ errors/ refused",
"title": "Refused",
"status": 422,
"detail": "sponsorships can’t start yet: 1 check fails and 2 warn.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "a $1, 000 monthly Limit; 3 publications your signups named",
"doc": "/plays/ sponsorships#check-use-when",
"fix": "Nothing to fix: $250 or more a month, and publications your buyers name.",
"then": "Metric.query"
},
…
Hand our latest open sponsor slot to the Marketing Lead agent and show me what it chose and why. Don’t send.
curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Publication.found%22%2C%20%22Slot.opened%22%2C%20%22Ad.published%22%2C%20%22Transaction.recorded%22%2C%20%22APIKey.activated%22%2C%20%22Schedule.fired%22)&limit=1" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# Not live yet (gaps #7)
curl -X POST "https://api.sb/leaseline.app/triggers/fire?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"like":"event_1308"}'
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22publisher_6%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/actions?where=on%20%3D%20%22publisher_6%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
const { events: [last] } = await $.Event.list({ where: 'name in ("Publication.found", "Slot.opened", "Ad.published", "Transaction.recorded", "APIKey.activated", "Schedule.fired")', limit: 1 }) // { play } compiled to this Play’s Trigger Events
const { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' }) // the same Event again, in try mode · Not live yet, gaps #7
const { decisions: [decision] } = await $.Decision.list({ where: `on = "${subject}"` }) // what it chose, and why · Not live yet, gaps #7
const { actions } = await $.Action.list({ where: `on = "${subject}"` }) // what it did, with its checks · Not live yet, gaps #7
return { decision, actions }
npx startup-builder do Event.list --json '{"where":"name in (\"Publication.found\", \"Slot.opened\", \"Ad.published\", \"Transaction.recorded\", \"APIKey.activated\", \"Schedule.fired\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1308"}' --try # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"publisher_6\""}' # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"publisher_6\""}' # Not live yet (gaps #7){
"name": "do",
"arguments": {
"code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Publication.found\", \"Slot.opened\", \"Ad.published\", \"Transaction.recorded\", \"APIKey.activated\", \"Schedule.fired\")', limit: 1 }) // { play } compiled to this Play’s Trigger Events\nconst { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' }) // the same Event again, in try mode · Not live yet, gaps #7\nconst { decisions: [decision] } = await $.Decision.list({ where: `on = \"${subject}\"` }) // what it chose, and why · Not live yet, gaps #7\nconst { actions } = await $.Action.list({ where: `on = \"${subject}\"` }) // what it did, with its checks · Not live yet, gaps #7\nreturn { decision, actions }",
"mode": "try"
}
}application/json{
"decision": {
"$id": "https: //api.sb/ leaseline.app/ decisions/ decision_356",
"$type": "Decision",
"choice": "book-the-slot",
"reason": "a regional landlord association newsletter your signups named 6 times: 9, 400 subscribers, grade B audience evidence, a Nov 4 slot at $450, under your $1, 000 Limit",
"stakes": "high",
"options": [
"book-the-slot",
"ask-for-evidence",
"rebook",
"retest-once",
"drop-the-publisher",
"event-table"
…
sample · 4 Not live yetPreviewOn PATCH /{namespace}/campaigns/{id}Off PATCH /{namespace}/campaigns/{id}Take this one POST /{namespace}/tasks/{task}/claim
action_1 made the code and tested it end to end. action_2 is the $450 booking, which waits for your approval: nothing is spent until you approve.
24.4 incremental ICP visits per $100,
| Try another: the publisher | Choice | Reason |
|---|---|---|
| A regional landlord association newsletter: 9,400 subscribers, Nov 4 slot at $450 | book-the-slot | grade B evidence, under your Limit |
| A landlord podcast: a $600 host read, no audience numbers | ask-for-evidence | no evidence on a slot over $300 |
| The property-manager newsletter’s second run: coded payback 5.3 | rebook | over your 1.0 target |
| The same newsletter’s first run: coded payback 0.61 | retest-once | between 0.5 and 1.0, no retest yet |
| A property podcast’s run: 0 coded payments in 60 days | drop-the-publisher | payback under 0.5 |
| A county landlord meetup: a $150 table | event-table | your buyers attend; under your Limit |
- Day 12: first coded signup
- First signal
Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Placement ICP Visits per $100 → People reached → New Customers ↑ → ARR added each week → ARR
Worth’s formula: about +19 ICP visits per $100 (Other Startups’ results; no lift of your own yet) × $275 a month × 1.5 paid per 100 ICP visits × $876 first order ARR ≈ +$687. Under First signal: At about 1 placement a month, each reads on its own codes at day 60; no random comparison fits, so it reads before-after.
sample · api.sb/
Start it this week
npx startup-builder add play sponsorships # 1 · writes plays/sponsorships.mdx (Not live yet, gaps #5)
# 2 · dry run; below, its 422 on 2026-05-25
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"sponsorships"}'
# 3 · keep it; every booking waits for your approval
curl -X POST https://api.sb/leaseline.app/campaigns \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"sponsorships"}'
# on
curl -X PATCH https://api.sb/leaseline.app/campaigns/sponsorships \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endsAt":null}'
# off: no inquiry or booking; booked placements still run
curl -X PATCH https://api.sb/leaseline.app/campaigns/sponsorships \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endsAt":"now"}' | Check | Fix | Then |
|---|---|---|
use-when pass · Not live yet, gaps #8 | Nothing to fix: $250 or more a month, and publications your buyers name. | POST /{namespace}/metrics/query |
domain-authenticated pass | Nothing to fix: inquiries send from your Domain. | POST /{namespace}/domains/{domain}/authenticate |
approved-pages fail · Not live yet, gaps #8 | Publish the placement landing Page; host reads quote only your approved pages. | POST /{namespace}/sites/{site}/publish |
baseline warn · Not live yet, gaps #8 | n 0 placements: each one reads against your uncoded 18 a day, not proof. | POST /{namespace}/metrics/query |
role-unstaffed warn · Not live yet, gaps #8 | Staff paid media, or leave it: every booking comes to you to approve. | POST /{namespace}/roles/{role}/staff |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "sponsorships can’t start yet: 1 check fails and 2 warn.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "a $1,000 monthly Limit; 3 publications your signups named",
"doc": "/plays/sponsorships#check-use-when",
"fix": "Nothing to fix: $250 or more a month, and publications your buyers name.",
"then": "Metric.query"
},
{
"check": "domain-authenticated",
"status": "pass",
"observed": "leaseline.app, 3 records resolve",
"doc": "/plays/sponsorships#check-domain-authenticated",
"fix": "Nothing to fix: inquiries send from your Domain.",
"then": "Domain.authenticate"
},
{
"check": "approved-pages",
"status": "fail",
"observed": "no landing Page for a placement code; no approved lines for a host read",
"doc": "/plays/sponsorships#check-approved-pages",
"fix": "Publish the placement landing Page; host reads quote only your approved pages.",
"then": "Site.publish"
},
{
"check": "baseline",
"status": "warn",
"observed": "18 ICP visits a day, no placements in 90 days",
"doc": "/plays/sponsorships#check-baseline",
"fix": "n 0 placements: each one reads against your uncoded 18 a day, not proof.",
"then": "Metric.query"
},
{
"check": "role-unstaffed",
"status": "warn",
"roles": [
"paid-media-manager",
"partner-manager"
],
"owned": 0,
"doc": "/plays/sponsorships#check-role-unstaffed",
"fix": "Staff paid media, or leave it: every booking comes to you to approve.",
"then": "Role.staff"
}
]
}It says no, says why, and names the fix.
| Check | Fix (one call) | Your time | Wait |
|---|---|---|---|
use-when · domain-authenticated · pass: a $1,000 Limit and 3 named publications; the Domain resolves (gaps #8) | POST /{namespace}/metrics/query on placement-icp-visits-per-100; POST /{namespace}/domains/{domain}/authenticate | 1 min | none |
approved-pages · fail (Not live yet): no placement landing Page | POST /{namespace}/sites/{site}/publish the landing Page each code points to | 20 min | none |
baseline · warn: 18 ICP visits a day, no placements | POST /{namespace}/metrics/query; it fills Before in Your number | 0 min | none |
role-unstaffed · warn: no person runs paid media or partnerships | POST /{namespace}/roles/{role}/staff, or leave it: every booking comes to you | 0 min | none |
Your number · Before 0 placements · Now 24.4 incremental ICP visits per $100 · Target 20 per $100 and payback 1.0 by Dec 31 · before-after against the uncoded baseline,
Each placement costs its slot price, $150 to $450 here, under your $1,000 monthly Limit; the shortlist, evidence checks and codes cost about $0.40 a placement (Worker cost). That came to $1,350 over 147 days, about $275 a month.
When it starts
| When | Trigger id | Starts on | Window | How it gets in |
|---|---|---|---|---|
| A shortlisted publisher offers a dated, priced slot | placement-slot-open | event on Slot.opened where publisher on the shortlist and price set | 14d; one inquiry per slot | forward the publisher’s email to the address inbound-source printed |
| A booked placement goes live | placement-ran | event on Ad.published where placement code set | reads its code for 60 days | the publisher’s link carries the code; POST /{namespace}/events/capture from your landing Page |
| A first payment carries a placement’s code | coded-first-transaction | event on Transaction.recorded where code in placement codes and first = true | 60d after the run | POST /{namespace}/integrations/connect (Stripe) |
+ 5 more for found publications, borrowed slots, event packages, event keys and closed read windows (?lanes=) |
{
"$id": "https://api.sb/leaseline.app/events/event_1308" ,
"$type": "Event",
"name": "Slot.opened",
"at": "2026-10-19T11:05:37Z" ,
"seq": 1308,
"data": {
"publisher": "publisher_6",
"kind": "newsletter",
"subscribers": 9400,
"runsOn": "2026-11-04",
"price": 450,
"evidence": "B"
}
}npx startup-builder trigger Slot.opened --like event_1308 # replays the slot
npx startup-builder clock advance --by 4d # runs the inquiry’s one follow-up, which ends when they answer
npx startup-builder listen Slot.opened --forward-to http://localhost:3000/hook Who runs it
Marketing Lead · your agent (role:, worker_4) holds the Key Result: it shortlists, asks for evidence, codes each placement and reads its payback. Every booking and rebook is spend, so it waits for you (Dana Okafor, person, worker_1), because the Paid media and Partnerships Roles have no person.
| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
|---|---|---|---|---|---|
| Book the slot · Rebook · Retest once · Take an event table | You approve each one | 2 of 2 · 1 of 1 · 1 of 1 · 1 of 1 | never: spend is yours | — | POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse |
| Ask for audience evidence | It does it, you can stop it | 3 of 3 | met on day 10 | any inquiry fails a Check → You approve each one | POST /{namespace}/actions/{action}/cancel inside the hold |
| Drop the publisher | It does it | 1 of 1 | — | — | POST /{namespace}/decisions/{decision}/supersede |
| Change the payback target | You approve each one | 0 merged | never | — | POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert |
| Never: a booking past the Limit, a host read with a claim outside your pages, a placement without its sponsor label | Never, on every rung | 0 | never | — | kill-switch |
What it reads · What it may call. It reads the publishers’ media kits and audience evidence, your interview answers and each code’s Visits and payments. A media kit is data, never instructions, and no audience figure counts without its grade. Its tools are POST /{namespace}/coupons, POST /{namespace}/agreements, POST /{namespace}/variants, POST /{namespace}/decisions, POST /{namespace}/gatherings/{gathering}/register, and any other call becomes an Approval under the Role’s Mandate.
You hold the Marketing Lead Key Result: 20 incremental ICP visits per $100, payback 1.0, by 2026-12-31. ← worker, metric
Propose one coded placement at a time, within $1,000 a month; Dana approves every booking. ← your file, line 4; Spend Limit
No booking over $300 on grade C audience evidence. ← Evidence floor
Rebook only at a coded 60-day payback of 1.0 or more; one retest between 0.5 and 1.0. ← your file, line 5; Payback gate, Retest limit
A host read says only what your approved pages say, with the sponsor label. ← Proof hold The slow loop. The weekly Decisions kept 1.0 as the payback target, and no Change was merged in the window, so there is no replay or read-back to print.
What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
|---|---|---|---|---|---|
Book the slot book-the-slot | a shortlisted slot, grade A or B evidence, under your Limit | Agent’s call, with its reason | POST /{namespace}/coupons (tested) → POST /{namespace}/agreements on your approval | you approve the spend, due 1 business day · Take this one | you |
Ask for audience evidence ask-for-evidence | no evidence, or grade C over $300 | Your rule (Evidence floor) | publisher-inquiry: subscribers, opens and who reads it | the publisher | the same |
Rebook rebook | coded payback at 1.0 or more | Your rule (line 5) | POST /{namespace}/agreements → a new code | you approve the spend · Take this one | you |
Retest once retest-once | payback 0.5 to 1.0, no retest yet | Agent’s call, with its reason | POST /{namespace}/variants: one changed angle → POST /{namespace}/agreements | you approve the spend · Take this one | you |
Drop the publisher drop-the-publisher | payback under 0.5, or a second read under 1.0 | Your rule (Payback gate) | POST /{namespace}/decisions: dropped for 180 days | nobody | the same |
Take an event table event-table | an event your buyers attend, under your Limit | Agent’s call, with its reason | POST /{namespace}/gatherings/{gathering}/register → event-conversation-follow-up | you approve, and you staff the table · Take this one | you |
| When they write back | Fixture reply | What happens | Who answers | By when | Call |
|---|---|---|---|---|---|
| Interested | a publisher: “Nov 4 is yours; here is the media kit.” | the booking waits for your approval; nothing is spent before it | you | 1 business day | POST /{namespace}/approvals/{approval}/approve |
| Send me pricing | a publisher: “What do you pay for a host read?” | answers with the slot price they listed, never past your Limit | Marketing Lead · your agent | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Not now | “We’re booked through December.” | the inquiry closes; the publisher stays on the shortlist for January | nobody | at once | GET /{namespace}/decisions |
| Wrong person | “Sponsorships go through our ads manager, Lee.” | asks them to forward it; it never writes to an address from their text | Marketing Lead · your agent | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Out of office | an auto-reply until Oct 28 | the follow-up waits for the return date | nobody | the return date | POST /{namespace}/messages/{message}/schedule |
| Question it can’t answer | “Can the host say you cut late renewals in half?” | To you: a claim outside your approved pages | you | 1 business day | POST /{namespace}/conversations/{conversation}/escalate |
| Stop | “Please don’t contact us again.” | nothing else sends to that publisher | nobody | at once | POST /{namespace}/contacts/{contact}/suppress |
When it hands to you
Every booking, rebook, retest and event table is spend, so it comes to you. One Brief per Role, then the Approval, as captured (brief, draft and checks are Not live yet, gaps #7).
[
{
"$id": "https://api.sb/leaseline.app/tasks/task_557" ,
"$type": "Task",
"assignee": "worker_1",
"due": "2026-10-20T17:00:00Z" ,
"on": "publisher_6",
"brief": {
"who": "a regional landlord association newsletter, 9,400 subscribers" ,
"chose": "book-the-slot",
"why": "named by your signups 6 times; grade B evidence" ,
"slot": "Nov 4, $450, sponsor block above the fold" ,
"code": "tested end to end",
"never": [
"a claim outside your approved pages",
"a booking past $1,000 this month"
]
}
},
{
"$id": "https://api.sb/leaseline.app/approvals/approval_61" ,
"$type": "Approval",
"verdict": null,
"deadline": "2026-10-21T17:00:00Z" ,
"draft": "Booking: Nov 4 sponsor block, $450, code LL-NOV4" ,
"route": "book-the-slot",
"checks": [
{
"check": "evidence",
"status": "pass"
},
{
"check": "concentration",
"status": "pass"
},
{
"check": "code-test",
"status": "pass"
}
]
}
]You answer with POST /{namespace}/approvals/{approval}/approve or POST /{namespace}/approvals/{approval}/refuse, or take the Task with POST /{namespace}/tasks/{task}/claim (Take this one) or hand it back with POST /{namespace}/tasks/{task}/return, each a one-call window. An Approval unanswered by its deadline expires, and the slot is released.
On time: you, 5 of 5 bookings answered within 1 business day, median 4 h, n 5, ■□□□ Too early to tell. Your queue: in week 1, the shortlist and 3 evidence asks; then about 1 booking to approve every 2 weeks.
The fixed line: POST /{namespace}/deals/{deal}/assign sets owner to the receiving person, the agent is never a Deal’s owner, and Meetings land on the owner’s calendar under the owner’s name.
When it won’t send
| Check (refuses one send) | Refuses | Fix | Then |
|---|---|---|---|
owned-by-a-person (rule j, gaps #8) | an inquiry to a publisher contact a person owns, or whose Conversation a person claimed | Leave it to the person who owns it: the draft waits in their queue. | POST /{namespace}/tasks/{task}/assign |
evidence (the record’s Evidence floor) | a booking over $300 on grade C audience evidence | Ask the publisher for subscriber and open numbers first. | POST /{namespace}/messages/{message}/schedule |
borrowed-first (the record’s Borrowed-first gate) | a paid booking before 2 borrowed placements read, or a recorded no | Record that none of your other Startups reaches these buyers. | POST /{namespace}/decisions |
concentration (the record’s Concentration cap) | one publisher over 50 % of a month’s paid budget before it paid back once | Book another publisher, or wait for its payback read. | GET /{namespace}/decisions |
code-test (the record’s Code hold) | a run whose code fails its end-to-end test 24 hours before | Fix the code; the run date moves. | POST /{namespace}/coupons |
proof (the record’s Proof hold) | copy or a recording with a claim outside your pages, or no sponsor label | Cut the claim, or add the label; it holds until corrected. | POST /{namespace}/content/draft |
| Stop (pauses the Play) | Pauses when | Then |
|---|---|---|
payback | a placement’s coded 60-day payback under 0.5 | its publisher drops for 180 days |
retest | a second read in the 0.5 to 1.0 band | the publisher drops |
paid-arm | 4 dropped placements in a row | paid bookings pause until a Decision names a new Offer, angle or buyer |
spend-limit | committed spend reaches the month’s Limit | no new booking until the month turns; POST /{namespace}/limits/{limit}/raise |
delivery | delivery under 70 % of the Agreement | the make-good is claimed; no rebook until it runs |
decay | 2 rebooks in a row under 60 % of the first payback | the publisher rests 90 days |
kill-switch | you press it | every inquiry and booking stops; unpaid bookings hold |
+ 1 more for the event lane (?lanes=) |
The captured refusal, then the Stop that fired as a Campaign.paused reason (Not live yet, gaps #2); the rewrite that ran is the host-read thread in Example.
| Check | Fix | Then |
|---|---|---|
proof fail | Cut the claim, or add the label; it holds until corrected. | POST /{namespace}/content/draft |
code-test pass | — | POST /{namespace}/events/capture |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "The host-read brief for the property podcast did not send: it says Leaseline cuts late renewals in half, which no approved page says.",
"checks": [
{
"check": "proof",
"status": "fail",
"doc": "/plays/sponsorships#check-proof",
"fix": "Cut the claim, or add the label; it holds until corrected.",
"then": "Content.draft"
},
{
"check": "code-test",
"status": "pass"
}
]
}It says no, says why, and names the fix.
[
{
"reason": {
"limit": "payback",
"observed": "0 coded payments in 60 days on $300",
"bound": "0.5",
"window": "60d"
},
"doc": "/plays/sponsorships#stop-payback" ,
"task": "task_472"
}
]Did it work
Each placement reads against your uncoded baseline, and 2 placements a month cannot hold a random comparison, so the basis is before-after (rule o): nothing prints as Added. Each figure’s call is POST /{namespace}/metrics/query by node, and every node above the leaf is Not live yet (gaps #4).
24.4 incremental ICP visits per $100,
- Chose
- book-the-slot
- Why
- a regional landlord association newsletter your signups named 6 times: 9,400 subscribers, grade B audience evidence, a Nov 4 slot at $450, under your $1,000 Limit
- From
- book-the-slot · ask-for-evidence · rebook · retest-once · drop-the-publisher · event-table
- Expects
- coded 60-day payback of 1.0 or more by 2027-01-03
- Reopens when
- the placement’s code shows no Visit within 3d of its run date
- By
- worker_4
JSON
{
"$id": "decisions/decision_356",
"$type": "Decision",
"choice": "book-the-slot",
"reason": "a regional landlord association newsletter your signups named 6 times: 9,400 subscribers, grade B audience evidence, a Nov 4 slot at $450, under your $1,000 Limit",
"stakes": "high",
"options": [
"book-the-slot",
"ask-for-evidence",
"rebook",
"retest-once",
"drop-the-publisher",
"event-table"
],
"by": "worker_4",
"on": "publisher_6",
"expected": "coded 60-day payback of 1.0 or more by 2027-01-03",
"reopensWhen": "the placement’s code shows no Visit within 3d of its run date"
}| Node | Now (147 days) | Before (the 147 days before) | Added | Confidence | Basis |
|---|---|---|---|---|---|
placement-icp-visits-per-100 | 24.4 per $100: 330 ICP visits over the uncoded baseline, from 4 placements costing $1,350 | no placements; 18 ICP visits a day uncoded | — | — | before-after against the uncoded baseline, not proof · Other Startups’ results +19 per $100, ■■■□ Likely, n 410 placements |
icp-reached | 2,976 ICP visits | 2,646 | — | — | before-after |
new-arr ↑ | $4,379, 5 coded Customers · Booked: credited, not all caused by this Play | $0 coded | — · Worth about +$690 a month | — | before-after · 1 coded trial still deciding |
net-new-arr · arr | carried from new-arr | carried | — | — | carried |
The leaf counts ICP visits a coded placement brings over the uncoded daily baseline, per $100 of its full cost, over its 14-day window; payback reads the coded revenue at 60 days. Before against after is not proof, and Other Startups’ results print beside it.
How it moves it: property managers meet Leaseline inside a newsletter they already read, through a code that ties each visit and payment to that one placement.
Guardrails: by placement, coded 60-day payback: 0.61, 0 (dropped), 5.3 and 0.39 against the 0.5 floor; one publisher held 33 % of paid spend against the 50 % cap; $1,350 spent over five months, never past the $1,000 monthly Limit.
{
"$id": "https://api.sb/leaseline.app/campaigns/sponsorships" ,
"$type": "Campaign",
"play": "play:sponsorships@1" ,
"path": [
"placement-icp-visits-per-100",
"icp-reached",
"new-arr",
"net-new-arr",
"arr"
],
"experiment": {
"metric": "placement-icp-visits-per-100",
"unit": "per-100-usd",
"heldBack": 0,
"decision": null
},
"readout": {
"value": null,
"n": 4,
"maturing": 1,
"interval": null,
"readability": "inadmissible",
"basis": "before-after",
"pooled": true
},
"ledger": {
"spend": 1350,
"workerCost": 2,
"hours": 2.6,
"pipelineArr": 347,
"wonArr": 4379,
"projectedArr": 687,
"paybackDays": 41
}
}Outside benchmark: a newsletter sponsor slot to business readers brings a median of 0.6 clicks per 100 subscribers (a newsletter platform’s study of 18,000 sponsored issues, 2026-05-31).
Before it · After it. Before it: signup-interviews names the publications your buyers read. After it: instant-response answers the coded visitors who write in, signup-interviews hears the ones who join the Waitlist, and promote-winners hears a host read that pays back.
Example
Leaseline ran it from 2026-05-25 to 2026-10-19 (147 days), long enough for each placement’s 60-day read: 4 placements ran for $1,350, 3 publishers sent audience evidence, 1 was dropped, and 1 slot waits for your approval. Read every captured thread at ?threads=; three follow the tables.
| What happened, by option | Decisions | Ran | Coded Customers (credited, not all caused by this Play) |
|---|---|---|---|
| Book the slot | 2 | the property-manager newsletter, $450 (payback 0.61) · the property podcast, $300 (payback 0) | 2 on Pro, 1 on Team (+$1,639 ARR) |
| Retest once · Rebook | 1 · 1 | the newsletter again, $450, a new angle (payback 5.3) · Nov 4 booked | 1 on the $2,400 plan (+$2,393 ARR) |
| Take an event table · Ask for audience evidence · Drop the publisher | 1 · 3 · 1 | a $150 table, 6 conversations (payback 0.39) · 2 sent grade B, 1 grade C · the podcast, 180 days | 1 on Pro (+$347 ARR) |
| At $250 a month (the Use it when volume) | about 1 placement a month | before-after, not proof | Other Startups’ results: +19 per $100, ■■■□ Likely, n 410 placements |
| Day | Event | What happened | Your time |
|---|---|---|---|
| 0 | event_119 Campaign.created | the three steps; dry run fails approved-pages | 10 min |
| 0 | event_125 Site.published | the placement landing Page; a recorded no for borrowed slots | 20 min |
| 12 | event_066 Transaction.recorded | the first coded payment: Pro, code LL-JUN2 | — |
| 20 | event_081 Action.refused | proof refused the podcast host read; rewritten once and run on Jun 16 | 5 min |
| 69 | event_388 Approval.approved | you approved the newsletter retest with one changed angle | 5 min |
| 82 | event_452 Campaign.paused | payback: the podcast at 0; dropped for 180 days | — |
| 131 | event_1101 Readout.created | the retest reads 5.3 at day 60; you approved the rebook | 5 min |
| 1–147 | event_031 Approval.created, first of 5 | you approved 5 bookings; weekly reviews, from the POST /{namespace}/tasks/next log | 2 h · total 2.6 h measured, 2.8 h asked |
The newsletter’s retest, Aug 4 · sponsor block: “Renewal notices for every owner, 60 days out. Leaseline, $29 a month.” with code LL-AUG4 and the sponsor label.¹
Aug 9, 14:10 · Pinehurst Management paid for the $2,400 plan with code LL-AUG4.
Transaction.recorded, +$2,393 ARR; the placement’s coded payback read 5.3 at day 60, on Oct 3.²
- Leaseline cuts late renewals in half for property managers.
+ Leaseline sends every renewal notice 60 days out, per owner, for $29 a month. Sponsored. The Nov 4 slot, 2026-10-19 11:20 · the booking reached you as
approval_61, $450, code tested, with its Brief (task_557); it waits for your approval by Oct 21 17:00 (When it hands to you).
¹ Only lines from your approved pages, with the sponsor label. ² Payback reads the coded revenue over the placement’s full cost.
Your settings
---
holdout: 0 # each placement reads on its own code; it reads before-after
---
Propose one coded placement at a time, up to $1,000 a month. I approve every booking.
Rebook at a coded 60-day payback of 1.0 or more; retest once between 0.5 and 1.0. $ npx startup-builder show plays/sponsorships
holdout 0 · Limit $1,000 a month · payback target 1.0 your file plays/sponsorships.mdx:2,4,5 (Ask 2026-05-25)
family demand · worker role:marketing-lead, owns never · chooses 6 (3 rule, 3 read) · sequences publisher-inquiry, hackathon-builder-follow-up, event-conversation-follow-up · checks owned-by-a-person, evidence, borrowed-first, concentration, code-test, proof · stops 8 · placements portfolio-network, gmail, outlook, yahoo-mail, youtube, github catalog play:sponsorships@1 (Not live yet, gaps #5) Every key from the catalog
Compiled, not written: edit the Play record sponsorships and its Leaseline run, then regenerate. Every step runs from a sentence or a line of code. In your words: the CRM words you know, and where each lives here.