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/plansScope 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-sitesScope 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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
site_id | path | integer | yes | The 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/refreshScope 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/ordersScope 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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
order_id | path | integer | yes | The 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/ordersScope 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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
plan | body | string | yes | A plan code from /money-sites/plans. |
months | body | integer (one of: 1, 3, 6, 12) | no | How many months to pay for. Default: 1. |
domain | body | string | no | The domain for the site. Leave it out to start on a temporary address. |
application | body | string | no | A one-click application key from /money-sites/plans. Default: wordpress. |
notes | body | string | no | Anything our team should know. |
accept_terms | body | boolean | no | Must 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}/cancelScope moneysites:write · destructive
Cancel an order that has not been paid. Nothing was charged, so nothing is refunded.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
order_id | path | integer | yes | The 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}/woocommerceScope 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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
site_id | path | integer | yes | A 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}/woocommerceScope 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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
site_id | path | integer | yes | A PBN-line site id (the same id the /sites endpoints use). |
on | body | boolean | no | true 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