8.5 KiB
Core
Core is the Nexuma control API. It stores platform state, authenticates users, coordinates nodes, builds node configuration revisions, records traffic, and serves public subscription exports.
This page is public operator documentation. It describes behavior, API, environment variables, and Docker deployment without requiring source-code access.
Capabilities
- User registration, login, Telegram OAuth, account approval, profile updates, and role-based access.
- Tariff management with price, duration, traffic limit, protocol permissions, node permissions, and external subscription sources.
- Subscription lifecycle with activation, cancellation, expiry, auto-renewal, traffic accounting, and public links.
- Balance management with deposit, withdrawal, refund, history, and auto-renewal charging rules.
- Node registration through one-time codes.
- Node heartbeat, status, sync state, revision tracking, config delivery, and error reporting.
- Per-node protocol configuration, routing configuration, masking sites, runtime operations, and outbounds.
- Routing rule sets with rules, balancers, and blocking options.
- External subscription source ingestion and testing.
- Public subscription exports for VPN clients.
- Platform settings management (panel, subscription delivery, Telegram, IPinfo).
- User IP history with optional daily country and ASN enrichment through IPinfo Lite.
- Telegram broadcast messages with user filtering and delivery tracking.
- Referral system with code-based self-approval for pending users.
- Audit logs, usage queries, metrics, and health checks.
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
PORT |
No | 3000 |
HTTP port. |
GRPC_PORT |
No | 3002 |
gRPC port for node-to-core communication. Expose this port to node servers. |
NODE_ENV |
No | development |
Runtime mode. |
DB_HOST |
Yes | localhost |
Database host. |
DB_PORT |
No | 5432 |
Database port. |
DB_USER |
Yes | postgres |
Database user. |
DB_PASSWORD |
Yes | empty | Database password. |
DB_NAME |
Yes | nexuma |
Database name. |
REDIS_HOST |
Yes | localhost |
Redis host. |
REDIS_PORT |
No | 6379 |
Redis port. |
REDIS_PASSWORD |
No | empty | Redis password. |
REDIS_DB |
No | 0 |
Redis database index. |
JWT_SECRET |
Yes | insecure dev value | Access token secret. Use a long random value. |
JWT_EXPIRES_IN |
No | 15m |
Access token lifetime. |
JWT_REFRESH_SECRET |
Yes | insecure dev value | Refresh token secret. Use a different long random value. |
JWT_REFRESH_EXPIRES_IN |
No | 7d |
Refresh token lifetime. |
TELEGRAM_BOT_TOKEN |
No | empty | Enables Telegram login and notifications. |
CORS_ORIGINS |
No | * |
Comma-separated allowed origins. |
Docker Compose
Minimal Core deployment with Redis and an external database:
version: '3.9'
services:
redis:
image: redis:7-alpine
container_name: nexuma-redis
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- nexuma
core:
image: nexuma/core:latest
container_name: nexuma-core
restart: unless-stopped
environment:
PORT: 3000
GRPC_PORT: 3002
DB_HOST: your-postgres-host
DB_PORT: 5432
DB_USER: postgres
DB_PASSWORD: change-me
DB_NAME: nexuma
REDIS_HOST: redis
REDIS_PORT: 6379
JWT_SECRET: replace-with-long-random-secret
JWT_REFRESH_SECRET: replace-with-another-long-random-secret
JWT_EXPIRES_IN: 15m
JWT_REFRESH_EXPIRES_IN: 7d
CORS_ORIGINS: https://panel.example.com
ports:
- "3000:3000"
- "3002:3002"
depends_on:
- redis
networks:
- nexuma
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:3000/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
volumes:
redis_data:
networks:
nexuma:
driver: bridge
Run:
docker compose up -d
Health check:
curl http://localhost:3000/health
API Conventions
- JSON request and response bodies are used unless a route explicitly returns text, YAML, or metrics.
- User and admin routes use
Authorization: Bearer <access_token>. - Admin routes require an admin account.
- Node-private routes use
x-node-auth-key. - Public subscription content is served by UUID and does not require login.
- Validation errors return HTTP error responses with an error message.
Public API
| Method | Route | Purpose |
|---|---|---|
GET |
/health |
Health status. |
GET |
/metrics |
Metrics text output. |
POST |
/auth/register |
Register with email and password. |
POST |
/auth/login |
Login with email and password. |
POST |
/auth/refresh |
Refresh tokens. |
POST |
/auth/telegram |
Login or register through Telegram OAuth. |
GET |
/auth/telegram/bot-id |
Return configured Telegram bot ID. |
GET |
/sub/:uuid/info |
Return public subscription metadata. |
GET |
/sub/:uuid |
Return generated VPN subscription content. |
GET /sub/:uuid supports:
?format=v2ray?format=clash?format=singbox
Missing or unknown format falls back to v2ray.
User API
| Method | Route | Purpose |
|---|---|---|
GET |
/me |
Current user profile. |
PATCH |
/me/profile |
Update name, email, or password. |
GET |
/me/stats |
User summary statistics. |
GET |
/me/traffic |
Traffic series by period. |
GET |
/me/traffic/daily |
Daily traffic series. |
GET |
/me/traffic/hourly-dist |
Hour-of-day traffic distribution. |
GET |
/me/balance |
Current balance. |
GET |
/me/balance/transactions |
User balance history. |
GET |
/me/subscriptions |
User subscriptions. |
GET |
/me/links |
User subscription links. |
GET |
/me/configs |
Available configs for the user. |
POST |
/me/links |
Create a public link. |
PATCH |
/me/links/:id |
Rename, enable, disable, or reconfigure a link. |
DELETE |
/me/links/:id |
Delete a link. |
POST |
/me/links/:id/reset |
Reset a link UUID. |
PATCH |
/me/subscriptions/:id/auto-renew |
Toggle auto-renew. |
Admin API Groups
/admin/users- users, approval status, block flag, profile fields, stats, referees, and IP history./admin/tariffs- tariff CRUD./admin/subscriptions- subscriptions and subscription links./admin/links- subscription link operations (reset, update, delete)./admin/nodes- nodes, protocols, sync, runtime operations, masking sites, outbounds, observatory, routing balancers./admin/routing-rule-sets- reusable routing templates./admin/external-subscriptions- external source CRUD and URL testing./admin/settings- platform settings (panel, subscription delivery, Telegram, IPinfo)./admin/broadcasts- Telegram broadcast messages with delivery tracking./admin/logs- audit log viewer data./admin/usage- traffic usage rows./admin/xray/parse-link- parse a proxy share link into outbound settings.
See Core API routes for the detailed route table.
Node-Private API
Node agents use two transports:
- HTTP — registration only (
POST /node/register). - gRPC (
GRPC_PORT, default3002) — heartbeat, usage reporting, config sync, and live stats. This is the primary node transport.
HTTP fallback routes (/node/heartbeat, /node/usage, etc.) remain available but the node agent uses gRPC by default.
See Core private node routes for the full payload contract and gRPC method table.
Data Behavior
- Users can be
active,pending, orrejected. - Nodes can be
active,disabled,maintenance, orerror. - Effective node status is computed from stored status and last heartbeat.
- Subscriptions can be
active,expired, orcancelled. - A tariff with
durationMonths = nullis indefinite and expires only by traffic limit or cancellation. - A subscription link UUID is the credential used in generated client configs.
- Disabling or resetting a link affects generated configs on the next node sync.
- Node config revisions increment when node-facing configuration changes.
- Active nodes receive only active subscription clients.
Operational Notes
- Run Core behind HTTPS in production.
- Keep database and Redis private.
- Use unique long secrets for access and refresh tokens.
- Restrict CORS to the panel domain.
- Back up the database before upgrades.
- Rotate node auth keys if a node host is compromised.
- Do not expose node-private endpoints directly to the internet.