---
title: "List bouquets, GET /ext/bouquets"
description: "Returns every bouquet the calling key can attach to a line, in the OneStream flat-array shape."
---

# GET /ext/bouquets

`/ext/bouquets` returns every bouquet the calling key can attach to a line. A bouquet is a named grouping of live channels and VOD items that the panel administrator (or a reseller with the right permissions) curates. Bouquets are the granularity at which line entitlements are assigned: when you create or update a line, you send a `bouquets` array of numeric ids, and this endpoint is where you look those ids up.

The response is the OneStream shape: a plain JSON array of bouquet objects. There is no envelope. The list is scoped by caller type in the same way as packages: an admin key sees every bouquet on the panel, and a reseller key sees only the bouquets its member group has been granted access to. An empty result set is returned as `[]`, not as an error.

## Endpoint

`GET https://<your-panel-domain>/panel-api/onestream/ext/bouquets`

## Authentication

Send the API key in `X-Api-Key`, `X-Auth-User`, or `Authorization: Bearer`. See the [OneStream overview](/docs/?page=os-ref-overview#base-url-and-authentication).

## Required scope

`bouquets:read`.

## Query parameters

None. The full list of visible bouquets is returned in one call. There is typically a small enough number of bouquets per panel that pagination is not applied.

## Response

A plain JSON array. Each element has the following fields.

| Field | Type | Description |
| ----- | ---- | ----------- |
| `id` | int | Numeric bouquet id. Stable across the panel's lifetime. Pass this in the `bouquets` array when creating a line. |
| `name` | string | Human-readable bouquet name shown in the panel UI. |
| `order` | int | Display order the panel uses when rendering this bouquet next to others. `0` means "unordered" and lists rendered alphabetically. |

Example response:

```json
[
  {"id": 1, "name": "World Restream", "order": 0},
  {"id": 5, "name": "Sports", "order": 0},
  {"id": 6, "name": "Movies", "order": 0},
  {"id": 118, "name": "Europe Movies", "order": 0}
]
```

## Examples

### cURL

```bash
curl -H "X-Api-Key: <your-api-key>" \
     https://<your-panel-domain>/panel-api/onestream/ext/bouquets
```

### PHP raw

```php
$ch = curl_init('https://<your-panel-domain>/panel-api/onestream/ext/bouquets');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-Api-Key: <your-api-key>']);
$bouquets = json_decode(curl_exec($ch), true);
curl_close($ch);
foreach ($bouquets as $b) {
    echo $b['id'] . ' ' . $b['name'] . "\n";
}
```

### Python raw

```python
import requests

bouquets = requests.get(
    "https://<your-panel-domain>/panel-api/onestream/ext/bouquets",
    headers={"X-Api-Key": "<your-api-key>"},
    timeout=30,
).json()

for b in bouquets:
    print(b["id"], b["name"])
```

## Errors

| HTTP | Error slug | When it happens | How to fix |
| ---- | ---------- | --------------- | ---------- |
| 401 | `invalid_key` | Header is missing, the token is unknown, the key was disabled, expired, deleted, or the caller IP is not on the key's IP allow-list. | Check the header. If the key was rotated, mint a new one from the panel. |
| 403 | `insufficient_scope` | The key does not carry `bouquets:read`. | Regenerate the key with `bouquets:read`, or use a key that has it. |
| 429 | `rate_limited` | The per-key or per-IP rate limit was hit. Response carries `Retry-After` and `X-RateLimit-*` headers. | Back off for the number of seconds in `Retry-After`. |
| 403 | `api_disabled` | An admin has turned the Panel API off for this panel. | Ask the admin to re-enable it. |

## See also

- [List packages](/docs/?page=os-ref-packages)
- [OneStream overview](/docs/?page=os-ref-overview)
- [Native bouquets endpoint](/docs/?page=xai-ref-catalog-bouquets)
