PBN.LTD API docs
View as Markdown

Money sites

Hosting on Zinn Digital's platform: plans, orders, sites, usage, and the free WooCommerce tick on a PBN-line WordPress site.

Money-site plans and prices

GET/api/v1/money-sites/plans

Scope moneysites:read

Every money-site hosting tier on sale, with the price for 1, 3, 6 and 12 months, what the plan includes, and whether it can be ordered straight away. Money sites run on Zinn Digital's platform - separate infrastructure from the PBN network - and Zinn Digital LTD bills them.

Example

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

Response

200

{
  "data": {
    "currency": "USD",
    "terms": [
      1,
      3,
      6,
      12
    ],
    "can_order": false,
    "plans": [
      {
        "code": "mainstream_starter",
        "name": "Starter",
        "monthly": "$7.99",
        "currency": "USD",
        "on_sale": true,
        "woocommerce": false,
        "terms": [
          {
            "months": 1,
            "total": "$7.99",
            "per_month": "$7.99",
            "saving": "$0.00"
          },
          {
            "months": 12,
            "total": "$76.70",
            "per_month": "$6.39",
            "saving": "$19.18"
          }
        ],
        "includes": [
          {
            "label": "Websites",
            "value": "1"
          },
          {
            "label": "Disk",
            "value": "10 GB"
          }
        ]
      }
    ],
    "applications": [
      {
        "key": "wordpress",
        "name": "WordPress"
      }
    ]
  }
}

Errors: rate_limited, scope_missing, unauthorized

My money sites

GET/api/v1/money-sites

Scope moneysites:read

Every money site on this account, with its state, plan, application and last known usage.

Example

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

Response

200

{
  "data": [
    {
      "id": 7,
      "domain": "example.com",
      "state": "live",
      "state_label": "Live",
      "application": "WordPress",
      "woocommerce": false,
      "hosted_by": "Zinn Digital LTD",
      "plan": {
        "code": "mainstream_plus",
        "name": "Plus",
        "monthly": "$15.00"
      },
      "usage": [
        {
          "label": "Disk",
          "used": "2,100",
          "allowed": "30,720",
          "percent": 7
        }
      ],
      "panel_url": "https://app.zinndigital.com/sites/abc123"
    }
  ]
}

Errors: rate_limited, scope_missing, unauthorized

One money site

GET/api/v1/money-sites/{site_id}

Scope moneysites:read

One money site in full: state, plan, hostnames, PHP version, region, usage against the plan's allowances, recent jobs and errors, and the links for the few jobs that are finished in the Zinn Digital panel.

Parameters

NameInTypeRequiredDescription
site_idpathintegeryesThe money site id.

Example

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

Response

200

{
  "data": {
    "id": 7,
    "domain": "example.com",
    "state": "live",
    "state_label": "Live",
    "application": "WordPress",
    "woocommerce": false,
    "hosted_by": "Zinn Digital LTD",
    "plan": {
      "code": "mainstream_plus",
      "name": "Plus",
      "monthly": "$15.00"
    },
    "usage": [
      {
        "label": "Disk",
        "used": "2,100",
        "allowed": "30,720",
        "percent": 7
      }
    ],
    "panel_url": "https://app.zinndigital.com/sites/abc123"
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized

Re-read everything from Zinn Digital

POST/api/v1/money-sites/refresh

Scope moneysites:read

Ask Zinn Digital for this account's sites and orders again. Use it after paying, or if a site was set up for you by our team and is not listed yet.

Example

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

Response

200

{
  "data": {
    "found": 1,
    "sites": 2
  }
}

Errors: rate_limited, scope_missing, unauthorized

My money-site orders

GET/api/v1/money-sites/orders

Scope moneysites:read

Every money-site order on this account, newest first, with its state and what it cost.

Example

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

Response

200

{
  "data": [
    {
      "id": 12,
      "state": "paying",
      "status": "Awaiting payment",
      "plan": {
        "code": "mainstream_plus",
        "name": "Plus",
        "line": "money-site hosting"
      },
      "term_months": 12,
      "domain": "example.com",
      "application": "WordPress",
      "total": "$153.00",
      "reference": "ZD-10023",
      "billed_by": "Zinn Digital LTD"
    }
  ]
}

Errors: rate_limited, scope_missing, unauthorized

One money-site order

GET/api/v1/money-sites/orders/{order_id}

Scope moneysites:read

One order, re-read from Zinn Digital if it is still open.

Parameters

NameInTypeRequiredDescription
order_idpathintegeryesThe order id.

Example

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

Response

200

{
  "data": {
    "id": 12,
    "state": "paying",
    "status": "Awaiting payment",
    "plan": {
      "code": "mainstream_plus",
      "name": "Plus",
      "line": "money-site hosting"
    },
    "term_months": 12,
    "domain": "example.com",
    "application": "WordPress",
    "total": "$153.00",
    "reference": "ZD-10023",
    "billed_by": "Zinn Digital LTD"
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized

Order a money-site plan

POST/api/v1/money-sites/orders

Scope moneysites:write

Place a money-site order. Zinn Digital LTD bills it, so the answer carries a one-time pay_url on Zinn Digital's own secure page - open it to pay. Nothing is charged by this call. If Zinn Digital cannot take a partner order for that tier, the order is recorded as a request, a support ticket is opened, and the answer says so plainly instead of pretending.

Parameters

NameInTypeRequiredDescription
planbodystringyesA plan code from /money-sites/plans.
monthsbodyinteger (one of: 1, 3, 6, 12)noHow many months to pay for. Default: 1.
domainbodystringnoThe domain for the site. Leave it out to start on a temporary address.
applicationbodystringnoA one-click application key from /money-sites/plans. Default: wordpress.
notesbodystringnoAnything our team should know.
accept_termsbodybooleannoMust be true: it records that this account accepts the Terms and Conditions for this purchase, exactly as the tick box on the website does. Default: False.

Example

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

Response

201

{
  "data": {
    "order": {
      "id": 12,
      "state": "paying",
      "status": "Awaiting payment",
      "plan": {
        "code": "mainstream_plus",
        "name": "Plus",
        "line": "money-site hosting"
      },
      "term_months": 12,
      "domain": "example.com",
      "application": "WordPress",
      "total": "$153.00",
      "reference": "ZD-10023",
      "billed_by": "Zinn Digital LTD"
    },
    "pay_url": "https://zinndigital.com/pay/...",
    "requested": false,
    "ticket_id": null
  }
}

Errors: conflict, rate_limited, scope_missing, unauthorized, unavailable

Cancel an unpaid money-site order

POST/api/v1/money-sites/orders/{order_id}/cancel

Scope moneysites:write · destructive

Cancel an order that has not been paid. Nothing was charged, so nothing is refunded.

Parameters

NameInTypeRequiredDescription
order_idpathintegeryesThe order id.

Example

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

Response

200

{
  "data": {
    "id": 12,
    "state": "paying",
    "status": "Awaiting payment",
    "plan": {
      "code": "mainstream_plus",
      "name": "Plus",
      "line": "money-site hosting"
    },
    "term_months": 12,
    "domain": "example.com",
    "application": "WordPress",
    "total": "$153.00",
    "reference": "ZD-10023",
    "billed_by": "Zinn Digital LTD"
  }
}

Errors: conflict, not_found, rate_limited, scope_missing, unauthorized

WooCommerce on a PBN-line site

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

Scope moneysites:read

Whether WooCommerce is installed on one of your PBN-line WordPress sites, which version, and the health checks: plugin active, shop/cart/checkout pages, a currency, pretty permalinks, HTTPS, and cart and checkout kept out of any page cache.

Parameters

NameInTypeRequiredDescription
site_idpathintegeryesA PBN-line site id (the same id the /sites endpoints use).

Example

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

Response

200

{
  "data": {
    "site_id": 12345,
    "eligible": true,
    "on": true,
    "busy": false,
    "version": "9.3.3",
    "free": true,
    "health": [
      {
        "key": "plugin_active",
        "label": "WooCommerce is active",
        "ok": true
      }
    ]
  }
}

Errors: not_found, rate_limited, scope_missing, unauthorized

Add or remove WooCommerce (free)

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

Scope moneysites:write · returns a job

Adds WooCommerce to a PBN-line WordPress site, free of charge, or switches it off again. The install runs in the background and usually takes a minute or two; poll GET /sites/{site_id}/woocommerce for the result. WooCommerce is a WordPress plugin, so a site of another type is refused with the reason - use the WooCommerce money-site plan instead.

Parameters

NameInTypeRequiredDescription
site_idpathintegeryesA PBN-line site id (the same id the /sites endpoints use).
onbodybooleannotrue installs and activates WooCommerce; false deactivates it (products and orders stay in the database). Default: True.

Example

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

Response

200

{
  "data": {
    "site_id": 12345,
    "state": "queued",
    "free": true
  },
  "job": {
    "id": "job_4f1c0a9e2b7d6c5a3e10",
    "kind": "...",
    "status": "running",
    "url": "https://app.pbn.ltd/api/v1/jobs/job_4f1c0a9e2b7d6c5a3e10"
  }
}

Errors: conflict, not_found, rate_limited, scope_missing, unauthorized