Skip to content

Domain.findLinks

List who links to a domain, with anchors and follow status, and the sites that link to your rivals but not to you.

Price
2¢ per 100 links
Success rate
100% of 3,967 calls
Freshness
Fresh for 30 days
Emits
Domain.linksFound
Capability
Market data
POST https://api.sb/{your-domain}/domains/find-links

Options and prices

You getInput that selects itPriceSuccess rate
Every link, with its anchor and follow status{"group":"links"}About 2¢ per 100 links100% of 3,967 calls
The sites that link{"group":"sites"}About 2¢ per 100 sites100% of 3,967 calls
Sites linking to your rivals and not to you{"group":"sites","gap":["rentrival.example"]}About 2¢ per 100 site compareds100% of 3,967 calls
Anchor text, counted{"group":"anchors"}About 0.7¢ a report100% of 491 calls
Links gained and lost by month{"group":"changes"}About 2.4¢ a report100% of 298 calls
Is a link you earned still live{"check":["https://nwpropertymanagers.org/vendors"]}About 1.3¢ a source checked100% of 4 calls

Inputs

NameTypeDefaultMeaning
hostnameHostnameRequiredThe domain to read links to: yours or a rival’s.
scope'domain' | 'host' | 'url''domain'Links to the whole domain, one host, or one URL in hostname.
group'links' | 'sites' | 'anchors' | 'changes''links'What the rows are. Each is its own job with its own price.
gapHostname[]None.Up to 5 rivals: sites linking to them and not to hostname. Use with group: sites.
checkstring[]None.Up to 50 page URLs that should link to you: is each link still there?
where{ follow?: boolean; minAuthority?: number; maxSpam?: number; since?: string }None.Filters run before rows are billed. Gap lists fill with hubs and directories, so set minAuthority and maxSpam.
limitnumber100Rows a page, at most 10,000. You pay for rows returned, never rows asked for.
afterCursorNone.The cursor from the last page.
maxCostnumber0.50The 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
links{ from: string; to: string; anchor: string | null; follow: boolean; firstSeen: string | null; lastSeen: string | null; live?: boolean }[]Present with group: links or check; anchor: null is an image link.
sites{ hostname: Hostname; authority: number | null; spamScore: number | null; links: number; follow: boolean | null; linksTo: Hostname[] }[]Present with group: sites. linksTo names the rivals each site links to with gap; follow: null means mixed.
anchors{ text: string; links: number }[]Present with group: anchors.
changes{ month: string; gained: number; lost: number }[], in referring domains a monthPresent with group: changes; a month with no reading is left out.
afterCursorThe last page: there are no more rows.
(report)ObservedThe report 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
sites.linksTo2 or more rivalsThe site links to products like yours already, so it may link to one more.Find the editor, then send one ask that names the page and why it helps their reader. (the link-gap playbook)
sitesA gap list of 120 domainsPlanning: 120 filter to about 40 worth asking, 70% have an editor you can find, and 10% to 15% say yes.Expect 3 to 4 links from 28 asks; replace these rates with your own after the first 30. (our planning numbers)
followfalseThe link sends visitors but passes no ranking weight.Count it toward referral traffic, not toward your referring-domain target. (how search engines treat nofollow and ugc links)
links.toMostly your home pageYour target pages earn no weight of their own.Point the next asks at the pages you want ranked, and link them from the home page. (the backlinks playbook)
changes.lostEvery weekListings are lapsing or paid placements are expiring.Check each source with check; renew only those that send visitors. (the backlinks playbook)

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

Nothing is written to your records. Link readings are shared across startups for 30 days.

Emits

Domain.linksFound with { hostname, group, gap, rows }

Performed by

Analyst

Price

About 2¢ per 100 links. Free: rows filtered out by where before they return. maxCost defaults to 50¢. 3 rivals × 200 linking sites, diffed against yours: 600 × 0.02¢ a site compared is about 12¢.

Reliability

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

Freshness

A reading younger than 30 days returns at $0. Readings are shared across startups for the same subject and locale.

Batch and pages

Up to 10,000 rows a page. Pages with an after cursor, 25 rows a page by default and 100 at most. 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
Which sites link to rentrival.example and ledgerly.example but not to
leaseline.app? Spend up to 15¢.

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: 'Domain.findLinks',
  input: { hostname: 'leaseline.app', group: 'changes' },
  change: 'link-lost',
  every: '1w',
})

Used by