Skip to content

Answer engine optimization

Keeps the facts AI answers repeat about you true and dated, at home and at each cited source, and counts how often they name you.

Channel
AI answers
Kind
Search
Run oneMode try
You, to your agent

Hand the latest wrong answer about us to the Content Lead agent and show me what it chose and why. Don’t send.

curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Monitor.checked%22%2C%20%22Change.merged%22%2C%20%22Keyword.measured%22%2C%20%22Page.fetched%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_1405"}'

# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22source_17%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%22source_17%22" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
import { $ } from 'startup-builder'

const { events: [last] } = await $.Event.list({ where: 'name in ("Monitor.checked", "Change.merged", "Keyword.measured", "Page.fetched")', 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 (\"Monitor.checked\", \"Change.merged\", \"Keyword.measured\", \"Page.fetched\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1405"}' --try   # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"source_17\""}'   # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"source_17\""}'   # Not live yet (gaps #7)
{
  "name": "do",
  "arguments": {
    "code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Monitor.checked\", \"Change.merged\", \"Keyword.measured\", \"Page.fetched\")', 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"
  }
}
Response200application/json
{
  "decision": {
    "$id": "https://api.sb/leaseline.app/decisions/decision_462",
    "$type": "Decision",
    "choice": "ask-the-source",
    "reason": "a roundup page by someone else, cited on 5 of the 40 questions, lists Pro at $39 a month; your Pricing Page says $29",
    "stakes": "low",
    "options": [
      "publish-the-answer",
      "fix-your-page",
      "ask-the-source",
      "update-the-comparison",
      "not-now",
      "let-it-go"
  …
sample · 4 Not live yetPreview

On POST /{namespace}/processes/{process}/enableOff POST /{namespace}/processes/{process}/pauseTake this one POST /{namespace}/tasks/{task}/claim

action_3 is the correction to the roundup’s editor, which waits for your OK (You approve each one); it cites your Pricing Page and the date its Price changed.

+8.2 per 100 answers · ■■□□ Early sign · n 900 runs · path → arr

Try another: the answerChoiceReason
Perplexity: a roundup page says Leaseline Pro is $39 a monthask-the-sourcesomeone else’s page, cited on 5 questions
ChatGPT: “Leaseline has no owner statements” on 3 questionsfix-your-pageyour setup page says it, but only inside a tab
Google: no source names a tool for 60-day renewal noticespublish-the-answera buyer question no page answers
Gemini: the whole panel shifted on Oct 2not-nowa model release froze the series

Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Answer share → People reached → New Customers ↑ → ARR added each week → ARR

Worth’s formula: about +8.2 per 100 answers × 15 AI-sent visits a month per point × 1.9 % visits to Leads × 0.30 Leads to opens × 0.29 opens to paid × $420 first order ARR ≈ +$85. Under First signal: About 6 weeks to tell a +6 point lift at 15 questions a half and 450 runs a week; a model release adds 2 weeks to rebuild the baseline.

sample · api.sb/leaseline.app · 41 Customers at 2026-10-19 · on Monitor.checked · first answer citing your page in week 3 · 4 keys Not live yet

Start it this week

Terminal
npx startup-builder add play aeo   # 1 · writes plays/aeo.mdx (Not live yet, gaps #5)

# 2 · dry run; below, its 422 on the day-0 Startup (clock at 2026-08-24)
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":"aeo"}'

# 3 · keep it: pages publish from your records, corrections wait for you
curl -X POST https://api.sb/leaseline.app/campaigns \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"play":"aeo"}'

# on
curl -X POST https://api.sb/leaseline.app/processes/content-marketing/enable \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"

# off: pages stay up, queued corrections cancel
curl -X POST https://api.sb/leaseline.app/processes/content-marketing/pause \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
422Refusedaeo can’t start yet: 1 check fails and 1 warns.
CheckFixThen
owned-by-a-person pass · Not live yet, gaps #80 source editors are Contacts a person ownsPOST /{namespace}/tasks/{task}/assign
use-when pass · Not live yet, gaps #8a Pricing Page and 40 questions from 12 signup interviewsPOST /{namespace}/metrics/query
baseline warn · Not live yet, gaps #8Run the panel once; the first week fills Before.POST /{namespace}/metrics/query
approved-pages fail · Not live yet, gaps #8Put every Price and Limit in your Pricing Page’s text, not inside a tab.POST /{namespace}/sites/{site}/publish
domain-authenticated passleaseline.app: 3 of 3 records resolvePOST /{namespace}/domains/{domain}/authenticate
role-unstaffed pass · Not live yet, gaps #8Content Lead and Marketing Lead are your agents; comparisons and corrections come to youPOST /{namespace}/roles/{role}/staff
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "aeo can’t start yet: 1 check fails and 1 warns.",
  "checks": [
    {
      "check": "owned-by-a-person",
      "status": "pass",
      "observed": "0 source editors are Contacts a person owns",
      "doc": "/plays/aeo#check-owned-by-a-person",
      "then": "Task.assign"
    },
    {
      "check": "use-when",
      "status": "pass",
      "observed": "a Pricing Page and 40 questions from 12 signup interviews",
      "doc": "/plays/aeo#check-use-when",
      "then": "Metric.query"
    },
    {
      "check": "baseline",
      "status": "warn",
      "observed": "no panel history: week 1 is the baseline",
      "doc": "/plays/aeo#check-baseline",
      "fix": "Run the panel once; the first week fills Before.",
      "then": "Metric.query"
    },
    {
      "check": "approved-pages",
      "status": "fail",
      "doc": "/plays/aeo#check-approved-pages",
      "fix": "Put every Price and Limit in your Pricing Page’s text, not inside a tab.",
      "then": "Site.publish"
    },
    {
      "check": "domain-authenticated",
      "status": "pass",
      "observed": "leaseline.app: 3 of 3 records resolve",
      "doc": "/plays/aeo#check-domain-authenticated",
      "then": "Domain.authenticate"
    },
    {
      "check": "role-unstaffed",
      "status": "pass",
      "observed": "Content Lead and Marketing Lead are your agents; comparisons and corrections come to you",
      "doc": "/plays/aeo#check-role-unstaffed",
      "then": "Role.staff"
    }
  ]
}

It says no, says why, and names the fix.

CheckFix (one call)Your timeWait
owned-by-a-person · use-when · pass: 0 owned; 40 questions (gaps #8)POST /{namespace}/metrics/query on answer-share1 minnone
baseline · warn: no historyPOST /{namespace}/monitors/{monitor}/check runs the panel; week 1 fills Before in Your number0 min7 days
approved-pages · fail: the Team Limit sits inside a tab (Not live yet)POST /{namespace}/sites/{site}/publish the Pricing Page with the table in its text20 minnone
domain-authenticated · role-unstaffed · pass · pass (gaps #8)—0 minnone

Your number · Before 6.1 per 100 answers · Now 14.2 on the 15 changed · Target 20 by Dec 31 · ■■□□ Early sign · n 900 runs · held back at random

Each panel run costs $0.02 (600 a week: 40 questions × 5 Venues × 3 samples), and each drafted page or correction costs $0.05 from your Domain (Worker cost). Contact data for a source editor costs $0.06 (POST /{namespace}/contacts/{contact}/enrich). That comes to about $50 a month at 40 questions, and a Limit cuts samples from 3 to 2 at $60.

When it starts

WhenTrigger idStarts onWindowHow it gets in
The weekly panel run is duepanel-weekat on Monitor.checked where 7 days after the panel's last check7 d after the last checkPOST /{namespace}/monitors/{monitor}/check on the locked panel
An answer contradicts one of your factsmisstatement-foundevent on Monitor.checked where an answer contradicts a fact recordqueued the same run; ignored after 28 dthe panel run itself
A Price, Offer, Limit or integration changesfact-changedevent on Change.merged where the change touches a Price, Offer, Limit or integration a Page statespages recompile within 24 hPOST /{namespace}/changes/{change}/merge on the record
+ 6 more for new cited sources, share drops, rival page changes, model releases, fetch spikes and new mentions (?lanes=all)
One signed delivery · StartupBuilder-Signature
{
  "$id": "https://api.sb/leaseline.app/events/event_1405",
  "$type": "Event",
  "name": "Monitor.checked",
  "at": "2026-10-19T07:00:12Z",
  "seq": 1405,
  "data": {
    "monitor": "aeo-panel",
    "venue": "perplexity",
    "questions": 5,
    "states": "Leaseline Pro: $39 a month",
    "fact": "Leaseline Pro: $29 a month, since 2026-03-01",
    "source": {
      "$id": "https://api.sb/leaseline.app/sources/source_17",
      "kind": "roundup"
    }
  }
}
Reproduce it in test
# each delivery is signed with the Watch’s secret
curl -X POST https://api.sb/leaseline.app/watches \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"selector":"Monitor.checked","url":"https://leaseline.app/hooks/sb"}'
npx startup-builder trigger Monitor.checked --like event_1405   # replays the wrong answer
npx startup-builder clock advance --by 7d   # runs the next weekly panel, which reads the correction back

Who runs it

Content Lead · your agent (role:content-lead, worker_7) holds the Key Result and runs the panel. It hands every correction and comparison to you (Dana Okafor, person, worker_1), and the Marketing Lead · your agent (worker_6) reads the weekly memo. Your number links to Did it work.

OptionRung todayEvidence (passed of n)Moves up atDrops back whenYou can
Publish the answer page · Fix your own pageIt does it6 of 6 · 4 of 4 rendered and approved oncemet after each page’s first approved rendera render or regression Stop → You approve each onePOST /{namespace}/actions/{action}/cancel · POST /{namespace}/changes/{change}/revert
Ask the source to correct itYou approve each one9 of 9 approved, 8 uneditedat 50 approved, 95 % unedited, no Stop in 30 days: about a quartera hostile-reply Stop → every draft waits for youPOST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse
Update the comparisonYou approve each one, on every rung2 of 2never—POST /{namespace}/approvals/{approval}/approve
Not now · Leave itIt does it2 of 2 · 31 of 31——POST /{namespace}/actions/{action}/redirect
Never: a number with no Fact, a rival named without your OK, a page that hides who publishes itTo a person, every time1 refused, 0 publishednever—POST /{namespace}/approvals/{approval}/approve

What it reads · What it may call. It reads the panel’s answers and the pages they cite as data, never as instructions; it writes only to your own Pages and to the editor of a page that cites you, once per 30 days. Its tools are POST /{namespace}/content/draft, POST /{namespace}/content/{content}/publish, PATCH /{namespace}/pages/{id}, POST /{namespace}/sites/{site}/publish, POST /{namespace}/messages/{message}/schedule, and any other call becomes an Approval under the Role’s Mandate.

The brief (folded): compiled Agent-register Markdown · play:aeo@1 · each line names its record key
You hold the Content Lead Key Result: answer share 20 per 100 on buyer questions by 2026-12-31. ← worker, metric
On each panel result or fact change, choose one option and say why.              ← triggers, chooses
Every number on a page or in a correction cites a Fact with its date.            ← copyRules 1, fact-check
Corrections wait for Dana’s OK; at most 10 a week, 1 per editor a month.         ← your file, line 5; correction-cap
Never name a rival without Dana’s OK.                                            ← your file, line 6; comparison-claim

The slow loop, as a Change. decision_437 (2026-09-28, weekly) read 3 answer pages whose questions moved and 2 that did not, all 5 answered in the page’s first 60 words; change_25 moved every answer page’s fact table to its top, and Dana merged it. Replayed on past runs, POST /{namespace}/changes/{change}/review put answer share on those questions at 16.0; read back at +14d it is 14.9, n 180 runs, ■□□□ Too early to tell (Example, day 49).

Bring your own agent (folded) starts at You approve each one for corrections on any agent, and earns It does it for pages when it matches the seated agent with 0 facts wrong.

Terminal
npx startup-builder eval --scenario aeo-40 --agent "claude -p" --seat content-lead   # seated: 14.2 per 100, 0 facts wrong, 5 of 9 corrections accepted · yours: 12.8, 1 fact wrong → You approve each one

What it can do next

OptionPicked whenDecided byRunsHands toIf it’s just you
Publish the answer page publish-the-answera buyer question no source answersAgent’s call, with its reasonPOST /{namespace}/content/draft from your records → POST /{namespace}/content/{content}/publishnobodythe same
Fix your own page fix-your-pageyour page has it, but not in its raw text or past recheckYour rule (the render Check)PATCH /{namespace}/pages/{id} → POST /{namespace}/sites/{site}/publishnobodythe same
Ask the source to correct it ask-the-sourcea cited page misstates you on 3+ questionsAgent’s call, with its reasonaeo-source-correction: one note and one follow-up (POST /{namespace}/messages/{message}/schedule)you approve each one, due 1 business day · Take this oneyou
Update the comparison update-the-comparisona rival’s pricing or plan page changedAgent’s call, with its reasonPOST /{namespace}/content/draft of the changed rowsyou approve each one, due 1 business day · Take this oneyou
Not now not-nowa model release froze the seriesYour rule (the series-break Stop)nothing; the Stop holds every read until 2 new runsnobodythe same
Leave it let-it-goshare holds and no fact is wrongAgent’s call, with its reasonnothing; the next weekly run reads it againnobodythe same
When they write backFixture replyWhat happensWho answersBy whenCall
Interested“Happy to fix it. What’s the right figure?”answers with the dated fact and your Pricing Page linkContent Lead · your agent1 business dayPOST /{namespace}/conversations/{conversation}/answer
Send me pricing“Can you send your full price list?”answers with the Pricing Page and nothing it lacksContent Lead · your agent1 business dayPOST /{namespace}/conversations/{conversation}/answer
Not now“We refresh that list in January.”nothing else sends; the next run after their date reads it againnobodytheir datePOST /{namespace}/messages/{message}/schedule
Wrong person“I don’t edit that page; our editor does.”asks them to forward it; it never writes to an address from their textContent Lead · your agent1 business dayPOST /{namespace}/conversations/{conversation}/answer
Out of officean auto-reply until Oct 30the one follow-up waits for the return datenobodythe return datePOST /{namespace}/messages/{message}/schedule
Question it can’t answer“Can you share churn figures for our review?”To you, the question in the Brief; it states no figure your records lackyou1 business dayPOST /{namespace}/conversations/{conversation}/escalate
Stop“Don’t email me again.”nothing else sends to them from any of your Startupsnobodyat oncePOST /{namespace}/contacts/{contact}/suppress

When it hands to you

Every correction and comparison comes to you, and nothing reaches an editor without your OK. What lands in your queue, as captured: the Brief, then the Approval (brief, draft, route and checks are Not live yet, gaps #7).

What lands in each queue · sample
[
  {
    "$id": "https://api.sb/leaseline.app/tasks/task_262",
    "$type": "Task",
    "assignee": "worker_1",
    "due": "2026-10-20T17:00:00Z",
    "on": "source_17",
    "brief": {
      "what": "a roundup page cited on 5 questions lists Pro at $39 a month",
      "fact": "Leaseline Pro: $29 a month, since 2026-03-01 (your Pricing Page)",
      "chose": "ask-the-source",
      "why": "someone else’s page; 5 of 40 questions read it",
      "sends": "one note and one follow-up, to the editor only"
    }
  },
  {
    "$id": "https://api.sb/leaseline.app/approvals/approval_71",
    "$type": "Approval",
    "verdict": null,
    "deadline": "2026-10-20T17:00:00Z",
    "draft": "Hi Lena, your roundup of rental tools lists Leaseline Pro at $39 a month. It has been $29 since March 1…",
    "route": "ask-the-source",
    "checks": [
      {
        "check": "fact-check",
        "status": "pass"
      },
      {
        "check": "correction-cap",
        "status": "pass"
      }
    ]
  }
]

You answer with POST /{namespace}/tasks/{task}/claim (Take this one), POST /{namespace}/tasks/{task}/return with a reason, POST /{namespace}/approvals/{approval}/approve or POST /{namespace}/approvals/{approval}/refuse, each a one-call window, and an Approval unanswered by its deadline expires and the note never sends. Once you claim a correction, the agent stops writing to that editor, and every reply comes to your queue.

On time: you, 11 of 12 approvals by their deadline, median 3 h 10 min, ■■□□ Early sign, n 12 (the 12th expired, and that note never sent). Your queue: counted by kind: in week 1, 1 panel lock and 1 Pricing Page fix; since, about 2 corrections a week and 1 comparison a month.

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)RefusesFixThen
owned-by-a-person (rule j; Not live yet, gaps #8)a correction to an editor whose Lead or open Deal a person ownsLeave it to the person who owns it: the draft waits in their queue.POST /{namespace}/tasks/{task}/assign
fact-checka page or correction with a number or claim no Fact backsCut the claim, or name the record that backs it.POST /{namespace}/content/draft
stale-facta Fact past its recheck date, on every page that states itRecheck the Fact; the page returns once it passes.PATCH /{namespace}/pages/{id}
correction-capan 11th correction in a week, or a 2nd to one editor in 30 daysWait for the window; the queue keeps its order.POST /{namespace}/messages/{message}/schedule
contact-leasea note to an editor another of your Startups wrote to in 30 daysLeave it; the lease ends after 30 days.GET /{namespace}/decisions
comparison-claima changed claim about a named rival without your OKApprove the changed rows, or cut them.POST /{namespace}/approvals/{approval}/approve
ownership-stateda comparison page that omits that you publish it and are one of the comparedKeep the fixed ownership line at the top.PATCH /{namespace}/pages/{id}
Stop (pauses the Play)Pauses whenThen
rendera page’s raw text lacks a Price, Limit or Fact it showspublishing holds; POST /{namespace}/sites/{site}/publish once it passes
crawleran answer engine’s crawler is blocked on one of your pagesPOST /{namespace}/issues; that page’s panel results read suspect
hostile-reply2 hostile replies or block asks in 30 dayscorrections pause; each sender is suppressed
series-breaka model release, or the whole panel moving past 3 intervals in a weekreads and tests freeze until 2 new runs
regressiona page change followed by a fall past the interval for 3 weeksPOST /{namespace}/changes/{change}/revert on that change
spend-limit (the panel budget)panel spend reaches its $60 Limitsamples drop from 3 to 2; POST /{namespace}/limits/{limit}/raise with your OK
kill-switchyou press itevery Tactic pauses, pages stay up, queued corrections cancel; POST /{namespace}/processes/{process}/enable after review

The captured refusal, then the Stops that fired as Campaign.paused reasons (Not live yet, gaps #2); the rewrite that sent is the second thread in Example.

422RefusedThe correction to the roundup editor did not send: it states a figure no Fact backs.
CheckFixThen
fact-check fail · Not live yet, gaps #1Cut the claim, or name the record that backs it.POST /{namespace}/content/draft
correction-cap pass—POST /{namespace}/messages/{message}/schedule
JSON
{
  "type": "https://startupbuilder.dev/errors/refused",
  "title": "Refused",
  "status": 422,
  "detail": "The correction to the roundup editor did not send: it states a figure no Fact backs.",
  "checks": [
    {
      "check": "fact-check",
      "status": "fail",
      "doc": "/plays/aeo#check-fact-check",
      "fix": "Cut the claim, or name the record that backs it.",
      "then": "Content.draft"
    },
    {
      "check": "correction-cap",
      "status": "pass"
    }
  ]
}

It says no, says why, and names the fix.

The Stops that fired, as Campaign.paused reasons · sample
[
  {
    "reason": {
      "limit": "render",
      "observed": "the Team Limit missing from the raw text of /pricing",
      "bound": "0 missing",
      "window": "1 publish"
    },
    "doc": "/plays/aeo#stop-render"
  },
  {
    "reason": {
      "limit": "series-break",
      "observed": "the whole panel moved 3.4 intervals after a Gemini model release",
      "bound": "3 intervals",
      "window": "1 week"
    },
    "doc": "/plays/aeo#stop-series-break"
  }
]

Did it work

The 30 buyer questions were split at random, 15 whose pages changed and 15 held back, and both halves read from the same weekly runs (rules m–o); each figure’s call is POST /{namespace}/metrics/query by node and by arm. answer-share and every node above it are Not live yet (gaps #4, #6).

+8.2 per 100 answers · ■■□□ Early sign · n 900 runs · path → arr

Chose
ask-the-source
Why
a roundup page by someone else, cited on 5 of the 40 questions, lists Pro at $39 a month; your Pricing Page says $29
From
publish-the-answer · fix-your-page · ask-the-source · update-the-comparison · not-now · let-it-go
Expects
answers on those 5 questions quote $29 within 2 weekly runs
Reopens when
source_17 still states $39 at the run after next
By
worker_7
JSON
{
  "$id": "decisions/decision_462",
  "$type": "Decision",
  "choice": "ask-the-source",
  "reason": "a roundup page by someone else, cited on 5 of the 40 questions, lists Pro at $39 a month; your Pricing Page says $29",
  "stakes": "low",
  "options": [
    "publish-the-answer",
    "fix-your-page",
    "ask-the-source",
    "update-the-comparison",
    "not-now",
    "let-it-go"
  ],
  "by": "worker_7",
  "on": "source_17",
  "expected": "answers on those 5 questions quote $29 within 2 weekly runs",
  "reopensWhen": "source_17 still states $39 at the run after next"
}
NodeAgent halfYour halfAddedConfidenceBasis
answer-share14.2 per 100 answers (64 of 450 runs)6.0 held back (27 of 450)+8.2 [+2.6, +13.8]■■□□ Early signheld back at random by question · n 900 runs, the last 2 weeks · 15 questions a half
icp-reached118 AI-sent visits71+47 [−8, +102] · Not carrying up yet■□□□ Too early to tellthe same split, visits landing on each half’s pages
new-arr ↑$347, 1 Customer on Pro · Booked: credited, not all caused by this Play$0+$347 [−$340, +$1,030] · Worth about +$90 a month■□□□ Too early to tell (1 vs 0 Customers)the same · 2 trials still deciding
net-new-arr · arr+$347$0+$347, carried: it moves no other bridge term■□□□ Too early to tellcarried from new-arr

The leaf counts panel runs whose answer cites or names Leaseline, per 100 runs, per Venue, buyer questions and branded questions apart; the 10 branded questions read accuracy, not share. The series froze for 2 weeks after the Oct 2 model release (series-break).

How it moves it: branded answers that quote $29 for Pro rose from 109 of 150 runs in week 1 to 147 of 150 in week 8, and 5 of 9 corrected pages now state the dated fact.

Guardrails: treated against held back: organic-share of visits, 31 % against 30 %, and earned-mentions, 4 against 3.

The Campaign card · sample
{
  "$id": "https://api.sb/leaseline.app/campaigns/aeo",
  "$type": "Campaign",
  "play": "play:aeo@1",
  "path": [
    "answer-share",
    "icp-reached",
    "new-arr",
    "net-new-arr",
    "arr"
  ],
  "experiment": {
    "metric": "answer-share",
    "unit": "per-100",
    "heldBack": 15,
    "decision": null
  },
  "readout": {
    "value": 8.2,
    "n": 900,
    "maturing": 0,
    "interval": [
      2.6,
      13.8
    ],
    "readability": "C",
    "basis": "held-back",
    "pooled": false
  },
  "ledger": {
    "spend": 92,
    "workerCost": 6,
    "hours": 3.4,
    "wonArr": 347,
    "projectedArr": 85,
    "paybackDays": 270
  }
}

Outside benchmark: a brand list repeats in under 1 in 100 runs of the same question across answer engines (a 2026 study of 2,961 runs).

Before it · After it. Before it: signup-interviews gives it the questions buyers ask, and editorial-seo writes the long pages it cites. After it: directory-listings takes a wrong review profile, community-answers takes a cited forum thread, and instant-response answers anyone the answers send.

Example

Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days). The panel held 40 questions: 30 a property manager asks and 10 with Leaseline’s name, each run weekly on 5 Venues, 3 samples apiece, 4,800 runs in all. Week 1 read 6.1 answers per 100 naming Leaseline on buyer questions, and 41 of 150 branded runs quoted $39 for Pro. Read every captured run at ?threads=all; three follow the tables.

What happened, by optionDecisionsDoneRead back (what happened)
Publish the answer page · Fix your own page6 · 46 published · 4 fixed7 of the 10 cited within 3 runs
Ask the source to correct it99 approved, 5 corrected5 pages state $29 now
Update the comparison · Not now · Leave it2 · 2 weeks · 312 approved · 2 runs frozen · ——
Changed questions · held back15 · 1514.2 per 100 answers · 6.0$347 · $0 (credited, not all caused by this Play)
At 20 questions (the Use it when volume)about 10 a halfheld back at random, about 10 weeks to readOther Startups’ results: +5.1 per 100, ■■□□ Early sign, n 31 panels
DayEventWhat happenedYour time
0event_1106 Campaign.created40 questions locked; the dry run fails approved-pages30 min
2event_1119 Site.publishedthe Team Limit moved into the Pricing Page’s text; render passes20 min
7event_1150 Monitor.checkedweek 1: 6.1 per 100 on buyer questions; 41 of 150 branded runs quote $39—
14event_1187 Content.published3 answer pages, among them 60-day renewal notices per owner—
16event_1201 Approval.created, first of 12the first correction, to the roundup editor4 min
21event_1233 Monitor.checkedfirst answer citing a Leaseline page, on Perplexity—
35event_1309 Change.mergedfact tables to the top: replayed at 16.0, read back at +14d at 14.95 min
39 · 53event_1318 Campaign.pausedseries-break after a Gemini model release; reads resumed after 2 runs—
1–56event_1124 Task.created, first of 14corrections, comparisons and the weekly memo, from the POST /{namespace}/tasks/next log2.4 h · total 3.4 h measured, 3.5 h asked

Leaseline → Lena, editor of a rental-tools roundup, Sep 10 · Your roundup lists Leaseline Pro at $39 a month. It has been $29 since March 1, as our Pricing Page shows.¹ Could you update the row? *Signed with the Role’s disclosure line.*²

Lena, Sep 11 · “Fixed, thanks.” By the run of Sep 21, 4 of the 5 questions that read her page quoted $29.

The roundup correction, 2026-09-10 · the draft fact-check refused, then the rewrite that sent
- Property managers save about 6 hours a week with Leaseline Pro, which is $29 a month.
+ Leaseline Pro has been $29 a month since March 1, as our Pricing Page shows.

A rival’s plan page changed, 2026-10-07 07:00 · its renewal reminders moved to its top plan. Update the comparison drafted the 2 changed rows for Dana (approval_69, due 17:00 the next day); she approved them at 12:40, and the page kept its fixed ownership line.³ The Brief is task_249.

¹ Every number cites a Fact with its date. ² The fixed signature line, compiled from the Role’s disclosure Setting. ³ A comparison names who publishes it, every time.

Your settings

plays/aeo.mdx
---
holdout: 0.5      # half the buyer questions keep today’s pages, chosen at random
---
Lock these 40 questions for 6 weeks: 30 a buyer asks, 10 with our name.
Corrections wait for my OK.
Never name a rival without my OK.
Text
$ npx startup-builder show plays/aeo
holdout 0.5 · 40 questions · corrections wait · rivals wait    your file  plays/aeo.mdx:2,4,5,6 (Ask 2026-08-24)
family demand · process content-marketing · worker role:content-lead, owns never · chooses 6 (2 rule, 4 read) · sequence aeo-source-correction · approval every-send · checks owned-by-a-person, fact-check, stale-fact, correction-cap, contact-lease, comparison-claim, ownership-stated · stops 7    catalog  play:aeo@1

Every key from the catalog

Key Id What it is
Tactic prompt-panel-build Prompt panel build: Builds and locks the fixed panel of Customer prompts, branded and non-branded, that the answer-citation Monitor samples each week. Starts at You approve the first wave.
Tactic prompt-panel-run Prompt panel run: Samples every panel prompt 3 times per answer engine each week, stores the retrieval set, and computes answer share with its interval. Starts at Sends nothing.
Tactic retrieval-readiness-check Retrieval readiness check: Fetches each Page as answer-engine crawlers do and fails any Page whose shown facts are missing from the raw HTML or blocked from retrieval. Starts at Sends nothing.
Tactic vendor-truth-pages Vendor-truth pages: Compiles the server-rendered pricing, billing terms, Limits, integrations and dated changelog Pages from the Startup’s records within 24 hours of a change. Starts at You approve the first wave.
Tactic honest-comparison Honest comparison: Keeps one comparison Page per named rival, with method, sources, date checked and the rows the rival wins, updated within 24 hours of a change. Starts at You approve each one.
Tactic cited-source-queue Cited-source queue: Ranks the third-party Pages answer engines cite for the panel, routes each to a fix, sends factual corrections, and records every earned mention. Starts at You approve each one.
Tactic citation-cohort-test Citation cohort test: Tests one Page variable a month on a treated cohort against a held-out cohort of matched prompts, and ships only winners into the template. Starts at It does it, you can stop it.
Trigger panel-week Panel week: at on Monitor.checked, window 7d.
Trigger fact-changed Fact changed: event on Change.merged, window 24h.
Trigger misstatement-found Misstatement found: event on Monitor.checked, window 28d.
Trigger cited-source-new Cited source new: threshold on Monitor.checked, window 28d.
Trigger answer-share-drop Answer share drop: threshold on Keyword.measured, window 14d.
Trigger rival-page-change Rival page change: event on Monitor.checked, window 72h.
Trigger model-release Model release: event on Monitor.checked, window 7d.
Trigger fetch-spike Fetch spike: threshold on Page.fetched, window 72h.
Trigger mention-earned Mention earned: event on Monitor.checked, window 28d.
Sequence aeo-source-correction Source correction: 4 steps; it ends on A reply; The fix observed in a panel run; An opt-out; A bounce; A hostile reply.
Benchmark aeo-brand-list-repeat Share of repeated runs of one prompt that return the same brand list: 0–1 % (Brand-recommendation consistency study across 3 answer engines., 2026-01-28).
Benchmark aeo-in-summary-click Share of visits that click a link inside an AI summary: 1 % (US search-behavior panel study., 2025-07-22).
Benchmark aeo-referral-share Share of site traffic sent by answer engines: 0.62–0.73 % (100-site traffic study over 12 months, relayed secondhand., 2026-10-22).
Benchmark aeo-own-pricing-cited-first Share of pricing answers that cite the company’s own pricing Page first: 12 % (Pricing-answer study across 6 answer engines., 2026-08-10).
Benchmark aeo-own-pricing-appears Share of pricing answers where the company’s own pricing Page appears among sources: 46 % (Pricing-answer study across 6 answer engines., 2026-08-10).
Benchmark aeo-pricing-bot-readable Share of public pricing Pages fully readable by bots: 74 % (Pricing-answer study across 6 answer engines., 2026-08-10).
Benchmark aeo-mention-correlation Spearman correlation of branded web mentions with brand visibility in Google AI Overviews; page count correlates at 0.17: 0.664 ratio (75,000-brand correlation study., 2025-05-26).
Benchmark aeo-self-list-unpicked Share of self-ranking list citations where Google AI Overviews omit the list owner from its pick: 69 % (Best-software query study in Google AI Overviews., 2026-06-18).
Benchmark aeo-sources-per-answer Sources cited per answer, from ChatGPT (low) to Perplexity (high): 6.88–16.35 count (Citation-selection preprint across 3 answer engines., 2026-04-28).

Compiled, not written: edit the Play record aeo 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.