List backlink outreach prospects
curl --request GET \
--url https://api.snowseo.com/v3/outreach/prospects \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.snowseo.com/v3/outreach/prospects"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.snowseo.com/v3/outreach/prospects', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.snowseo.com/v3/outreach/prospects",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.snowseo.com/v3/outreach/prospects"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.snowseo.com/v3/outreach/prospects")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.snowseo.com/v3/outreach/prospects")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"prospects": [
{
"id": "<string>",
"domain": "<string>",
"source": "<string>",
"status": "<string>",
"isNew": true,
"createdAt": "<string>",
"updatedAt": "<string>",
"lastActivityAt": "<string>",
"targetPage": {
"id": "<string>",
"url": "<string>",
"title": "<string>",
"source": "<string>",
"matchedQuery": "<string>",
"pageType": "<string>",
"linkStatus": "<string>",
"topicalFit": 123
},
"domainRating": 123,
"opportunity": "<string>",
"opportunityDetails": {
"code": "<string>",
"label": "<string>",
"description": "<string>",
"strength": 123,
"action": "<string>"
},
"lane": {
"code": "<string>",
"label": "<string>",
"action": "<string>",
"hint": "<string>",
"channel": "<string>"
},
"linkStatus": "<string>",
"linkEvidence": "<string>",
"reasons": [
"<string>"
],
"nextStep": "<string>",
"worth": 123,
"worthBand": "strong",
"worthDetails": {
"score": 123,
"band": "<string>",
"label": "<string>"
},
"odds": 123,
"oddsBand": "high",
"oddsDetails": {
"score": 123,
"band": "<string>",
"label": "<string>"
},
"relationship": "<string>",
"relationshipDetails": {
"code": "<string>",
"label": "<string>",
"description": "<string>"
},
"actionable": true,
"linkPlay": "<string>",
"playbook": {
"play": "<string>",
"title": "<string>",
"summary": "<string>",
"steps": [
"<string>"
]
},
"outreachStage": "<string>",
"contactReadiness": {
"code": "<string>",
"label": "<string>",
"description": "<string>",
"rank": 123,
"channel": "<string>"
},
"peopleCount": 123,
"pageCount": 123,
"emails": [
{
"id": "<string>",
"email": "<string>",
"name": "<string>",
"role": "<string>",
"verifiedStatus": "<string>",
"confidence": 123,
"isPrimary": true
}
],
"analysis": "<string>",
"doNotContact": true
}
],
"discoveryStatus": "running",
"mentionCheckStatus": "running",
"relationshipSweepStatus": "running",
"mentionCheckProgress": {
"done": 123,
"total": 123
}
}Backlink Outreach
Prospects
Find sites worth pitching for a backlink, manage the list, and check whether the links went live.
GET
/
v3
/
outreach
/
prospects
List backlink outreach prospects
curl --request GET \
--url https://api.snowseo.com/v3/outreach/prospects \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.snowseo.com/v3/outreach/prospects"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.snowseo.com/v3/outreach/prospects', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.snowseo.com/v3/outreach/prospects",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.snowseo.com/v3/outreach/prospects"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.snowseo.com/v3/outreach/prospects")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.snowseo.com/v3/outreach/prospects")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"prospects": [
{
"id": "<string>",
"domain": "<string>",
"source": "<string>",
"status": "<string>",
"isNew": true,
"createdAt": "<string>",
"updatedAt": "<string>",
"lastActivityAt": "<string>",
"targetPage": {
"id": "<string>",
"url": "<string>",
"title": "<string>",
"source": "<string>",
"matchedQuery": "<string>",
"pageType": "<string>",
"linkStatus": "<string>",
"topicalFit": 123
},
"domainRating": 123,
"opportunity": "<string>",
"opportunityDetails": {
"code": "<string>",
"label": "<string>",
"description": "<string>",
"strength": 123,
"action": "<string>"
},
"lane": {
"code": "<string>",
"label": "<string>",
"action": "<string>",
"hint": "<string>",
"channel": "<string>"
},
"linkStatus": "<string>",
"linkEvidence": "<string>",
"reasons": [
"<string>"
],
"nextStep": "<string>",
"worth": 123,
"worthBand": "strong",
"worthDetails": {
"score": 123,
"band": "<string>",
"label": "<string>"
},
"odds": 123,
"oddsBand": "high",
"oddsDetails": {
"score": 123,
"band": "<string>",
"label": "<string>"
},
"relationship": "<string>",
"relationshipDetails": {
"code": "<string>",
"label": "<string>",
"description": "<string>"
},
"actionable": true,
"linkPlay": "<string>",
"playbook": {
"play": "<string>",
"title": "<string>",
"summary": "<string>",
"steps": [
"<string>"
]
},
"outreachStage": "<string>",
"contactReadiness": {
"code": "<string>",
"label": "<string>",
"description": "<string>",
"rank": 123,
"channel": "<string>"
},
"peopleCount": 123,
"pageCount": 123,
"emails": [
{
"id": "<string>",
"email": "<string>",
"name": "<string>",
"role": "<string>",
"verifiedStatus": "<string>",
"confidence": 123,
"isPrimary": true
}
],
"analysis": "<string>",
"doNotContact": true
}
],
"discoveryStatus": "running",
"mentionCheckStatus": "running",
"relationshipSweepStatus": "running",
"mentionCheckProgress": {
"done": 123,
"total": 123
}
}A prospect is one website that could link to you, plus the specific page the link would go on. This group covers finding them, curating the list, and re-checking earned links.
Key fields on each prospect
The response also carries
Costs 25 AI credits. Your brand’s very first prospect list is generated automatically and free of charge the first time the prospects list is read.
This endpoint never fails as a whole. Unparseable entries are counted in
Backlink Outreach is in beta. Endpoints live under
/v3/outreach and every request is scoped to the brand your API key belongs to, so there is no teamId to pass. See Authentication.Several of these endpoints spend credits. Every one that does says so below. Background work is tracked through the prospect and mailbox statuses, without exposing queue job IDs.
List prospects
GET /outreach/prospects
Every prospect for the brand, most recently active first, with the page it would be pitched about, its Domain Rating, contact counts and pipeline stage. Activity on a prospect’s people or pages moves it up the list. This is the starting point for any outreach question.
Query parameters
| Parameter | Description |
|---|---|
status | Filter by how far the contact search got: pending, finding_people, people_found, no_people, failed |
source | Filter to prospects with at least one page from this discovery source: query-expansion, keyword-serp, ai-citation, manual |
| Field | What it tells you |
|---|---|
domain | The site |
targetPage | The page the pitch is about - URL, title, page type, and the search that surfaced it. null for a hand-added bare domain |
domainRating | Domain Rating, 0-100. null until fetched |
opportunity | The ask: fix-broken-link, ask-for-link, offer-alternative, get-listed, pitch, or already-linked |
linkStatus | What the crawl found about your domain on their pages: linked, unlinked, broken, absent, or unknown |
worth / worthBand | What the link is worth, 0-100 and a band |
odds / oddsBand | How likely the ask is to land: high, medium, long |
reasons / nextStep | Evidence behind the recommendation and the suggested next action |
actionable | false when there is nothing left to pitch or the site is a direct competitor |
relationship | Who publishes it: publisher, vendor_adjacent, directory, community, competitor, unknown |
linkPlay | How the link is actually earned: outreach, creator, self-serve, community |
playbook | Step-by-step instructions, present only when linkPlay is not outreach |
outreachStage | Pipeline stage: not_started, people_found, enriched, contacted, negotiating, won |
peopleCount | People found at the site |
emails | Contact addresses found so far |
doNotContact | Excluded from sending, but still on the list |
discoveryStatus, mentionCheckStatus and relationshipSweepStatus. Keep polling while any is running. Each prospect’s status reports contact search progress; analysis: "rechecking" reports a link re-check in progress.
The API returns activity order. You can sort the returned rows by
odds for quick wins or by worth for high-value targets. Those signals can disagree: a valuable link may still be unlikely to earn.Find new prospects
POST /outreach/discover/run
Open the request and response reference.
Searches for pages that mention your brand, your category or your competitors and turns them into prospects. Takes no arguments - the search plan is built from your brand name and website, so both must be set in brand settings first.
Runs in the background. Poll the prospects list while its discovery, mention-check or relationship-sweep status is running.
Response
| Field | Description |
|---|---|
status | running while discovery is underway |
creditsCharged | Credits spent on this search |
alreadyRunning | true when a search was already in flight; nothing is charged |
A
409 means every search angle has been used recently and a new pass would return the same sites. Track more keywords or add a topic cluster, then try again. Nothing is charged. A 503 means the search is briefly unavailable and is safe to retry; a 402 means you are out of credits.Add prospects
POST /outreach/prospects
Add sites you already know are worth pitching. Discovery finds prospects on its own - use this for the ones you bring yourself.
Body
| Field | Description |
|---|---|
domain | A single domain or full URL. Shorthand for a one-entry domains |
domains | Array of domains or full URLs, up to 200 per call |
Pass the full URL of the page you want the link on whenever you know it: the site becomes the prospect and that page becomes what the pitch is written about. A bare domain or a home page records no page, which leaves the draft writer with nothing specific to point at.
invalid, domains already on the list in skipped, and prospects carries only the rows actually created. New prospects start with no contacts - run Find people next.
Delete a prospect
DELETE /outreach/prospects/{id}
Removes one prospect. It can be found again by a future search - use Block below to keep it out for good.
Block prospects
POST /outreach/prospects/block
Removes prospects and stops them ever returning from discovery. Use this for sites you do not want to be associated with, or anyone who has asked not to be contacted.
Body
| Field | Description |
|---|---|
prospectIds | Prospect IDs to block, up to 50 |
reason | Optional note shown in the blocked list, up to 200 characters |
An ordinary site is blocked by domain, so
removed can be higher than the number of IDs you sent when that site has several prospect rows. A prospect on a creator platform (a YouTube channel, a Substack) blocks only that creator and leaves the rest of the platform discoverable.Unblock a domain
DELETE /outreach/prospects/blocked/{domain}
Removes the block so the site can be discovered again. Pass creatorHandle as a query parameter to unblock a single creator rather than the whole domain.
Set a prospect’s relationship
PATCH /outreach/prospects/relationship
Corrects who SnowSEO thinks publishes a site. The common use is rescuing a prospect wrongly filed as a competitor.
Body: prospectIds, and relationship - one of publisher, vendor_adjacent, directory, community, competitor.
A decision made here is final: it outranks anything the classifier later concludes.
Override a prospect’s stage
PATCH /outreach/prospects/{id}/stage
Pins a prospect to a pipeline stage, or clears the override.
Body: stage - one of contacted, negotiating, won, or null to clear.
The stage is normally derived from real signals - contacts found, mail sent, replies received, links confirmed - so only override it to record something that happened off-platform. A prospect cannot be moved backwards, and an override never hides a reply or a confirmed link that arrives later.
Choose which page to pitch
PATCH /outreach/prospects/{id}/target-page
Picks a different page as the one the pitch is about.
Body: mentionId - the ID of one of the prospect’s pages, or null to go back to the automatic choice.
List a prospect’s pages
GET /outreach/prospects/{id}/pages
Every page found on one site, with its link status, page type, the query that surfaced it and where it ranked. Paginate with limit and offset.
List every page
GET /outreach/prospects/pages
The same rows across all prospects, one per page, for export. Cap with limit. The response flags when the ceiling was hit so you never hand over a quietly short file.
Re-check links
POST /outreach/prospects/recheck
Re-crawls a prospect’s pages to see whether the backlink went live, and updates linkStatus. A confirmed link moves the prospect to won on its own.
Body: prospectIds, up to 50.
Runs in the background. The response includes the accepted prospectIds. Poll the prospects list while those rows have analysis: "rechecking", then read linkStatus for the verdict. No job ID or separate job-status endpoint is needed.
Costs one page crawl per page read. Run it after a reply suggests the link was added, not speculatively.
To have this run on a schedule instead, switch on auto re-checking in Outreach automation.
Rate limits
Outreach endpoints are individually rate limited, with the tightest limits on the ones that spend money - discovery, enrichment, re-checks and sending. A429 carries a Retry-After header. Back off rather than retrying immediately.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Query Parameters
Filter by how far the contact search has got for each prospect.
Available options:
pending, finding_people, people_found, no_people, failed Filter to prospects with at least one page from this discovery source.
Response
200 - application/json
Default Response
Was this page helpful?

