Batch Lookup
Look up backlinks for up to 50 domains in a single request, charged only for lookups that succeed.
POST
/v1/batch2 credits (per successful domain, charged after the lookups)API keyRuns a backlinks lookup for each domain in your list and returns one result per domain. Use it to screen a list of prospects or competitors without making dozens of separate calls. Each lookup is the same as Backlinks with its defaults (limit=100, no scoring). Data comes from the pre-processed link graph snapshot (see Response format).
Request
Body
Send JSON with a Content-Type: application/json header.
| Field | Type | Required | Description |
|---|---|---|---|
domains | array of strings | Yes | Between 1 and 50 domains, for example ["stripe.com", "github.com"]. |
Notes on the list:
- Domains are lowercased and trimmed. Entries that are not valid domains (no dot, illegal characters) are silently dropped. If none are valid, the call fails with
invalid_domains. - The limit of 50 applies after invalid entries are dropped.
- Duplicates are not removed. A domain listed twice is looked up and charged twice.
- There are no per-domain options. To use
limit,sort,scoreor filters, call Backlinks directly.
Example
curl -X POST "https://api.rankparse.com/v1/batch" \
-H "X-API-Key: rp_your_key" \
-H "Content-Type: application/json" \
-d '{"domains": ["stripe.com", "github.com", "smartify.in"]}'import requests
res = requests.post(
"https://api.rankparse.com/v1/batch",
json={"domains": ["stripe.com", "github.com", "smartify.in"]},
headers={"X-API-Key": "rp_your_key"},
timeout=120,
)
res.raise_for_status()
body = res.json()
for item in body["data"]:
if item["success"]:
print(item["domain"], item["total"])
else:
print(item["domain"], "failed:", item["error"])
print("charged", body["credits_used"])const res = await fetch("https://api.rankparse.com/v1/batch", {
method: "POST",
headers: {
"X-API-Key": "rp_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({ domains: ["stripe.com", "github.com", "smartify.in"] }),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const { data, credits_used } = await res.json();
for (const item of data) {
console.log(item.domain, item.success ? item.total : item.error);
}
console.log("charged", credits_used);Response
{
"data": [
{
"domain": "stripe.com",
"data": [
{
"from_domain": "techcrunch.com",
"from_url": "https://techcrunch.com/2025/11/04/stripe-launches-new-billing-tools/",
"to_url": "https://stripe.com/billing",
"anchor_text": "Stripe Billing",
"rel": null,
"link_type": "hyperlink",
"crawled_at": "2026-02-10"
}
],
"total": 1,
"success": true
},
{
"domain": "github.com",
"data": [],
"total": 0,
"success": true
},
{
"domain": "smartify.in",
"data": [],
"total": 0,
"success": false,
"error": "R2 SQL timeout after 45000ms"
}
],
"credits_used": 4,
"credits_remaining": 996
}Response fields
Top level:
| Field | Type | Description |
|---|---|---|
data | array | One result per valid input domain, in input order. |
credits_used | integer | 2 times the number of successful lookups. |
credits_remaining | integer | Your balance after this call. |
Each result in data:
| Field | Type | Description |
|---|---|---|
domain | string | The normalized domain. |
success | boolean | true when the lookup completed (including when it found nothing), false when it failed. |
data | array | Up to 100 backlink rows, the same shape as Backlinks. Empty on failure or when there is no data. |
total | integer | Number of rows in this result's data. |
error | string | Only on failed results: a short message describing the failure. |
Behavior and limits
- Cost: 2 credits per successful domain. Failed domains (
success: false) are not charged. The total is deducted in one atomic step after all lookups finish, so the response shows the real amount. - Insufficient credits: because charging happens after the lookups, a balance that cannot cover the successful lookups returns
402 insufficient_creditsand nothing is deducted. Keep a balance of at least2 xthe number of domains. - Partial failure: one failing domain does not fail the request. Check
successon every result and retry failed domains separately. - Concurrency: up to 6 lookups run in parallel, so a full batch of 50 can take a while. Use a generous client timeout.
- No caching of the batch: each call runs its lookups fresh, unlike the single-domain endpoints.
- Empty results: a domain with no data returns
success: truewithdata: []andtotal: 0. - Rate limit: 60 requests per minute per key. A batch counts as one request.
Errors
| HTTP | Code | When |
|---|---|---|
| 400 | invalid_domains | domains is missing, not an array, empty, or contains no valid domains. |
| 400 | too_many_domains | More than 50 valid domains. The message reads max 50 domains per batch request. |
| 401 | invalid_api_key | Missing, invalid or revoked API key. |
| 402 | insufficient_credits | Balance cannot cover the successful lookups. |
| 402 | spend_cap_reached | Your monthly spend cap is reached. |
| 429 | rate_limited | More than 60 requests in a minute. |
See Errors for the full list and the error body format.
Related
MCP tool: batch_lookup (accepts domains).