Base URL
Every endpoint lives under the /api/v1 prefix on your own domain:
https://your-server/api/v1
All traffic is HTTPS, all bodies are application/json, and collection endpoints support pagination and search.
Authentication
ISPCore uses the same credentials as the panel. You exchange them once for a pair of tokens, then send the access token as a bearer token on every request.
POST/api/v1/auth/login
Three fields are required. tenant_id is the short slug of the operator you are signing in to — easy to miss, and the most common reason a first request fails.
curl -X POST https://your-server/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{
"email": "you@example.com",
"password": "••••••••",
"tenant_id": "your_slug"
}'
The response carries both tokens, the lifetime of the access token in seconds, and the signed-in user:
{
"access_token": "eyJhbGciOi…",
"refresh_token": "eyJhbGciOi…",
"token_type": "bearer",
"expires_in": 3600,
"user": { "id": "…", "email": "you@example.com", … }
}
GET/api/v1/auth/tenants
Not sure of your slug? This endpoint is public and lists the active operators on the installation, so you can pick the right tenant_id.
Using the token
curl https://your-server/api/v1/clients \ -H 'Authorization: Bearer <access_token>'
When the access token expires, exchange the refresh token at POST /api/v1/auth/refresh. POST /api/v1/auth/logout invalidates both.
Core resources
The surface is broad — around 330 endpoints across 40 groups. These are the ones most integrations start with.
Subscribers & billing
| Endpoint | What it does |
|---|---|
GET/api/v1/clients | List and search subscribers |
GET/api/v1/clients/{id} | One subscriber with contacts and status |
GET/api/v1/subscriptions | Services, plans and their state |
GET/api/v1/plans | Tariff plans and speeds |
GET/api/v1/invoices | Invoices, with totals and payment state |
POST/api/v1/payments | Record a payment against an invoice |
POST/api/v1/fiscal/invoices/{id}/fiscalize | File an invoice with the tax authority |
Fibre & network
| Endpoint | What it does |
|---|---|
GET/api/v1/olt/ | The OLTs on the installation |
GET/api/v1/olt/all-onus | Every ONU with status and optical readings |
GET/api/v1/olt/all-unregistered | ONUs seen on the fibre but not yet provisioned |
GET/api/v1/olt/onu-search | Find an ONU by serial, MAC, name or interface |
GET/api/v1/olt/stats | Totals per OLT — online, offline, signal |
GET/api/v1/nas | NAS devices for RADIUS |
GET/api/v1/ip-pools | Address pools |
POST/api/v1/cpe/{id}/reboot | Reboot a CPE through TR-069 |
Live state & support
| Endpoint | What it does |
|---|---|
GET/api/v1/dashboard/online-clients | Who is online right now |
GET/api/v1/dashboard/online-stats | Session counts over time |
GET/api/v1/dashboard/kpis | Headline numbers for the period |
GET/api/v1/dashboard/unpaid-clients | Who owes money |
GET/api/v1/tickets | Support tickets |
GET/api/v1/stock | Warehouse items and movements |
Conventions & errors
- Pagination. Collections accept
limitand an offset or cursor, and report the total where it is cheap to compute. - Identifiers are UUIDs unless stated otherwise.
- Timestamps are ISO 8601 with timezone.
- Errors use standard HTTP codes with a JSON body:
401missing or expired token,403the account lacks the permission,404not found,409a conflict such as an occupied ONU index,422validation,429rate limited.
{ "detail": "Porti 1/2/8 s'ka indeks te lire." }
Interactive reference
Every installation can serve a live OpenAPI reference generated from the running code — always matching the version you have, never a stale document:
https://your-server/docs Swagger UI https://your-server/redoc ReDoc https://your-server/openapi.json machine-readable spec
Need a hand?
Building something against ISPCore and stuck on a detail? Write to info@isp-core.com or message us on WhatsApp — a person answers.