PBN.LTD API docs
View as Markdown

Backups

List, create, download and restore backups.

List backups

GET/api/v1/sites/{site_id}/backups

Scope backups:read

The site's backups, newest first (automatic daily ones, manual ones and uploaded ones).

Parameters

NameInTypeRequiredDescription
site_idpathintegeryesThe site id (see GET /sites).
statequerystring (one of: Pending, Creating, Ok, Error, Storing)noOnly backups in this state.
limitqueryintegernoItems per page (1-200). Default: 50.
cursorquerystringnoThe next_cursor value of the previous page. Omit for the first page.

Example

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

Response

200

{
  "data": [
    {
      "id": 88001,
      "created_at": "2026-09-19T09:12:00Z",
      "type": "Automatic",
      "state": "Ok",
      "size_bytes": 52428800,
      "is_blueprint": false,
      "locked": false
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Errors: not_found, rate_limited, scope_missing, unauthorized

Create a backup now

POST/api/v1/sites/{site_id}/backups

Scope backups:write

Takes a full backup (files + database) now, as Create backup in the panel. Follow the job until the backup is Ok.

Parameters

NameInTypeRequiredDescription
site_idpathintegeryesThe site id (see GET /sites).

Example

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

Response

202

{
  "data": {
    "id": 88001,
    "created_at": "2026-09-19T09:12:00Z",
    "type": "Manual",
    "state": "Pending",
    "size_bytes": 52428800,
    "is_blueprint": false,
    "locked": false
  }
}

Errors: conflict, not_found, rate_limited, scope_missing, unauthorized

Get one backup

GET/api/v1/sites/{site_id}/backups/{backup_id}

Scope backups:read

One backup of the site.

Parameters

NameInTypeRequiredDescription
site_idpathintegeryesThe site id (see GET /sites).
backup_idpathintegeryesThe backup id.

Example

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

Response

200

{
  "data": {
    "id": 88001,
    "created_at": "2026-09-19T09:12:00Z",
    "type": "Automatic",
    "state": "Ok",
    "size_bytes": 52428800,
    "is_blueprint": false,
    "locked": false
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized

Download link

POST/api/v1/sites/{site_id}/backups/{backup_id}/download-link

Scope backups:read

A temporary link to download the backup archive (tar.gz) - valid about 4 hours.

Parameters

NameInTypeRequiredDescription
site_idpathintegeryesThe site id (see GET /sites).
backup_idpathintegeryesThe backup id.

Example

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

Response

200

{
  "data": {
    "url": "https://dl.dropboxusercontent.com/...",
    "expires_in_seconds": 14400,
    "size_bytes": 52428800
  }
}

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

Restore a backup

POST/api/v1/sites/{site_id}/backups/{backup_id}/restore

Scope backups:write · destructive

Replaces the site's files and database with the backup (as Restore in the panel). Refused while the site is busy, switched off or the plan has expired. Follow the job.

Parameters

NameInTypeRequiredDescription
site_idpathintegeryesThe site id (see GET /sites).
backup_idpathintegeryesThe backup id.
confirmbodybooleanyesMust be true: this action overwrites the site.

Example

curl -s -X POST "https://app.pbn.ltd/api/v1/sites/123/backups/88001/restore" \
  -H "Authorization: Bearer $PBN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"confirm": true}'
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.post("https://app.pbn.ltd/api/v1/sites/123/backups/88001/restore", headers=headers, json={"confirm": True}, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/sites/123/backups/88001/restore", {
  method: "POST",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`, "Content-Type": "application/json"},
  body: JSON.stringify({"confirm": true})
});
console.log(res.status, await res.json());

Response

202

{
  "data": {
    "restoring": true
  }
}

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

Delete a backup

DELETE/api/v1/sites/{site_id}/backups/{backup_id}

Scope backups:write · destructive

Deletes a backup. A backup that a blueprint uses cannot be deleted.

Parameters

NameInTypeRequiredDescription
site_idpathintegeryesThe site id (see GET /sites).
backup_idpathintegeryesThe backup id.

Example

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

Response

200

{
  "data": {
    "deleted": true,
    "id": 88001
  }
}

Errors: conflict, not_found, rate_limited, scope_missing, unauthorized