---
title: "Xtream AI API Reference"
description: "Native REST reference for the Xtream AI Panel API. JSON payloads, Bearer authentication, cursor pagination and idempotent writes."
---

# Xtream AI API Reference

The Xtream AI API is the native REST flavor of the Panel API. It is designed for new integrations that speak JSON, authenticate with a Bearer token and want a small, predictable surface. Every endpoint under this reference lives at the same base URL, returns JSON with the same envelope, and follows the same rules for pagination, errors and idempotency.

This flavor exists alongside two compatibility surfaces. The Xtream Codes and XUI.one dialect keeps the historical query string layout so legacy code keeps working after a base URL swap. The OneStream dialect keeps the header conventions used by OneStream integrations. All three flavors are served by the same panel and are backed by the same data, so a key issued for one works for all three. The v1 flavor is the one we recommend for new work because the request and response shapes are the most consistent and the SDKs are built on top of it.

## Base URL

All endpoints in this reference live under a single base:

```
https://<your-panel-domain>/panel-api/v1/*
```

Replace `<your-panel-domain>` with the domain your customers already use to reach the panel. Every endpoint page in this reference states the exact path it appends to that base, so you can copy the line straight into your client.

## Authentication in one paragraph

Every request except `GET /health` requires an API key sent as `Authorization: Bearer <your-api-key>`. Keys are issued from the panel UI, carry an explicit list of scopes and can be restricted to a set of source IPs. The full contract, including how to rotate a key, how scopes map to endpoints and how the per-key rate limit is configured, lives in [Authentication](/docs/?page=panel-api-authentication).

## Response shape

Success responses always carry HTTP status in the 2xx range with an `application/json` body. Single-resource endpoints return an object. List endpoints return the shape below, which is the same for every list in this reference.

```json
{
  "items": [
    { "id": 1, "name": "Package 42" },
    { "id": 2, "name": "Package 43" }
  ],
  "next_cursor": 2
}
```

Failures return a 4xx or 5xx status with a small envelope on every failing call.

```json
{
  "error": "validation_error",
  "message": "Field 'username' failed validation.",
  "request_id": "req_a1b2c3d4e5",
  "details": { "field": "username" }
}
```

Your code should branch on the `error` slug and treat `message` as documentation. The `request_id` also travels back in the `X-Request-Id` header. Quote it whenever you contact support. The full slug catalog and per-code retry guidance live in [Errors](/docs/?page=panel-api-errors).

## Pagination for list endpoints

List endpoints return at most 100 items per page. The default page size is 50. Pass `limit` on the query string to change it within that range.

Every list response includes `next_cursor`. It is `null` when the current page is the last one. When it is not null, pass it back as the `cursor` query parameter to fetch the next page. Treat the value as opaque: today it happens to be a numeric identifier, but future changes may switch it to a token you cannot interpret, and integrations that parse it will break.

```bash
curl -H "Authorization: Bearer <your-api-key>" \
     "https://<your-panel-domain>/panel-api/v1/lines?limit=100&cursor=172511964"
```

The order of items on a list is stable across pages, so you can safely walk `next_cursor` until it comes back `null` and know you have seen every row exactly once.

## Idempotency for writes

Every write endpoint requires an `Idempotency-Key` header. The API stores the response the first time you send a given key. If your integration retries the same request after a timeout, the API replays the stored response instead of running the write a second time. The value can be any opaque string up to 255 bytes. Business identifiers like `invoice-INV-2026-00814` are recommended because they make retries deterministic across restarts of your integration.

The header applies to every `POST` in this reference, including endpoints that end in `/enable`, `/disable`, `/renew` or `/delete`. Sending the same key again with a different body returns `409 idempotency_conflict`. Sending it while the first request is still running returns `409 idempotency_in_flight`. The full contract, retry recipes and worked examples live in [Rate limits and Idempotency](/docs/?page=panel-api-rate-limits-idempotency).

## Endpoints in this reference

Every endpoint below is versioned under `/panel-api/v1`. Public endpoints do not require a key. All other endpoints require a Bearer token with the scope named on the endpoint page.

### Public

| Endpoint | Method and path | What it does |
|---|---|---|
| [Health check](/docs/?page=xai-ref-health) | `GET /health` | Returns 200 with `{"status":"ok"}` when the API layer is up. |

### Identity

| Endpoint | Method and path | What it does |
|---|---|---|
| [Get caller identity](/docs/?page=xai-ref-me) | `GET /me` | Returns the identity attached to the calling key. Type (admin or reseller), scopes, billing state and effective permissions. |

### Lines

Customer lines. One row per subscription. Every write endpoint under this group requires an `Idempotency-Key` header.

| Endpoint | Method and path | What it does |
|---|---|---|
| [List lines](/docs/?page=xai-ref-lines-list) | `GET /lines` | Paginated list. Filters by owner, package and expiry. |
| [Create a line](/docs/?page=xai-ref-lines-create) | `POST /lines` | Creates a subscription against a package. Returns the credentials the customer will use to log in. |
| [Get a line](/docs/?page=xai-ref-lines-get) | `GET /lines/{id}` | Full record for a single line. |
| [Update a line](/docs/?page=xai-ref-lines-update) | `POST /lines/{id}/update` | Applies a partial update. Only the fields you send are touched. |
| [Enable a line](/docs/?page=xai-ref-lines-enable) | `POST /lines/{id}/enable` | Marks the line as active and allows logins. |
| [Disable a line](/docs/?page=xai-ref-lines-disable) | `POST /lines/{id}/disable` | Marks the line as inactive without deleting it. |
| [Renew a line](/docs/?page=xai-ref-lines-renew) | `POST /lines/{id}/renew` | Extends the expiry date by a number of months and charges the caller's billing budget. |
| [Reset password](/docs/?page=xai-ref-lines-reset-password) | `POST /lines/{id}/reset-password` | Generates a fresh password for the line. |
| [Delete a line](/docs/?page=xai-ref-lines-delete) | `POST /lines/{id}/delete` | Removes the line and its associations. |
| [List current connections](/docs/?page=xai-ref-lines-connections) | `GET /lines/{id}/connections` | Snapshot of the sessions currently open against this line. |

### Catalog

Read-only. Everything a storefront or reseller dashboard needs to render packages, bouquets, live streams and VODs.

| Endpoint | Method and path | What it does |
|---|---|---|
| [List packages](/docs/?page=xai-ref-catalog-packages) | `GET /packages` | Every package the caller can sell. |
| [List bouquets](/docs/?page=xai-ref-catalog-bouquets) | `GET /bouquets` | Every bouquet the caller can assign to a line. |
| [List live streams](/docs/?page=xai-ref-catalog-streams) | `GET /streams` | Paginated list of live channels. |
| [Get a live stream](/docs/?page=xai-ref-catalog-stream) | `GET /streams/{id}` | Full record for one channel. |
| [List VODs](/docs/?page=xai-ref-catalog-vods) | `GET /vods` | Paginated list of movies. |
| [Get a VOD](/docs/?page=xai-ref-catalog-vod) | `GET /vods/{id}` | Full record for one movie. |

### Resellers

Admin-only endpoints for managing resellers and their billing. A reseller key can only reach `POST /resellers` and only to create a sub-reseller under itself.

| Endpoint | Method and path | What it does |
|---|---|---|
| [List resellers](/docs/?page=xai-ref-resellers-list) | `GET /resellers` | Paginated list of every reseller on the panel. |
| [Create a reseller](/docs/?page=xai-ref-resellers-create) | `POST /resellers` | Creates a reseller (admin) or a sub-reseller under the caller (reseller with `subresellers:write`). |
| [Get a reseller](/docs/?page=xai-ref-resellers-get) | `GET /resellers/{id}` | Full record for one reseller. |
| [Update a reseller](/docs/?page=xai-ref-resellers-update) | `POST /resellers/{id}/update` | Applies a partial update to the reseller's profile and permissions. |
| [Read billing state](/docs/?page=xai-ref-resellers-billing) | `GET /resellers/{id}/billing` | Current billing mode (credits or users), balance and effective caps. |
| [Adjust billing](/docs/?page=xai-ref-resellers-billing-adjust) | `POST /resellers/{id}/billing/adjust` | Applies a delta to the reseller's credit balance or user cap. |

## Compat flavors

If your code was written for another panel, use the compatibility flavor that already matches its request shape. Both are served alongside the native v1 endpoints and accept the same API keys.

- **Xtream Codes and XUI.one compatibility.** Same query string layout your existing code already sends. See [Xtream Codes compatibility](/docs/?page=panel-api-xtream-codes-compatibility).
- **OneStream compatibility.** Same header conventions used by OneStream integrations. See [OneStream compatibility](/docs/?page=panel-api-onestream-compatibility).

For a broader map of how the three flavors fit together, and when to pick one over another, read the [Panel API Overview](/docs/?page=panel-api-overview).
