# Reputation monitoring

Star rating, review count and the latest reviews on Google, Trustpilot and Tripadvisor for the businesses you watch (poor unanswered reviews first), plus brand page one.

## Reputation monitoring: plan and usage

`GET /reputation` · scope `reputation:read`

Your plan, how many businesses and brand terms it covers and how many you watch.

### Example

```bash
curl -s "https://app.pbn.ltd/api/v1/reputation" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/reputation", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`200`

```json
{
  "data": {
    "active": true,
    "plan": "Reputation 3",
    "unlimited": false,
    "paid_until": "2026-10-25",
    "businesses": 2,
    "businesses_included": 3,
    "profiles": 5,
    "brand_terms": 2,
    "brand_terms_included": 10,
    "brand_page_one": true,
    "poor_unanswered": 1,
    "price_from": "12.00",
    "plans_url": "https://app.pbn.ltd/reputation/plans/"
  }
}
```

Errors: `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`

## Countries a business can be in

`GET /reputation/countries` · scope `reputation:read`

The countries you can choose when adding a business (pass `location_code` as `country`).

### Example

```bash
curl -s "https://app.pbn.ltd/api/v1/reputation/countries" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/reputation/countries", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/countries", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`200`

```json
{
  "data": [
    {
      "location_code": 2826,
      "name": "United Kingdom",
      "country": "GB"
    }
  ]
}
```

Errors: `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`

## List your watched businesses

`GET /reputation/businesses` · scope `reputation:read`

Every business you watch with its confirmed review profiles and their latest reading (null = not read yet, never zero). `covered` is false for a business your plan no longer pays to read.

### Example

```bash
curl -s "https://app.pbn.ltd/api/v1/reputation/businesses" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/reputation/businesses", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/businesses", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`200`

```json
{
  "data": [
    {
      "id": 41,
      "name": "Test Cafe",
      "website": "testcafe.com",
      "country": "United Kingdom",
      "location_code": 2826,
      "covered": true,
      "poor_unanswered": 1,
      "waiting_for_confirmation": false,
      "profiles": [
        {
          "platform": "google",
          "platform_name": "Google",
          "state": "ok",
          "name": "Test Cafe",
          "address": "1 High Street, London",
          "url": "https://maps.google.com/?cid=123",
          "rating": 4.6,
          "reviews_count": 212,
          "previous_rating": 4.5,
          "poor_unanswered": 1,
          "last_read_at": "2026-09-26T06:00:00Z",
          "error": ""
        }
      ],
      "created_at": "2026-09-20T10:00:00Z"
    }
  ]
}
```

Errors: `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`

## One watched business

`GET /reputation/businesses/{business_id}` · scope `reputation:read`

One business: per platform its confirmed profile (or the candidates found, waiting for you to confirm which is yours), the latest reviews (poor unanswered first), the rating history, and each brand term with its latest page one and what dropped off it.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `business_id` | path | integer | yes | The watched business id. |

### Example

```bash
curl -s "https://app.pbn.ltd/api/v1/reputation/businesses/business_id" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/reputation/businesses/business_id", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/businesses/business_id", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`200`

```json
{
  "data": {
    "id": 41,
    "name": "Test Cafe",
    "website": "testcafe.com",
    "country": "United Kingdom",
    "location_code": 2826,
    "covered": true,
    "poor_unanswered": 1,
    "waiting_for_confirmation": false,
    "profiles": [
      {
        "platform": "google",
        "platform_name": "Google",
        "state": "ok",
        "name": "Test Cafe",
        "address": "1 High Street, London",
        "url": "https://maps.google.com/?cid=123",
        "rating": 4.6,
        "reviews_count": 212,
        "previous_rating": 4.5,
        "poor_unanswered": 1,
        "last_read_at": "2026-09-26T06:00:00Z",
        "error": ""
      }
    ],
    "created_at": "2026-09-20T10:00:00Z",
    "searching": false,
    "reading": false,
    "platforms": [
      {
        "platform": "google",
        "platform_name": "Google",
        "profile": {
          "platform": "google",
          "platform_name": "Google",
          "state": "ok",
          "name": "Test Cafe",
          "address": "1 High Street, London",
          "url": "https://maps.google.com/?cid=123",
          "rating": 4.6,
          "reviews_count": 212,
          "previous_rating": 4.5,
          "poor_unanswered": 1,
          "last_read_at": "2026-09-26T06:00:00Z",
          "error": ""
        },
        "candidates": [],
        "reviews": [
          {
            "rating": 2.0,
            "title": "",
            "text": "Cold coffee.",
            "author": "A. Visitor",
            "url": "https://maps.google.com/...",
            "published_at": "2026-09-24T10:00:00Z",
            "replied": false,
            "poor": true
          }
        ],
        "history": [
          {
            "read_at": "2026-09-19T06:00:00Z",
            "rating": 4.5,
            "reviews_count": 205,
            "poor_unanswered": 0
          }
        ]
      }
    ],
    "brand_terms": [
      {
        "id": 7,
        "term": "Test Cafe",
        "last_checked_at": "2026-09-26T06:00:00Z",
        "page_one": [
          {
            "position": 1,
            "url": "https://testcafe.com/",
            "domain": "testcafe.com",
            "title": "Test Cafe",
            "yours": true,
            "new": false
          }
        ],
        "lost": []
      }
    ]
  }
}
```

Errors: `not_found`, `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`

## Watch a business

`POST /reputation/businesses` · scope `reputation:write`

Adds a business and searches Google, Trustpilot and Tripadvisor for its profiles. The results arrive as `candidates` within a minute or two: confirm which one is yours with POST /reputation/businesses/{business_id}/profiles. Refused if your plan has no room.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `name` | body | string | yes | The business name as customers know it. |
| `country` | body | integer | yes | The country it is in: a `location_code` from GET /reputation/countries (2826 = United Kingdom, 2840 = United States). |
| `website` | body | string | no | Its own website, optional (e.g. testcafe.com). |

### Example

```bash
curl -s -X POST "https://app.pbn.ltd/api/v1/reputation/businesses" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.post("https://app.pbn.ltd/api/v1/reputation/businesses", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/businesses", {
  method: "POST",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`201`

```json
{
  "data": {
    "id": 41,
    "name": "Test Cafe",
    "website": "testcafe.com",
    "country": "United Kingdom",
    "location_code": 2826,
    "covered": true,
    "poor_unanswered": 1,
    "waiting_for_confirmation": false,
    "profiles": [
      {
        "platform": "google",
        "platform_name": "Google",
        "state": "ok",
        "name": "Test Cafe",
        "address": "1 High Street, London",
        "url": "https://maps.google.com/?cid=123",
        "rating": 4.6,
        "reviews_count": 212,
        "previous_rating": 4.5,
        "poor_unanswered": 1,
        "last_read_at": "2026-09-26T06:00:00Z",
        "error": ""
      }
    ],
    "created_at": "2026-09-20T10:00:00Z",
    "searching": false,
    "reading": false,
    "platforms": [
      {
        "platform": "google",
        "platform_name": "Google",
        "profile": {
          "platform": "google",
          "platform_name": "Google",
          "state": "ok",
          "name": "Test Cafe",
          "address": "1 High Street, London",
          "url": "https://maps.google.com/?cid=123",
          "rating": 4.6,
          "reviews_count": 212,
          "previous_rating": 4.5,
          "poor_unanswered": 1,
          "last_read_at": "2026-09-26T06:00:00Z",
          "error": ""
        },
        "candidates": [],
        "reviews": [
          {
            "rating": 2.0,
            "title": "",
            "text": "Cold coffee.",
            "author": "A. Visitor",
            "url": "https://maps.google.com/...",
            "published_at": "2026-09-24T10:00:00Z",
            "replied": false,
            "poor": true
          }
        ],
        "history": [
          {
            "read_at": "2026-09-19T06:00:00Z",
            "rating": 4.5,
            "reviews_count": 205,
            "poor_unanswered": 0
          }
        ]
      }
    ],
    "brand_terms": [
      {
        "id": 7,
        "term": "Test Cafe",
        "last_checked_at": "2026-09-26T06:00:00Z",
        "page_one": [
          {
            "position": 1,
            "url": "https://testcafe.com/",
            "domain": "testcafe.com",
            "title": "Test Cafe",
            "yours": true,
            "new": false
          }
        ],
        "lost": []
      }
    ]
  }
}
```

Errors: `payment_required`, `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`, `validation_failed`

## Stop watching a business

`DELETE /reputation/businesses/{business_id}` · scope `reputation:write` · **destructive**

Removes the business with its profiles, reviews, history and brand terms.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `business_id` | path | integer | yes | The watched business id. |

### Example

```bash
curl -s -X DELETE "https://app.pbn.ltd/api/v1/reputation/businesses/business_id" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.delete("https://app.pbn.ltd/api/v1/reputation/businesses/business_id", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/businesses/business_id", {
  method: "DELETE",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`200`

```json
{
  "data": {
    "deleted": true
  }
}
```

Errors: `not_found`, `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`

## Search for its profiles again

`POST /reputation/businesses/{business_id}/search` · scope `reputation:write`

Searches the three platforms again for this business's profiles (the same daily limit per business as the button). New candidates replace the old ones.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `business_id` | path | integer | yes | The watched business id. |

### Example

```bash
curl -s -X POST "https://app.pbn.ltd/api/v1/reputation/businesses/business_id/search" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.post("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/search", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/search", {
  method: "POST",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`202`

```json
{
  "data": {
    "queued": true,
    "id": 41
  }
}
```

Errors: `not_found`, `payment_required`, `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`

## Confirm which profile is yours

`POST /reputation/businesses/{business_id}/profiles` · scope `reputation:write`

Only a profile you confirm is ever read. Its first reading starts at once.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `business_id` | path | integer | yes | The watched business id. |
| `platform` | body | string (one of: google, trustpilot, tripadvisor) | yes | The platform. |
| `candidate` | body | string | yes | The `id` of the candidate that is yours (from GET /reputation/businesses/{business_id}), or "none" when none of them is. |

### Example

```bash
curl -s -X POST "https://app.pbn.ltd/api/v1/reputation/businesses/business_id/profiles" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.post("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/profiles", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/profiles", {
  method: "POST",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`200`

```json
{
  "data": {
    "id": 41,
    "name": "Test Cafe",
    "website": "testcafe.com",
    "country": "United Kingdom",
    "location_code": 2826,
    "covered": true,
    "poor_unanswered": 1,
    "waiting_for_confirmation": false,
    "profiles": [
      {
        "platform": "google",
        "platform_name": "Google",
        "state": "ok",
        "name": "Test Cafe",
        "address": "1 High Street, London",
        "url": "https://maps.google.com/?cid=123",
        "rating": 4.6,
        "reviews_count": 212,
        "previous_rating": 4.5,
        "poor_unanswered": 1,
        "last_read_at": "2026-09-26T06:00:00Z",
        "error": ""
      }
    ],
    "created_at": "2026-09-20T10:00:00Z",
    "searching": false,
    "reading": false,
    "platforms": [
      {
        "platform": "google",
        "platform_name": "Google",
        "profile": {
          "platform": "google",
          "platform_name": "Google",
          "state": "ok",
          "name": "Test Cafe",
          "address": "1 High Street, London",
          "url": "https://maps.google.com/?cid=123",
          "rating": 4.6,
          "reviews_count": 212,
          "previous_rating": 4.5,
          "poor_unanswered": 1,
          "last_read_at": "2026-09-26T06:00:00Z",
          "error": ""
        },
        "candidates": [],
        "reviews": [
          {
            "rating": 2.0,
            "title": "",
            "text": "Cold coffee.",
            "author": "A. Visitor",
            "url": "https://maps.google.com/...",
            "published_at": "2026-09-24T10:00:00Z",
            "replied": false,
            "poor": true
          }
        ],
        "history": [
          {
            "read_at": "2026-09-19T06:00:00Z",
            "rating": 4.5,
            "reviews_count": 205,
            "poor_unanswered": 0
          }
        ]
      }
    ],
    "brand_terms": [
      {
        "id": 7,
        "term": "Test Cafe",
        "last_checked_at": "2026-09-26T06:00:00Z",
        "page_one": [
          {
            "position": 1,
            "url": "https://testcafe.com/",
            "domain": "testcafe.com",
            "title": "Test Cafe",
            "yours": true,
            "new": false
          }
        ],
        "lost": []
      }
    ]
  }
}
```

Errors: `not_found`, `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`, `validation_failed`

## Stop watching one profile

`DELETE /reputation/businesses/{business_id}/profiles/{platform}` · scope `reputation:write`

Forgets the confirmed profile on one platform (search again to pick another).

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `business_id` | path | integer | yes | The watched business id. |
| `platform` | path | string (one of: google, trustpilot, tripadvisor) | yes | The platform. |

### Example

```bash
curl -s -X DELETE "https://app.pbn.ltd/api/v1/reputation/businesses/business_id/profiles/platform" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.delete("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/profiles/platform", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/profiles/platform", {
  method: "DELETE",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`200`

```json
{
  "data": {
    "deleted": true
  }
}
```

Errors: `not_found`, `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`

## Read a business now

`POST /reputation/businesses/{business_id}/refresh` · scope `reputation:write`

Asks for a fresh reading of every confirmed profile and brand term of this business within the next few minutes. The same bound as the "Read now" button: once per business in the interval the page states (24 hours today). Weekly readings carry on regardless.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `business_id` | path | integer | yes | The watched business id. |

### Example

```bash
curl -s -X POST "https://app.pbn.ltd/api/v1/reputation/businesses/business_id/refresh" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.post("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/refresh", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/refresh", {
  method: "POST",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`202`

```json
{
  "data": {
    "queued": true,
    "id": 41
  }
}
```

Errors: `not_found`, `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`, `validation_failed`

## Watch a brand term

`POST /reputation/businesses/{business_id}/terms` · scope `reputation:write`

Adds a brand term whose Google page one is read every week (within your plan's brand terms, up to 10 per business).

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `business_id` | path | integer | yes | The watched business id. |
| `term` | body | string | yes | The search term, e.g. the brand name. |

### Example

```bash
curl -s -X POST "https://app.pbn.ltd/api/v1/reputation/businesses/business_id/terms" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.post("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/terms", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/terms", {
  method: "POST",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`201`

```json
{
  "data": {
    "id": 7,
    "term": "Test Cafe reviews"
  }
}
```

Errors: `not_found`, `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`, `validation_failed`

## Stop watching a brand term

`DELETE /reputation/businesses/{business_id}/terms/{term_id}` · scope `reputation:write`

Removes a brand term and its page-one history.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `business_id` | path | integer | yes | The watched business id. |
| `term_id` | path | integer | yes | The brand term id. |

### Example

```bash
curl -s -X DELETE "https://app.pbn.ltd/api/v1/reputation/businesses/business_id/terms/term_id" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.delete("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/terms/term_id", headers=headers, timeout=120)
print(r.status_code, r.json())
```

```javascript
const res = await fetch("https://app.pbn.ltd/api/v1/reputation/businesses/business_id/terms/term_id", {
  method: "DELETE",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
```

### Response

`200`

```json
{
  "data": {
    "deleted": true
  }
}
```

Errors: `not_found`, `rate_limited`, `scope_missing`, `unauthorized`, `unavailable`
