Veloxiom API Reference

Reference for the Veloxiom ISP Management Platform: the public REST API v1 (token) plus the internal panel / mobile action endpoints. Every parameter listed here is taken from the current production code.

API Sections


🔐 Authentication

Veloxiom exposes two distinct surfaces. Choose the right one for your integration:

API Tokens (REST API v1)

Create scoped tokens in the panel under Admin → API & Webhooks. Each token is shown once (only a SHA-256 hash is stored), carries per-module scopes, supports an expiry, and can be revoked. A token is tenant-scoped — it only ever sees its own tenant's data.

# Send the token one of three ways (Bearer preferred): Authorization: Bearer vlx_xxxxxxxxxxxxxxxxxxxxxxxx X-Api-Token: vlx_xxxxxxxxxxxxxxxxxxxxxxxx ?token=vlx_xxxxxxxxxxxxxxxxxxxxxxxx # Base URL (tenant resolved by host/slug) https://{your-domain-or-slug}/api/v1.php
# Example: list customers (needs customers:view scope) curl https://panel.veloxiom.com/{tenant}/api/v1.php?resource=customers&limit=3 \ -H "Authorization: Bearer vlx_..."

Token Scopes

Each token grants per-module access at level none / view / write (write implies view). Endpoints require a specific scope; insufficient scope returns HTTP 403.

Scope moduleGrants access to
customersCustomers / subscribers
plansService plans
billingInvoices & billing
routersNetwork devices / routers
monitoringMonitoring data (can also read routers)
crmTickets & messaging (write required to send)

2FA (Two-Factor Authentication) (panel session actions)

POST
action=start_2fa_enroll
Initiate TOTP 2FA enrollment — returns QR code and secret
POST
action=finish_2fa_enroll
Complete 2FA enrollment with verification code
POST
action=disable_own_2fa
Disable 2FA for current admin account
POST
action=reset_admin_2fa
Reset 2FA for another admin (requires admin password)

Mobile app authentication

The Veloxiom mobile app uses the same /process.php endpoint. The actions below need no session; everything else in the app sends the mobile_token POST field (tokens expire and are typed staff or customer).

POST
action=mobile_tenant_info
Pre-login branding for the URL the user typed. Returns {ok, name, logo_url}. No auth.
POST
action=mobile_auth_staff
Staff login. Params: username, password. Returns {ok, token, user{id, username, name, role, permissions}}.
POST
action=mobile_auth_customer
Subscriber login (PPPoE username/password). Params: username, password. Returns a customer-typed token.
POST
action=mobile_check_token
Validate a token. Param: mobile_token.
POST
action=mobile_user_create
Create a subscriber from the app (permission customers/write). Params: username, password, plan (required), name, email, phone. Errors: password_required, plan_required plus the standard add errors.

🔌 REST API v1 (Token)

The public REST API at /api/v1.php. Reads (GET ?resource=…) work on every installation. Writes (POST ?action=…) let a customer build their own app (CRM, mobile, billing integration) and are available on Veloxiom Standalone when the license includes the api_write feature; on hosted tenants they answer 403 feature_not_licensed unless enabled by Veloxiom. Check ?resource=me → write_enabled. All writes go through the exact same panel logic as the admin UI (RADIUS, IPAM, billing, audit log, webhooks) — no second write path.

Licensing: the api_write feature is part of the Standalone license (issued per installation). Read endpoints and send_message never require it. Tokens are created in the panel under Settings → API tokens with per-module scopes (customers, plans, billing, routers, monitoring, crm × view|write).

Read Resources (GET)

GET
?resource=ping
Health check. Returns {ok, pong, ts}.
GET
?resource=me
Token name, scopes, write_enabled, standalone.
GET
?resource=customers
List subscribers. Fields: username, name, email, phone. Supports q, limit, offset. Scope: customers:view.
GET
?resource=customer&username=…
Single subscriber: username, plan, rate_limit, disabled, comment, static_ip, expire_date, name, email, phone, afm, address, online, session{}, meta{} (password/secret fields stripped). Scope: customers:view.
GET
?resource=sessions[&username=…]
Active RADIUS sessions: id, session_id, username, nas, ip, ipv6_prefix, ipv6_delegated, mac, started_at, seconds, download_bytes, upload_bytes. Scope: customers:view or monitoring:view.
GET
?resource=usage&username=…[&from=&to=]
Traffic totals for a period (default: current month) + daily[] breakdown: sessions, seconds, download_bytes, upload_bytes. Scope: customers:view or monitoring:view.
GET
?resource=online
Currently online subscribers (same fields as sessions). Scope: customers:view or monitoring:view.
GET
?resource=plans
Service plans: id, name, rate_limit, price. Scope: plans:view.
GET
?resource=invoices
List invoices. Filters status, q, username. Fields: id, number, customer, username, total, status, issue_date. Scope: billing:view.
GET
?resource=invoice&id=…
Invoice detail incl. VAT breakdown, payment info, e-invoicing status (einv_*) and items[]. Scope: billing:view.
GET
?resource=payments[&username=|&invoice_id=]
Payments: id, invoice_id, username, amount, method, gateway, reference, paid_at. Scope: billing:view.
GET
?resource=routers
Network devices: id, name, ip, hostname, site, role, health. Scope: routers:view or monitoring:view.
GET
?resource=tickets
Tickets: id, subject, customer, status, priority, created_at, updated_at. Filter q. Scope: crm:view.
GET
?resource=ticket&id=…
Ticket detail with replies[]. Scope: crm:view.
GET
?resource=messages
Messages. Filters direction, channel, phone. Scope: crm:view.

Write Actions (POST) Standalone / licensed · api_write

Send POST /api/v1.php?action=<name> with a JSON body (Content-Type: application/json) or form fields. Every write is audit-logged as api:<token name> and fires the listed webhook event.

POST
action=send_message
Send an outbound message. Available everywhere (no api_write). Scope: crm:write. Params: channel (sms|viber|whatsapp), to, text, username. Returns: status, channel, to. Webhook: message.sent.
POST
action=create_customer [api_write]
Creates the RADIUS account, billing profile and (optional) static IPv4 / IPv6 prefix. 409 username_exists, 422 unknown_plan. Scope: customers:write. Params: username, password, plan, name, email, phone, phone2, afm, doy, address, id_card, activity, comment, static_ip, expire_date, expire_time, billing_price, billing_vat, ipv6_mode, ipv6_pool_id, ipv6_prefix. Returns: username, plan, disabled, created. Webhook: customer.created.
POST
action=update_customer [api_write]
Edit customer data, password, plan, expiry, static IP. Scope: customers:write. Params: username + any field of create_customer (only sent fields change). Returns: username, plan, disabled, updated. Webhook: customer.updated.
POST
action=disable_customer [api_write]
Blocks authentication and kicks the active session. Idempotent. Scope: customers:write. Params: username. Returns: username, disabled, changed. Webhook: customer.disabled.
POST
action=enable_customer [api_write]
Re-enables a disabled customer. Scope: customers:write. Params: username. Returns: username, disabled, changed. Webhook: customer.enabled.
POST
action=change_plan [api_write]
RADIUS group, router profile and plan history are updated; session is re-provisioned. Scope: customers:write. Params: username, plan. Returns: username, plan, previous_plan, changed. Webhook: customer.plan_changed.
POST
action=set_expire [api_write]
Set or clear the expiry date. Scope: customers:write. Params: username, expire_date (empty = clear), expire_time. Returns: username, expire_date, expire_time. Webhook: customer.updated.
POST
action=reconnect [api_write]
Drops the PPPoE session(s) so the CPE reconnects with fresh attributes. Scope: customers:write. Params: username. Returns: username, kicked_sessions, closed_accounting. Webhook: customer.reconnected.
POST
action=delete_customer [api_write]
Permanent deletion (RADIUS, meta, static IP, IPv6 lease). Scope: customers:write. Params: username, confirm=yes. Returns: username, deleted. Webhook: customer.deleted.
POST
action=create_plan [api_write]
Creates the plan and syncs it to all routers. Scope: plans:write. Params: name, rate_limit, price, price_vat_mode, price_vat_rate, price_sub_fee, burst_rate, burst_threshold, burst_time, priority, min_rate, aggregation, data_cap_gb, fup_rate, fup_action. Returns: id, name, rate_limit, created. Webhook: plan.created.
POST
action=update_plan [api_write]
Edit a plan. Scope: plans:write. Params: id or current_name, name, rate_limit, … (as create_plan). Returns: id, name, rate_limit, updated. Webhook: plan.updated.
POST
action=delete_plan [api_write]
409 plan_in_use if customers are assigned, unless force=yes. Scope: plans:write. Params: id or name, force=yes. Returns: id, deleted. Webhook: plan.deleted.
POST
action=create_invoice [api_write]
Issues an invoice with the tenant numbering series; without items the customer's plan price is used. einv_submit=1 submits to myDATA/e-invoicing provider. Scope: billing:write. Params: username, month (YYYY-MM), items[{description, qty, unit_price, discount_pct, vat_rate}], vat, doctype_title, due_date, einv_submit (0|1, default 1). Returns: invoice_id, number, total, status, issue_date, due_date. Webhook: invoice.created.
POST
action=record_payment [api_write]
Applies a payment (partial/full); with username it settles the oldest unpaid invoices, surplus becomes credit. Scope: billing:write. Params: invoice_id or username, amount, method (cash|card|pos|bank|iban|other), reference, note. Returns: invoice_id, amount, method, result{paid, applied, remaining, invoice_status, credited}. Webhook: payment.recorded, invoice.paid.
POST
action=set_invoice_status [api_write]
Change invoice status (e.g. cancel). Scope: billing:write. Params: invoice_id, status (unpaid|paid|cancelled|draft|issued|overdue|partial), payment_method, payment_reference, payment_note. Returns: invoice_id, status, reactivated. Webhook: invoice.status_changed.
POST
action=create_ticket [api_write]
Opens a ticket, optionally linked to a customer. Scope: crm:write. Params: subject, message, username, priority (low|medium|high|urgent), category, contact_email, contact_name. Returns: id, subject, customer, status, priority. Webhook: ticket.created.
POST
action=reply_ticket [api_write]
Adds a reply (and optionally changes status). Scope: crm:write. Params: id, message, status. Returns: ticket_id, reply_id, status. Webhook: ticket.replied.
POST
action=update_ticket [api_write]
Update ticket fields. Scope: crm:write. Params: id, status, priority, subject, assigned_to, category. Returns: ticket_id, updated. Webhook: ticket.updated.
# Example — create a customer and change plan (curl) # 1) create curl -X POST "https://panel.example.gr/api/v1.php?action=create_customer" \ -H "Authorization: Bearer vlx_…" -H "Content-Type: application/json" \ -d '{"username":"user123","password":"S3cret!","plan":"PPPoE-100/10","name":"Γιώργος Π.","phone":"6941234567"}' # → {"ok":true,"data":{"username":"user123","plan":"PPPoE-100/10","disabled":false,"created":true},"meta":{…}} # 2) change plan curl -X POST "https://panel.example.gr/api/v1.php?action=change_plan" \ -H "Authorization: Bearer vlx_…" -H "Content-Type: application/json" \ -d '{"username":"user123","plan":"PPPoE-200/20"}' # → {"ok":true,"data":{"username":"user123","plan":"PPPoE-200/20","previous_plan":"PPPoE-100/10","changed":true}} # 3) live session + usage curl "https://panel.example.gr/api/v1.php?resource=sessions&username=user123" -H "Authorization: Bearer vlx_…" curl "https://panel.example.gr/api/v1.php?resource=usage&username=user123&from=2026-09-01&to=2026-09-30" -H "Authorization: Bearer vlx_…"

Common Query Parameters

ParameterTypeDescription
resource / rstringResource name (GET)
actionstringAction name (POST; query or body)
limitintPage size, 1–500 (default 100)
offsetintRow offset for pagination (default 0)
qstringFree-text search (customers/invoices/tickets)
from / toYYYY-MM-DDPeriod for usage

Errors

HTTPerrorMeaning
401unauthorizedMissing/invalid/revoked/expired token
403insufficient_scopeToken lacks the required scope (error_details.need)
403feature_not_licensedWrite actions not licensed on this installation (api_write)
404unknown_resource / not_foundNo such resource, or customer/plan/invoice/ticket not found
400unknown_action / invalid_jsonUnknown POST action or malformed JSON body
409username_exists / plan_in_useConflict with existing data
422missing_parameter / invalid_parameter / invalid_username / unknown_plan / invalid_amountValidation failure (error_details.param)
429rate_limitedRate limit exceeded (120 req/min per token)
502upstream_errorRouter / SMS provider / e-invoicing provider failure

Error body: {"ok":false,"error":"<code>","error_code":"<code>","error_message":"…","error_details":{…},"meta":{"request_id":"req_…"}}. Send envelope=2 for error as a structured object.

Envelope, Pagination & Request IDs

FieldDescription
okAlways present. true on success, false on error.
dataThe payload (array for lists, object for single resources).
countNumber of rows in the current response.
paginationlimit, offset, total, has_more, next_offset — on list resources.
meta.request_idPer-call id, also returned as the X-Request-Id header (quote it in bug reports).

Errors stay flat for backward compatibility ({ok:false,error:"…"}). Send envelope=2 for a structured error: {ok:false,error:{code,message,details},meta:{request_id}}. Validation failures return 422. Callers still using ?token=… receive Deprecation/Sunset headers — prefer Authorization: Bearer or X-Api-Token.

Field values

invoice.statusunpaid · paid · partial · overdue · cancelled
message.channelsms · viber · whatsapp

Machine-readable spec (OpenAPI)

GET /api/v1.php?resource=openapi returns the OpenAPI 3.0.3 document (v1.2) of your installation, including all write actions with request/response schemas — load it into Postman/Insomnia or generate a client (openapi-generator, Swagger Codegen) in any language.


👥 Customers / Subscribers (panel/mobile session action)

Manage ISP subscribers — create, edit, delete, and control service status.

POST
action=add
Create a new customer/subscriber with PPPoE/DHCP credentials, service plan, and contact details
POST
action=edit
Update existing customer details — username, plan, speed, contact info, custom fields
POST
action=delete
Delete a customer and associated RADIUS/MikroTik entries
POST
action=toggle_status
Enable/disable a customer service (suspend/unsuspend)
POST
action=save_billing_customer
Save billing-specific settings for a customer (billing cycle, tax info, payment method)
POST
action=aade_lookup
Lookup customer tax info from AADE (Greek Tax Authority) by VAT number

Customer Parameters (action=add / action=edit)

ParameterTypeDescription
user (alias: user_name)stringPPPoE/DHCP username (unique, validated format)
pass (alias: password)stringPPPoE password (required on add)
limitstringService plan name (required; must exist as a plan / rate profile)
commentstringDisplay name / comment stored on the RADIUS user
static_ip (alias: ip_address)stringStatic IPv4 (Framed-IP-Address), optional
expire_datedateExpiration date (YYYY-MM-DD), optional
expire_timetimeExpiration time (HH:MM), optional

action=delete and action=toggle_status take user_id (alias username). action=aade_lookup takes afm (VAT number, digits only).

Billing profile parameters (action=save_billing_customer)

ParameterTypeDescription
usernamestringSubscriber username (required)
cust_namestringLegal / full name
cust_afmstringVAT number (ΑΦΜ)
cust_doystringTax office (ΔΟΥ)
cust_activitystringBusiness activity
cust_addrstringBilling address
cust_phonestringPhone
cust_emailstringEmail
cust_idcardstringID card number
billing_pricefloatPer-customer price override (optional)
billing_vatfloatPer-customer VAT rate override (optional)

📋 Service Plans

Create and manage internet service plans with speed profiles, pricing, and FUP policies.

POST
action=add_plan
Create a new service plan with speed limits, price, and MikroTik queue parameters
POST
action=edit_plan
Update an existing service plan
POST
action=delete_plan
Delete a service plan (fails if customers are assigned)

Plan Parameters (action=add_plan / action=edit_plan)

ParameterTypeDescription
plan_namestringPlan name (e.g. 'FTTH 100Mbps')
rate_limitstringSpeed in MikroTik rate-limit syntax, upload/download (e.g. 10M/100M)
default_pricefloatPrice (EUR)
price_vat_modestringWhether default_price is entered net or gross of VAT
price_vat_ratefloatVAT rate (%)
price_sub_feefloatSubscriber fee / surcharge added to the price
aggregationstringAggregation / burst policy preset
burst_timestringBurst time (MikroTik)
priorityintQueue priority (1–8)
data_cap_gbintMonthly data cap in GB (0 = unlimited)
fup_actionstringAction when the cap is reached (throttle / block)

action=delete_plan takes plan_id.


💰 Billing & Invoicing

Automated billing engine with invoice generation, status tracking, and batch operations.

POST
action=save_billing_settings
Configure global billing settings — tax rates, billing cycles, invoice numbering, company details
POST
action=generate_invoices_month
Generate invoices for a billing month. Params: month (YYYY-MM), users[] (optional subset of usernames), einv_submit (1 = submit to e-invoicing)
POST
action=create_invoice_manual
Create a manual invoice. Params: users, month, items_json, vat, taxes_json, transport_json, doctype_title, einv_submit
POST
action=invoice_set_status
Update invoice status. Params: id, status ∈ unpaid · paid · overdue · cancelled
POST
action=delete_invoice
Delete an invoice. Param: id. Refused for issued/submitted/paid invoices.

💳 Payments

Payments are recorded manually from the panel or arrive automatically from the configured gateways (DIAS, Revolut, Stripe, Viva, PayPal, myPOS) and are matched to invoices by the payment-sync jobs.

POST
action=pay_invoice
Record a payment for one invoice. Params: invoice_id, amount, method, reference, note
POST
action=customer_bulk_pay
Pay all outstanding invoices of a customer. Params: username, amount, method, reference, note
POST
action=manual_retry_charge
Retry a failed automatic gateway charge. Param: invoice_id

Supported Payment Gateways

GatewayTypeDescription
DIASbankGreek interbank payment system (RF codes)
RevolutonlineOnline card payments via Revolut Business
StripeonlineInternational card & subscription payments
Viva WalletonlineGreek/EU card payments
PayPalonlinePayPal payments
myPOSonline / POSCard payments & POS terminals (Checkout / REST)

📄 e-Invoicing (AADE / myDATA)

Submit invoices electronically to AADE myDATA. Supports multiple e-invoicing providers.

POST
action=einvoicing_submit_now
Submit an invoice via a provider. Params: invoice_id, provider (see table)
POST
action=einvoicing_history
Submission history for an invoice (MARK, UID, errors). Param: invoice_id

Supported e-Invoicing Providers

Provider (provider value)StatusDescription
myDATA (AADE) — mydataactiveDirect AADE myDATA API submission
Elorus — elorusactiveElorus invoicing / ERP platform
ΕΣΚΑΠ — eskapactiveAADE e-invoicing provider channel
ΕΣΥΠ / ΤΗΛΕΔ (ΓΓΠΣ) — esypactivePublic-sector e-invoicing (B2G)
SoftOne — softonebetaSoftOne ERP connector
IMPACT — impactcoming soonIMPACT e-invoicing provider
Primer (Cosmos) — primercoming soonPrimer/Cosmos e-invoicing
Retail@Link — retail_at_linkcoming soonRetail@Link e-invoicing
Edpsoft — edpsoftcoming soonEdpsoft e-invoicing
Epsilon Net / Entersoft / Galaxy — epsilon, entersoft, galaxycoming soonERP connectors

📡 RADIUS / PPPoE / DHCP

FreeRADIUS integration for PPPoE and DHCP authentication, CoA (Change of Authorization), and session management.

PPPoE/DHCP authentication, accounting and CoA are fully active and driven by the panel (customer add/edit/disable, plan change, reconnect). There are no public HTTP actions for listing/disconnecting RADIUS sessions yet (radius_sessions, radius_disconnect, radius_coa are on the roadmap). Active sessions are available in the panel and via the mobile action mobile_online_users; subscriber reconnect via mobile_user_reconnect.


🔧 MikroTik Routers

Manage MikroTik RouterOS devices — add, configure, monitor, and execute API commands.

GET
action=get_routers
List all configured routers with connection status
GET
action=list_routers_ui
Router list with extended UI metadata (uptime, version, CPU, RAM)
POST
action=add_router
Add a new MikroTik router (IP, API credentials, RADIUS secret)
POST
action=edit_router
Update router configuration
POST
action=delete_router
Remove a router and clean up RADIUS/firewall rules
POST
action=switch_router
Switch active router context (for multi-router setups)

Router Parameters (action=add_router / action=edit_router)

ParameterTypeDescription
r_ipstringRouter management IP address
r_namestringRouter display name
r_userstringRouterOS API username
r_passstringRouterOS API password
r_radius_ipstringRADIUS NAS IP (defaults to management IP)
r_radius_secretstringRADIUS shared secret
r_radius_vendorstringNAS vendor (mikrotik, cisco)
orig_ip (edit only)stringCurrent IP of the router being edited

action=delete_router and action=switch_router take ip.


🌐 Network Settings

POST
action=save_network_settings
Configure IP pools, VLAN settings, OSPF, VPLS, and routing parameters

🗺️ Topology & Maps

Network topology visualization with 2D/3D maps. Supports multiple monitoring backends.

POST
action=save_topology_metrics_source
Set the topology data source. Param: metrics_source ∈ librenms · observium · zabbix · mikrotik

Supported Monitoring Backends

BackendProtocolDescription
LibreNMSREST APIOpen-source network monitoring
ObserviumREST APINetwork monitoring platform
ZabbixJSON-RPCEnterprise monitoring solution
MikroTikRouterOS APIDirect router SNMP/API polling

📦 Device Inventory (IPAM)

IP Address Management and network device inventory with approval workflows.

POST
action=save_inventory_node
Add or update an inventory node (name, IP, type, location, notes)
POST
action=approve_inventory_node
Approve a pending inventory node
POST
action=approve_inventory_all
Bulk approve all pending inventory nodes
POST
action=delete_inventory_node
Delete a single inventory node
POST
action=delete_inventory_bulk
Bulk delete inventory nodes (all_pending, all_approved, or all)

📊 SNMP Monitoring

Real-time network monitoring via SNMP. Collect bandwidth, latency, and interface metrics from routers and switches.

Collection runs via scheduled collectors and is visualised in the built-in Grafana dashboards. Router health (CPU, RAM, uptime, version) is returned by action=list_routers_ui and, per device, by the REST resource routers (health field). Mobile: mobile_snmp_devices, mobile_uptime. On-demand snmp_collect / router_health actions are not exposed.


📞 VoIP / Telephony (MOR)

MOR/M2 telephony integration — SIP trunk management, CDR records, tariffs, balance management, and VoIP billing.

GET
action=mor_balance_get
Get VoIP account balance and credit info
GET
action=mor_cdr_list_local
Retrieve Call Detail Records with filters (date, number, duration)
GET
action=mor_tariffs_list_local
List available VoIP tariff plans
POST
action=mor_topup_invoice_create
Add credit/balance to a VoIP account
POST
action=mor_create_remote_user
Provision new SIP accounts and assign DID numbers

🔒 WireGuard VPN

POST
action=router_wg_provision
Provision WireGuard VPN tunnel — generate keys, configure peer on MikroTik

🎫 Helpdesk / Tickets

Customer support ticket system with assignment, priorities, categories and status tracking. Integrations: REST ?resource=tickets, ?resource=ticket and (Standalone/licensed) action=create_ticket / reply_ticket / update_ticket.

GET
action=crm_tickets
List tickets (panel permission tickets/view_all or view_own)
POST
action=crm_tickets
Create or update a ticket. Params: subject (required), description, customer, priority, status, assigned_to, category; send ticket_id to update, delete_id to delete.
POST
action=customer_crm&sub=create_ticket | ticket_detail | update_ticket | ticket_reply | ticket_note
Ticket operations from the customer card (create, view with replies, update, public reply, internal note)
POST
action=crm_tickets_bulk
Bulk update. Params: ids (comma-separated), bulk_action ∈ status · assign · close, bulk_value
POST
action=mobile_customer_ticket_create / mobile_customer_ticket_reply / mobile_customer_tickets
Subscriber-side tickets from the mobile app (customer token)

Field values

statusopen · in_progress · waiting · resolved · closed
prioritylow · medium · high · urgent

🤖 AI Assistant

POST
action=save_ai_settings
Configure the AI assistant — provider/model (OpenAI GPT-4o, GPT-4.1, o1-mini, GPT-realtime; Anthropic Claude 3.5/3.7/Sonnet 4.5), API key, behaviour

🔔 Notifications

Multi-channel notification system — Telegram, Email, Push notifications.

POST
action=save_telegram_settings
Telegram channel. Params: telegram_enabled, telegram_bot_token, telegram_bot_username, telegram_admin_chat_id
POST
action=incident_notify
Send an incident notification. Params: title, body, severity, channels, users (target subscribers)
POST
action=admin_save_notif_overrides
Set per-admin notification override preferences

👤 Admin Management

POST
action=add_web_admin
Create an admin. Params: admin_user, admin_pass, admin_email, perms (module→level map)
POST
action=edit_web_admin
Update an admin. Params: admin_id, optional admin_pass, admin_email, perms
POST
action=delete_web_admin
Delete an admin (cannot delete the primary admin). Param: admin_id

🏢 Multi-Tenant

Multi-tenant architecture — each tenant is an isolated ISP instance with its own database, domain, branding, and configuration.

Tenant provisioning is a super-admin operation performed from the control panel; it runs the full pipeline (database, schema, RADIUS, WireGuard/NPM, captive portal) internally with rollback on failure.

POST
action=provision
Super-admin: provision a new tenant (database, schema, RADIUS, WireGuard/NPM, captive portal)

⚙️ System Settings

POST
action=save_settings
Save general system settings — company info, logo, favicon, timezone, language, theme

🔗 Webhooks

Receive real-time notifications when events occur in Veloxiom. Configure outbound webhooks in the panel under Admin → API & Webhooks. The signing secret (whsec_…) is shown once at creation.

Available Events

EventDescription
message.receivedAn inbound message (SMS/other channel) arrived
message.sentAn outbound message was dispatched (e.g. via API send_message)
pingTest event sent from the admin UI
*Subscribe to all current and future events

Additional business events (customer.*, invoice.*, ticket.*, router.*) are on the roadmap and not yet emitted.

Delivery & Signature

Each delivery is an HTTPS POST with a JSON body. Verify authenticity with the HMAC-SHA256 signature computed over the raw request body using your webhook secret. Only public HTTPS URLs are accepted (loopback/private/CGNAT ranges are rejected — SSRF protection).

# Delivery headers Content-Type: application/json X-Veloxiom-Event: message.sent X-Veloxiom-Signature: sha256=<hex hmac-sha256 of raw body> # Body shape { "event": "ping", "ts": "2026-06-17T12:00:00+00:00", "data": { ... } } # Verify (PHP) $expected = 'sha256=' . hash_hmac('sha256', $rawBody, $secret); if (hash_equals($expected, $_SERVER['HTTP_X_VELOXIOM_SIGNATURE'])) { /* trusted */ }

🏗️ ERP Integrations

Connect Veloxiom with your ERP system for synchronized billing, customer data, and financial reporting.

ERPStatusIntegration Type
ElorusactiveFull sync — invoices, customers, payments
SoftOnecoming soonREST API integration
Epsilon Netcoming soonREST API integration
Entersoftcoming soonREST API integration
Galaxy / Realcoming soonREST API integration
QuickBooks OnlinebetaOAuth2 — customers, invoices, payments via sync queue
XerobetaOAuth2 — customers, invoices, payments via sync queue
1C:EnterprisebetaOData — customers, invoices, payments via sync queue

📨 Response Format

REST API v1 and all JSON panel/mobile actions return ok: true|false. Some legacy panel actions used by HTML forms respond with a redirect instead of JSON. Error codes for REST are listed in the REST section; panel actions return a short error string (e.g. password_required, plan_required).

// Success response { "ok": true, "data": { ... } } // Error response { "ok": false, "error": "missing_username" }

⏱️ Rate Limits

ScopeLimitWindow
REST API v1 token120 requestsper minute, per token (HTTP 429 on excess)

Need Help?

For API support and custom integration assistance, contact us via the contact form.