| name | splynx-api |
| description | Splynx REST API client for validated operations on ISP management data. Use when creating, updating, or deleting customers, services, tariffs, invoices, documents, or tickets in Splynx. Validates data before writing. Reference: src/apis/splynx_client.py |
Splynx REST API
REST API client for Splynx ISP management platform.
Authentication
import base64
# HTTP Basic Auth
credentials = base64.b64encode(f"{api_key}:{api_secret}".encode()).decode()
headers = {
"Authorization": f"Basic {credentials}",
"Content-Type": "application/json",
"Accept": "application/json"
}
Environment variables:
SPLYNX_URL- Base URL (e.g.,http://localhostorhttps://splynx.example.com)SPLYNX_API_KEY- API keySPLYNX_PASSWORD- API secret/password
Base endpoint: {SPLYNX_URL}/api/2.0/
Using the Client
from src.apis.splynx_client import SplynxAPIClient, SplynxConfig
from src.config.settings import config
splynx_config = SplynxConfig(
base_url=config.splynx_url,
api_key=config.splynx_api_key,
api_secret=config.splynx_password
)
client = SplynxAPIClient(splynx_config)
# Test connection
result = client.test_connection()
if result['success']:
print("Connected!")
Request Methods
# GET - Retrieve data
result = client.get('admin/tariffs/internet', params={'limit': 100})
# POST - Create new record
result = client.post('admin/tariffs/internet', data={'title': 'Basic Plan', 'price': 49.99})
# PUT - Update existing record
result = client.put('admin/customers/customer/123', data={'name': 'Updated Name'})
# DELETE - Remove record
result = client.delete('admin/tariffs/internet/456')
# OPTIONS - Get schema/metadata
result = client.options('admin/tariffs/internet')
# POST Multipart - File upload
result = client.post_multipart('admin/customers/customer-documents/123--upload',
files={'file': ('doc.pdf', content, 'application/pdf')})
Response Format
All methods return:
{
'success': True, # or False
'status_code': 200, # HTTP status code
'data': {...}, # On success
'error': {...} # On failure
}
Working Endpoints
Tariffs (Full CRUD)
# Internet tariffs
client.get('admin/tariffs/internet')
client.post('admin/tariffs/internet', {'title': 'Plan', 'price': 50})
client.put('admin/tariffs/internet/1', {'price': 55})
client.delete('admin/tariffs/internet/1')
# Voice tariffs
client.get('admin/tariffs/voice')
client.post('admin/tariffs/voice', {...})
# Bundle tariffs
client.get('admin/tariffs/bundle')
client.post('admin/tariffs/bundle', {...})
# One-time tariffs
client.get('admin/tariffs/one-time')
client.post('admin/tariffs/one-time', {...})
# Recurring tariffs
client.get('admin/tariffs/recurring')
Networking
# Routers
client.get('admin/networking/routers')
client.get('admin/networking/routers/1')
client.put('admin/networking/routers/1', {'title': 'Main Router'})
Documents
# Create document record
result = client.post('admin/customers/customer-documents', {
'customer_id': 123,
'type': 'uploaded',
'title': 'Contract',
'description': 'Service agreement'
})
doc_id = result['data']['id']
# Upload file content
client.post_multipart(f'admin/customers/customer-documents/{doc_id}--upload',
files={'file': ('contract.pdf', pdf_bytes, 'application/pdf')})
Administration
# API check
client.get('admin/api/check')
# Administrators
client.get('admin/administration/administrators')
client.post('admin/administration/administrators', {...})
# Custom fields
client.get('admin/config/additional-fields/customers')
client.post('admin/config/additional-fields/customers', {...})
Restricted Endpoints (May Return 403)
These require additional API permissions:
# Customers - often restricted
client.get('admin/customers/customer')
client.post('admin/customers/customer', {...})
# Finance - often restricted
client.get('admin/finance/invoices')
client.get('admin/finance/payments')
client.get('admin/finance/transactions')
# Tickets - often restricted
client.get('admin/support/tickets')
Workaround: Use direct MySQL for restricted operations (faster anyway).
Pagination
# First page
result = client.get('admin/tariffs/internet', params={'limit': 100, 'offset': 0})
# Next page
result = client.get('admin/tariffs/internet', params={'limit': 100, 'offset': 100})
# Fetch all
all_items = []
offset = 0
while True:
result = client.get('admin/tariffs/internet', params={'limit': 100, 'offset': offset})
if not result['success'] or not result['data']:
break
all_items.extend(result['data'])
if len(result['data']) < 100:
break
offset += 100
File Upload Pattern
from src.apis.splynx_client import SplynxAPIClient
def upload_document(client, customer_id, filename, content, mime_type):
# Step 1: Create document record
doc_result = client.post('admin/customers/customer-documents', {
'customer_id': customer_id,
'type': 'uploaded',
'title': filename,
'visible_by_customer': '0'
})
if not doc_result['success']:
return None
doc_id = doc_result['data']['id']
# Step 2: Upload file content
upload_result = client.post_multipart(
f'admin/customers/customer-documents/{doc_id}--upload',
files={'file': (filename, content, mime_type)}
)
if not upload_result['success']:
# Rollback on failure
client.delete(f'admin/customers/customer-documents/{doc_id}')
return None
return doc_id
Error Handling
result = client.post('admin/tariffs/internet', tariff_data)
if result['success']:
tariff_id = result['data']['id']
print(f"Created tariff {tariff_id}")
else:
error = result.get('error', {})
status = result.get('status_code')
if status == 403:
print("Permission denied - check API permissions")
elif status == 404:
print("Endpoint not found")
elif status == 422:
print(f"Validation error: {error}")
else:
print(f"Error {status}: {error}")
Customer Operations (via PUT)
Customers are typically created via MySQL, but updated via API:
# Update customer (set portal password)
result = client.put(f'admin/customers/customer/{customer_id}', {
'id': customer_id,
'name': 'John Doe',
'login': 'johndoe',
'password': 'new_password',
'password_confirm': 'new_password'
})
Schema Discovery
# Get field definitions for an endpoint
schema = client.options('admin/tariffs/internet')
if schema['success']:
fields = schema['data']
for field_name, field_info in fields.items():
print(f"{field_name}: {field_info.get('type')}")
When to Use API vs MySQL
| Use API | Use MySQL |
|---|---|
| Creating documents | Bulk customer imports |
| Setting passwords | Reading large datasets |
| Validated writes | Invoice/payment inserts |
| Schema discovery | Service assignments |
| Router updates | Custom field values |
Reference
- Client implementation:
src/apis/splynx_client.py - Config:
src/config/settings.py - Test:
python -c "from src.apis.splynx_client import SplynxAPIClient, SplynxConfig; from src.config.settings import config; c = SplynxAPIClient(SplynxConfig(config.splynx_url, config.splynx_api_key, config.splynx_password)); print(c.test_connection())"