PBN.LTD API docs
View as Markdown

Billing

Subscription, payment due, invoices and invoice PDFs, add-ons.

Billing overview

GET/api/v1/billing

Scope billing:read

Subscription (state, plan, paid-until date, days left, payment method), unpaid state with the date sites are removed if it stays unpaid, site slots, add-ons, VAT treatment and the panel links.

Example

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

Response

200

{
  "data": {
    "subscription": {
      "state": "active",
      "payment_method": "paypal",
      "paid_until": "2026-10-19T00:00:00Z",
      "expired": false,
      "days_left": 29,
      "trial": false,
      "next_plan": null,
      "pending_change": false,
      "cancelled": false,
      "staff_account": false,
      "plans": [
        {
          "name": "Standard",
          "slug": "standard",
          "sites_per_unit": 20,
          "units": 1,
          "sites": 20,
          "interval": "month",
          "trial": false,
          "price_usd": "49.00",
          "price_eur": "45.00",
          "price_gbp": "39.00"
        }
      ]
    },
    "slots": {
      "used": 12,
      "limit": 20
    },
    "addons": {},
    "vat": {
      "treatment": "reverse_charge",
      "rate_percent": "0",
      "country": "DE"
    },
    "invoices_url": "https://app.pbn.ltd/invoices/"
  }
}

Errors: rate_limited, scope_missing, unauthorized

Payments and invoices

GET/api/v1/billing/invoices

Scope billing:read

Every payment and refund of the account, newest first. document is the invoice / credit note when one has been issued; download it with GET /billing/invoices/{number}.pdf.

Parameters

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

Response

200

{
  "data": [
    {
      "key": "pp:I-ABC123",
      "date": "2026-09-01T10:00:00Z",
      "description": "Hosting plan (PayPal subscription)",
      "amount": "49.00",
      "currency": "USD",
      "kind": "payment",
      "seller": "pbn",
      "document": {
        "number": "PBN-2026-001234",
        "type": "invoice",
        "total": "49.00",
        "vat": "0.00",
        "net": "49.00",
        "issued_at": "2026-09-01T10:05:00Z",
        "pdf_api_url": "https://app.pbn.ltd/api/v1/billing/invoices/PBN-2026-001234.pdf",
        "pdf_panel_url": "https://app.pbn.ltd/invoices/PBN-2026-001234.pdf"
      }
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Errors: rate_limited, scope_missing, unauthorized

Download an invoice PDF

GET/api/v1/billing/invoices/{number}.pdf

Scope billing:read

The PDF of an invoice or credit note of this account (Content-Type application/pdf).

Parameters

NameInTypeRequiredDescription
numberpathstringyesInvoice number, e.g. PBN-2026-001234.

Example

curl -s "https://app.pbn.ltd/api/v1/billing/invoices/PBN-2026-001234.pdf" \
  -H "Authorization: Bearer $PBN_API_KEY" \
  -o invoice.pdf
import os
import requests

headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/billing/invoices/PBN-2026-001234.pdf", headers=headers, timeout=120)
r.raise_for_status()
open("invoice.pdf", "wb").write(r.content)
const res = await fetch("https://app.pbn.ltd/api/v1/billing/invoices/PBN-2026-001234.pdf", {
  method: "GET",
  headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
const pdf = Buffer.from(await res.arrayBuffer());  // Node 18+

Response

200 with the file (application/pdf).

Errors: not_found, rate_limited, scope_missing, unauthorized