REST API

Manage your servers and orders from your own tooling. Create a key on the billing page — it is shown once and stored only as a hash.

Authentication

Send your key as Authorization: Bearer YOUR_API_KEY (or as an X-API-Key header). All responses are JSON.

curl -H "Authorization: Bearer bhk_your_key_here" \
  /api/v1/servers

Keys are scoped to your account only. Rate limit: 60 requests per minute per key. A key never carries panel or payment-provider credentials.

Endpoints

MethodPathDescription
GET/api/v1/pingVerify a key and return your account summary.
GET/api/v1/plansList plans with memory, disk, CPU and price. /packages is the same endpoint.
GET/api/v1/ordersList your orders and their provisioning status.
POST/api/v1/ordersCreate an order in pending. Body: {"plan":"1gb","server_name":"My WhatsApp Bot","runtime":"nodejs"}. The price always comes from the plan.
GET/api/v1/orders/{ref}One order, e.g. BH1A2B3C4D. Returns 404 if it is not yours.
POST/api/v1/orders/{ref}/payStart the M-Pesa STK push. Body: {"phone":"2547XXXXXXXX"}. Returns the checkout id.
GET/api/v1/serversList your servers with IP, port and limits.
GET/api/v1/servers/{id}One server. Returns 404 if it is not yours.

Order lifecycle

An order moves through pendingpaidprovisioningactive (failed if provisioning gives up). A server's own status is mirrored from the panel: installing, starting, running, offline or suspended. Read either through /api/v1/orders/{ref}.

Example response

{
  "data": [
    {
      "id": 12,
      "name": "my-discord-bot",
      "identifier": "a1b2c3d4",
      "order_ref": "BH1A2B3C4D",
      "package": "1 GB",
      "memory_mb": 1024,
      "disk_mb": 2048,
      "cpu_percent": 100,
      "ip": "62.171.140.132",
      "port": 26061,
      "status": "running",
      "created_at": "2026-01-14 09:12:44"
    }
  ],
  "panel_url": "http://62.171.140.132"
}

Errors

StatusMeaning
401Missing, invalid or revoked API key.
404The resource does not exist or is not yours. We never reveal another account's resources.
409Conflict, e.g. paying an order that is already paid.
422Validation failed. The response names the offending field.
429Rate limit exceeded. Back off and retry.
502The payment provider could not start the checkout.

Payments

Checkout is a server-side M-Pesa STK push. Our backend polls the payment provider for the status of the checkout and only releases a server once the status is completed. There is no browser-visible payment callback, so a redirect is never proof of payment.