---
title: "action=get_bouquets"
description: "List every bouquet the calling key can assign to a line. Admin sees all; a reseller sees the union of bouquets across the packages they can sell."
---

# 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.

```json
{
  "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

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

### PHP raw

```php
$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

```python
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](/docs/?page=panel-api-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

- [XC and XUI API Reference](/docs/?page=xc-ref-overview). Envelope, authentication, action list.
- [action=packages](/docs/?page=xc-ref-packages). Companion listing of packages, each of which references bouquet ids.
- [Panel API Catalog](/docs/?page=xai-ref-overview). Native v1 read-only catalog endpoints.
