> ## Documentation Index
> Fetch the complete documentation index at: https://docs.footstep.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Query

> Accept a natural language query and return structured geospatial results. The endpoint classifies intent (route, geocode, isochrone, etc.), extracts locations and parameters, calls the appropriate backend, and returns the full result with a natural language summary. Use context.location to help resolve relative references like 'nearest' or 'nearby'.

Send a natural language query and get back structured geospatial results. The endpoint figures out what you're asking for (directions, a location, reachability, etc.), resolves any text locations to coordinates, calls the appropriate backend, and returns the full result.

## How intent is classified

The endpoint maps queries to the backend that best fits:

| Your query sounds like...          | Intent            | Backend called                                   |
| ---------------------------------- | ----------------- | ------------------------------------------------ |
| "Directions from A to B"           | `route`           | [/v1/routing/route](/api/endpoint/route)         |
| "Best order to visit these stops"  | `optimize`        | [/v1/routing/optimize](/api/endpoint/optimize)   |
| "How far can I walk in 30 minutes" | `isochrone`       | [/v1/routing/isochrone](/api/endpoint/isochrone) |
| "What's the elevation at..."       | `elevation`       | [/v1/routing/elevation](/api/endpoint/elevation) |
| "Distance between A, B, and C"     | `matrix`          | [/v1/routing/matrix](/api/endpoint/matrix)       |
| "Where is..." / "Find..."          | `geocode`         | [/v1/geocoding/search](/api/endpoint/search)     |
| "What's at these coordinates"      | `reverse_geocode` | [/v1/geocoding/reverse](/api/endpoint/reverse)   |

## Using context

Pass `context.location` when your query uses relative terms like "nearest", "nearby", or "from here". Without it, the endpoint can't resolve those references.

Pass `context.country` to disambiguate place names. "Springfield" with `country: "GBR"` resolves differently than with `country: "USA"`.

```json theme={null}
{
  "query": "Walking directions to the nearest park",
  "context": {
    "location": { "lat": 51.5322, "lon": -0.1240 },
    "country": "GBR"
  }
}
```

## Response structure

The response always includes:

| Field        | What it contains                                                         |
| ------------ | ------------------------------------------------------------------------ |
| `intent`     | What the query was classified as (`route`, `geocode`, `isochrone`, etc.) |
| `parameters` | The parameters inferred from the query and passed to the backend         |
| `result`     | The full backend response (same schema as calling the endpoint directly) |
| `summary`    | A natural language summary of the result                                 |

The `result` field contains the exact same response you'd get calling the backend endpoint directly. If the intent is `route`, `result` contains a `RouteResponse`. If `geocode`, it contains a `GeocodingSearchResponse`. No new schemas to learn.

## Error handling

If the query is ambiguous or can't be resolved:

```json theme={null}
{
  "error": "ambiguous_query",
  "message": "Could not determine a specific intent from your query.",
  "suggestions": [
    "Try: 'Directions from A to B'",
    "Try: 'Where is [place name]?'",
    "Try: 'How far can I drive in 30 minutes from [location]?'"
  ]
}
```

If a location in the query can't be geocoded, the response includes what was resolved and what failed:

```json theme={null}
{
  "error": "geocode_failed",
  "message": "Could not find a location matching 'the old pub near the river'.",
  "partial": {
    "intent": "route",
    "resolved_locations": [
      { "text": "Kings Cross", "resolved": { "lat": 51.53, "lon": -0.12 } }
    ],
    "unresolved_locations": [
      { "text": "the old pub near the river" }
    ]
  }
}
```


## OpenAPI

````yaml POST /v1/ai/query
openapi: 3.1.0
info:
  title: Footstep API
  description: >-
    Terrain-intelligent routing, geocoding, elevation, and spatial analysis.
    Every routing response includes terrain analytics by default. Routing
    endpoints support two response formats: footstep (default, compact) and
    geojson (standard GeoJSON).
  version: 1.0.0
servers:
  - url: https://api.footstep.ai
    description: Production
security:
  - apiKey: []
paths:
  /v1/ai/query:
    post:
      tags:
        - AI
      summary: Natural language geospatial query
      description: >-
        Accept a natural language query and return structured geospatial
        results. The endpoint classifies intent (route, geocode, isochrone,
        etc.), extracts locations and parameters, calls the appropriate backend,
        and returns the full result with a natural language summary. Use
        context.location to help resolve relative references like 'nearest' or
        'nearby'.
      operationId: aiQuery
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AIQueryRequest'
            examples:
              route:
                summary: Get walking directions
                value:
                  query: Walking route from Kings Cross to Tower Bridge
              geocode:
                summary: Find a place
                value:
                  query: Where is Buckingham Palace?
              isochrone:
                summary: Reachability query
                value:
                  query: >-
                    How far can I cycle in 20 minutes from Liverpool Street
                    station?
              with_context:
                summary: With location context
                value:
                  query: Directions to the nearest train station
                  context:
                    location:
                      lat: 51.5322
                      lon: -0.124
                    country: GBR
      responses:
        '200':
          description: Structured result from the resolved query
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AIQueryResponse'
        '400':
          description: Invalid or unresolvable query
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: AI or backend engine unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    AIQueryRequest:
      type: object
      required:
        - query
      properties:
        query:
          type: string
          maxLength: 1000
          description: >-
            Natural language query (e.g. 'Walking route from Kings Cross to
            Tower Bridge', 'Where is Buckingham Palace?', 'How far can I drive
            in 30 minutes from Liverpool Street?')
        context:
          type: object
          description: Optional context to improve query understanding
          properties:
            location:
              $ref: '#/components/schemas/Coordinate'
              description: >-
                User's current location. Helps resolve relative references like
                'nearest' or 'nearby'.
            country:
              type: string
              description: >-
                ISO 3166-1 alpha-3 country code to bias geocoding (e.g. GBR,
                USA)
    AIQueryResponse:
      type: object
      required:
        - intent
        - parameters
        - result
        - summary
      properties:
        intent:
          type: string
          enum:
            - route
            - optimize
            - isochrone
            - elevation
            - matrix
            - geocode
            - reverse_geocode
          description: Classified intent of the query
        parameters:
          type: object
          description: >-
            Parameters inferred from the query and passed to the backend
            endpoint
        result:
          type: object
          description: >-
            Full response from the backend endpoint (RouteResponse,
            GeocodingSearchResponse, IsochroneResponse, etc.)
        summary:
          type: string
          description: Natural language summary of the result
    Error:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
        message:
          type: string
    Coordinate:
      type: object
      required:
        - lat
        - lon
      properties:
        lat:
          type: number
          minimum: -90
          maximum: 90
        lon:
          type: number
          minimum: -180
          maximum: 180
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: Your Footstep API key

````