Answer page per question
A buyer’s question in; out comes a page on your site that settles it in 60 words, every claim sourced, then found by search engines.
- Kind
- Agent task
- Price
- 12¢ per page
- Your time
- 6 minutes
- Approval
- Goes out on its own
- Deepens
- Publish content
Get Leaseline named in AI answers for the 10 questions small landlords ask most about tracking rent, spend up to $15, and show me the plan first.
curl -X POST "https: //api.sb/ leaseline.app/ pages/ answer? mode= try" \
-H "Authorization: Bearer $SB_TOKEN" \
-H "Content-Type: application/ json" \
-d '{"goal": "Get Leaseline named in AI answers for the 10 questions small landlords ask most about tracking rent, spend up to $15, and show me the plan first.", "budget": {"amount": 15, "currency": "USD"}}'
npx startup-builder do Page.answer --try --data '{"goal": "Get Leaseline named in AI answers for the 10 questions small landlords ask most about tracking rent, spend up to $15, and show me the plan first.", "budget": {"amount": 15, "currency": "USD"}}'
{
"name": "do",
"arguments": {
"mode": "try",
"code": "return await $.Page.answer({ goal: 'Get Leaseline named in AI answers for the 10 questions small landlords ask most about tracking rent, spend up to $15, and show me the plan first.', budget: { amount: 15, currency: 'USD' } })"
}
}
import { $ } from 'startup-builder'
const result = await $.try.Page.answer({ goal: 'Get Leaseline named in AI answers for the 10 questions small landlords ask most about tracking rent, spend up to $15, and show me the plan first.', budget: { amount: 15, currency: 'USD' } })
- Find candidate questions:
Keyword.findin question form, 200 rows, about 10¢. - Rank them in the buyer’s own words:
Keyword.searchfor problem posts on Reddit, Hacker News and X, 12 searches, about 1¢. - Measure volume and intent:
Keyword.measure, 200 terms, about 10¢. - Read who is named now, and whether any page of yours answers: AI answer audit, 10 questions × 4 engines, about 25¢.
- Write a page for each unanswered question: Answer page per question, about 8 pages at about 12¢, about 96¢.
- Get each page indexed: Index the site, free on your own accounts; it waits days.
- Read the answers again at day 21: AI answer audit, about 15¢.
- The Key Result: 10 of 10 questions answered by an indexed page of yours by 2026-11-17. Answer share is reported at day 21, not promised.
Planning is free. You see the plan and its price before anything runs.
Decisions
- D2rank the 10 questions by volume, then by how often buyers ask them in problem posts.“Best rent tracking app” is a buyer comparing tools, so it went to the paid-search list instead of an answer page.
- D3write 7 new pages, update 2 existing ones, leave 1 alone.An update beats a near-duplicate page; one question already had a page that answers it.
- D4on day 10, press Request indexing on the one page still crawled and not indexed.It had sat 7 days; 10 browser steps cost 16¢ against a page that cost 12¢ to write.
By call
| Call | Calls | Cost | Outcomes |
|---|---|---|---|
Keyword.find | 1 | $0.10 | Done |
Keyword.search | 1 | $0.0105 | Done |
Keyword.measure | 1 | $0.10 | Done |
Keyword.audit | 2 | $0.3975 | Done |
Site.publish | 1 | $0 | Done |
Page.answer | 3 | $1.09 | Done |
Site.index | 1 | $0 | Done |
Integration.call | 1 | $0.16 | Done |
| Spent | 107 | $1.94 | of $15.00, $13.06 left; the agent's own planning $0.08 |
Agent time 60 minutes, over 21 days.
Every call, 11 rows
Loading the rows.
What you get
- 1 page · A buyer’s question in; out comes a page on your site that settles it in 60 words, every claim sourced, then found by search engines. · Page
page· The published page: URL, title, word count and status.claims[]· Every claim on the page with the record or cited page it rests on.review· Both Review passes: the adversarial verdict with what it cut, and the affirmative one with what it added.indexed·pendingwhen it returns; Index the site reads it daily until it is indexed or names why not.
Connect once: Google Search Console. How long: About 8 minutes; then it waits days on the index.
Trigger
It runs when you call it, per question, or in a batch from the AI answer audit’s unanswered questions.
on.Keyword.audited((audit, $) => audit.questions.filter((q) => !q.yourPage?.answers).map((q) => $.Page.answer({ question: q.question, site: 'leaseline.app' })))Steps
Your agent does these steps, one row per step; each step’s check is part of its row and its price.
| Step | Verb | Returns | Price | Approval |
|---|---|---|---|---|
| 1. Read the results page for the question | Keyword.search | The top 10 results, and the forum or video slots in them | About 0.03¢ | Runs on its own |
| 2. Ask four answer engines the question | Keyword.ask | Who each engine names and the pages it cites | About 1.6¢ | Runs on its own |
| 3. Read the five pages answers cite most | Page.audit | What the cited pages say, and what they leave out | About 0.1¢ | Runs on its own |
| 4. Choose the angle and the outline | Content.draft | What the cited pages miss that your records can show, as an outline with a source per section | About 1¢ | Runs on its own |
| 5. Write the page | Content.draft | The page: a 60-word answer first, then the detail, an FAQ block and its schema | About 9¢ | Runs on its own |
| 6. Audit the page before it goes live | Page.audit | Title, headings, schema and links checked | About 0.02¢ | Runs on its own |
| 7. Publish it on your site | Content.publish | The page live, which pings the engines as an effect of the publish | Free | Goes out on its own |
| 8. Read its index state | Domain.verify | The page’s index state, handed to Index the site | Free | Runs on its own |
Calls: Keyword.search, then Keyword.ask, then Page.audit, then Content.draft, then Page.audit, then Content.publish, then Domain.verify.
About 12¢ a page, each time it runs, capped at 30¢.
Example: give it a goal
Get Leaseline named in AI answers for the 10 questions small landlords ask most about tracking rent, spend up to $15, and show me the plan first.
Run it above shows the plan it showed before it spent anything, and the receipt of every call.
When something fails
Each failure, and what happens next
| When | Then |
|---|---|
| The adversarial Review fails | The page is redrafted once with the findings; a second failure leaves a draft, raises a task and settles at cost with nothing published. |
| An existing page nearly answers the question | With update set, or in goal mode as a Decision, the page is revised as a new version: an update beats a near-duplicate. |
| The page is crawled and not indexed after 7 days | Index the site presses Request indexing on it when pressRequest is on, about 16¢; otherwise it is reported with the engine’s reason. |
| You call it again for the same question and site | It updates the same page as a new version: it is idempotent per question and site. |
Each step retries three times, then falls through to the next route; one item's failure lands in skipped with its reason, never failing the call. Before a step would cross maxCost it stops and returns what it has, with a resume link. Each step's idempotency key is the call's key plus the step and the item: leaseline-page-answer-1-<step>-<item>.
How it is graded
A second model checks every claim on the page against its cited sources and your offer; Index the site reads whether each engine holds it. It passes when the page passes the adversarial review, goes live on your site, and Index the site reads it indexed or names the engine’s reason. A miss is redone at no charge.
Change it
| Ask | Compiles to |
|---|---|
| Update my features page instead of writing a new one. | Page.answer |
| Write one for every question my audit found unanswered. | Page.answer |
| Write eight of these every month from my keyword map. | Site.grow |
import { $, workflow } from 'startup-builder'
export default workflow({
name: 'answer-page',
verb: 'Page.answer',
input: { question: 'string', site: 'string', facts: "'offer' | string[]", update: 'string?' },
maxCost: 0.3,
review: [
{ pattern: 'adversarial', rubric: 'every claim resolves to a record or a cited page' },
{ pattern: 'affirmative', rubric: 'answers in the first 60 words; FAQ block; schema' },
],
grade: { evaluator: 'claims against the cited pages and the Offer; index state read back' , passWhen: 'live, reviewed, and indexed or a reason' , remedy: 'redo' },
execute: async (ctx, { question, site, facts = 'offer', update }) => {
const results = await ctx.step('results', () => $.Keyword.search({ keywords: [question], venue: 'google-search', maxCost: 0.01 }))
const answers = await ctx.step('answers', () => $.Keyword.ask({ questions: [question], venues: ['chatgpt', 'perplexity', 'gemini', 'google-ai-mode'], maxCost: 0.03 }))
const cited = await ctx.step('cited', () => $.Page.audit({ urls: topCited(answers, 5), fields: ['content'], maxCost: 0.01 }))
const draft = await ctx.step('write', () => $.Content.draft({ kind: 'answer-page', question, from: { results, answers, cited }, facts, update, maxCost: 0.08 }))
const page = await ctx.step('publish', () => $.Content.publish({ content: draft.$id, site })) // reviewed before it publishes
return { page, indexed: (await ctx.step('index', () => $.Domain.verify({ hostname: site, pages: [page.url] }))).pages[0].state }
},
})Extend it with extends: and base(), or compose your own from these steps.
Works with
Plays that order it: Answer engine optimization, Category hubs, Switch kit.
It serves Make content, and runs in Launch and search. It deepens Publish content.
For agents
For agents: the guide, its approvals, retries and lookups
| Fact | Value |
|---|---|
| Guide | Page.answer |
| Guide approval | limits |
| Goal | Get Leaseline named in AI answers for the 10 questions small landlords ask most about tracking rent, spend up to $15, and show me the plan first. It may change counts, the order of steps, soft filters and the route a read takes, and it stops early when the goal is met. It never relaxes your words, raises its own budget, answers its own approval, calls a Play or acts outside your standing approval. |
| Trigger | on.Keyword.audited((audit, |
| Retry | Three times with backoff, then the next route; the same idempotency key never charges, sends or posts twice |
| Idempotency key | leaseline-page-answer-1 |
| Lookups | A find: input asks unless exactly one record fits |
| Step |
|---|
| 1. Read the results page for the question |
| 2. Ask four answer engines the question |
| 3. Read the five pages answers cite most |
| 4. Choose the angle and the outline |
| 5. Write the page |
| 6. Audit the page before it goes live |
7. Publish it on your site Action class publish |
| 8. Read its index state |
The amounts live once, on the hub (approvals).
Who does each step, and how it is checked
| Step | Function | Doer | Checker | Assurance | Inputs |
|---|---|---|---|---|---|
| 1. Read the results page for the question | code | Code | Code checks each result against its declared type | measured | $0.question |
| 2. Ask four answer engines the question | code | Code | Code checks each result against its declared type | measured | $0.question |
| 3. Read the five pages answers cite most | code | Code | Code checks each result against its declared type | measured | $1, |
| 4. Choose the angle and the outline | agentic | The Content lead agent | A second model grades the output | graded | $3, |
| 5. Write the page | agentic | The Content lead agent | Affirmative review by a second model: Pass, with what it added: the 60-word answer, the FAQ, the schema | graded | $4.outline, |
| 6. Audit the page before it goes live | code | Code | Code checks each result against its declared type | measured | $5.draft |
| 7. Publish it on your site | code | Code | Code reads the result back from where it landed | measured | $6.draft, |
| 8. Read its index state | code | Code | Code checks each result against its declared type | measured | $7.url |
The doer is never the checker, and the weakest assurance on the path is the whole call’s.
Under the hood
Under the hood: the Systems, Nouns and Events it touches
Reference
Inputs, outputs, its Event and its errors
| Name | Type | Default | Meaning |
|---|---|---|---|
question | string | Required | The question, in the buyer’s words, as the AI answer audit or a problem post found it. |
site | Hostname | Required | Your site. |
facts | 'offer' | string[] | 'offer' | The records a claim may rest on: your offer, your pages, or a list. A claim with no source is cut, never softened. |
update | Url | Required | An existing page that nearly answers the question: it is revised as a new version instead of adding a near-duplicate. |
maxCost | number | 0.30 | The most this call spends each time it runs, in USD. It stops before a step would cross it and returns what it has, with a resume link. |
Emits Page.answered. Refuses with max-cost before it spends, and with the Data calls and Accounts groups (refusals).