# Country lock

Limit a site to the countries you choose; everyone else gets a "not available in your country" page.

## Country lock of a site

`GET /sites/{site_id}/country-lock` · scope `sites:read`

Whether the site is locked to certain countries, which ones, whether search-engine crawlers are let in, the addresses that are always let in, and whether the change is live yet (`status`: pending = being applied, applied = live, waiting = the site is not live on its server yet, off).

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `site_id` | path | integer | yes | The site id (see GET /sites). |

### Example

```bash
curl -s "https://app.pbn.ltd/api/v1/sites/123/country-lock" \
  -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/sites/123/country-lock", headers=headers, timeout=120)
print(r.status_code, r.json())
```

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

### Response

`200`

```json
{
  "data": {
    "enabled": true,
    "mode": "allow",
    "countries": [
      "GB",
      "IE"
    ],
    "allow_search_engines": true,
    "allow_ips": [
      "203.0.113.7/32"
    ],
    "status": "applied",
    "status_label": "Active",
    "applied_at": "2026-09-28T12:00:00+00:00",
    "summary": "Only United Kingdom, Ireland",
    "paused_by_us": false
  }
}
```

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

## Set the country lock of a site

`PUT /sites/{site_id}/country-lock` · scope `sites:write`

Locks the site to the countries given (or everyone except them), or switches the lock off. Live on the site within about a minute - read it back with GET until `status` is "applied".

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `site_id` | path | integer | yes | The site id (see GET /sites). |
| `enabled` | body | boolean | yes | true = lock the site; false = open it to every country (the saved countries are kept). |
| `mode` | body | string (one of: allow, block) | no | "allow" = only these countries can open the site; "block" = everyone except these. Default: `allow`. |
| `countries` | body | array | no | Two-letter country codes (ISO 3166), e.g. ["GB"]. Required when enabled. |
| `allow_search_engines` | body | boolean | no | Let Google, Bing, Apple and DuckDuckGo crawlers in (by their published addresses). false = the site drops out of search results. Default: `True`. |
| `allow_ips` | body | array | no | Addresses or ranges always let in (at most 50), e.g. ["203.0.113.7"]. |

### Example

```bash
curl -s -X PUT "https://app.pbn.ltd/api/v1/sites/123/country-lock" \
  -H "Authorization: Bearer $PBN_API_KEY"
```

```python
import os
import requests

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

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

### Response

`200`

```json
{
  "data": {
    "enabled": true,
    "mode": "allow",
    "countries": [
      "GB",
      "IE"
    ],
    "allow_search_engines": true,
    "allow_ips": [
      "203.0.113.7/32"
    ],
    "status": "applied",
    "status_label": "Active",
    "applied_at": "2026-09-28T12:00:00+00:00",
    "summary": "Only United Kingdom, Ireland",
    "paused_by_us": false
  }
}
```

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