{
  "openapi": "3.0.3",
  "info": {
    "title": "OneMap API Platform",
    "version": "2.0.0",
    "description": "A production-ready Location Intelligence API Platform. The REST API documented here **is the product** — every endpoint below is independently usable with an API key, with no dependency on any web dashboard. The customer portal (organizations, API keys, billing, webhooks) exists to help you manage your account; it does not gate or wrap the APIs themselves.\n\n### Products\n- **Tracking** — ingest and query live and historical entity locations\n- **Routing** — calculate routes and assign them to entities\n- **Geocoding / Reverse Geocoding** — resolve addresses ↔ coordinates\n- **Nearby Search** — radius and proximity queries with clustering\n- **Geofencing** — circle/polygon geofences with enter/exit events\n- **Analytics** — density heatmaps, fraud signals, distance/travel stats\n\nEverything else (organizations, API keys, usage, billing, webhooks, notifications, admin) supports customers integrating those APIs into their own tracking, delivery, logistics, ride-sharing, or field-service products.\n\n### Authentication\nThree auth models are accepted. Both `X-API-Token` and `Authorization: Bearer <token>` are checked on every request (whichever is present wins, `X-API-Token` first) — the token type is then auto-detected from its shape, not from which header carried it:\n\n- `pk_live_...` or `pk_test_...` — publishable client key (read-only / tracked writes)\n- `sk_live_...` or `sk_test_...` — secret service key (full access)",
    "contact": {
      "name": "OneMap Platform Engineering",
      "email": "support@onemaps.app",
      "url": "https://onemaps.app"
    }
  },
  "servers": [
    {
      "url": "https://onemaps.app",
      "description": "Production API"
    },
    {
      "url": "http://localhost:8085",
      "description": "Local Gateway & Reverse Proxy"
    }
  ],
  "security": [
    {
      "apiToken": []
    },
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Tracking & Nearby",
      "description": "Ingest real-time GPS telemetry, stream breadcrumbs, track trips, and execute proximity searches."
    },
    {
      "name": "Routing",
      "description": "High-performance OSRM routing, turn-by-turn polyline generation, and multi-origin distance matrices."
    },
    {
      "name": "Geocoding",
      "description": "Forward address search, reverse geocoding, and place details coordinate resolution."
    },
    {
      "name": "Geofencing",
      "description": "Circular and polygonal boundary definitions with automatic enter/exit event triggers."
    },
    {
      "name": "Analytics",
      "description": "Spatial density heatmaps, trip velocity profiles, and fleet travel intelligence."
    }
  ],
  "paths": {
    "/v1/locations/": {
      "post": {
        "tags": ["Tracking & Nearby"],
        "summary": "Submit a new real-time location update.",
        "description": "Ingest live GPS telemetry data for a tracked vehicle or user entity.",
        "operationId": "submitLocationUpdate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["entity_id", "latitude", "longitude"],
                "properties": {
                  "entity_id": { "type": "string", "example": "driver_78291" },
                  "latitude": { "type": "number", "format": "double", "example": 27.717245 },
                  "longitude": { "type": "number", "format": "double", "example": 85.323961 },
                  "heading": { "type": "number", "example": 142.5 },
                  "speed": { "type": "number", "example": 36.8 },
                  "accuracy": { "type": "number", "example": 4.2 },
                  "timestamp": { "type": "string", "format": "date-time", "example": "2026-10-20T12:00:00Z" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Location accepted and buffered to spatial store.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "message": { "type": "string", "example": "Location recorded successfully" },
                    "entity_id": { "type": "string", "example": "driver_78291" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/entities/{id}/location": {
      "get": {
        "tags": ["Tracking & Nearby"],
        "summary": "Get the current state/location of a specific entity.",
        "description": "Retrieve the latest recorded coordinates, heading, and activity state for an entity.",
        "operationId": "getEntityLocation",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "description": "Unique identifier of the entity (e.g. driver ID)"
          }
        ],
        "responses": {
          "200": {
            "description": "Latest position returned successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "entity_id": { "type": "string", "example": "driver_78291" },
                    "latitude": { "type": "number", "example": 27.717245 },
                    "longitude": { "type": "number", "example": 85.323961 },
                    "heading": { "type": "number", "example": 142.5 },
                    "speed": { "type": "number", "example": 36.8 },
                    "updated_at": { "type": "string", "format": "date-time" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/entities/{id}/tracks": {
      "get": {
        "tags": ["Tracking & Nearby"],
        "summary": "Get the historical breadcrumb trail of an entity.",
        "description": "Retrieve chronological GPS track breadcrumbs for the specified time window.",
        "operationId": "getEntityTracks",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "from",
            "in": "query",
            "schema": { "type": "string", "format": "date-time" },
            "description": "Start timestamp filter (ISO 8601)"
          },
          {
            "name": "to",
            "in": "query",
            "schema": { "type": "string", "format": "date-time" },
            "description": "End timestamp filter (ISO 8601)"
          }
        ],
        "responses": {
          "200": {
            "description": "Array of breadcrumb coordinates.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "entity_id": { "type": "string" },
                    "points": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "lat": { "type": "number" },
                          "lng": { "type": "number" },
                          "time": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/trips": {
      "get": {
        "tags": ["Tracking & Nearby"],
        "summary": "List trips",
        "description": "Fetch a paginated list of recorded trips.",
        "operationId": "listTrips",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "default": 20 }
          },
          {
            "name": "status",
            "in": "query",
            "schema": { "type": "string", "enum": ["active", "completed", "cancelled"] }
          }
        ],
        "responses": {
          "200": {
            "description": "List of trips.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "type": "object" } },
                    "total": { "type": "integer" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/trips/{id}": {
      "get": {
        "tags": ["Tracking & Nearby"],
        "summary": "Get a single trip",
        "description": "Fetch detailed geometry, coordinates, and telemetry stats for a trip.",
        "operationId": "getTripDetails",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Trip details.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "string" },
                    "distance_meters": { "type": "number" },
                    "duration_seconds": { "type": "integer" },
                    "polyline": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/nearby/entities": {
      "get": {
        "tags": ["Tracking & Nearby"],
        "summary": "Spatial search for nearby entities.",
        "description": "Query entities within a geographic radius with optional density clustering.",
        "operationId": "searchNearbyEntities",
        "parameters": [
          { "name": "latitude", "in": "query", "required": true, "schema": { "type": "number" } },
          { "name": "longitude", "in": "query", "required": true, "schema": { "type": "number" } },
          { "name": "radius_km", "in": "query", "schema": { "type": "number", "default": 5.0 } },
          { "name": "type", "in": "query", "schema": { "type": "string", "example": "driver" } }
        ],
        "responses": {
          "200": {
            "description": "Nearby entities found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": { "type": "integer" },
                    "entities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "string" },
                          "distance_meters": { "type": "number" },
                          "lat": { "type": "number" },
                          "lng": { "type": "number" }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/routes/directions": {
      "post": {
        "tags": ["Routing"],
        "summary": "Calculate routes and turn-by-turn navigation.",
        "description": "Compute optimal path, polyline geometry, and estimated time of arrival between points.",
        "operationId": "calculateRoute",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["origin", "destination"],
                "properties": {
                  "origin": {
                    "type": "object",
                    "properties": { "lat": { "type": "number" }, "lng": { "type": "number" } }
                  },
                  "destination": {
                    "type": "object",
                    "properties": { "lat": { "type": "number" }, "lng": { "type": "number" } }
                  },
                  "vehicle_profile": { "type": "string", "enum": ["car", "bike", "truck"], "default": "car" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculated route geometry.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "distance_meters": { "type": "number", "example": 8450 },
                    "duration_seconds": { "type": "integer", "example": 1140 },
                    "polyline": { "type": "string", "example": "_p~iF~ps|U_ulLnnqC_mqN..." }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/geocode": {
      "get": {
        "tags": ["Geocoding"],
        "summary": "Forward address and place search.",
        "description": "Search place names or addresses and convert to geographic coordinates.",
        "operationId": "forwardGeocode",
        "parameters": [
          { "name": "query", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 5 } }
        ],
        "responses": {
          "200": {
            "description": "Candidate places with coordinates.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "display_name": { "type": "string" },
                      "lat": { "type": "number" },
                      "lng": { "type": "number" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/reverse-geocode": {
      "get": {
        "tags": ["Geocoding"],
        "summary": "Reverse geocoding — coordinates to address.",
        "description": "Convert latitude and longitude coordinates into human-readable street addresses.",
        "operationId": "reverseGeocode",
        "parameters": [
          { "name": "lat", "in": "query", "required": true, "schema": { "type": "number" } },
          { "name": "lng", "in": "query", "required": true, "schema": { "type": "number" } }
        ],
        "responses": {
          "200": {
            "description": "Structured address object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "address": { "type": "string", "example": "Durbar Marg, Kathmandu, Nepal" },
                    "city": { "type": "string", "example": "Kathmandu" },
                    "country": { "type": "string", "example": "Nepal" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/geofences": {
      "get": {
        "tags": ["Geofencing"],
        "summary": "List all active geofences.",
        "operationId": "listGeofences",
        "responses": {
          "200": {
            "description": "List of active geofences.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": { "type": "string" },
                      "name": { "type": "string" },
                      "type": { "type": "string", "enum": ["polygon", "circle"] }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/heatmaps": {
      "get": {
        "tags": ["Analytics"],
        "summary": "Generate density heatmaps.",
        "description": "Query spatial heatmaps for driver concentration, ride demand, and trip density.",
        "operationId": "getHeatmapData",
        "responses": {
          "200": {
            "description": "Heatmap points returned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "points": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "lat": { "type": "number" },
                          "lng": { "type": "number" },
                          "weight": { "type": "number" }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiToken": {
        "type": "apiKey",
        "name": "X-API-Token",
        "in": "header",
        "description": "Your API key (pk_live_.. / sk_live_.. / pk_test_.. / sk_test_..) — the primary way to authenticate requests."
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key or Token",
        "description": "Pass your API key as a Bearer token in the standard Authorization header."
      }
    }
  }
}
