action=get_bouquets

Lists every bouquet visible to the calling key. Admin keys see every bouquet on the panel. Reseller keys see the union of bouquets across the packages they are authorized to sell, cached server-side for five minutes. The response is unpaginated.

Use this endpoint to populate a bouquet-picker in your provisioning UI, or to validate a bouquets_selected[] list before calling create_line.

Endpoint

GET https://<your-panel-domain>/panel-api/xc/{accesscode}/admin/index.php?action=get_bouquets

Also accepted: POST with action=get_bouquets in the body, and the /reseller/index.php sub-path.

Authentication

Send the API key as ?api_key=<token>, as an api_key=<token> POST field, or as Authorization: Bearer <token>.

Required scope

bouquets:read. A key without the scope gets STATUS_NO_PERMISSIONS with error: "insufficient_scope".

Query parameters

Name Type Required Default Description
action string Yes Must be get_bouquets.
api_key string Yes (if not using Bearer) The API key.

There are no pagination or filter parameters.

Response

data.items is the list of Bouquet objects.

{
  "status": "STATUS_SUCCESS",
  "data": {
    "items": [
      { "id": 119, "name": "Bouquet 119", "order": 0 },
      { "id": 136, "name": "Bouquet 136", "order": 0 },
      { "id": 135, "name": "Bouquet 135", "order": 0 },
      { "id": 133, "name": "Bouquet 133", "order": 0 },
      { "id": 132, "name": "Bouquet 132", "order": 0 }
    ]
  }
}

Field-by-field.

Field Type Description
id int Bouquet id. Use it in bouquets_selected[] on create_line (aliased to bouquets[]).
name string Human-readable name shown in the panel UI.
order int Display order hint. Lower first. Zero means the panel admin has not set an order.

Examples

cURL

curl "https://<your-panel-domain>/panel-api/xc/panel_api/admin/index.php?api_key=<your-api-key>&action=get_bouquets"

PHP raw

$url = 'https://<your-panel-domain>/panel-api/xc/panel_api/admin/index.php'
     . '?' . http_build_query([
         'api_key' => '<your-api-key>',
         'action'  => 'get_bouquets',
       ]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($body['status'] ?? '') !== 'STATUS_SUCCESS') {
    throw new RuntimeException('get_bouquets failed: ' . ($body['data']['message'] ?? 'unknown'));
}
$byId = [];
foreach ($body['data']['items'] as $b) {
    $byId[$b['id']] = $b['name'];
}
// Now $byId is a lookup table id => name for your UI.

Python raw

import requests

r = requests.get(
    "https://<your-panel-domain>/panel-api/xc/panel_api/admin/index.php",
    params={"api_key": "<your-api-key>", "action": "get_bouquets"},
    timeout=30,
)
r.raise_for_status()
body = r.json()
if body["status"] != "STATUS_SUCCESS":
    raise RuntimeError(f"get_bouquets failed: {body['data'].get('message')}")
by_id = {b["id"]: b["name"] for b in body["data"]["items"]}

Errors

status error slug When it happens How to fix
STATUS_INVALID_DATA validation_error action parameter is missing. Include action=get_bouquets.
STATUS_NO_PERMISSIONS insufficient_scope Key does not carry bouquets:read. Issue a new key with the scope.
STATUS_FAILURE invalid_key Key not sent or not recognized. Check the key value.
STATUS_FAILURE rate_limited Per-minute request budget exceeded. Slow down. See Rate limits & Idempotency.

Reseller visibility

A reseller key sees the union of bouquets across every package their group is authorized to sell. If the panel admin authorizes the reseller for packages P1 (bouquets {1, 4}) and P2 (bouquets {4, 9}), the reseller sees bouquets {1, 4, 9}. The union is computed on the panel side and cached for five minutes; new authorizations may take up to that long to become visible.

An empty visible set is returned as {"items": []} with STATUS_SUCCESS. It is not an error.

See also