Skip to content

Page.audit

Check one page the way a search engine reads it, from title and canonical to structured data and load time, with each fix.

Price
2¢ per 100 pages
Success rate
100% of 14,847 calls
Freshness
Fresh for 1 day
Emits
Page.audited
Capability
Web
POST https://api.sb/{your-domain}/pages/audit

Options and prices

You getInput that selects itPriceSuccess rate
The page as served{"render":"none"}About 2¢ per 100 pages100% of 14,847 calls
The page after its scripts run{"render":"js"}About 15¢ per 100 pages100% of 14,847 calls
Fully rendered, with Core Web Vitals{"render":"full"}About 50¢ per 100 pages100% of 14,847 calls

Inputs

NameTypeDefaultMeaning
pagePageNone.One of your pages. Also served at /pages/{page}/audit. Pass this or url.
urlstringNone.Any public page, a rival’s included.
render'none' | 'js' | 'full''none'How far to render. A page built in the browser needs js; full adds load timings.
maxAgestring'1d'An audit younger than this returns at $0.
maxCostnumber0.05The most this call may spend, in USD. Over it, the call is refused before it spends, or stops early with what it has.

Outputs

FieldTypeWhat null means
urlstringNever null: the URL after redirects.
scorenumber, in 0 to 100, share of weighted checks passedNever null.
checks{ id: string; pass: boolean; detail: string | null; fix: string | null }[]Never null: every check run. fix is null on a pass.
timings{ lcpMs: number; cls: number; inpMs: number | null } | nullNull unless render: full; inpMs: null when the page has no interaction to time.
(page)ObservedThe audit carries observedAt and method.
costCost, in USDNever null. In try mode usd is 0 and maxUsd is what the call would have cost.

Read the result

FieldValueWhat it meansWhat to do
timings.lcpMsOver 2,500The largest element paints too slowly to rate good.Compress and size the hero image, and serve it first. (the Core Web Vitals thresholds: 2.5 seconds, 0.1 and 200 milliseconds)
timings.clsOver 0.1The layout jumps while loading.Give images and embeds their width and height. (the Core Web Vitals thresholds)
checksai-crawlers failingThe AI search crawlers are blocked, so answer engines cannot cite the page.Allow them in robots.txt; check the page again before you track AI answers. (the AEO playbook)
checksstructured-data failing on a page of questionsSearch engines cannot tell the questions and answers apart.Add FAQ structured data with the exact question wording buyers use. (the AEO playbook)
scoreUnder 80 on a page you want indexedFailing checks are likely holding it back.Fix the failing checks before the page is published or asked for links. (our planning number)

Effects

Action class

None: it reads, so no approval rule names it

Modes
  • try: Runs the read and returns real rows; nothing is saved and nothing is billed.
  • send: Returns a pending Action at once; its Event carries the rows when the read finishes.
  • do: Waits for the read and returns the rows, billed per result.
Idempotency

The same Idempotency-Key with the same input replays the first answer at $0; with other input it returns 409.

Saved or shared

Writes the audit onto your page when page is passed; a held page leaves held only once its checks pass. Audits of other sites are yours alone.

Emits

Page.audited with { url, score, checks, timings }

Performed by

Analyst

Price

About 2¢ per 100 pages. Free: an audit younger than maxAge. maxCost defaults to 5¢. Every page of a 48-page site, fully rendered: 48 × 0.5¢ a page is about 24¢.

Reliability

The first route succeeds 100% of 14,847 calls. If it fails, the call refuses with sources-busy and nothing is spent.

Freshness

A reading younger than 1 day returns at $0. Readings about people are never shared across startups.

Batch and pages

Up to 1 page a call. It answers in one response.

Rate

The shared rate rules: 10 calls a second per key, and an array input counts as one call.

Refuses when

This call has no refusals of its own. Every data call can also meet the shared data-call refusals: filter-unsupported, input-missing, limit-exceeded, max-cost, rate-limited, sources-busy, venue-unsupported.

When it waits

Returns in one response; nothing waits.

Example

Text
What is wrong with leaseline.app/rent-ledger-template the way a search
engine reads it? Spend up to 1¢.

To retry, send the same Idempotency-Key: the retry returns the first answer for $0. A new key reads again.

Test values, and watching it

A sk_test_ key answers these the same way every time, at $0 (every test value).

Test valueAlways returnsWhat it is for
maxCost: 0.0001Refuses with max-costAny priced call with a maxCost of 0.0001 is refused before it spends: the price is above the cap.
rate-limited.testRefuses with rate-limitedAny call naming this hostname answers 429 with Retry-After, so your retry logic runs.
sources-busy.testRefuses with sources-busyAny call naming this hostname answers 503 as if every route were busy, and nothing is spent.

Watch it on a schedule: a Monitor runs this call and records an Event only when the reading changes.

TypeScript
await $.Monitor.create({
  verb: 'Page.audit',
  input: { url: 'https://rentrival.example/pricing' },
  change: 'page-change',
  every: '1d',
})

Used by