Skip to main content

OmniLCS REST API Reference

The OmniLCS REST API is served over HTTPS on port 8443. The base URL is https://<host>:8443/api.

API documentation (Swagger UI) is available at https://<host>:8443/api/docs. The OpenAPI schema is at https://<host>:8443/api/schema.

Authentication

The API does not currently enforce authentication. Access should be restricted at the network level.

Response Format

All responses use JSON. Successful responses include a "status": "ok" field. Error responses include "status": "error" and a "reason" field.


System Status

GET /api/status

Returns system health and operational status.

Response (200)

{
"status": "ok",
"version": "1.0.0",
"name": "OmniLCS",
"diameter_peers": [
{
"host": "dra01.epc.mnc380.mcc313.3gppnetwork.org",
"realm": "epc.mnc380.mcc313.3gppnetwork.org",
"state": "Connected",
"transport": "sctp"
}
],
"active_sessions": 2,
"completed_sessions": 47,
"cells_loaded": 128,
"cell_sync": {
"last_sync": "2025-01-15T10:30:00Z",
"last_result": "ok (128 cells)",
"sync_count": 42
},
"uptime_seconds": 86400
}
FieldTypeDescription
versionstringApplication version
namestringInstance name
diameter_peersarrayConnected Diameter peers with state
active_sessionsintegerNumber of in-progress location sessions
completed_sessionsintegerNumber of completed location sessions
cells_loadedintegerNumber of cells in the database
cell_syncobjectInfluxDB sync status
uptime_secondsintegerProcess uptime in seconds

Location Services

POST /api/location

Request a new location for a UE.

Request Body

{
"imsi": "001010000000001",
"method": "gnss",
"timeout": 30000,
"mme_host": "mme01.epc.mnc380.mcc313.3gppnetwork.org",
"accuracy": 50
}
ParameterTypeRequiredDefaultDescription
imsistringYes--IMSI of the UE to locate
methodstringNo"cell"Positioning method: "cell", "ecid", "gnss", "otdoa", "hybrid"
timeoutintegerNo30000Timeout in milliseconds
mme_hoststringNo--Target MME Diameter host. If omitted, uses connected peers.
accuracyintegerNo--Desired accuracy in meters. Overrides method selection.

When accuracy is provided, the method is auto-selected:

Accuracy (meters)Selected Method
<= 50GNSS
<= 200OTDOA
<= 500E-CID
> 500Cell ID

Response (200)

{
"status": "ok",
"imsi": "001010000000001",
"method": "gnss",
"latitude": 40.7128,
"longitude": -74.0060,
"altitude": null,
"uncertainty": 10.5,
"confidence": null,
"source": "gnss",
"duration_ms": 5230,
"timestamp": "2025-01-15T10:30:00Z"
}
FieldTypeDescription
imsistringUE identifier
methodstringMethod requested
latitudefloat/nullLatitude in decimal degrees
longitudefloat/nullLongitude in decimal degrees
altitudefloat/nullAltitude in meters (if available)
uncertaintyfloat/nullPosition uncertainty in meters
confidencefloat/nullConfidence percentage
sourcestringActual positioning source used
duration_msintegerTime taken in milliseconds
timestampstringISO 8601 timestamp

Error Responses

StatusReasonDescription
400"imsi is required"Missing IMSI parameter
404"User not found"IMSI unknown
404"User not connected"UE not attached to network
422"No MME host available for this subscriber"No MME to route the request
504"Positioning timed out"Positioning method did not complete in time
500(varies)Internal error

GET /api/location

List recent completed location fixes.

Query Parameters

ParameterTypeDefaultDescription
limitinteger50Maximum number of results

Response (200)

{
"status": "ok",
"data": [
{
"imsi": "001010000000001",
"method": "gnss",
"state": "completed",
"latitude": 40.7128,
"longitude": -74.0060,
"uncertainty": 10.5,
"source": "gnss",
"created_at": "2025-01-15T10:29:55Z",
"completed_at": "2025-01-15T10:30:00Z"
}
],
"count": 1
}

GET /api/location/:imsi

Get the last known location for a UE by IMSI.

Path Parameters

ParameterTypeDescription
imsistringIMSI of the UE

Response (200)

{
"status": "ok",
"imsi": "001010000000001",
"latitude": 40.7128,
"longitude": -74.0060,
"altitude": null,
"uncertainty": 10.5,
"confidence": null,
"source": "gnss",
"timestamp": "2025-01-15T10:30:00Z"
}

Error Responses

StatusReason
404"No location found for IMSI"
404"No completed location for IMSI"

GET /api/location/:imsi/history

Get location fix history for an IMSI.

Path Parameters

ParameterTypeDescription
imsistringIMSI of the UE

Query Parameters

ParameterTypeDefaultDescription
fromstring--Start of time range (ISO 8601 or date)
tostring--End of time range (ISO 8601 or date)
limitinteger100Maximum number of results

Response (200)

{
"status": "ok",
"data": [
{
"timestamp": "2025-01-15T10:30:00Z",
"imsi": "001010000000001",
"method": "gnss",
"latitude": 40.7128,
"longitude": -74.0060,
"altitude": null,
"uncertainty": 10.5,
"confidence": null,
"source": "gnss",
"duration_ms": 5230
}
],
"count": 1
}

GET /api/location/:imsi/history/csv

Export location history for an IMSI as a CSV file.

Path Parameters

ParameterTypeDescription
imsistringIMSI of the UE

Query Parameters

Same as /api/location/:imsi/history.

Response (200)

Returns a CSV file download with headers:

timestamp,imsi,method,latitude,longitude,altitude,uncertainty,confidence,source,duration_ms

Content-Type: text/csv Content-Disposition: attachment; filename="location_history_<imsi>_<date>.csv"


Cell Database

GET /api/cells

List all cells in the database.

Response (200)

{
"status": "ok",
"data": [
{
"cell_id": "001-01-0001-01",
"latitude": 40.7128,
"longitude": -74.0060,
"pci": 100,
"earfcn": 1300,
"radius": 500,
"azimuth": null,
"height": null,
"prs_config": null,
"updated_at": "2025-01-15T10:00:00Z"
}
],
"count": 1
}

GET /api/cells/:id

Get a single cell by cell_id.

Path Parameters

ParameterTypeDescription
idstringCell identifier

Response (200)

{
"status": "ok",
"data": {
"cell_id": "001-01-0001-01",
"latitude": 40.7128,
"longitude": -74.0060,
"pci": 100,
"earfcn": 1300,
"radius": 500,
"azimuth": null,
"height": null,
"prs_config": {
"bandwidth": 50,
"config_index": 0,
"num_dl_frames": 1,
"cp_length": null,
"num_antenna_ports": null
},
"updated_at": "2025-01-15T10:00:00Z"
}
}

Error Response

StatusReason
404"Cell not found: <id>"

POST /api/cells

Create a new cell.

Request Body

{
"cell_id": "001-01-0001-01",
"latitude": 40.7128,
"longitude": -74.0060,
"pci": 100,
"earfcn": 1300,
"radius": 500,
"azimuth": 120.0,
"height": 30.0,
"prs_config": {
"bandwidth": 50,
"config_index": 0,
"num_dl_frames": 1,
"cp_length": "normal",
"num_antenna_ports": 2
}
}
ParameterTypeRequiredDefaultDescription
cell_idstringYes--Unique cell identifier
latitudefloatYes--Cell latitude (-90 to 90)
longitudefloatYes--Cell longitude (-180 to 180)
pciintegerNo--Physical Cell Identity (0-503)
earfcnintegerNo--E-UTRA Absolute Radio Frequency Channel Number
radiusintegerNo1000Coverage radius in meters
azimuthfloatNo--Antenna azimuth in degrees
heightfloatNo--Antenna height in meters
prs_configobjectNo--PRS configuration for OTDOA
tacintegerNo--Tracking Area Code (used for 4G CAP alert broadcast targeting)
lacintegerNo--Location Area Code (used for 2G and 3G CAP alert broadcast targeting)
ratstringNo--Radio Access Technology: "4g", "3g", or "2g"

Response (201)

Returns the created cell in the same format as GET /api/cells/:id.

Error Responses

StatusReason
400"cell_id is required"
400"latitude and longitude are required"

PUT /api/cells/:id

Update an existing cell. Only provided fields are updated.

Path Parameters

ParameterTypeDescription
idstringCell identifier

Request Body

Any cell fields to update (same as POST, but all fields are optional).

Response (200)

Returns the updated cell.

Error Response

StatusReason
404"Cell not found: <id>"

DELETE /api/cells/:id

Delete a cell from the database.

Path Parameters

ParameterTypeDescription
idstringCell identifier

Response (204)

Empty body on success.

Error Response

StatusReason
404"Cell not found: <id>"

GET /api/cells/nearby

Find cells near a geographic point.

Query Parameters

ParameterTypeRequiredDefaultDescription
latfloatYes--Latitude of search center
lonfloatYes--Longitude of search center
radiusfloatNo10Search radius in kilometers

Response (200)

{
"status": "ok",
"data": [
{
"cell_id": "001-01-0001-01",
"latitude": 40.7128,
"longitude": -74.0060,
"pci": 100,
"earfcn": 1300,
"distance_km": 0.523
}
],
"count": 1
}

Results are sorted by distance (nearest first). Each entry includes a distance_km field.

Error Response

StatusReason
400"lat and lon query parameters are required"

POST /api/cells/sync

Trigger an immediate InfluxDB cell sync.

Request Body

None required.

Response (200)

{
"status": "ok",
"cells_synced": 128
}

Error Responses

StatusReason
500"Sync failed: <reason>"
503"Cell sync service unavailable"

Deferred Location (GMLC)

Manage periodic and geo-fence triggered location sessions. See the GMLC & Le Interface guide for full details on session types and Diameter integration.

GET /api/deferred_location

List all active deferred location sessions.

Response (200):

{
"status": "ok",
"count": 1,
"data": [
{
"session_id": "a1b2c3d4-e5f6-...",
"type": "periodic",
"imsi": "001010000000001",
"method": "cell",
"client_name": "rest-api",
"status": "active",
"interval_ms": 60000,
"remaining_reports": 7,
"total_reports": 10,
"started_at": "2026-04-09T10:00:00Z",
"last_fix_at": "2026-04-09T10:03:00Z"
}
]
}

POST /api/deferred_location

Create a new deferred location session.

Periodic session request body:

{
"type": "periodic",
"imsi": "001010000000001",
"method": "cell",
"interval_seconds": 60,
"count": 10
}
FieldTypeRequiredDescription
typestringYes"periodic"
imsistringYesSubscriber IMSI
methodstringNoPositioning method: cell, ecid, gnss, otdoa. Default: cell
interval_secondsintegerYesSeconds between fixes
countintegerYesTotal number of fixes to perform

Triggered session request body:

{
"type": "triggered",
"imsi": "001010000000001",
"method": "cell",
"event_type": "entering",
"poll_interval_seconds": 30,
"max_reports": 0,
"areas": [
{
"type": "circle",
"center": {"lat": -33.8688, "lon": 151.2093},
"radius_meters": 500
}
]
}
FieldTypeRequiredDescription
typestringYes"triggered"
imsistringYesSubscriber IMSI
methodstringNoPositioning method. Default: cell
event_typestringYes"entering", "leaving", or "being_inside"
poll_interval_secondsintegerNoSeconds between position polls. Default: 30
max_reportsintegerNoMax trigger reports. 0 = unlimited
areasarrayYesList of area definitions (circle or polygon)

Response (201):

{"status": "ok", "message": "Periodic session created"}

GET /api/deferred_location/:session_id

Get the status of a deferred session.

Response (200):

{
"status": "ok",
"data": {
"session_id": "a1b2c3d4-...",
"type": "periodic",
"imsi": "001010000000001",
"status": "active",
"remaining_reports": 7,
"total_reports": 10
}
}

DELETE /api/deferred_location/:session_id

Cancel an active deferred session.

Response (200):

{"status": "ok", "message": "Session cancelled"}
StatusError
400Missing or invalid parameters
404Session not found

CAP Alerts

POST /api/cap

Submit a CAP XML alert for processing. The alert is parsed, polygon warning areas are resolved to TACs/LACs via the cell database, and the alert is either queued for approval or auto-broadcast depending on configuration.

Request Body

{
"xml": "<alert xmlns=\"urn:oasis:names:tc:emergency:cap:1.2\">...</alert>"
}
ParameterTypeRequiredDescription
xmlstringYesComplete CAP v1.2 XML alert document

Response (201)

{
"status": "ok",
"data": {
"id": "a1b2c3d4-e5f6-...",
"status": "pending",
"source": "http_post",
"received_at": "2025-01-15T10:30:00Z",
"matched_cells": 42,
"tacs": [100, 101],
"lacs": [5001],
"mcc": "001",
"mnc": "01",
"broadcast_params": {
"message_id": 4370,
"repetition_period": 30,
"num_broadcasts": 10,
"message_text": "Tornado Warning...",
"event": "Tornado Warning",
"severity": "Extreme",
"urgency": "Immediate"
}
}
}

The status field is "pending" when require_approval is true, or "sent" when auto-approved.

Error Responses

StatusReason
400"xml field is required"
422Parse error details

GET /api/cap

List all alerts across all states (pending, active, history).

Response (200)

{
"status": "ok",
"data": {
"pending": [...],
"active": [...],
"history": [...]
}
}

GET /api/cap/:id

Get a single alert by ID.

Path Parameters

ParameterTypeDescription
idstringAlert UUID

Response (200)

Returns the alert object.

Error Response

StatusReason
404"Alert not found: <id>"

PUT /api/cap/:id

Approve or reject a pending alert.

Request Body

{
"action": "approve",
"operator": "operator1"
}
ParameterTypeRequiredDescription
actionstringYes"approve" or "reject"
operatorstringNoOperator name for audit trail (defaults to "unknown")

Response (200)

Returns the updated alert object.

Error Responses

StatusReason
400"action must be 'approve' or 'reject'"
404"Alert not found: <id>"

Error Response Format

All error responses follow this structure:

{
"status": "error",
"reason": "Human-readable error description"
}

Common HTTP status codes:

CodeMeaning
200Success
201Created (cell creation)
204No Content (cell deletion)
400Bad Request (missing or invalid parameters)
404Not Found (unknown resource)
422Unprocessable Entity (valid request but cannot be fulfilled)
500Internal Server Error
503Service Unavailable
504Gateway Timeout (positioning timeout)