API Documentation

Base URL

https://reseller.makelicense.com/api/v1

Authentication

All requests need the Authorization header:

Authorization: Bearer YOUR_TOKEN
Generate token at: Panel → API Tokens

Roles & Permissions

The API uses 4 roles with a clear chain of command. The /admin/* endpoints accept either admin or master_reseller tokens — master resellers can manage their own sub-resellers through the same endpoints as the platform admin.

Role Can do Cannot do
admin Everything. Create resellers, master_resellers, sub_resellers, credit/debit any account, view all sub-resellers. —
master_reseller Create sub_resellers under their own account, credit them, view their balance, suspend them. Cannot create another master_reseller. Cannot manage resellers belonging to other master_resellers.
reseller Register/renew/suspend their own licenses, view their own sub-resellers and balance. Cannot create other resellers. Cannot access /admin/* endpoints.
sub_reseller Same as reseller but linked to a master_reseller. Receives commission discounts based on chain. Same as reseller.
Commission chain rule (for master_reseller): A master_reseller can grant their sub_reseller a commission rate up to (own_rate - 1)%. Example: if the master_reseller's commission is 20%, the sub_reseller's max commission is 19%. This ensures at least 1% margin remains in the chain.
GET /license/install-command

Get install command for a license (host/IP combinations to install on customer server).

Query Params

?ip=1.2.3.4&type=cpanel

Response 200 (Success)

{
  "success": true,
  "install_url": "https://deploy.yourcompany.com/pre.sh",
  "full_command": "bash <(curl -s https://deploy.yourcompany.com/pre.sh) cpanel; MLSCP",
  "short_command": "MLSCP",
  "prefix": "MLS",
  "domain": "yourcompany.com"
}

Error Responses

401:
{ "success": false, "error": "Unauthorized" }

cURL Example

curl -X GET "https://reseller.makelicense.com/api/v1/license/install-command?ip=1.2.3.4&type=cpanel" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json"
GET /license/list

List all licenses belonging to the authenticated user.

Response 200 (Success)

{
  "success": true,
  "licenses": [
    {
      "id": 142,
      "user_id": 7,
      "ip_address": "1.2.3.4",
      "type": "cpanel",
      "status": "active",
      "registered_at": "2026-10-07 09:00:00",
      "expires_at": "2027-10-07 09:00:00",
      "reseller_prefix": null,
      "rc_response": "{\"ok\":\"True\"}",
      "created_at": "2026-10-07T09:00:00.000000Z",
      "updated_at": "2026-10-07T09:00:00.000000Z"
    }
  ]
}

Error Responses

401:
{ "success": false, "error": "Unauthorized" }

cURL Example

curl -X GET "https://reseller.makelicense.com/api/v1/license/list" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json"
POST /license/register

Register a new license on the given IP for the given product.

Request Body (JSON)

{"ip":"1.2.3.4","type":"cpanel","billingcycle":12}

Response 200 (Success)

{
  "success": true,
  "message": "License registered! Expiry: 2027-10-07"
}

Error Responses

400:
{ "success": false, "error": "Insufficient balance" }
400:
{ "success": false, "error": "RC API failed" }
403:
{ "success": false, "error": "IP 1.2.3.4 is already licensed by another reseller. Transfer ownership first." }
404:
{ "success": false, "error": "Product not found" }
422:
{ "message": "The ip field is required. (and 1 more error)", "errors": { "ip": ["The ip field is required."] } }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/license/register" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"ip":"1.2.3.4","type":"cpanel","billingcycle":12}'
POST /license/renew

Renew an existing license. billingcycle must be one of: 1, 3, 6, 12, 24, 36.

Request Body (JSON)

{"ip":"1.2.3.4","type":"cpanel","billingcycle":12}

Response 200 (Success)

{ "success": true, "message": "Renewed for 12 months!" }

Error Responses

400:
{ "success": false, "error": "Insufficient balance" }
400:
{ "success": false, "error": "API: Invalid license" }
404:
{ "success": false, "error": "Product not found" }
422:
{ "message": "The billingcycle must be one of: 1, 3, 6, 12, 24, 36.", "errors": { "billingcycle": ["..."] } }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/license/renew" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"ip":"1.2.3.4","type":"cpanel","billingcycle":12}'
POST /license/suspend

Suspend a license on the panel and locally.

Request Body (JSON)

{"ip":"1.2.3.4","type":"cpanel"}

Response 200 (Success)

{ "success": true, "message": "License suspended" }

Error Responses

400:
{ "success": false, "error": "Failed to suspend on API" }
422:
{ "message": "Validation error", "errors": { "ip": ["..."] } }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/license/suspend" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"ip":"1.2.3.4","type":"cpanel"}'
POST /license/unsuspend

Unsuspend a previously suspended license.

Request Body (JSON)

{"ip":"1.2.3.4","type":"cpanel"}

Response 200 (Success)

{ "success": true }

Error Responses

400:
{ "success": false, "error": "API: License already active" }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/license/unsuspend" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"ip":"1.2.3.4","type":"cpanel"}'
POST /license/change-ip

Change the IP address of an existing license.

Request Body (JSON)

{"ip":"1.2.3.4","newip":"5.6.7.8","type":"cpanel"}

Response 200 (Success)

{ "success": true }

Error Responses

400:
{ "success": false, "error": "New IP already licensed" }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/license/change-ip" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"ip":"1.2.3.4","newip":"5.6.7.8","type":"cpanel"}'
POST /license/change-core

Change the LiteSpeed core variant (4/8/X core).

Request Body (JSON)

{"ip":"1.2.3.4","old_type":"litespeed","new_type":"litespeed4core"}

Response 200 (Success)

{ "success": true, "message": "Core changed for free!" }

Error Responses

400:
{ "success": false, "error": "Invalid LiteSpeed type" }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/license/change-core" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"ip":"1.2.3.4","old_type":"litespeed","new_type":"litespeed4core"}'
POST /bundles

List all active bundle packages available to the authenticated reseller (with install commands).

Response 200 (Success)

[
  {
    "key": "VPSBUNDLE",
    "name": "VPS Bundle",
    "description": "cPanel + Softaculous + SitePad",
    "price": 25.00,
    "command": "bash <(curl -s https://deploy.yourcompany.com/pre.sh) cpanel; MLSCP\nbash <(curl -s https://deploy.yourcompany.com/pre.sh) softaculous; MLSSoftaculous\nbash <(curl -s https://deploy.yourcompany.com/pre.sh) sitepad; MLSSitePad",
    "software_list": ["cpanel", "softaculous", "sitepad"]
  }
]

Error Responses

401:
{ "success": false, "error": "Unauthorized" }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/bundles" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json"
POST /bundles/status

Check whether a specific bundle key is active.

Request Body (JSON)

{"bundle_key":"VPSBUNDLE"}

Response 200 (Success)

[
  { "key": "VPSBUNDLE", "status": "active" }
]

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/bundles/status" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"bundle_key":"VPSBUNDLE"}'
GET /sub-reseller

List sub-resellers. Admin sees all; master_reseller sees only their own. Use the <code>id</code> field in the response as the path parameter for <code>PATCH /sub-reseller/{id}</code> to update commission or status.

Response 200 (Success)

{
  "success": true,
  "count": 1,
  "sub_resellers": [
    {
      "id": 3,
      "user_id": 12,
      "parent_reseller_id": 5,
      "name": "John Doe",
      "email": "[email protected]",
      "balance": 150.00,
      "commission_rate": 10,
      "status": "active",
      "role": "sub_reseller"
    }
  ]
}

Error Responses

401:
{ "success": false, "error": "Unauthorized" }

cURL Example

curl -X GET "https://reseller.makelicense.com/api/v1/sub-reseller" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json"
POST /sub-reseller

Create a new sub-reseller (or master_reseller, if admin) under the authenticated account. <strong>Available to <code>admin</code> (any role) and <code>master_reseller</code> (sub_reseller role only, commission capped at own_rate - 1)</strong>.

Request Body (JSON)

{"name":"John","email":"[email protected]","password":"secret123","role":"sub_reseller","commission_rate":10}

Response 200 (Success)

{
  "success": true,
  "credentials": { "email": "[email protected]", "password": "secret123" },
  "role": "sub_reseller"
}

Error Responses

400:
{ "success": false, "error": "Email already exists" }
403:
{ "success": false, "error": "You do not have permission to create resellers" }
403:
{ "success": false, "error": "Master-Reseller can only create Sub-Resellers" }
422:
{ "message": "The email must be a valid email address.", "errors": { "email": ["..."] } }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/sub-reseller" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"name":"John","email":"[email protected]","password":"secret123","role":"sub_reseller","commission_rate":10}'
POST /sub-reseller/{id}/credit

Credit a sub-reseller's balance (floating balance — no debit from sender). Available to admin (any sub_reseller) and master_reseller (only own sub-resellers).

Request Body (JSON)

{"amount":100}

Response 200 (Success)

{
  "success": true,
  "message": "Credit extended (floating balance)",
  "balance": 250.00
}

Error Responses

404:
{ "success": false, "error": "Reseller user not found" }
422:
{ "message": "The amount must be at least 1.", "errors": { "amount": ["..."] } }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/sub-reseller/{id}/credit" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"amount":100}'
PATCH /sub-reseller/{id}

Update a sub-reseller — change <strong>commission_rate</strong> and/or <strong>status</strong>. <strong>Available to <code>admin</code> (any sub-reseller) and <code>master_reseller</code> (only their own sub-resellers)</strong>. The path parameter accepts either a numeric sub-reseller DB <code>id</code> OR the sub-reseller's <code>email</code> address (URL-encode the @ as %40). Send only the fields you want to change (partial update).

Field reference (click to expand)
Path parameter accepts two formats:
• By ID:     PATCH /v1/sub-reseller/3
• By email:  PATCH /v1/sub-reseller/john%40example.com   (URL-encode @ as %40)

Use the email form when integrating from your own panel — you do not need to look up the numeric ID first.

Partial update — only the fields you send are changed. Examples:
• Just change commission: body: {"commission_rate": 15}
• Just suspend:          body: {"status": "suspended"}
• Change both:           body: {"commission_rate": 15, "status": "suspended"}

Commission chain rule: master_reseller cannot set a commission_rate higher than their own commission_rate - 1 (so the chain keeps at least 1% margin).

Request Body (JSON)

{"commission_rate": 12, "status": "suspended"}

Response 200 (Success)

{
  "success": true,
  "message": "Reseller updated successfully",
  "sub_reseller": {
    "id": 3,
    "user_id": 12,
    "name": "John Doe",
    "email": "[email protected]",
    "commission_rate": 12,
    "status": "suspended",
    "role": "sub_reseller"
  }
}

Error Responses

400:
{ "success": false, "error": "Path parameter must be a numeric sub-reseller ID or an email address" }
400:
{ "success": false, "error": "Commission rate cannot exceed 19%" }
403:
{ "success": false, "error": "Sub-reseller not under your account" }
403:
{ "success": false, "error": "Forbidden: admin or master_reseller role required" }
404:
{ "success": false, "error": "Sub-reseller with email [email protected] not found" }
422:
{ "message": "The commission rate must be between 0 and 100.", "errors": { "commission_rate": ["..."] } }

cURL Example

curl -X PATCH "https://reseller.makelicense.com/api/v1/sub-reseller/{id}" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"commission_rate": 12, "status": "suspended"}'
GET /branding

Get the authenticated reseller's branding settings.

Response 200 (Success)

{
  "success": true,
  "branding": {
    "id": 1,
    "user_id": 7,
    "domain": "yourcompany.com",
    "prefix": "TIP",
    "subdomain": "api",
    "logo_url": "https://yourcompany.com/logo.png",
    "enabled": true,
    "install_url": "https://api.yourcompany.com/pre.sh",
    "created_at": "2026-10-01T09:00:00+00:00",
    "updated_at": "2026-10-07T09:00:00+00:00"
  }
}

Error Responses

404:
{ "success": false, "error": "Branding not configured. Create one first." }

cURL Example

curl -X GET "https://reseller.makelicense.com/api/v1/branding" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json"
POST /branding

Create or update the reseller's branding settings. All fields optional (only sent fields are updated).

Request Body (JSON)

{"domain":"yourcompany.com","prefix":"TIP","subdomain":"api","logo_url":"https://yourcompany.com/logo.png","enabled":true}

Response 200 (Success)

{
  "success": true,
  "message": "Branding updated successfully",
  "branding": {
    "id": 1,
    "user_id": 7,
    "domain": "yourcompany.com",
    "prefix": "TIP",
    "subdomain": "api",
    "logo_url": "https://yourcompany.com/logo.png",
    "enabled": true,
    "install_url": "https://api.yourcompany.com/pre.sh"
  }
}

Error Responses

422:
{ "message": "The prefix format is invalid.", "errors": { "prefix": ["The prefix format is invalid."] } }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/branding" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"domain":"yourcompany.com","prefix":"TIP","subdomain":"api","logo_url":"https://yourcompany.com/logo.png","enabled":true}'
DELETE /branding

Delete the authenticated reseller's branding settings.

Response 200 (Success)

{ "success": true, "message": "Branding deleted successfully" }

Error Responses

404:
{ "success": false, "error": "No branding found to delete" }

cURL Example

curl -X DELETE "https://reseller.makelicense.com/api/v1/branding" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json"
GET /branding/install-command

Generate a branded install command for a given product. The customer runs the command on their server.

Query Params

?product=cpanel

Response 200 (Success)

{
  "success": true,
  "product": "cpanel",
  "map_key": "cpanel",
  "prefix": "TIP",
  "suffix": "CP",
  "short_command": "TIPCP",
  "install_url": "https://api.yourcompany.com/pre.sh",
  "full_command": "bash <(curl -s https://api.yourcompany.com/pre.sh) cpanel; TIPCP"
}

Error Responses

422:
{ "message": "The product field is required.", "errors": { "product": ["..."] } }

cURL Example

curl -X GET "https://reseller.makelicense.com/api/v1/branding/install-command?product=cpanel" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json"
GET /branding/shim

Get the encoded branded pre.sh shim script. Upload this as pre.sh on the reseller's branded domain (e.g. api.yourcompany.com/pre.sh). The script forwards calls to the master install with branding applied.

Response 200 (Success)

{
  "success": true,
  "subdomain": "api",
  "domain": "yourcompany.com",
  "master_url": "https://reseller.makelicense.com",
  "install_url": "https://api.yourcompany.com/pre.sh",
  "encoded_base64": "aHR0cHM6Ly9yZXNlbGxlci5tYWtlbGljZW5zZS5jb20=",
  "shim_script": "#!/bin/sh\n# Encoded installer - executes the master installer with branding applied.\n\n_u=$(printf \u0027%s\u0027 \u0027aHR0cHM6Ly9yZXNlbGxlci5tYWtlbGljZW5zZS5jb20=\u0027 | base64 -d)\nexec bash <(curl -fsSL \"${_u}/pre.sh\") \"$@\"\n"
}

cURL Example

curl -X GET "https://reseller.makelicense.com/api/v1/branding/shim" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json"
POST /admin/reseller

Create a new reseller under the caller's account — including branding, prefix, subdomain, and optional initial balance. <strong>Available to both <code>admin</code> and <code>master_reseller</code></strong> tokens. Admins can create any role (reseller/master_reseller/sub_reseller/user). Master resellers can only create <code>sub_reseller</code> and <code>reseller</code> roles, and their commission is capped at <code>(own_rate - 1)%</code>.

Field reference (click to expand)
Field reference:
• name (required): full name
• email (required, unique)
• password (required, min 6 chars)
• role: reseller | master_reseller | sub_reseller | user (default: reseller)
• commission / commission_rate: 0..100 (admin: any, master_reseller: ≤ own - 1)
• balance: initial funds credited to the new account (creates a transaction record)
• domain: branded domain (e.g. "agent1.com") — used in install URL
• prefix: command prefix, 2-10 alphanumeric chars, auto-uppercased (e.g. "AGT" → install commands prefixed AGTMLSCP, AGTLSWS, etc.). Auto-generated from name's first 3 chars if omitted.
• subdomain: subdomain prepended to domain (e.g. "api" → https://api.agent1.com/pre.sh). Default: "api"
• enabled: true/false — whether branded install scripts are active (default: true)

Request Body (JSON)

{
  "name":     "Sub Agent 1",
  "email":    "[email protected]",
  "password": "secret123",
  "role":     "sub_reseller",
  "commission": 15,
  "balance":  500,
  "domain":   "agent1.com",
  "prefix":   "AGT",
  "subdomain": "api",
  "enabled":  true
}

Response 201 (Success)

{
  "success": true,
  "message": "Reseller created successfully",
  "reseller": {
    "id": 22,
    "name": "Sub Agent 1",
    "email": "[email protected]",
    "role": "sub_reseller",
    "balance": 500.00,
    "api_token": "f1a2b3c4d5e6f7g8h9...",
    "branding": {
      "domain":     "agent1.com",
      "prefix":     "AGT",
      "subdomain":  "api",
      "enabled":    true,
      "install_url": "https://api.agent1.com/pre.sh"
    }
  }
}

Error Responses

400:
{ "success": false, "error": "Commission rate cannot exceed 19% (your maximum allowed)" }
403:
{ "success": false, "error": "Master-Reseller can only create Sub-Resellers" }
403:
{ "success": false, "error": "Forbidden: admin role required" }
422:
{ "message": "The email has already been taken.", "errors": { "email": ["..."] } }
422:
{ "message": "The prefix format is invalid.", "errors": { "prefix": ["The prefix format is invalid."] } }
422:
{ "message": "The subdomain format is invalid.", "errors": { "subdomain": ["The subdomain format is invalid."] } }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/admin/reseller" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{ "name": "Sub Agent 1", "email": "[email protected]", "password": "secret123", "role": "sub_reseller", "commission": 15, "balance": 500, "domain": "agent1.com", "prefix": "AGT", "subdomain": "api", "enabled": true }'
GET /admin/reseller/{id}/balance

Get a reseller's current balance. <strong>Available to <code>admin</code> (any account) and <code>master_reseller</code> (only their own sub-resellers)</strong>.

Response 200 (Success)

{
  "success": true,
  "reseller": {
    "id": 22,
    "name": "Acme",
    "email": "[email protected]",
    "role": "reseller",
    "balance": 250.00
  }
}

Error Responses

403:
{ "success": false, "error": "Forbidden: admin role required" }
403:
{ "success": false, "error": "Reseller not under your account" }
404:
{ "success": false, "error": "Reseller not found" }

cURL Example

curl -X GET "https://reseller.makelicense.com/api/v1/admin/reseller/{id}/balance" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json"
POST /admin/reseller/{id}/credit

Add funds to a reseller's balance. <strong>Available to <code>admin</code> (any account, no debit from caller) and <code>master_reseller</code> (only their own sub-resellers, debits from caller's balance)</strong>.

Request Body (JSON)

{"amount":100,"description":"Top-up via API"}

Response 200 (Success)

{
  "success": true,
  "message": "Credit added successfully",
  "reseller": {
    "id": 22,
    "balance": 350.00
  }
}

Error Responses

400:
{ "success": false, "error": "Insufficient balance" }
403:
{ "success": false, "error": "Forbidden: admin role required" }
403:
{ "success": false, "error": "Reseller not under your account" }
404:
{ "success": false, "error": "Reseller not found" }
422:
{ "message": "The amount must be at least 0.01.", "errors": { "amount": ["..."] } }

cURL Example

curl -X POST "https://reseller.makelicense.com/api/v1/admin/reseller/{id}/credit" -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"amount":100,"description":"Top-up via API"}'

Product Types (DB codes)

Use these exact codes in API calls. The system also accepts WHMCS-style CamelCase (e.g. WHMReseller) and will normalize automatically.

cpanel cpaneldedicated cloudlinux litespeed litespeedadc litespeed4core litespeed8core litespeedxcore imunify360 wp2 softaculous sitepad plesk virtualizor jetbackup kernelcare backuply webuzo whmreseller plesklinuxvps plesklinuxdedicated whmsonic directadmin dareseller osm cxs cpguard syscare

Common Errors (all endpoints)

401: { "success": false, "error": "Unauthorized" } — Missing or invalid Bearer token
403: { "success": false, "error": "Forbidden: admin role required" } — Role check failed
422: { "message": "...", "errors": { "field": ["..."] } } — Validation error (Laravel default)
500: { "success": false, "error": "Server error" } — Unexpected server error