# Account

The account behind the key: profile, plan, site slots, limits and usage.

## Who am I

`GET /me` · scope `account:read`

The account and the key making the call. The cheapest call there is: use it to test a key.

### Example

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

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

### Response

`200`

```json
{
  "data": {
    "id": 1234,
    "username": "example",
    "email": "you@example.com",
    "first_name": "Ann",
    "last_name": "Example",
    "company": null,
    "country": "GB",
    "staff": false,
    "created_at": "2025-01-10T09:00:00Z",
    "last_login_at": "2026-09-19T21:03:11Z",
    "key": {
      "name": "Dashboard",
      "prefix": "pbn_1a2b3c4d5e6f",
      "kind": "key",
      "full_access": false,
      "scopes": [
        "account:read",
        "sites:read"
      ],
      "site_ids": null,
      "expires_at": null,
      "created_at": "2026-09-20T08:00:00Z"
    }
  }
}
```

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

## Plan, slots, limits and frozen sites

`GET /account/limits` · scope `account:read`

Site slots (plan + extra-site add-ons), subscription state and paid-until date, the default per-site limits, every paused (frozen) site with the reason(s) it is paused, and the add-ons on the account.

### Example

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

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

### Response

`200`

```json
{
  "data": {
    "slots": {
      "used": 12,
      "limit": 20,
      "from_plan": 20,
      "extra_site_addons": 0,
      "free": 8,
      "can_create": true
    },
    "subscription": {
      "state": "active",
      "paid_until": "2026-10-19T00:00:00Z",
      "expired": false,
      "days_left": 29
    },
    "default_site_limits": {
      "disk_mib": 1024,
      "database_mib": 500,
      "files": 50000
    },
    "frozen_sites": {
      "count": 1,
      "sites": [
        {
          "site_id": 123,
          "domain": "example.com",
          "reasons": [
            {
              "code": "site_oversize",
              "text": "The site is over its disk space or file-count limit."
            }
          ],
          "temporary_unfreeze": {
            "available": true,
            "why_not": null,
            "left_today": 3
          }
        }
      ]
    },
    "addons": {
      "extra_sites": [],
      "usage": [],
      "site_cleaner": {
        "active": false,
        "ends_at": null
      },
      "wayback_credits": 0,
      "staff_free": false
    }
  }
}
```

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

## Measure usage of the whole account now

`POST /account/limits/refresh` · scope `account:write`

Starts a fresh disk / database / file-count measurement for the account's sites - the usage tab's "Check now", for many sites at once. It returns at once: each site is reported as started, busy, throttled (the panel's own per-site cooldown and per-account budget apply unchanged) or skipped with the reason. Poll GET /account/limits or GET /sites/{site_id}/usage for the new figures a few seconds later.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `site_ids` | body | array | no | Only these sites (default: every installed site of the account, newest first). |
| `max_sites` | body | integer | no | How many sites to start a measurement for in this call (1-100). Default: `25`. |

### Example

```bash
curl -s -X POST "https://app.pbn.ltd/api/v1/account/limits/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/account/limits/refresh", headers=headers, timeout=120)
print(r.status_code, r.json())
```

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

### Response

`202`

```json
{
  "data": {
    "requested": 12,
    "started": 9,
    "busy": 1,
    "throttled": 2,
    "skipped": 0,
    "sites": [
      {
        "site_id": 123,
        "domain": "example.com",
        "result": "started",
        "message": null
      }
    ],
    "limits": {
      "slots": {
        "used": 12,
        "limit": 20
      }
    }
  }
}
```

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

## API limits for this key

`GET /limits` · scope `kb:read`

The rate limits and size limits that apply to the key making the call. `overridden` is true when support has raised or lowered a limit for this key or for the whole account.

### Example

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

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

### Response

`200`

```json
{
  "data": {
    "per_minute": 120,
    "per_hour": 5000,
    "writes_per_minute": 30,
    "upload_max_mb": 25,
    "read_max_mb": 5,
    "max_keys_per_customer": 50,
    "overridden": false,
    "override_scope": null
  }
}
```

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