/api-reference/ask

POST /v1/ask

cURL

curl --request POST \
  --url https://api.example.com/v1/ask \
  --header 'Content-Type: application/json' \
  --data '
{
  "question": "<string>",
  "lat": 123,
  "lng": 123,
  "address": "<string>",
  "include_trace": false
}
'

Natural-language Q&A over US coordinates with per-citation provenance.

cURL

curl --request POST \
  --url https://api.example.com/v1/ask \
  --header 'Content-Type: application/json' \
  --data '
{
  "question": "<string>",
  "lat": 123,
  "lng": 123,
  "address": "<string>",
  "include_trace": false
}
'

​ When to use this

​ Asking about an address

cURL
curl -s https://api.mireye.com/v1/ask \
  -H "Authorization: Bearer $MIREYE_API_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"address": "350 5th Ave, New York, NY 10118",
       "question": "Is this in a flood zone?"}' | jq

​ How it works

  • Planner (Claude Haiku 4.5) — receives the question, the coordinate, and the field catalog rendered into the system prompt. Returns a structured tool call naming the catalog fields it wants fetched (capped at 15 per question — note that preset expansions larger than the cap, e.g. site_selection or data_center_siting, are truncated to the first 15 fields of the preset). The planner system prompt is prompt-cached (catalog-sized), so steady-state input cost is ~90% below the uncached path.
  • Fetch (deterministic, parallel) — the orchestrator groups the selected fields by layer and dispatches one fan-out per layer. Each layer returns Field_[T] wrappers carrying value + provenance.
  • Synthesizer (Claude Sonnet 4.6) — receives the question and the rendered values, returns a structured tool call with the prose answer and the list of fields it actually used.
  • Citation extraction (deterministic) — walks fields_used, groups them by source, and emits one citation per source.

​ Worked example: wildfire risk in rural Minnesota

curl -s https://api.mireye.com/v1/ask \
  -H "Authorization: Bearer $MIREYE_API_TOKEN" \
  -H 'content-type: application/json' \
  -d '{
    "lat": 46.6,
    "lng": -93.7,
    "question": "What is the wildfire risk at this location and what fuel is on the ground?"
  }' | jq

​ Confidence calibration

​ Latency and cost

  • Steady-state warm path: ~6–15 s — single-field questions at the low end, multi-field synthesis at the high end. Planner 2–6 s, fetch fan-out sub-second when the layer cache is warm, synthesizer 3–8 s.
  • Tail latency comes from the fetch stage, not the models. A question that selects a slow source lets that source’s own budget dominate: Earth Engine fields allow up to 60 s, road/building fields 30–35 s. One such field can push a single request well past 30 s while the models stay fast — expected, not a failure.
  • Deadline: requests are bounded at 110 seconds end-to-end — past that you get a structured 504 ask_timeout (carrying a Retry-After header) instead of a hang. Per-stage timeouts inside the pipeline: planner 20 s, synthesizer 30 s, one SDK retry.
  • Cold start: the hosted deploy keeps machines running, but the first requests after a deploy can be slower while geospatial sources warm in the background (/readyz reports warm state). Self-hosted instances pay this on every boot.
  • Cache savings: the planner system prompt is catalog-sized; cache reads land at a ~90% input-token discount. Per-question incremental cost is dominated by synthesizer output (~500 tokens at Sonnet rates).

​ Streaming responses

cURL
curl -sN https://api.mireye.com/v1/ask/stream \
  -H "Authorization: Bearer $MIREYE_API_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"lat": 46.6, "lng": -93.7, "question": "Wildfire risk here?"}'

​ Including the trace

JSON
"trace": {
  "planner_model": "claude-haiku-4-5",
  "synthesizer_model": "claude-sonnet-4-6",
  "planner_reasoning": "The user is asking about wildfire risk and ground fuel at this location. This is a broad wildfire underwriting/risk assessment question that combines multiple factors: land cover/fuel type (lcms_class, tree_canopy_pct), vegetation health and change (ndvi_current, ndvi_change_5y), and terrain (slope_degrees, elevation). This matches the wildfire_underwrite preset directly. Additionally, for \"fuel on the ground\" context, land_use_class and cdl_class could add detail, but the preset already covers the primary fuel signals.",
  "fields_requested": [
    "lcms_class",
    "tree_canopy_pct",
    "ndvi_current",
    "ndvi_change_5y",
    "slope_degrees",
    "elevation"
  ],
  "preset_expanded": "wildfire_underwrite",
  "latency_ms": {
    "planner_ms": 5977,
    "fetch_ms": 719,
    "synth_ms": 7504,
    "total_ms": 14200
  },
  "cache_creation_input_tokens": 431,
  "cache_read_input_tokens": 11767
}

​ Errors

​ Partial-failure handling

JSON
"data_gaps": [
  {
    "field": "parcel_zoning",
    "reason": "source returned null: no Regrid parcel at this point"
  }
]

Successful Response