Domain .verify
Check your domain’s DNS and certificate, whether Google and Bing read its sitemap, and each key page’s index state with its fix.
- Price
- Free
- Success rate
- 99.8% of 45,746 calls
- Freshness
- Read fresh each call
- Emits
Domain.verified- Capability
- Domains
POST https: //api.sb/ {your-domain}/ domains/ verify
Inputs
| Name | Type | Default | Meaning |
|---|---|---|---|
domain | Domain | Required | Your Domain id. Also served at /, as the hub defines it. |
pages | string[] | the Site’s key Pages | Pages to inspect, up to 2,000 a day per site, shared with every other tool on that property. |
Outputs
| Field | Type | What null means |
|---|---|---|
domain | Domain | Never null: with its state after the checks. |
dns | { ok: | Never null. fix is null when ok. |
certificate | { ok: | Never null. fix is null when ok. |
searchEngines | { venue: | Never null. sitemap: means no sitemap was read yet. |
pages | { url: | Never null: one row per page inspected. |
pages[].state | 'indexed' | 'discovered-not-indexed' | 'crawled-not-indexed' | 'duplicate' | 'not-seen' | 'excluded' | Never null. |
pages[].reason | string | null | Null when indexed; otherwise the engine’s own wording. |
pages[].lastCrawl | string | null, in ISO 8601 | Never crawled. |
pages[].canonical | string | null | The engine has not chosen one yet. |
lagDays | number, in days | Never null: how far behind the engine’s own report runs, about 2 days. |
observedAt | string, in ISO 8601 | Never null. |
method | 'reported' | 'sampled' | Never null. Google reads reported; Bing has no reporting API, so its fields are read by a browser agent and read sampled. |
Read the result
| Field | Value | What it means | What to do |
|---|---|---|---|
pages[].state | not-seen | The engine has never found the page. | Confirm it is in the sitemap, link it from 2 indexed pages, and earn one followed outside link. (the index-state playbook) |
pages[].state | discovered-not-indexed | Found, not crawled yet: low priority on a new domain. | Link it from the home and pricing pages; request indexing for key pages only. (the index-state playbook) |
pages[].state | crawled-not-indexed | Crawled and judged not worth indexing yet. | Merge thin pages and add a fact only you have. Do not request again until the page changed. (the index-state playbook) |
pages | Key pages indexed | Under 80% by week 2, or under 100% by week 4, means discovery is the problem, not content. | Fix discovery before you write another page. (our planning numbers) |
pages | Over 30% crawled-not-indexed at week 6 | A quality problem across the site. | Pause publishing and fix the thin pages first. (our planning number) |
Effects
- Action class
None: no approval rule names it, so it runs within its seat’s Permissions and Limits
- Modes
try: Runs every check and returns the results; nothing is written onto the Domain.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-Keywith the same input replays the first answer at $0; with other input it returns 409.- Saved or shared
Writes each check onto the Domain; a failed check moves a live Domain to
degraded, and a degraded canonical Domain opens an Incident.- Emits
Domain.verifiedwith{ domain,dns, certificate, searchEngines, pages } - Performed by
- Price
Free. Free: every check, read from your own Search Console.
- Reliability
The first route succeeds 99.8% of 45,746 calls. If it fails, the call refuses with
sources-busyand nothing is spent.- Freshness
Every call reads fresh. Readings about people are never shared across startups. The source runs 2 days behind.
- Batch and pages
Up to 2,000 pages a day per site. 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
| Check | Error | Fix | Then call |
|---|---|---|---|
| The call needs an account you have not connected, such as your Search Console property or your Meta ad account | account-not-connected | Connect the account with POST /{namespace}/integrations/connect, approve it at the connectUrl, then send the call again. | Integration.connect |
| The account’s own daily or per-minute cap is used up, such as 2,000 page checks a day per Search Console property | quota-reached | Retry after the reset time the response gives; nothing was sent or spent. | Action.retry |
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.
The account-not-connected payload
{
"type": "https://startupbuilder.dev/errors/account-not-connected" ,
"title": "Account not connected",
"status": 409,
"detail": "The call needs an account you have not connected, such as your Search Console property or your Meta ad account." ,
"fix": "Connect the account with Integration.connect, approve it at the connectUrl, then send the call again." ,
"next": {
"verb": "Integration.connect",
"input": {
"system": "ads",
"venue": "facebook",
"scope": "startup",
"grants": [
"ads_management",
"ads_read"
]
}
},
"instance": "https://api.sb/leaseline.app/actions/action_1"
}When it waits
Returns in one response; nothing waits.
Example
Is leaseline.app verified on Google and Bing, and is the rent ledger
template page indexed yet? Spend nothing. 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 value | Always returns | What it is for |
|---|---|---|
maxCost: | Refuses with max-cost | Any priced call with a maxCost of 0.0001 is refused before it spends: the price is above the cap. |
rate-limited.test | Refuses with rate-limited | Any call naming this hostname answers 429 with Retry-After, so your retry logic runs. |
sources-busy.test | Refuses with sources-busy | Any 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.
await $.Monitor.create({
verb: 'Domain.verify',
input: { domain: 'domain_ut1ZlxY4Z1' },
change: 'index-change',
every: '1d',
})Used by
- Workflows: AI answer audit · Index the site
- Agent tasks: Answer page per question
- Jobs: Get indexed · Measure