Operator Management Service — API Contracts
Status: populated Owner: Platform Engineering Last updated: 2026-04-18 Companion: APPLICATION_LOGIC · SECURITY_MODEL
1. Admin REST API (via Kong)
Base path: /v1/admin/operators
Auth: Kong jwt plugin — requires scope ops:admin in JWT claims.
Headers injected by Kong: X-Request-Id, traceparent, X-Admin-Id.
1.1 POST /v1/admin/operators
Create a new operator.
Request body:
{
"name": "Carrier Alpha UK",
"host": "smpp.carrier-alpha.co.uk",
"port": 2775,
"systemId": "ghasi_prod",
"systemType": "",
"bindType": "TRANSCEIVER",
"password": "s3cr3t!",
"tpsLimit": { "maxTps": 500, "burstMultiplier": 1.5, "enforcementMode": "HARD_REJECT" }
}
Note: password is write-only — never returned in responses.
Response 201:
{
"operatorId": "018f1a2b-...",
"name": "Carrier Alpha UK",
"host": "smpp.carrier-alpha.co.uk",
"port": 2775,
"systemId": "ghasi_prod",
"bindType": "TRANSCEIVER",
"tpsLimit": { "maxTps": 500, "burstMultiplier": 1.5, "enforcementMode": "HARD_REJECT" },
"status": "INACTIVE",
"healthState": "UNKNOWN",
"createdAt": "2026-04-18T10:00:00.000Z"
}
Errors:
| HTTP | Code | Meaning |
|---|---|---|
| 400 | INVALID_PAYLOAD | Zod schema failure |
| 409 | DUPLICATE_OPERATOR | Same (host, port, systemId) exists |
| 503 | VAULT_UNAVAILABLE | Vault write failed |
1.2 GET /v1/admin/operators
List operators. Supports ?status=ACTIVE&page=1&limit=50.
Response 200:
{
"data": [ { "operatorId": "...", "name": "...", "status": "ACTIVE", "healthState": "HEALTHY", ... } ],
"meta": { "total": 12, "page": 1, "limit": 50 }
}
1.3 GET /v1/admin/operators/:id
Fetch single operator. Returns 404 for soft-deleted.
1.4 PATCH /v1/admin/operators/:id
Partial update. Accepts any subset of operator fields. To rotate password, include "password": "<new>".
Response 200: updated operator object (no password field).
Errors: 404, 409 (duplicate check on host/port/systemId), 503 (Vault on password rotation).
1.5 DELETE /v1/admin/operators/:id
Soft-delete. Sets deleted_at = now(), status = INACTIVE. Publishes operator.config.deleted.v1.
Response 204.
1.6 GET /v1/admin/operators/:id/routing-rules
List routing rules for operator.
1.7 POST /v1/admin/operators/:id/routing-rules
{ "prefix": "+44", "mcc": "234", "mnc": "30", "priority": 10, "weight": 100, "costPerSegment": "0.006500", "active": true }
Returns 201 with created rule. 409 on prefix overlap.
1.8 PATCH /v1/admin/operators/:id/routing-rules/:ruleId
Update rule fields.
1.9 DELETE /v1/admin/operators/:id/routing-rules/:ruleId
Hard-delete routing rule (no audit concern; operator is the aggregate boundary).
1.10 GET /v1/admin/operators/:id/health
Returns current health state + last 24h log entries.
1.11 GET /health/live, GET /health/ready, GET /metrics
Operational; not exposed via Kong.
2. Internal REST API (mTLS, no Kong route)
Base path: http://operator-management-service.svc.cluster.local:3020
Auth: mutual TLS — caller certificate must be in cluster CA bundle.
No public exposure. Not in Kong config.
2.1 GET /v1/internal/operators/:id/credentials
Returns Vault-backed credentials for smpp-connector to bind.
Response 200:
{
"operatorId": "018f1a2b-...",
"host": "smpp.carrier-alpha.co.uk",
"port": 2775,
"systemId": "ghasi_prod",
"password": "s3cr3t!",
"bindType": "TRANSCEIVER",
"tpsLimit": { "maxTps": 500, "burstMultiplier": 1.5, "enforcementMode": "HARD_REJECT" }
}
Errors: 404 (operator unknown), 503 (Vault unavailable — smpp-connector falls back to in-memory cache).
2.2 GET /v1/internal/operators
Returns all active operators (without passwords) for routing-engine bootstrap.
2.3 GET /v1/internal/operators/:id/routing-rules
Returns routing rules for a single operator — used by routing-engine on cache miss.
3. Error Response Shape
{
"type": "https://errors.ghasi.io/ops/DUPLICATE_OPERATOR",
"title": "Operator already exists",
"status": 409,
"code": "DUPLICATE_OPERATOR",
"detail": "An operator with host=smpp.carrier-alpha.co.uk, port=2775, systemId=ghasi_prod already exists",
"instance": "/v1/admin/operators",
"requestId": "req_01H..."
}
4. OpenAPI
Generated from NestJS decorators into openapi.json. Admin API committed and linted in CI against Kong route config.