PBN.LTD API docs
View as Markdown

AI visibility

Do AI assistants (ChatGPT, Google AI answers and others) name your brand when people ask the questions you care about? Track prompts, answers and competitors.

AI visibility: plan and usage

GET/api/v1/ai-visibility

Scope aivis:read

Whether AI visibility is on this account, the plan, how many prompts it covers and how many are tracked, how often they are asked, the number of tracked brands and your average visibility (% of answers that named you). When it is not on the account, plans_url is the page to buy it.

Example

curl -s "https://app.pbn.ltd/api/v1/ai-visibility" \
  -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/ai-visibility", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "active": true,
    "plan": "Growth",
    "paid_until": "2026-10-31",
    "prompts": {
      "used": 12,
      "limit": 25
    },
    "cadence": "weekly",
    "brands": 2,
    "visibility": 38.5,
    "reduced_this_month": false,
    "plans_url": "https://app.pbn.ltd/ai-visibility/plans/"
  }
}

Errors: rate_limited, scope_missing, unauthorized

AI visibility plans, prices and assistants

GET/api/v1/ai-visibility/plans

Scope aivis:read

The plans and the extra-prompt pack with their live prices (US dollars a month, before VAT), and the AI assistants a prompt can be asked of (their keys are what engines takes). Buying happens on plans_url in the browser - the API never charges.

Example

curl -s "https://app.pbn.ltd/api/v1/ai-visibility/plans" \
  -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/ai-visibility/plans", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/plans", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "plans": [
      {
        "key": "ai25",
        "name": "Growth",
        "price_usd": "19.00",
        "prompts": 25,
        "cadence": "weekly",
        "summary": ""
      }
    ],
    "pack": {
      "key": "ai10",
      "name": "+10 prompts",
      "price_usd": "5.00",
      "prompts": 10,
      "max_per_account": 40
    },
    "engines": [
      {
        "key": "chatgpt",
        "name": "ChatGPT",
        "default": true
      }
    ],
    "months_offered": [
      1,
      3,
      6,
      12
    ],
    "can_buy": true,
    "plans_url": "https://app.pbn.ltd/ai-visibility/plans/"
  }
}

Errors: rate_limited, scope_missing, unauthorized

List tracked brands

GET/api/v1/ai-visibility/brands

Scope aivis:read

Every brand (domain) you track, with its visibility numbers.

Example

curl -s "https://app.pbn.ltd/api/v1/ai-visibility/brands" \
  -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/ai-visibility/brands", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/brands", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": [
    {
      "id": 14,
      "domain": "example.com",
      "brand_name": "Example",
      "hosted_site_id": null,
      "market": {
        "location_code": 2840,
        "location": "United States",
        "country": "US",
        "language_code": "en",
        "language": "English"
      },
      "prompts": 12,
      "visibility": 41.7,
      "prev_visibility": 33.3,
      "share_of_voice": 12.5,
      "mentions": 20,
      "answers": 48,
      "last_checked_at": "2026-09-24T06:00:00Z",
      "url": "https://app.pbn.ltd/ai-visibility/brand/14/"
    }
  ]
}

Errors: rate_limited, scope_missing, unauthorized

One brand: prompts, latest answers, competitors, trend

GET/api/v1/ai-visibility/brands/{brand_id}

Scope aivis:read

The brand, every prompt with the latest answer from each assistant, the domains cited instead of you, the daily visibility trend and starter prompts you could add.

Parameters

NameInTypeRequiredDescription
brand_idpathintegeryesThe tracked brand id.
daysqueryintegernoDays of daily visibility trend (1-400). Default: 90.

Example

curl -s "https://app.pbn.ltd/api/v1/ai-visibility/brands/brand_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/ai-visibility/brands/brand_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/brands/brand_id", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "id": 14,
    "domain": "example.com",
    "brand_name": "Example",
    "hosted_site_id": null,
    "market": {
      "location_code": 2840,
      "location": "United States",
      "country": "US",
      "language_code": "en",
      "language": "English"
    },
    "prompts": 12,
    "visibility": 41.7,
    "prev_visibility": 33.3,
    "share_of_voice": 12.5,
    "mentions": 20,
    "answers": 48,
    "last_checked_at": "2026-09-24T06:00:00Z",
    "url": "https://app.pbn.ltd/ai-visibility/brand/14/",
    "prompt_list": [
      {
        "id": 311,
        "brand_id": 14,
        "text": "What are the best widget shops?",
        "active": true,
        "engines": [
          "chatgpt",
          "aio"
        ],
        "visibility": 50.0,
        "change": 16.7,
        "checks": 9,
        "answers": 18,
        "mentions": 9,
        "last_checked_at": "2026-09-24T06:00:00Z",
        "latest": [
          {
            "engine": "chatgpt",
            "assistant": "ChatGPT",
            "checked_at": "2026-09-24T06:00:00Z",
            "mentioned": true,
            "cited": true,
            "rank": 2,
            "cited_url": "https://example.com/",
            "snippet": "... Example is a popular choice ...",
            "sources": 6
          }
        ]
      }
    ],
    "competitors": [
      {
        "domain": "rival.com",
        "citations": 14,
        "prompts_hit": 6,
        "last_seen_at": "2026-09-24T06:00:00Z"
      }
    ],
    "trend": [
      {
        "day": "2026-09-24",
        "visibility": 41.7,
        "answers": 12
      }
    ],
    "suggested_prompts": [
      "What are the best Example alternatives?"
    ]
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized

One prompt: each assistant's answer and the history

GET/api/v1/ai-visibility/prompts/{prompt_id}

Scope aivis:read

What each assistant answered last time (the full answer text, as on the prompt page) and the last 30 results.

Parameters

NameInTypeRequiredDescription
prompt_idpathintegeryesThe prompt id.

Example

curl -s "https://app.pbn.ltd/api/v1/ai-visibility/prompts/prompt_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/ai-visibility/prompts/prompt_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/prompts/prompt_id", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "id": 311,
    "brand_id": 14,
    "text": "What are the best widget shops?",
    "active": true,
    "engines": [
      "chatgpt",
      "aio"
    ],
    "visibility": 50.0,
    "change": 16.7,
    "checks": 9,
    "answers": [
      {
        "engine": "chatgpt",
        "assistant": "ChatGPT",
        "checked_at": "2026-09-24T06:00:00Z",
        "mentioned": true,
        "cited": true,
        "rank": 2,
        "cited_url": "https://example.com/",
        "snippet": "... Example is a popular choice ...",
        "sources": 6,
        "answer": "Here are some widget shops ..."
      }
    ],
    "mentions": 9,
    "last_checked_at": "2026-09-24T06:00:00Z",
    "history": [
      {
        "engine": "chatgpt",
        "assistant": "ChatGPT",
        "checked_at": "2026-09-24T06:00:00Z",
        "mentioned": true,
        "cited": true,
        "rank": 2,
        "cited_url": "https://example.com/",
        "snippet": "... Example is a popular choice ...",
        "sources": 6
      }
    ]
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized

Track a brand

POST/api/v1/ai-visibility/brands

Scope aivis:write

Starts tracking a brand (any domain, hosted with us or not). Then add prompts. Adding one you track already returns it.

Parameters

NameInTypeRequiredDescription
domainbodystringyesThe brand's domain, e.g. example.com.
brand_namebodystringnoThe name people use for it (optional).
location_codebodyintegernoCountry the answers should be for (codes from GET /rank/locations; default United States).
language_codebodystringnoLanguage of the answers (default English).

Example

curl -s -X POST "https://app.pbn.ltd/api/v1/ai-visibility/brands" \
  -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/ai-visibility/brands", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/brands", {
  method: "POST",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

201

{
  "data": {
    "id": 14,
    "domain": "example.com",
    "brand_name": "Example",
    "hosted_site_id": null,
    "market": {
      "location_code": 2840,
      "location": "United States",
      "country": "US",
      "language_code": "en",
      "language": "English"
    },
    "prompts": 12,
    "visibility": 41.7,
    "prev_visibility": 33.3,
    "share_of_voice": 12.5,
    "mentions": 20,
    "answers": 48,
    "last_checked_at": "2026-09-24T06:00:00Z",
    "url": "https://app.pbn.ltd/ai-visibility/brand/14/"
  }
}

Errors: payment_required, rate_limited, scope_missing, unauthorized, validation_failed

Change a brand's name or market

PATCH/api/v1/ai-visibility/brands/{brand_id}

Scope aivis:write

The next round of answers uses the new settings.

Parameters

NameInTypeRequiredDescription
brand_idpathintegeryesThe tracked brand id.
brand_namebodystringnoThe name people use for it.
location_codebodyintegernoCountry of the answers.
language_codebodystringnoLanguage of the answers.

Example

curl -s -X PATCH "https://app.pbn.ltd/api/v1/ai-visibility/brands/brand_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/ai-visibility/brands/brand_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/brands/brand_id", {
  method: "PATCH",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "id": 14,
    "domain": "example.com",
    "brand_name": "Example",
    "hosted_site_id": null,
    "market": {
      "location_code": 2840,
      "location": "United States",
      "country": "US",
      "language_code": "en",
      "language": "English"
    },
    "prompts": 12,
    "visibility": 41.7,
    "prev_visibility": 33.3,
    "share_of_voice": 12.5,
    "mentions": 20,
    "answers": 48,
    "last_checked_at": "2026-09-24T06:00:00Z",
    "url": "https://app.pbn.ltd/ai-visibility/brand/14/"
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized, validation_failed

Stop tracking a brand

DELETE/api/v1/ai-visibility/brands/{brand_id}

Scope aivis:write · destructive

Stops tracking the brand and all its prompts. The history is kept, but re-adding the brand does not restart its prompts. Needs "confirm": true.

Parameters

NameInTypeRequiredDescription
brand_idpathintegeryesThe tracked brand id.
confirmbodybooleanyesMust be true: this cannot be undone from the API.

Example

curl -s -X DELETE "https://app.pbn.ltd/api/v1/ai-visibility/brands/brand_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/ai-visibility/brands/brand_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/brands/brand_id", {
  method: "DELETE",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "removed": true,
    "id": 14
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized, validation_failed

Add prompts

POST/api/v1/ai-visibility/brands/{brand_id}/prompts

Scope aivis:write

Adds prompts with the panel's own rule: what fits inside your plan is added, the rest is listed in not_added (add a prompt pack or move up a plan). The first answers usually arrive within the hour.

Parameters

NameInTypeRequiredDescription
brand_idpathintegeryesThe tracked brand id.
promptsbodyarrayyesWhole questions, the way somebody would ask them (or one string, one per line). 6-400 characters each.
enginesbodyarraynoAssistant keys from GET /ai-visibility/plans (engines). Leave out for the default set. Keys that are not on sale are ignored.

Example

curl -s -X POST "https://app.pbn.ltd/api/v1/ai-visibility/brands/brand_id/prompts" \
  -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/ai-visibility/brands/brand_id/prompts", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/brands/brand_id/prompts", {
  method: "POST",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

201

{
  "data": {
    "added": [
      {
        "id": 311,
        "brand_id": 14,
        "text": "What are the best widget shops?",
        "active": true,
        "engines": [
          "chatgpt",
          "aio"
        ],
        "visibility": 50.0,
        "change": 16.7,
        "checks": 9,
        "answers": 18,
        "mentions": 9,
        "last_checked_at": "2026-09-24T06:00:00Z"
      }
    ],
    "not_added": {
      "count": 0,
      "prompts": [],
      "limit": 25,
      "plans_url": null
    }
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized, validation_failed

Choose which assistants a prompt is asked of

PATCH/api/v1/ai-visibility/prompts/{prompt_id}

Scope aivis:write

The next round asks exactly those assistants.

Parameters

NameInTypeRequiredDescription
prompt_idpathintegeryesThe prompt id.
enginesbodyarrayyesAssistant keys from GET /ai-visibility/plans. Keys not on sale are ignored; none left means the default set.

Example

curl -s -X PATCH "https://app.pbn.ltd/api/v1/ai-visibility/prompts/prompt_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/ai-visibility/prompts/prompt_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/prompts/prompt_id", {
  method: "PATCH",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "id": 311,
    "brand_id": 14,
    "text": "What are the best widget shops?",
    "active": true,
    "engines": [
      "chatgpt",
      "aio"
    ],
    "visibility": 50.0,
    "change": 16.7,
    "checks": 9,
    "answers": 18,
    "mentions": 9,
    "last_checked_at": "2026-09-24T06:00:00Z"
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized, validation_failed

Remove a prompt

DELETE/api/v1/ai-visibility/prompts/{prompt_id}

Scope aivis:write · destructive

Removes the prompt AND its answers history (the same as the Remove button). Needs "confirm": true.

Parameters

NameInTypeRequiredDescription
prompt_idpathintegeryesThe prompt id.
confirmbodybooleanyesMust be true: this cannot be undone from the API.

Example

curl -s -X DELETE "https://app.pbn.ltd/api/v1/ai-visibility/prompts/prompt_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/ai-visibility/prompts/prompt_id", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/prompts/prompt_id", {
  method: "DELETE",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

200

{
  "data": {
    "removed": true,
    "id": 311
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized, validation_failed

Ask the assistants now

POST/api/v1/ai-visibility/prompts/{prompt_id}/check

Scope aivis:write

Asks the prompt's assistants again now (answers usually within the hour). The same bounds as the button: once per prompt in 24 hours and a daily number per account, and not while checks are paused.

Parameters

NameInTypeRequiredDescription
prompt_idpathintegeryesThe prompt id.

Example

curl -s -X POST "https://app.pbn.ltd/api/v1/ai-visibility/prompts/prompt_id/check" \
  -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/ai-visibility/prompts/prompt_id/check", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/ai-visibility/prompts/prompt_id/check", {
  method: "POST",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());

Response

202

{
  "data": {
    "queued": true,
    "id": 311
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized, unavailable