Update a line, POST /ext/line/{uuid}/update-advanced
If you are starting a new integration instead of migrating, prefer the native v1 API with the official SDKs. The OneStream dialect exists to let existing OneStream code point at Xtream AI with only a base URL change.
Change selected fields on an existing line. Only five fields are editable through this endpoint: password, expire_at, is_enabled, is_restreamer, and max_connections. Anything else your OneStream client sends (username, bouquets, reseller_notes, is_trial, and so on) is rejected up front with 422 validation_error so you never get a silent 200 OK on a change that did not actually apply.
The response is the full line object with the updated values, in the same shape as an element of GET /ext/lines. If you need to change a field that is not in the editable list, use the native update endpoint.
Endpoint
POST https://<your-panel-domain>/panel-api/onestream/ext/line/{uuid}/update-advanced
Authentication
X-Api-Key. X-Auth-User and Authorization: Bearer also accepted. See Authentication.
Required scope
lines:write.
Idempotency
Optional but recommended. Pass a unique rid per intended change. A retried rid with the same body returns the cached response; a retried rid with a different body returns 409 Transaction already processed.
Path parameters
| Name | Type | Description |
|---|---|---|
uuid |
string | The opaque line UUID. |
Request body
At least one editable field must be present. If none are supplied, the request is rejected with 422 validation_error.
| Field | Type | Description |
|---|---|---|
password |
string | New line password. Reseller keys whose group has allow_change_pass=0 receive 403 password_change_not_allowed. |
expire_at |
string, int, or null | Absolute expiry. ISO 8601 with offset (2026-12-31T00:00:00+00:00) is canonical. A unix integer is accepted. Pass null to remove the expiry (make the line perpetual). Passing 0 is a validation error because the engine treats exp_date = 0 as expired. |
is_enabled |
bool | Set to false to disable, true to re-enable. Truthy strings ("true", "1", "yes", "on") are also accepted. |
is_restreamer |
bool | Toggle the restreamer flag. |
max_connections |
int | Concurrent connections cap. Clamped to [1, 100] by the underlying handler. |
rid |
string | Idempotency key. |
Fields that OneStream historically allowed but this endpoint does not accept (username, bouquets, reseller_notes, is_trial) trigger the "no editable fields provided" error even when they are the only ones sent. That is intentional: silently succeeding on a rejected field is the worst possible outcome for a billing integration.
{
"password": "new-s3cret",
"is_enabled": false,
"max_connections": 3,
"expire_at": "2026-12-31T00:00:00+00:00",
"rid": "upd-user-42-2026-08"
}
Response
200 OK with the full line object. Same shape as an element of GET /ext/lines.
{
"line_id": "b32c1a04-11ea-4c67-8fd1-0001000000f1",
"username": "reseller1_20260808",
"password": "new-s3cret",
"expire_at": "2026-12-31T00:00:00+00:00",
"is_enabled": false,
"is_restreamer": false,
"is_trial": false,
"package_id": null,
"bouquets": [],
"max_connections": 3,
"reseller_notes": "",
"mac_addr": null,
"owner": "billing",
"type": "regular"
}
package_id is always null in the OneStream dialect (the internal API does not surface the source package on a line row). mac_addr is always null because the product does not provision physical devices.
Examples
cURL
curl -X POST "https://<your-panel-domain>/panel-api/onestream/ext/line/b32c1a04-11ea-4c67-8fd1-0001000000f1/update-advanced" \
-H "X-Api-Key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"password": "new-s3cret",
"is_enabled": false,
"max_connections": 3,
"expire_at": "2026-12-31T00:00:00+00:00",
"rid": "upd-user-42-2026-08"
}'
PHP raw
$uuid = 'b32c1a04-11ea-4c67-8fd1-0001000000f1';
$ch = curl_init("https://<your-panel-domain>/panel-api/onestream/ext/line/{$uuid}/update-advanced");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'X-Api-Key: <your-api-key>',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'password' => 'new-s3cret',
'is_enabled' => false,
'max_connections' => 3,
'expire_at' => '2026-12-31T00:00:00+00:00',
'rid' => 'upd-user-42-2026-08',
]),
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
Python raw
import requests
uuid_ = "b32c1a04-11ea-4c67-8fd1-0001000000f1"
r = requests.post(
f"https://<your-panel-domain>/panel-api/onestream/ext/line/{uuid_}/update-advanced",
headers={"X-Api-Key": "<your-api-key>"},
json={
"password": "new-s3cret",
"is_enabled": False,
"max_connections": 3,
"expire_at": "2026-12-31T00:00:00+00:00",
"rid": "upd-user-42-2026-08",
},
timeout=30,
)
r.raise_for_status()
print(r.json())
Errors
| HTTP | Error slug (or message) | When it happens | How to fix |
|---|---|---|---|
| 401 | Invalid API key |
Token is unknown, expired, disabled, or deleted. | Check the token or issue a new one. |
| 403 | insufficient_scope |
Token lacks lines:write. |
Issue a key with the scope. |
| 403 | password_change_not_allowed |
Reseller group has allow_change_pass=0 and the body carried password. |
Omit password, or ask the panel operator to enable password changes for the group. |
| 409 | Transaction already processed |
Same rid was reused with a different body. |
Use a fresh rid, or replay with the exact original body. |
| 422 | line_id not found or invalid |
The UUID in the URL is malformed, was not issued by this panel, or belongs to a different panel. Uniform on purpose. | Verify the UUID you stored on line-creation. |
| 422 | update-advanced: none of the provided fields is editable by this API. Supported: password, expire_at, is_enabled, is_restreamer, max_connections. |
Body contained only rejected fields (username, bouquets, reseller_notes, is_trial), or no editable fields at all. |
Send at least one editable field. Use the native update endpoint for other fields. |
| 422 | Invalid expire_at format: expected ISO 8601 or unix timestamp |
expire_at is neither a parseable ISO 8601 timestamp, a positive unix integer, nor explicit null. |
Send 2026-12-31T00:00:00+00:00, a positive integer, or null. |
| 429 | Rate limit exceeded |
The key hit its per-minute cap. | Back off and retry after Retry-After seconds. |
| 501 | not_implemented |
A GET request was sent to this URL. |
Only POST is accepted. |