PBN.LTD API docs
View as Markdown

Agency SEO data

Authority and link data for up to 200 domains hosted anywhere, read every week: domain rank, referring domains, backlinks, spam score and the organic traffic estimate.

Agency SEO data: plan and usage

GET/api/v1/agency-seo-data

Scope agency:read

Your plan, how many domains it covers and how many you track.

Example

curl -s "https://app.pbn.ltd/api/v1/agency-seo-data" \
  -H "Authorization: Bearer $PBN_API_KEY"
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/agency-seo-data", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/agency-seo-data", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "plan": "200 domains",
    "unlimited": false,
    "paid_until": "2026-10-25",
    "tracked": 184,
    "switched_off": 3,
    "domains_included": 200,
    "moves_this_week": 2,
    "labels": [
      "Acme Ltd"
    ],
    "price_from": "49.00"
  }
}

Errors: rate_limited, scope_missing, unauthorized

List your tracked domains

GET/api/v1/agency-seo-data/domains

Scope agency:read

Every domain you track, with its latest weekly reading (null = not measured, never zero).

Parameters

NameInTypeRequiredDescription
labelquerystringnoOnly the domains with this client label.

Example

curl -s "https://app.pbn.ltd/api/v1/agency-seo-data/domains" \
  -H "Authorization: Bearer $PBN_API_KEY"
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/agency-seo-data/domains", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/agency-seo-data/domains", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": [
    {
      "id": 31,
      "domain": "client-site.com",
      "label": "Acme Ltd",
      "note": "",
      "country": "GB",
      "switched_on": true,
      "covered": true,
      "state": "ok",
      "domain_rank": 312,
      "referring_domains": 1480,
      "new_referring_domains": 22,
      "lost_referring_domains": 9,
      "backlinks": 40211,
      "spam_score": 4,
      "organic_traffic": "5210.4",
      "organic_keywords": 1893,
      "last_read_at": "2026-09-26T12:00:00Z"
    }
  ]
}

Errors: rate_limited, scope_missing, unauthorized

One tracked domain

GET/api/v1/agency-seo-data/domains/{item_id}

Scope agency:read

One domain with the history of its weekly readings (newest first, up to two years).

Parameters

NameInTypeRequiredDescription
item_idpathintegeryesThe tracked domain id.

Example

curl -s "https://app.pbn.ltd/api/v1/agency-seo-data/domains/item_id" \
  -H "Authorization: Bearer $PBN_API_KEY"
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/agency-seo-data/domains/item_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/agency-seo-data/domains/item_id", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "id": 31,
    "domain": "client-site.com",
    "label": "Acme Ltd",
    "note": "",
    "country": "GB",
    "switched_on": true,
    "covered": true,
    "state": "ok",
    "domain_rank": 312,
    "referring_domains": 1480,
    "new_referring_domains": 22,
    "lost_referring_domains": 9,
    "backlinks": 40211,
    "spam_score": 4,
    "organic_traffic": "5210.4",
    "organic_keywords": 1893,
    "last_read_at": "2026-09-26T12:00:00Z",
    "history": [
      {
        "read_at": "2026-09-19T12:00:00Z",
        "domain_rank": 309,
        "referring_domains": 1466,
        "backlinks": 39870,
        "spam_score": 4,
        "organic_traffic": "5102.0",
        "organic_keywords": 1870
      }
    ]
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized

Track domains

POST/api/v1/agency-seo-data/domains

Scope agency:write

Adds domains to your list; their first reading arrives within minutes. Adds as many as your plan has room for and says why each other one was skipped. Nothing is spent on a refusal.

Parameters

NameInTypeRequiredDescription
domainsbodyarrayyesThe domains, e.g. ["client-site.com", "other-client.co.uk"] (up to 500 per call).
countrybodystring (one of: US, GB, DE, FR, ES, IT, CA, AU)yesThe country for the organic traffic estimate (the list is kept by us and may grow).
labelbodystringnoA client label for all of them (up to 60 characters).

Example

curl -s -X POST "https://app.pbn.ltd/api/v1/agency-seo-data/domains" \
  -H "Authorization: Bearer $PBN_API_KEY"
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.post("https://app.pbn.ltd/api/v1/agency-seo-data/domains", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/agency-seo-data/domains", {
  method: "POST",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

201

{
  "data": {
    "added": [
      {
        "id": 31,
        "domain": "client-site.com",
        "label": "Acme Ltd",
        "note": "",
        "country": "GB",
        "switched_on": true,
        "covered": true,
        "state": "ok",
        "domain_rank": 312,
        "referring_domains": 1480,
        "new_referring_domains": 22,
        "lost_referring_domains": 9,
        "backlinks": 40211,
        "spam_score": 4,
        "organic_traffic": "5210.4",
        "organic_keywords": 1893,
        "last_read_at": "2026-09-26T12:00:00Z"
      }
    ],
    "skipped": [
      {
        "domain": "localhost",
        "reason": "does not look like a public domain"
      }
    ],
    "room_left": 15
  }
}

Errors: payment_required, rate_limited, scope_missing, unauthorized, validation_failed

Label or switch a tracked domain

PATCH/api/v1/agency-seo-data/domains/{item_id}

Scope agency:write

Changes the client label or note, or switches the domain off / on.

Parameters

NameInTypeRequiredDescription
item_idpathintegeryesThe tracked domain id.
labelbodystringnoThe client label (up to 60 characters).
notebodystringnoYour note (up to 120 characters).
switched_onbodybooleannofalse = keep it with its history but stop reading and counting it.

Example

curl -s -X PATCH "https://app.pbn.ltd/api/v1/agency-seo-data/domains/item_id" \
  -H "Authorization: Bearer $PBN_API_KEY"
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.patch("https://app.pbn.ltd/api/v1/agency-seo-data/domains/item_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/agency-seo-data/domains/item_id", {
  method: "PATCH",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "id": 31,
    "domain": "client-site.com",
    "label": "Acme Ltd",
    "note": "",
    "country": "GB",
    "switched_on": true,
    "covered": true,
    "state": "ok",
    "domain_rank": 312,
    "referring_domains": 1480,
    "new_referring_domains": 22,
    "lost_referring_domains": 9,
    "backlinks": 40211,
    "spam_score": 4,
    "organic_traffic": "5210.4",
    "organic_keywords": 1893,
    "last_read_at": "2026-09-26T12:00:00Z"
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized, validation_failed

Stop tracking a domain

DELETE/api/v1/agency-seo-data/domains/{item_id}

Scope agency:write

Removes the domain from your list.

Parameters

NameInTypeRequiredDescription
item_idpathintegeryesThe tracked domain id.

Example

curl -s -X DELETE "https://app.pbn.ltd/api/v1/agency-seo-data/domains/item_id" \
  -H "Authorization: Bearer $PBN_API_KEY"
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.delete("https://app.pbn.ltd/api/v1/agency-seo-data/domains/item_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/agency-seo-data/domains/item_id", {
  method: "DELETE",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "deleted": true
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized