Add Category 3: Line API with management operations
This commit is contained in:
@@ -0,0 +1,962 @@
|
|||||||
|
# Line API - Subscription Management
|
||||||
|
|
||||||
|
Complete documentation for subscription line management in the XUI.ONE Admin API.
|
||||||
|
|
||||||
|
## 📋 Overview
|
||||||
|
|
||||||
|
The Line API provides complete control over subscription lines (M3U/Xtream Codes accounts). You can create, modify, enable, disable, and delete subscription lines programmatically.
|
||||||
|
|
||||||
|
### Available Operations
|
||||||
|
|
||||||
|
| Operation | Action | Method | Description |
|
||||||
|
|-----------|--------|--------|-------------|
|
||||||
|
| **View** | `get_line` | GET | Get specific line details |
|
||||||
|
| **Create** | `create_line` | POST | Create new subscription |
|
||||||
|
| **Update** | `edit_line` | POST | Modify existing line |
|
||||||
|
| **Delete** | `delete_line` | POST | Permanently remove line |
|
||||||
|
| **Enable** | `enable_line` | POST | Activate disabled line |
|
||||||
|
| **Disable** | `disable_line` | POST | Temporarily suspend line |
|
||||||
|
| **Ban** | `ban_line` | POST | Block abusive account |
|
||||||
|
| **Unban** | `unban_line` | POST | Remove ban from line |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Get Specific Line
|
||||||
|
|
||||||
|
### Action: `get_line`
|
||||||
|
|
||||||
|
Retrieve detailed information about a specific subscription line.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `id` (required) - Line ID
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```bash
|
||||||
|
curl "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=get_line&id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "STATUS_SUCCESS",
|
||||||
|
"data": {
|
||||||
|
"id": "123",
|
||||||
|
"username": "testuser",
|
||||||
|
"password": "testpass123",
|
||||||
|
"exp_date": "1735689600",
|
||||||
|
"max_connections": "1",
|
||||||
|
"is_trial": "0",
|
||||||
|
"enabled": "1",
|
||||||
|
"is_restreamer": "0",
|
||||||
|
"bouquet": "[1,2,3]",
|
||||||
|
"notes": "Premium customer",
|
||||||
|
"created_at": "1609459200"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ➕ Create New Line
|
||||||
|
|
||||||
|
### Action: `create_line`
|
||||||
|
|
||||||
|
Create a new subscription line with specified settings.
|
||||||
|
|
||||||
|
**Required Parameters:**
|
||||||
|
- `username` - Username for the line
|
||||||
|
- `password` - Password for the line
|
||||||
|
|
||||||
|
**Optional Parameters:**
|
||||||
|
- `max_connections` - Maximum concurrent connections (default: 1)
|
||||||
|
- `exp_date` - Expiration date (YYYY-MM-DD, timestamp, or relative like "1month")
|
||||||
|
- `is_trial` - Trial status (0 = No, 1 = Yes)
|
||||||
|
- `is_restreamer` - Reseller status (0 = No, 1 = Yes)
|
||||||
|
- `bouquets_selected[]` - Array of bouquet/package IDs
|
||||||
|
- `notes` - Admin notes
|
||||||
|
- `contact` - Contact information
|
||||||
|
- `isp_lock` - Lock to specific IP address
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=create_line" \
|
||||||
|
-d "username=newuser" \
|
||||||
|
-d "password=securepass123" \
|
||||||
|
-d "max_connections=1" \
|
||||||
|
-d "exp_date=2025-12-31" \
|
||||||
|
-d "bouquets_selected[]=1" \
|
||||||
|
-d "bouquets_selected[]=2" \
|
||||||
|
-d "notes=Premium customer"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "STATUS_SUCCESS",
|
||||||
|
"data": {
|
||||||
|
"line_id": "456",
|
||||||
|
"username": "newuser",
|
||||||
|
"password": "securepass123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✏️ Edit Existing Line
|
||||||
|
|
||||||
|
### Action: `edit_line`
|
||||||
|
|
||||||
|
Modify settings of an existing subscription line.
|
||||||
|
|
||||||
|
**Required Parameters:**
|
||||||
|
- `id` - Line ID to edit
|
||||||
|
|
||||||
|
**Optional Parameters:**
|
||||||
|
- `username` - New username
|
||||||
|
- `password` - New password
|
||||||
|
- `max_connections` - Update connection limit
|
||||||
|
- `exp_date` - Update expiration date
|
||||||
|
- `is_trial` - Update trial status
|
||||||
|
- `bouquets_selected[]` - Update assigned packages
|
||||||
|
- `notes` - Update notes
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=edit_line" \
|
||||||
|
-d "id=123" \
|
||||||
|
-d "password=newpassword456" \
|
||||||
|
-d "max_connections=2" \
|
||||||
|
-d "exp_date=2026-06-30"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "STATUS_SUCCESS",
|
||||||
|
"data": {
|
||||||
|
"message": "Line updated successfully"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🗑️ Delete Line
|
||||||
|
|
||||||
|
### Action: `delete_line`
|
||||||
|
|
||||||
|
Permanently remove a subscription line from the panel.
|
||||||
|
|
||||||
|
⚠️ **Warning:** This action cannot be undone!
|
||||||
|
|
||||||
|
**Required Parameters:**
|
||||||
|
- `id` - Line ID to delete
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=delete_line" \
|
||||||
|
-d "id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "STATUS_SUCCESS",
|
||||||
|
"data": {
|
||||||
|
"message": "Line deleted successfully"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Enable Line
|
||||||
|
|
||||||
|
### Action: `enable_line`
|
||||||
|
|
||||||
|
Activate a previously disabled line.
|
||||||
|
|
||||||
|
**Required Parameters:**
|
||||||
|
- `id` - Line ID to enable
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=enable_line" \
|
||||||
|
-d "id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⛔ Disable Line
|
||||||
|
|
||||||
|
### Action: `disable_line`
|
||||||
|
|
||||||
|
Temporarily suspend a line without deleting it.
|
||||||
|
|
||||||
|
**Required Parameters:**
|
||||||
|
- `id` - Line ID to disable
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=disable_line" \
|
||||||
|
-d "id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚫 Ban Line
|
||||||
|
|
||||||
|
### Action: `ban_line`
|
||||||
|
|
||||||
|
Permanently block an abusive or fraudulent account.
|
||||||
|
|
||||||
|
**Required Parameters:**
|
||||||
|
- `id` - Line ID to ban
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=ban_line" \
|
||||||
|
-d "id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✓ Unban Line
|
||||||
|
|
||||||
|
### Action: `unban_line`
|
||||||
|
|
||||||
|
Remove ban from a previously banned line.
|
||||||
|
|
||||||
|
**Required Parameters:**
|
||||||
|
- `id` - Line ID to unban
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=unban_line" \
|
||||||
|
-d "id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💻 Code Examples
|
||||||
|
|
||||||
|
### Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
import requests
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
class XUILineManager:
|
||||||
|
def __init__(self, base_url, api_key):
|
||||||
|
self.base_url = base_url
|
||||||
|
self.api_key = api_key
|
||||||
|
|
||||||
|
def _make_request(self, action, data=None):
|
||||||
|
"""Make API request"""
|
||||||
|
params = {
|
||||||
|
"api_key": self.api_key,
|
||||||
|
"action": action
|
||||||
|
}
|
||||||
|
|
||||||
|
if data:
|
||||||
|
response = requests.post(self.base_url, params=params, data=data)
|
||||||
|
else:
|
||||||
|
response = requests.get(self.base_url, params=params)
|
||||||
|
|
||||||
|
result = response.json()
|
||||||
|
if result["status"] != "STATUS_SUCCESS":
|
||||||
|
raise Exception(f"API Error: {result.get('error', 'Unknown error')}")
|
||||||
|
|
||||||
|
return result["data"]
|
||||||
|
|
||||||
|
def get_line(self, line_id):
|
||||||
|
"""Get specific line details"""
|
||||||
|
return self._make_request("get_line", {"id": line_id})
|
||||||
|
|
||||||
|
def create_line(self, username, password, **kwargs):
|
||||||
|
"""Create new subscription line"""
|
||||||
|
data = {
|
||||||
|
"username": username,
|
||||||
|
"password": password,
|
||||||
|
**kwargs
|
||||||
|
}
|
||||||
|
return self._make_request("create_line", data)
|
||||||
|
|
||||||
|
def edit_line(self, line_id, **kwargs):
|
||||||
|
"""Edit existing line"""
|
||||||
|
data = {"id": line_id, **kwargs}
|
||||||
|
return self._make_request("edit_line", data)
|
||||||
|
|
||||||
|
def delete_line(self, line_id):
|
||||||
|
"""Delete line"""
|
||||||
|
return self._make_request("delete_line", {"id": line_id})
|
||||||
|
|
||||||
|
def enable_line(self, line_id):
|
||||||
|
"""Enable line"""
|
||||||
|
return self._make_request("enable_line", {"id": line_id})
|
||||||
|
|
||||||
|
def disable_line(self, line_id):
|
||||||
|
"""Disable line"""
|
||||||
|
return self._make_request("disable_line", {"id": line_id})
|
||||||
|
|
||||||
|
def ban_line(self, line_id):
|
||||||
|
"""Ban line"""
|
||||||
|
return self._make_request("ban_line", {"id": line_id})
|
||||||
|
|
||||||
|
def unban_line(self, line_id):
|
||||||
|
"""Unban line"""
|
||||||
|
return self._make_request("unban_line", {"id": line_id})
|
||||||
|
|
||||||
|
# Usage Example
|
||||||
|
manager = XUILineManager(
|
||||||
|
base_url="http://your-server.com/cSbuFLhp/",
|
||||||
|
api_key="8D3135D30437F86EAE2FA4A2A8345000"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create new line
|
||||||
|
new_line = manager.create_line(
|
||||||
|
username="customer001",
|
||||||
|
password="secure123",
|
||||||
|
max_connections=1,
|
||||||
|
exp_date="2025-12-31",
|
||||||
|
bouquets_selected=[1, 2, 3],
|
||||||
|
notes="Premium customer"
|
||||||
|
)
|
||||||
|
print(f"Created line ID: {new_line['line_id']}")
|
||||||
|
|
||||||
|
# Get line details
|
||||||
|
line = manager.get_line(123)
|
||||||
|
print(f"Line: {line['username']} - Expires: {line['exp_date']}")
|
||||||
|
|
||||||
|
# Edit line
|
||||||
|
manager.edit_line(
|
||||||
|
line_id=123,
|
||||||
|
password="newpassword",
|
||||||
|
max_connections=2
|
||||||
|
)
|
||||||
|
print("Line updated successfully")
|
||||||
|
|
||||||
|
# Disable line
|
||||||
|
manager.disable_line(123)
|
||||||
|
print("Line disabled")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### PHP
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
class XUILineManager {
|
||||||
|
private $baseUrl;
|
||||||
|
private $apiKey;
|
||||||
|
|
||||||
|
public function __construct($baseUrl, $apiKey) {
|
||||||
|
$this->baseUrl = $baseUrl;
|
||||||
|
$this->apiKey = $apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function makeRequest($action, $data = null) {
|
||||||
|
$url = $this->baseUrl . "?api_key=" . $this->apiKey . "&action=" . $action;
|
||||||
|
|
||||||
|
if ($data) {
|
||||||
|
$options = [
|
||||||
|
'http' => [
|
||||||
|
'method' => 'POST',
|
||||||
|
'header' => 'Content-type: application/x-www-form-urlencoded',
|
||||||
|
'content' => http_build_query($data)
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$context = stream_context_create($options);
|
||||||
|
$response = file_get_contents($url, false, $context);
|
||||||
|
} else {
|
||||||
|
$response = file_get_contents($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = json_decode($response, true);
|
||||||
|
|
||||||
|
if ($result['status'] !== 'STATUS_SUCCESS') {
|
||||||
|
throw new Exception("API Error: " . ($result['error'] ?? 'Unknown error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result['data'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLine($lineId) {
|
||||||
|
return $this->makeRequest("get_line", ["id" => $lineId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createLine($username, $password, $options = []) {
|
||||||
|
$data = array_merge([
|
||||||
|
"username" => $username,
|
||||||
|
"password" => $password
|
||||||
|
], $options);
|
||||||
|
|
||||||
|
return $this->makeRequest("create_line", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function editLine($lineId, $updates) {
|
||||||
|
$data = array_merge(["id" => $lineId], $updates);
|
||||||
|
return $this->makeRequest("edit_line", $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteLine($lineId) {
|
||||||
|
return $this->makeRequest("delete_line", ["id" => $lineId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function enableLine($lineId) {
|
||||||
|
return $this->makeRequest("enable_line", ["id" => $lineId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function disableLine($lineId) {
|
||||||
|
return $this->makeRequest("disable_line", ["id" => $lineId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage Example
|
||||||
|
$manager = new XUILineManager(
|
||||||
|
"http://your-server.com/cSbuFLhp/",
|
||||||
|
"8D3135D30437F86EAE2FA4A2A8345000"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create new line
|
||||||
|
$newLine = $manager->createLine(
|
||||||
|
"customer001",
|
||||||
|
"secure123",
|
||||||
|
[
|
||||||
|
"max_connections" => 1,
|
||||||
|
"exp_date" => "2025-12-31",
|
||||||
|
"notes" => "Premium customer"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
echo "Created line ID: " . $newLine['line_id'] . "\n";
|
||||||
|
|
||||||
|
// Edit line
|
||||||
|
$manager->editLine(123, [
|
||||||
|
"password" => "newpassword",
|
||||||
|
"max_connections" => 2
|
||||||
|
]);
|
||||||
|
echo "Line updated successfully\n";
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### JavaScript (Node.js)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
|
class XUILineManager {
|
||||||
|
constructor(baseUrl, apiKey) {
|
||||||
|
this.baseUrl = baseUrl;
|
||||||
|
this.apiKey = apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
async makeRequest(action, data = null) {
|
||||||
|
const url = `${this.baseUrl}?api_key=${this.apiKey}&action=${action}`;
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
method: data ? 'POST' : 'GET',
|
||||||
|
};
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
const formData = new URLSearchParams();
|
||||||
|
for (const [key, value] of Object.entries(data)) {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
value.forEach(v => formData.append(`${key}[]`, v));
|
||||||
|
} else {
|
||||||
|
formData.append(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options.body = formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(url, options);
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.status !== 'STATUS_SUCCESS') {
|
||||||
|
throw new Error(`API Error: ${result.error || 'Unknown error'}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getLine(lineId) {
|
||||||
|
const url = `${this.baseUrl}?api_key=${this.apiKey}&action=get_line&id=${lineId}`;
|
||||||
|
const response = await fetch(url);
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.status !== 'STATUS_SUCCESS') {
|
||||||
|
throw new Error(`API Error: ${result.error || 'Unknown error'}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async createLine(username, password, options = {}) {
|
||||||
|
const data = { username, password, ...options };
|
||||||
|
return this.makeRequest('create_line', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async editLine(lineId, updates) {
|
||||||
|
const data = { id: lineId, ...updates };
|
||||||
|
return this.makeRequest('edit_line', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteLine(lineId) {
|
||||||
|
return this.makeRequest('delete_line', { id: lineId });
|
||||||
|
}
|
||||||
|
|
||||||
|
async enableLine(lineId) {
|
||||||
|
return this.makeRequest('enable_line', { id: lineId });
|
||||||
|
}
|
||||||
|
|
||||||
|
async disableLine(lineId) {
|
||||||
|
return this.makeRequest('disable_line', { id: lineId });
|
||||||
|
}
|
||||||
|
|
||||||
|
async banLine(lineId) {
|
||||||
|
return this.makeRequest('ban_line', { id: lineId });
|
||||||
|
}
|
||||||
|
|
||||||
|
async unbanLine(lineId) {
|
||||||
|
return this.makeRequest('unban_line', { id: lineId });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage Example
|
||||||
|
(async () => {
|
||||||
|
const manager = new XUILineManager(
|
||||||
|
'http://your-server.com/cSbuFLhp/',
|
||||||
|
'8D3135D30437F86EAE2FA4A2A8345000'
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Create new line
|
||||||
|
const newLine = await manager.createLine(
|
||||||
|
'customer001',
|
||||||
|
'secure123',
|
||||||
|
{
|
||||||
|
max_connections: 1,
|
||||||
|
exp_date: '2025-12-31',
|
||||||
|
bouquets_selected: [1, 2, 3],
|
||||||
|
notes: 'Premium customer'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
console.log('Created line ID:', newLine.line_id);
|
||||||
|
|
||||||
|
// Get line details
|
||||||
|
const line = await manager.getLine(123);
|
||||||
|
console.log('Line:', line.username, '- Expires:', line.exp_date);
|
||||||
|
|
||||||
|
// Edit line
|
||||||
|
await manager.editLine(123, {
|
||||||
|
password: 'newpassword',
|
||||||
|
max_connections: 2
|
||||||
|
});
|
||||||
|
console.log('Line updated successfully');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error.message);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Common Use Cases
|
||||||
|
|
||||||
|
### 1. Bulk Create Lines
|
||||||
|
|
||||||
|
```python
|
||||||
|
def bulk_create_lines(manager, count=10, package_ids=[1,2,3]):
|
||||||
|
"""Create multiple lines at once"""
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
|
created_lines = []
|
||||||
|
|
||||||
|
for i in range(count):
|
||||||
|
# Generate random credentials
|
||||||
|
username = f"user{''.join(random.choices(string.digits, k=6))}"
|
||||||
|
password = ''.join(random.choices(string.ascii_letters + string.digits, k=12))
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = manager.create_line(
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
max_connections=1,
|
||||||
|
exp_date="1month", # 1 month from now
|
||||||
|
bouquets_selected=package_ids
|
||||||
|
)
|
||||||
|
|
||||||
|
created_lines.append({
|
||||||
|
'id': result['line_id'],
|
||||||
|
'username': username,
|
||||||
|
'password': password
|
||||||
|
})
|
||||||
|
|
||||||
|
print(f"✓ Created: {username}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ Failed to create line {i+1}: {e}")
|
||||||
|
|
||||||
|
return created_lines
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Auto-Disable Expired Lines
|
||||||
|
|
||||||
|
```python
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
def disable_expired_lines(manager):
|
||||||
|
"""Automatically disable lines that have expired"""
|
||||||
|
# Get all lines
|
||||||
|
response = requests.get(
|
||||||
|
manager.base_url,
|
||||||
|
params={"api_key": manager.api_key, "action": "get_lines"}
|
||||||
|
)
|
||||||
|
lines = response.json()['data']
|
||||||
|
|
||||||
|
now = datetime.now().timestamp()
|
||||||
|
expired_count = 0
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
exp_date = int(line['exp_date'])
|
||||||
|
|
||||||
|
# Check if expired and still enabled
|
||||||
|
if exp_date < now and line['enabled'] == '1':
|
||||||
|
try:
|
||||||
|
manager.disable_line(line['id'])
|
||||||
|
print(f"✓ Disabled expired line: {line['username']}")
|
||||||
|
expired_count += 1
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ Failed to disable {line['username']}: {e}")
|
||||||
|
|
||||||
|
print(f"\nDisabled {expired_count} expired lines")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Reset Password for Line
|
||||||
|
|
||||||
|
```python
|
||||||
|
import secrets
|
||||||
|
import string
|
||||||
|
|
||||||
|
def reset_line_password(manager, line_id):
|
||||||
|
"""Generate and set a new secure password"""
|
||||||
|
# Generate secure password
|
||||||
|
alphabet = string.ascii_letters + string.digits
|
||||||
|
new_password = ''.join(secrets.choice(alphabet) for i in range(16))
|
||||||
|
|
||||||
|
# Update line
|
||||||
|
manager.edit_line(line_id, password=new_password)
|
||||||
|
|
||||||
|
return new_password
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
new_pass = reset_line_password(manager, 123)
|
||||||
|
print(f"New password: {new_pass}")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Extend Expiration Date
|
||||||
|
|
||||||
|
```python
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
def extend_subscription(manager, line_id, months=1):
|
||||||
|
"""Extend line expiration by specified months"""
|
||||||
|
# Get current line
|
||||||
|
line = manager.get_line(line_id)
|
||||||
|
|
||||||
|
# Calculate new expiration
|
||||||
|
current_exp = datetime.fromtimestamp(int(line['exp_date']))
|
||||||
|
new_exp = current_exp + timedelta(days=30 * months)
|
||||||
|
new_exp_timestamp = int(new_exp.timestamp())
|
||||||
|
|
||||||
|
# Update line
|
||||||
|
manager.edit_line(line_id, exp_date=new_exp_timestamp)
|
||||||
|
|
||||||
|
print(f"Extended to: {new_exp.strftime('%Y-%m-%d')}")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Upgrade Line to Different Package
|
||||||
|
|
||||||
|
```python
|
||||||
|
def upgrade_line_package(manager, line_id, new_package_ids):
|
||||||
|
"""Change line's assigned packages"""
|
||||||
|
manager.edit_line(
|
||||||
|
line_id,
|
||||||
|
bouquets_selected=new_package_ids
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"Upgraded line {line_id} to packages: {new_package_ids}")
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
upgrade_line_package(manager, 123, [1, 2, 3, 4, 5]) # Premium package
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Export Line Credentials
|
||||||
|
|
||||||
|
```python
|
||||||
|
import csv
|
||||||
|
|
||||||
|
def export_lines_to_csv(manager, filename="lines_export.csv"):
|
||||||
|
"""Export all lines to CSV file"""
|
||||||
|
# Get all lines
|
||||||
|
response = requests.get(
|
||||||
|
manager.base_url,
|
||||||
|
params={"api_key": manager.api_key, "action": "get_lines"}
|
||||||
|
)
|
||||||
|
lines = response.json()['data']
|
||||||
|
|
||||||
|
# Write to CSV
|
||||||
|
with open(filename, 'w', newline='') as csvfile:
|
||||||
|
fieldnames = ['id', 'username', 'password', 'exp_date', 'max_connections', 'enabled']
|
||||||
|
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
||||||
|
|
||||||
|
writer.writeheader()
|
||||||
|
for line in lines:
|
||||||
|
writer.writerow({
|
||||||
|
'id': line['id'],
|
||||||
|
'username': line['username'],
|
||||||
|
'password': line['password'],
|
||||||
|
'exp_date': datetime.fromtimestamp(int(line['exp_date'])).strftime('%Y-%m-%d'),
|
||||||
|
'max_connections': line['max_connections'],
|
||||||
|
'enabled': 'Yes' if line['enabled'] == '1' else 'No'
|
||||||
|
})
|
||||||
|
|
||||||
|
print(f"Exported {len(lines)} lines to {filename}")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Expiration Date Formats
|
||||||
|
|
||||||
|
XUI.ONE accepts multiple formats for expiration dates:
|
||||||
|
|
||||||
|
### 1. Specific Date (YYYY-MM-DD)
|
||||||
|
```bash
|
||||||
|
-d "exp_date=2025-12-31"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Unix Timestamp
|
||||||
|
```bash
|
||||||
|
-d "exp_date=1735689600"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Relative Time
|
||||||
|
```bash
|
||||||
|
# Hours
|
||||||
|
-d "exp_date=24hours"
|
||||||
|
|
||||||
|
# Days
|
||||||
|
-d "exp_date=7days"
|
||||||
|
|
||||||
|
# Months
|
||||||
|
-d "exp_date=1month"
|
||||||
|
-d "exp_date=3months"
|
||||||
|
|
||||||
|
# Years
|
||||||
|
-d "exp_date=1year"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Python Helper Function
|
||||||
|
|
||||||
|
```python
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
def format_exp_date(days=None, months=None, years=None, date=None):
|
||||||
|
"""Convert various formats to Unix timestamp"""
|
||||||
|
if date:
|
||||||
|
# Specific date
|
||||||
|
dt = datetime.strptime(date, '%Y-%m-%d')
|
||||||
|
else:
|
||||||
|
# Relative date
|
||||||
|
dt = datetime.now()
|
||||||
|
if days:
|
||||||
|
dt += timedelta(days=days)
|
||||||
|
if months:
|
||||||
|
dt += timedelta(days=30 * months)
|
||||||
|
if years:
|
||||||
|
dt += timedelta(days=365 * years)
|
||||||
|
|
||||||
|
return int(dt.timestamp())
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
exp_date = format_exp_date(months=3) # 3 months from now
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ Important Notes
|
||||||
|
|
||||||
|
### Username/Password Requirements
|
||||||
|
|
||||||
|
- **Username:** 3-50 characters, alphanumeric
|
||||||
|
- **Password:** Minimum 6 characters recommended
|
||||||
|
- **No special characters** in username (use only letters, numbers, underscore)
|
||||||
|
|
||||||
|
### Bouquet Selection
|
||||||
|
|
||||||
|
When assigning bouquets, use array notation:
|
||||||
|
```bash
|
||||||
|
# cURL
|
||||||
|
-d "bouquets_selected[]=1" \
|
||||||
|
-d "bouquets_selected[]=2"
|
||||||
|
|
||||||
|
# Python
|
||||||
|
bouquets_selected=[1, 2, 3]
|
||||||
|
|
||||||
|
# PHP
|
||||||
|
["bouquets_selected" => [1, 2, 3]]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Max Connections
|
||||||
|
|
||||||
|
- **Minimum:** 1
|
||||||
|
- **Maximum:** Unlimited (but reasonable limits recommended)
|
||||||
|
- **Common values:** 1-5 for home users, 10-50 for resellers
|
||||||
|
|
||||||
|
### Trial vs. Regular Lines
|
||||||
|
|
||||||
|
Trial lines can be automatically converted to regular lines:
|
||||||
|
```python
|
||||||
|
# Create trial
|
||||||
|
manager.create_line(
|
||||||
|
username="trial001",
|
||||||
|
password="temp123",
|
||||||
|
is_trial=1,
|
||||||
|
exp_date="7days"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert to regular (when customer pays)
|
||||||
|
manager.edit_line(
|
||||||
|
line_id=123,
|
||||||
|
is_trial=0,
|
||||||
|
exp_date="1year"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Best Practices
|
||||||
|
|
||||||
|
### 1. Always Check Before Delete
|
||||||
|
|
||||||
|
```python
|
||||||
|
def safe_delete_line(manager, line_id):
|
||||||
|
"""Delete line with confirmation"""
|
||||||
|
try:
|
||||||
|
# Get line details first
|
||||||
|
line = manager.get_line(line_id)
|
||||||
|
|
||||||
|
# Confirm it's the right line
|
||||||
|
print(f"About to delete: {line['username']}")
|
||||||
|
confirm = input("Are you sure? (yes/no): ")
|
||||||
|
|
||||||
|
if confirm.lower() == 'yes':
|
||||||
|
manager.delete_line(line_id)
|
||||||
|
print("Line deleted successfully")
|
||||||
|
else:
|
||||||
|
print("Deletion cancelled")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Validate Input Data
|
||||||
|
|
||||||
|
```python
|
||||||
|
def validate_line_data(username, password, max_connections):
|
||||||
|
"""Validate line data before creation"""
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
if len(username) < 3 or len(username) > 50:
|
||||||
|
errors.append("Username must be 3-50 characters")
|
||||||
|
|
||||||
|
if not username.replace('_', '').isalnum():
|
||||||
|
errors.append("Username must be alphanumeric")
|
||||||
|
|
||||||
|
if len(password) < 6:
|
||||||
|
errors.append("Password must be at least 6 characters")
|
||||||
|
|
||||||
|
if max_connections < 1:
|
||||||
|
errors.append("Max connections must be at least 1")
|
||||||
|
|
||||||
|
return errors
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
errors = validate_line_data("user123", "pass", 1)
|
||||||
|
if errors:
|
||||||
|
print("Validation errors:")
|
||||||
|
for error in errors:
|
||||||
|
print(f" - {error}")
|
||||||
|
else:
|
||||||
|
# Create line
|
||||||
|
manager.create_line("user123", "secure123", max_connections=1)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Implement Rate Limiting
|
||||||
|
|
||||||
|
```python
|
||||||
|
import time
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
def rate_limit(calls_per_second=2):
|
||||||
|
"""Limit API calls to prevent overload"""
|
||||||
|
min_interval = 1.0 / calls_per_second
|
||||||
|
last_called = [0.0]
|
||||||
|
|
||||||
|
def decorator(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
elapsed = time.time() - last_called[0]
|
||||||
|
left_to_wait = min_interval - elapsed
|
||||||
|
|
||||||
|
if left_to_wait > 0:
|
||||||
|
time.sleep(left_to_wait)
|
||||||
|
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
last_called[0] = time.time()
|
||||||
|
return result
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
# Apply to methods
|
||||||
|
XUILineManager.create_line = rate_limit()(XUILineManager.create_line)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Error Handling
|
||||||
|
|
||||||
|
```python
|
||||||
|
def create_line_with_retry(manager, username, password, retries=3):
|
||||||
|
"""Create line with automatic retry on failure"""
|
||||||
|
for attempt in range(retries):
|
||||||
|
try:
|
||||||
|
return manager.create_line(username, password)
|
||||||
|
except Exception as e:
|
||||||
|
if attempt < retries - 1:
|
||||||
|
print(f"Attempt {attempt + 1} failed: {e}. Retrying...")
|
||||||
|
time.sleep(2 ** attempt) # Exponential backoff
|
||||||
|
else:
|
||||||
|
print(f"All {retries} attempts failed")
|
||||||
|
raise
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Related Documentation
|
||||||
|
|
||||||
|
- [GET INFO API - Query Lines](02-get-info.md#1-get-all-subscription-lines)
|
||||||
|
- [Authentication Guide](../authentication.md)
|
||||||
|
- [Error Handling](../error-codes.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🆘 Need Help?
|
||||||
|
|
||||||
|
- **GitHub Issues:** [Report problems](https://github.com/worldofiptvcom/xui-one-api-docs/issues)
|
||||||
|
- **Community:** [World of IPTV Forums](https://www.worldofiptv.com)
|
||||||
|
- **Documentation:** [Getting Started Guide](../getting-started.md)
|
||||||
+545
@@ -758,6 +758,551 @@ paths:
|
|||||||
'401':
|
'401':
|
||||||
$ref: '#/components/responses/Unauthorized'
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
|
||||||
|
/?action=get_line:
|
||||||
|
get:
|
||||||
|
summary: Get Specific Line Details
|
||||||
|
description: |
|
||||||
|
Retrieves detailed information about a specific subscription line by ID.
|
||||||
|
|
||||||
|
**Purpose:** View detailed information for a single line.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Example Request:**
|
||||||
|
```bash
|
||||||
|
curl "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=get_line&id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Cases:**
|
||||||
|
- ✅ View specific line details
|
||||||
|
- ✅ Check line status before editing
|
||||||
|
- ✅ Verify line configuration
|
||||||
|
- ✅ Audit line settings
|
||||||
|
operationId: getLine
|
||||||
|
tags:
|
||||||
|
- Line API
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ApiKey'
|
||||||
|
- name: action
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [get_line]
|
||||||
|
- name: id
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
description: Line ID
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
example: 123
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Line details retrieved successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/SuccessResponse'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/components/schemas/Line'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/?action=create_line:
|
||||||
|
post:
|
||||||
|
summary: Create New Subscription Line
|
||||||
|
description: |
|
||||||
|
Creates a new subscription line (M3U/Xtream Codes account).
|
||||||
|
|
||||||
|
**Purpose:** Add new subscriptions to your panel.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Example Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=create_line" \
|
||||||
|
-d "username=newuser" \
|
||||||
|
-d "password=newpass123" \
|
||||||
|
-d "max_connections=1" \
|
||||||
|
-d "exp_date=2025-12-31" \
|
||||||
|
-d "bouquets_selected[]=1" \
|
||||||
|
-d "bouquets_selected[]=2"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response Example:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "STATUS_SUCCESS",
|
||||||
|
"data": {
|
||||||
|
"line_id": "456",
|
||||||
|
"username": "newuser",
|
||||||
|
"password": "newpass123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Cases:**
|
||||||
|
- ✅ Create new subscriptions
|
||||||
|
- ✅ Add trial accounts
|
||||||
|
- ✅ Set up reseller lines
|
||||||
|
- ✅ Bulk create accounts
|
||||||
|
operationId: createLine
|
||||||
|
tags:
|
||||||
|
- Line API
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ApiKey'
|
||||||
|
- name: action
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [create_line]
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- username
|
||||||
|
- password
|
||||||
|
properties:
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
description: Username for the line
|
||||||
|
example: "newuser"
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
description: Password for the line
|
||||||
|
example: "newpass123"
|
||||||
|
max_connections:
|
||||||
|
type: integer
|
||||||
|
description: Maximum concurrent connections
|
||||||
|
default: 1
|
||||||
|
example: 1
|
||||||
|
exp_date:
|
||||||
|
type: string
|
||||||
|
description: Expiration date (YYYY-MM-DD, Unix timestamp, or relative like "1month", "1year")
|
||||||
|
example: "2025-12-31"
|
||||||
|
is_trial:
|
||||||
|
type: integer
|
||||||
|
description: Trial account (0 = No, 1 = Yes)
|
||||||
|
enum: [0, 1]
|
||||||
|
default: 0
|
||||||
|
example: 0
|
||||||
|
is_restreamer:
|
||||||
|
type: integer
|
||||||
|
description: Reseller status (0 = No, 1 = Yes)
|
||||||
|
enum: [0, 1]
|
||||||
|
default: 0
|
||||||
|
example: 0
|
||||||
|
bouquets_selected:
|
||||||
|
type: array
|
||||||
|
description: Array of bouquet/package IDs to assign
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
example: [1, 2, 3]
|
||||||
|
notes:
|
||||||
|
type: string
|
||||||
|
description: Admin notes
|
||||||
|
example: "Premium customer"
|
||||||
|
contact:
|
||||||
|
type: string
|
||||||
|
description: Contact information
|
||||||
|
example: "customer@example.com"
|
||||||
|
isp_lock:
|
||||||
|
type: string
|
||||||
|
description: Lock to specific IP address
|
||||||
|
example: "192.168.1.100"
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Line created successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/SuccessResponse'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
|
||||||
|
/?action=edit_line:
|
||||||
|
post:
|
||||||
|
summary: Edit Existing Line
|
||||||
|
description: |
|
||||||
|
Modifies an existing subscription line.
|
||||||
|
|
||||||
|
**Purpose:** Update line settings and configuration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Example Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=edit_line" \
|
||||||
|
-d "id=123" \
|
||||||
|
-d "password=newpassword" \
|
||||||
|
-d "max_connections=2"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Cases:**
|
||||||
|
- ✅ Change passwords
|
||||||
|
- ✅ Update connection limits
|
||||||
|
- ✅ Modify expiration dates
|
||||||
|
- ✅ Change assigned packages
|
||||||
|
- ✅ Update notes
|
||||||
|
operationId: editLine
|
||||||
|
tags:
|
||||||
|
- Line API
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ApiKey'
|
||||||
|
- name: action
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [edit_line]
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
description: Line ID to edit
|
||||||
|
example: 123
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
description: New username
|
||||||
|
example: "updateduser"
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
description: New password
|
||||||
|
example: "newpass456"
|
||||||
|
max_connections:
|
||||||
|
type: integer
|
||||||
|
description: Maximum concurrent connections
|
||||||
|
example: 2
|
||||||
|
exp_date:
|
||||||
|
type: string
|
||||||
|
description: New expiration date
|
||||||
|
example: "2026-12-31"
|
||||||
|
is_trial:
|
||||||
|
type: integer
|
||||||
|
description: Trial status
|
||||||
|
enum: [0, 1]
|
||||||
|
example: 0
|
||||||
|
bouquets_selected:
|
||||||
|
type: array
|
||||||
|
description: Updated bouquet IDs
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
example: [1, 2, 3, 4]
|
||||||
|
notes:
|
||||||
|
type: string
|
||||||
|
description: Updated notes
|
||||||
|
example: "Extended subscription"
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Line updated successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SuccessResponse'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/?action=delete_line:
|
||||||
|
post:
|
||||||
|
summary: Delete Line
|
||||||
|
description: |
|
||||||
|
Permanently deletes a subscription line.
|
||||||
|
|
||||||
|
**Purpose:** Remove lines from the panel.
|
||||||
|
|
||||||
|
⚠️ **Warning:** This action cannot be undone!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Example Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=delete_line" \
|
||||||
|
-d "id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Cases:**
|
||||||
|
- ✅ Remove expired subscriptions
|
||||||
|
- ✅ Delete test accounts
|
||||||
|
- ✅ Clean up old lines
|
||||||
|
operationId: deleteLine
|
||||||
|
tags:
|
||||||
|
- Line API
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ApiKey'
|
||||||
|
- name: action
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [delete_line]
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
description: Line ID to delete
|
||||||
|
example: 123
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Line deleted successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SuccessResponse'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/?action=enable_line:
|
||||||
|
post:
|
||||||
|
summary: Enable Line
|
||||||
|
description: |
|
||||||
|
Enables a disabled subscription line.
|
||||||
|
|
||||||
|
**Purpose:** Reactivate suspended lines.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Example Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=enable_line" \
|
||||||
|
-d "id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Cases:**
|
||||||
|
- ✅ Reactivate suspended accounts
|
||||||
|
- ✅ Resume service after payment
|
||||||
|
- ✅ Restore access
|
||||||
|
operationId: enableLine
|
||||||
|
tags:
|
||||||
|
- Line API
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ApiKey'
|
||||||
|
- name: action
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [enable_line]
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
description: Line ID to enable
|
||||||
|
example: 123
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Line enabled successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SuccessResponse'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/?action=disable_line:
|
||||||
|
post:
|
||||||
|
summary: Disable Line
|
||||||
|
description: |
|
||||||
|
Disables an active subscription line without deleting it.
|
||||||
|
|
||||||
|
**Purpose:** Temporarily suspend access.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Example Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=disable_line" \
|
||||||
|
-d "id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Cases:**
|
||||||
|
- ✅ Suspend non-payment accounts
|
||||||
|
- ✅ Temporarily block access
|
||||||
|
- ✅ Pause service
|
||||||
|
operationId: disableLine
|
||||||
|
tags:
|
||||||
|
- Line API
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ApiKey'
|
||||||
|
- name: action
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [disable_line]
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
description: Line ID to disable
|
||||||
|
example: 123
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Line disabled successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SuccessResponse'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/?action=ban_line:
|
||||||
|
post:
|
||||||
|
summary: Ban Line
|
||||||
|
description: |
|
||||||
|
Bans a subscription line, blocking access and preventing reactivation.
|
||||||
|
|
||||||
|
**Purpose:** Permanently block abusive or fraudulent accounts.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Example Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=ban_line" \
|
||||||
|
-d "id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Cases:**
|
||||||
|
- ✅ Block fraudulent accounts
|
||||||
|
- ✅ Prevent abuse
|
||||||
|
- ✅ Enforce terms of service
|
||||||
|
operationId: banLine
|
||||||
|
tags:
|
||||||
|
- Line API
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ApiKey'
|
||||||
|
- name: action
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [ban_line]
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
description: Line ID to ban
|
||||||
|
example: 123
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Line banned successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SuccessResponse'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/?action=unban_line:
|
||||||
|
post:
|
||||||
|
summary: Unban Line
|
||||||
|
description: |
|
||||||
|
Removes ban from a previously banned line.
|
||||||
|
|
||||||
|
**Purpose:** Restore access to banned accounts.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Example Request:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://your-server.com/cSbuFLhp/?api_key=8D3135D30437F86EAE2FA4A2A8345000&action=unban_line" \
|
||||||
|
-d "id=123"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use Cases:**
|
||||||
|
- ✅ Unban false positives
|
||||||
|
- ✅ Restore access after appeal
|
||||||
|
- ✅ Second chances
|
||||||
|
operationId: unbanLine
|
||||||
|
tags:
|
||||||
|
- Line API
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ApiKey'
|
||||||
|
- name: action
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [unban_line]
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
description: Line ID to unban
|
||||||
|
example: 123
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Line unbanned successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SuccessResponse'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
components:
|
components:
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
ApiKeyAuth:
|
ApiKeyAuth:
|
||||||
|
|||||||
Reference in New Issue
Block a user