Ranked page
Pages on terms you can win, billed only when each reaches the top 20 on Google within 120 days; a miss is rewritten free.
- Kind
- Service
- Price
- $25 per ranked page
- Your time
- 35 minutes
- Approval
- Goes out on its own
- Deepens
- Demand generation
Rank 10 pages for property manager searches within 120 days, $25 each, and show me the terms first.
curl -X POST "https: //api.sb/ leaseline.app/ pages/ rank? mode= try" \
-H "Authorization: Bearer $SB_TOKEN" \
-H "Content-Type: application/ json" \
-d '{"goal": "Rank 10 pages for property manager searches within 120 days, $25 each, and show me the terms first.", "budget": {"amount": 250, "currency": "USD"}}'
npx startup-builder do Page.rank --try --data '{"goal": "Rank 10 pages for property manager searches within 120 days, $25 each, and show me the terms first.", "budget": {"amount": 250, "currency": "USD"}}'
{
"name": "do",
"arguments": {
"mode": "try",
"code": "return await $.Page.rank({ goal: 'Rank 10 pages for property manager searches within 120 days, $25 each, and show me the terms first.', budget: { amount: 250, currency: 'USD' } })"
}
}
import { $ } from 'startup-builder'
const result = await $.try.Page.rank({ goal: 'Rank 10 pages for property manager searches within 120 days, $25 each, and show me the terms first.', budget: { amount: 250, currency: 'USD' } })
{
"mode": "try",
"stored": false,
"estimate": "About $2.58 per 10 pages",
"bills": "$25 a ranked page",
"sample": {
"term": "rent ledger template",
"page": "leaseline.app/ rent-ledger-template",
"rank at day 120": "14",
"state": "ranked"
}
}
What you get
- 10 pages · pages on terms you can win, billed only when each reaches the top 20 on Google within 120 days; a miss is rewritten free. · Page
pages[]· Each page, its term, its rank each week, and its state:ranked,rewrittenorcredited.bill· Ranked pages times the price; a page that never ranks is never billed.
Connect once: Google Search Console, Bing Webmaster. How long: 120 days from each page going live, and 120 more for a rewrite.
Trigger
It runs when you call it, or on any Trigger you set.
await $.Workflow.create({ verb: 'Page.rank', trigger: { schedule: 'weekly' } })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. Pick winnable terms | Keyword.map | Ten terms at or under your difficulty ceiling, with 3 of the top 10 inside the links you can earn | About 87¢ | Runs on its own |
| 2. Write each page | Page.answer | A page that settles its term in the first 60 words, every claim sourced | About $1.18 | Goes out on its own |
| 3. Get each page indexed | Site.index | Each page held by Google and Bing, or the engine’s reason it is not | Free | Runs on its own |
| 4. Read each page’s rank every week | Keyword.search | Each page’s position for its term, weekly for 17 weeks | About 5.1¢ | Runs on its own |
| 5. Rewrite each page outside the top 20 at day 120 | Page.answer | The page rewritten against the pages that rank above it, at no charge | About 47¢ | Goes out on its own |
| 6. Read each rewrite’s rank for 120 more days | Keyword.search | Each rewrite’s position weekly; a second miss is credited | About 2¢ | Runs on its own |
Calls: Keyword.map, then Page.answer, then Site.index, then Keyword.search, then Page.answer, then Keyword.search.
About $2.58 per 10 pages, each time it runs, capped at $12.00.
Example: give it a goal
Rank 10 pages for property manager searches within 120 days, $25 each, and show me the terms first.
The plan it shows runs 6 steps, priced before it spends anything; Run it above shows the result it returns.
When something fails
Each failure, and what happens next
| When | Then |
|---|---|
| A page is not indexed by day 30 | Index the site names the engine’s reason, the fix runs, and the 120 days start from the day it is held. |
| Google changes the results page for a term | The weekly read records it; a term that turns into a results page with no organic slots in the top 20 is swapped for the next winnable term, at no charge. |
| You edit a page yourself | The warranty holds unless the edit removes the answer in its first 60 words; the read notes the edit date. |
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-rank-1-<step>-<item>.
What it promises
| Term | This Service |
|---|---|
| Done | The page ranks in the top 20 on Google Search for its term, in its locale, within 120 days of going live. |
| Counted by | Page.ranked |
| Billed | $25 a ranked page, on acceptance |
| Target | Each page in the order, one winnable term each. |
| Accepted when | Two weekly reads in a row in the top 20 accept the page. |
| Credited | A page that misses the top 20 after its free rewrite. |
| Remedy | A page outside the top 20 at day 120 is rewritten once at no charge and read for 120 more days; a second miss is credited. |
| Evaluator | Code reads the term’s results page on Google Search every week. |
| Window | 120 days from going live, then 120 more after a rewrite. |
| Assurance | measured, the weakest check on the way to done |
| Oversight | none: agents do every step |
Leaseline’s first order: 10 pages live on September 2, read at day 120 and again at day 240.
| Count | What happened |
|---|---|
| 10 | Ordered |
| 10 | Delivered |
| 6 | In the top 20 by day 120, and billed. |
| 4 | Outside it at day 120, so rewritten at no charge. |
| 2 | Rewrites in the top 20 by day 240, and billed. |
| 2 | Missed again: credited, never billed. |
| 8 | Accepted, billed 8 × $25 = $200 |
Change it
| Ask | Compiles to |
|---|---|
| Only terms at difficulty 20 or under. | Keyword.map |
| Read the rank on Bing too. | Keyword.search |
| Ten more pages next quarter, on the terms the first ten opened up. | Page.rank |
import { $, Service } from 'startup-builder'
export default Service({
name: 'page-rank',
verb: 'Page.rank',
input: { site: 'string', seeds: 'string[]', pages: 'integer', locale: 'string' },
maxCost: 12,
builtFrom: ['Keyword.map', 'Page.answer', 'Site.index'],
oversight: { posture: 'none' },
contract: {
done: 'Page.ranked', accept: { by: 'metric:rank' , top: 20, reads: 2 }, assurance: 'measured',
bills: { usd: 25, per: 'ranked page' }, window: '120d', remedy: 'rewrite-once-then-credit',
},
execute: async (ctx, { site, seeds, pages = 10, locale = 'en-US' }) => {
const map = await ctx.step('terms', () => $.Keyword.map({ seeds, site, winnable: true, limit: pages, maxCost: 1 }))
for (const term of map.terms) await ctx.step(`write: ${term.text}`, () => $.Page.answer({ question: term.text, site, maxCost: 0.3 }))
await ctx.step('index', () => $.Site.index({ site }))
await ctx.every('1w', { for: '120d' }, ($) => $.Keyword.search({ keywords: map.terms.map((t) => t.text), locale, maxCost: 0.3 }))
},
})Extend it with extends: and base(), or compose your own from these steps.
Works with
Plays that order it: Answer engine optimization, Category hubs, Editorial SEO, Programmatic SEO, Switch kit.
| Built from | Kind | Its own price |
|---|---|---|
| Keyword opportunity map | Workflow | About 87¢ per 300 terms |
| Answer page per question | Agent task | About 12¢ a page |
| Index the site | Workflow | Free |
It serves Make content. It deepens Content marketing and Demand generation.
For agents
For agents: the guide, its approvals, retries and lookups
| Fact | Value |
|---|---|
| Guide | Page.rank |
| Guide approval | limits |
| Goal | Rank 10 pages for property manager searches within 120 days, $25 each, and show me the terms 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. |
| Retry | Three times with backoff, then the next route; the same idempotency key never charges, sends or posts twice |
| Idempotency key | leaseline-page-rank-1 |
| Lookups | A find: input asks unless exactly one record fits |
| Step |
|---|
| 1. Pick winnable terms |
| 2. Write each page |
| 3. Get each page indexed |
| 4. Read each page’s rank every week |
| 5. Rewrite each page outside the top 20 at day 120 |
| 6. Read each rewrite’s rank for 120 more days |
The amounts live once, on the hub (approvals).
Who does each step, and how it is checked
| Step | Function | Doer | Checker | Assurance | Inputs |
|---|---|---|---|---|---|
| 1. Pick winnable terms | code | Code | Code keeps a term only when its difficulty and the top 10’s authority pass the declared winnable rule | measured | $0.seeds, |
| 2. Write each page | agentic | The Content lead agent | A second model checks every claim against its cited source before the page publishes | graded | $1.terms |
| 3. Get each page indexed | code | Code | Index state read daily from Google Search Console and Bing Webmaster until each page is held | measured | $2.pages |
| 4. Read each page’s rank every week | code | Code | The results page for the term, read on Google Search in your locale; two reads in a row in the top 20 settle it | measured | $1.terms, |
| 5. Rewrite each page outside the top 20 at day 120 | agentic | The Content lead agent | A second model reads the rewrite beside the top 3 results and names what it adds | graded | $4.missed |
| 6. Read each rewrite’s rank for 120 more days | code | Code | The same weekly results page read, for the rewrite’s 120 days | measured | $5.pages |
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 |
|---|---|---|---|
site | Hostname | Required | Your domain, connected once. |
seeds | string[] | Required | Three seed phrases in your buyers’ words; the map picks the winnable terms from them. |
pages | integer | 10 | Pages in the order, one term each. |
locale | string | 'en-US' | The results page each rank is read on. |
Emits Page.ranked. Refuses with max-cost before it spends, and with the Data calls and Accounts groups (refusals).