Developer docs
Cell Positioning API
Programmatic access to the cell tower records stored in this instance. Look up a single tower by its cell id and receive its coordinates and metadata as JSON.
Overview
The API exposes one read-only operation: given a
cell_id, it returns the stored tower record (position, network
identifiers, and import metadata) when a match exists. It is intended for
lightweight integrations and automated lookups.
Every response follows a consistent envelope format with three fields:
success (boolean), reason (string), and
data (object).
Authentication
Every request must include an API key in the X-API-Key request
header. The key is configured by an administrator in
config.json and is never shown on this page.
X-API-Key: <your-api-key>
Replace with the key provided by your
administrator. Requests with a missing or incorrect key receive a
401 response with reason: "unauthorized".
Endpoint
GET /api/v1/search
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
cell_id |
integer (≥ 0) | Yes | The cell id to look up. Must be a non-negative integer. |
Success responses (HTTP 200)
Found
A matching record exists. success is true,
reason is "cellid_found", and
data holds the tower record.
{
"success": true,
"reason": "cellid_found",
"data": {
"id": 13937,
"radio": "LTE",
"generation": "4G",
"mcc": 454,
"net": 12,
"area": 40804,
"cell": 26099283,
"unit": -1,
"longitude": 113.9108,
"latitude": 22.2953,
"range_meters": 1000,
"samples": 4,
"changeable": true,
"created_epoch": 1747783166,
"updated_epoch": 1784349193,
"average_signal": 0,
"source_file": "454.csv",
"first_imported_at": "2026-07-23T17:46:10.828039",
"last_imported_at": "2026-07-23T17:46:10.828039"
}
}
Not found
No record matches the given cell_id. success is
false, reason is "cellid_not_found",
and data is an empty object.
{
"success": false,
"reason": "cellid_not_found",
"data": {}
}
Error responses
Error responses also follow the {success, reason, data} envelope.
success is always false on errors.
401 Unauthorized
The X-API-Key header is missing or does not match the configured key.
{
"success": false,
"reason": "unauthorized",
"data": {}
}
422 Unprocessable Entity
cell_id is missing, not an integer, or negative. The data
object contains a details array describing the offending field.
{
"success": false,
"reason": "validation_error",
"data": {
"details": [
{
"type": "missing",
"loc": ["query", "cell_id"],
"msg": "Field required",
"input": null
}
]
}
}
Examples
curl
curl -H "X-API-Key: <your-api-key>" \
"https://your-host.example/api/v1/search?cell_id=26099283"
JavaScript (fetch)
const response = await fetch(
"https://your-host.example/api/v1/search?cell_id=26099283",
{ headers: { "X-API-Key": "<your-api-key>" } }
);
const json = await response.json();
if (json.success) {
console.log("Tower found:", json.data);
} else {
console.log("Reason:", json.reason);
}
Response fields reference
Top-level envelope fields.
| Field | Type | Description |
|---|---|---|
success | boolean | true when the request was processed successfully and a result was found; false otherwise. |
reason | string | Machine-readable result code. One of: cellid_found, cellid_not_found, unauthorized, validation_error. |
data | object | The tower record on success, an empty object on not-found/unauthorized, or a {"details": [...]} object on validation errors. |
Data object fields
Fields of the data object when reason is cellid_found.
| Field | Type | Description |
|---|---|---|
id | integer | Internal database row id of the record. |
radio | string | Radio access technology (e.g. "LTE", "GSM", "UMTS", "CDMA", "NR"). |
generation | string | Human-readable generation (e.g. "4G", "3G", "2G", "5G"). |
mcc | integer | Mobile Country Code. |
net | integer | Mobile Network Code (MNC). |
area | integer | Location/Tracking Area Code (LAC/TAC). |
cell | integer | The cell id used to look up the record. |
unit | integer | Cell unit (primary scrambling code / PCI); -1 when unavailable. |
longitude | number | WGS84 longitude of the estimated position. |
latitude | number | WGS84 latitude of the estimated position. |
range_meters | integer | Estimated accuracy radius in meters. |
samples | integer | Number of measurements contributing to the estimate. |
changeable | boolean | Whether the position is approximate (editable) rather than exact. |
created_epoch | integer | Unix epoch (seconds) when the record was first seen. |
updated_epoch | integer | Unix epoch (seconds) when the record was last updated. |
average_signal | integer | Average signal strength in dBm; 0 when unknown. |
source_file | string | Name of the source CSV file the record came from. |
first_imported_at | string (ISO 8601) | Timestamp the record was first imported. |
last_imported_at | string (ISO 8601) | Timestamp the record was last imported. |