---
title: "Get a live stream"
description: "Fetches a single live channel by its numeric id. Returns the same shape as one item in the /streams listing."
---

# Get a live stream

Fetches one live channel by its numeric id. The response has the same shape as an item in [List live streams](/docs/?page=xai-ref-catalog-streams), so any code that already renders channels from the list endpoint can render the single item response without changes.

Both admin and reseller keys can call this endpoint on any channel id, since the catalog is not reseller filtered. The endpoint never exposes stream source URLs, primary origins, DRM keys, or FFmpeg command flags. If your integration needs to play the channel, use the subscriber's Xtream Codes playlist after creating a line.

## Endpoint

`GET https://<your-panel-domain>/panel-api/v1/streams/{id}`

## Authentication

Bearer token in the `Authorization` header. See [Authentication](/docs/?page=panel-api-authentication).

## Required scope

`streams:read`.

## Path parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `id` | int | Numeric channel id. |

## Response

| Field | Type | Description |
| ----- | ---- | ----------- |
| `id` | int | Numeric channel id. |
| `name` | string | Channel display name. |
| `icon` | string | Logo URL. Empty string when the channel has no logo. |
| `categories` | array | List of `{id, name}` objects. A channel can belong to more than one category. |

Example response.

```json
{
  "id": 30,
  "name": "Channel 30 HD",
  "icon": "https://cdn.example.com/logos/channel-30.png",
  "categories": [
    {"id": 1, "name": "Regional TV"}
  ]
}
```

If the channel does not exist, the server returns `404 not_found`.

```json
{
  "error": "not_found",
  "message": "Stream not found",
  "request_id": "d2242318-b4af-4954-9fc2-50e096f7fbed"
}
```

## Examples

### cURL

```bash
curl -H "Authorization: Bearer <your-api-key>" \
     https://<your-panel-domain>/panel-api/v1/streams/30
```

### PHP SDK

```php
require __DIR__ . '/api-panel-php-sdk-1.0.0/autoload.php';
use XtreamAI\PanelApi\PanelApiClient;
use XtreamAI\PanelApi\Exceptions\NotFoundException;

$client = new PanelApiClient(baseUrl: 'https://<your-panel-domain>', token: '<your-api-key>');

try {
    $stream = $client->catalog->stream(30);
    echo $stream->name, PHP_EOL;
} catch (NotFoundException $e) {
    echo "stream not found\n";
}
```

### Python SDK

```python
from xtream_ai_panel_api import PanelApiClient
from xtream_ai_panel_api.exceptions import NotFoundException

client = PanelApiClient(base_url="https://<your-panel-domain>", token="<your-api-key>")

try:
    stream = client.catalog.stream(30)
    print(stream.name)
except NotFoundException:
    print("stream not found")
```

## Errors

| HTTP | Error slug | When it happens | How to fix |
| ---- | ---------- | --------------- | ---------- |
| 401 | `invalid_key` | The `Authorization` header is missing, malformed, or names a key that does not exist. | Check the header. See [Authentication](/docs/?page=panel-api-authentication). |
| 403 | `insufficient_scope` | The key does not carry `streams:read`. | Regenerate the key with `streams:read` in its scope list, or use a key that has it. |
| 404 | `not_found` | No channel exists with the given `id`. | Verify the id. Ids are stable, so a persistent 404 means the channel was deleted from the panel. |
| 429 | `rate_limited` | The per key rate limit has been exceeded. Response carries `Retry-After: 60` and `X-RateLimit-*` headers. | Back off for the number of seconds in `Retry-After` and retry. |

## See also

- [List live streams](/docs/?page=xai-ref-catalog-streams)
- [Get a VOD](/docs/?page=xai-ref-catalog-vod)
- [Catalog overview](/docs/?page=xai-ref-overview)
