PapilioHost Reseller API v1
Reseller API · v1

One call, and the server is live.

Provision real VPS instances straight from your prepaid balance. Every request bills your wholesale price — you resell to your own customers at any markup.

BASE https://reseller.papiliohost.com/api/v1 AUTH Bearer pk_live_…
create-server
$ curl -X POST https://reseller.papiliohost.com/api/v1/servers \ -H "Authorization: Bearer pk_live_…" \ -d '{"dc":"0","plan":"plid-1","os":"os-1200"}'
201 Created
{ "ok": true, "server": { "id": 12, "ip": "94.183.218.226", "ssh_pass": "s3cr3t" }, "charged": 740000, "balance": 4260000 }

Introduction #

A small REST API over HTTPS. All requests and responses are JSON. Success is {"ok":true, …}; an error is {"ok":false,"error":{"code","message"}} with a matching HTTP status.

Authentication #

Send your secret API key as a bearer token on every request. Your admin issues it — treat it like a password.

Authorization header
Authorization: Bearer pk_live_xxxxxxxxxxxxxxxx
Your key spends your balance. If it leaks, servers can be created on your account — ask your admin to revoke it and issue a new one.

Quickstart #

Create your first server in three steps.

1 — List plans & OS images

GET /catalog
curl -H "Authorization: Bearer pk_live_..." \
  https://reseller.papiliohost.com/api/v1/catalog

2 — Create a server

curl -X POST https://reseller.papiliohost.com/api/v1/servers \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"dc":"0","plan":"plid-1","os":"os-1200","hostname":"cust1","billing":"monthly"}'

3 — Response · 201 Created

Response body201
{
  "ok": true,
  "server": { "id": 12, "vpsid": "63", "ip": "94.183.218.226",
    "ssh_user": "root", "ssh_pass": "s3cr3t", "billing": "monthly", "status": "active" },
  "charged": 740000,
  "balance": 4260000
}
The root password (ssh_pass) is returned only in this create response — store it. It never appears in list or get.

Endpoints #

GET/catalog

Datacenters, plans and OS images available to you, each with your wholesale price (monthly & hourly).

Use the id fields here as the dc, plan and os values when creating a server.

Response200
{
  "ok": true,
  "catalog": [{
    "dc": "0", "name": "Tehran",
    "plans": [
      { "id": "plid-1", "name": "Skipper", "cpu": 1, "ram_mb": 1024,
        "disk_gb": 15, "bandwidth_gb": 100, "monthly": 740000, "hourly": 1100 }
    ],
    "os": [{ "id": "os-1200", "name": "almalinux-9.7-x86-64" }]
  }]
}
GET/balance

Your wallet balance and credit limit.

Response200
{ "ok": true, "balance": 4260000, "credit_limit": 0,
  "currency": "toman", "status": "active" }
GET/servers

List all your servers. The root password is never included here.

GET/servers/{id}

Retrieve a single server by its id.

Response200
{ "ok": true, "servers": [
  { "id": 12, "ip": "94.183.218.226", "plan": "plid-1",
    "dc_name": "Tehran", "billing": "monthly",
    "status": "active", "label": "cust1" }
]}
POST/servers

Create a real server. Your wholesale price is charged up front; if provisioning fails it is refunded automatically.

Body parameters

FieldType
dcstringREQUIRED — datacenter id from /catalog
planstringREQUIRED — plan id (e.g. plid-1)
osstringREQUIRED — OS id (e.g. os-1200)
billingstringoptionalmonthly (default) or hourly
hostnamestringoptional — server hostname
labelstringoptional — your own tag (e.g. customer id)
Send an Idempotency-Key: <unique> header so a retried request returns the same server instead of creating a second one.
Request
{
  "dc": "0",
  "plan": "plid-1",
  "os": "os-1200",
  "hostname": "cust1",
  "billing": "hourly",
  "label": "customer-42"
}
Response201
{ "ok": true,
  "server": { "id": 12, "vpsid": "63",
    "ip": "94.183.218.226", "ssh_user": "root",
    "ssh_pass": "s3cr3t", "billing": "hourly",
    "hourly_rate": 1100, "status": "active" },
  "charged": 1100, "balance": 4258900 }
POST/servers/{id}/action

Power control for a server.

FieldType
actionstringREQUIREDstart · stop · restart · poweroff
Request
{ "action": "stop" }
Response200
{ "ok": true, "id": 12, "action": "stop" }
POST/servers/{id}/rebuild

Reinstall the OS from scratch. Returns a fresh root password. All data on the server is erased.

FieldType
osstringREQUIRED — OS id from /catalog
Request
{ "os": "os-1200" }
Response200
{ "ok": true, "id": 12, "os": "almalinux-9.7-x86-64",
  "ssh_user": "root", "ssh_pass": "n3wp4ss" }
POST/servers/{id}/password

Reset the root password. Returns the new one (store it — it is shown once).

Response200
{ "ok": true, "id": 12, "ssh_user": "root", "ssh_pass": "n3wp4ss" }
GET/servers/{id}/stats

Live status & usage — power state, CPU/RAM/disk percent, bandwidth used. Build your customer dashboard on this.

Response200
{ "ok": true, "id": 12, "stats": {
  "online": true, "ip": "94.183.218.226",
  "cpu": 1, "ram_mb": 1024, "disk_gb": 15,
  "bandwidth_gb": 100, "bandwidth_used_gb": 12,
  "cpu_pct": 8, "ram_pct": 34, "disk_pct": 21 } }
DELETE/servers/{id}

Delete a server. For hourly servers the unused part of the current hour is refunded.

A freshly created server is locked during OS install (~1–2 min). An immediate delete may return delete_failed: VPS Locked — wait, or stop it first, then delete.
Response200
{ "ok": true, "id": 12 }

White-label customer panel #

Give your customers a hosted, branded web panel where they self-serve: view their servers, power on/off, reinstall the OS, reset the root password, and watch live usage — all under your reseller name, with no code from you.

Flow: create a customer → assign one or more of your servers to them → hand them the panel link and their access code.

Panelhttps://reseller.papiliohost.com/panel
Loginaccess code
Customers only ever see and control the servers you assign to them — never your other servers, balance, or customers.
POST/customers

Create a customer. Returns a one-time access_code and the panel URL — give both to your customer.

Also: GET /customers (list, with server counts) · DELETE /customers/{id} (remove & unassign their servers).

FieldType
namestringoptional — a label for you
Response201
{ "ok": true,
  "customer": { "id": 1, "name": "Ali", "servers": 0, "status": "active" },
  "access_code": "cust_9d24…0725",
  "panel_url": "https://reseller.papiliohost.com/panel" }
POST/servers/{id}/assign

Assign a server to one of your customers (so it shows in their panel), or pass null to unassign.

Request
{ "customer": 1 }
Response200
{ "ok": true, "id": 12, "customer": 1 }

Errors #

Every error is {"ok":false,"error":{"code","message"}}. Branch on error.code, not the message.

StatusCodeMeaning
401unauthorizedInvalid API key or inactive reseller
402insufficient_balanceNot enough wallet balance
403dc_forbidden · plan_forbidden · hourly_forbiddenNo access to that datacenter / plan / hourly billing
409dc_unavailable · plan_unavailable · limit_reachedOut of stock, or active-server limit reached
400plan_not_found · os_not_found · bad_actionInvalid input
429rate_limitedToo many requests (max 120/min)
502provision_failed · delete_failed · action_failedPanel operation failed (create is auto-refunded)

Billing #

  • Wholesale. Prices in /catalog are what leaves your balance. Sell to your own customers at any price — the difference is your margin.
  • Monthly. Full price charged on create; active until the renewal date.
  • Hourly. First hour prepaid on create, then each hour billed automatically. Out of balance → the server is suspended; top up and it resumes; unpaid past the grace period → deleted.
  • Top up. Ask your admin (send /charge in the bot).