{"openapi":"3.0.0","info":{"title":"Geo.qa Public API","description":"Ask a place what was observed there, and check the answer without an account. Verification endpoints need no credential and never will. Metered endpoints take `Authorization: Bearer on_…`, minted at https://geo.qa/chat/account/api-keys, and are bounded by the owner's storage quota. A refusal returns the full set of ways to reach that resource in `detail`, with `WWW-Authenticate` pointing at https://geo.qa/.well-known/oauth-protected-resource.","version":"2.1.0"},"servers":[{"url":"https://geo.qa","description":"Production"}],"paths":{"/api/tool/satellite/lulc/analyze":{"get":{"tags":["Geospatial tools"],"summary":"Analyze land use at a point","description":"Returns the LULC classification at a single lat/lon point.","security":[{"BearerAuth":[]}],"parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number"},"description":"Latitude."},{"name":"lon","in":"query","required":true,"schema":{"type":"number"},"description":"Longitude."}],"responses":{"200":{"description":"LULC classification result"},"401":{"description":"Missing or invalid API key."},"402":{"description":"Memory storage limit reached. Upgrade plan or free space."},"403":{"description":"Admin-scope key not allowed here — use a key generated at /api-docs."}}}},"/api/tool/satellite/lulc/bbox":{"post":{"tags":["Geospatial tools"],"summary":"Analyze land use for a bounding box","description":"Samples a grid across the bounding box and returns LULC proportions plus per-point classifications.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["min_lat","min_lon","max_lat","max_lon"],"properties":{"min_lat":{"type":"number","description":"Minimum latitude (south)."},"min_lon":{"type":"number","description":"Minimum longitude (west)."},"max_lat":{"type":"number","description":"Maximum latitude (north)."},"max_lon":{"type":"number","description":"Maximum longitude (east)."},"grid_size":{"type":"integer","minimum":2,"maximum":20,"default":5,"description":"Grid size (2-20 points per side)."}}},"example":{"min_lat":12.9,"min_lon":77.5,"max_lat":13,"max_lon":77.6,"grid_size":5}}}},"responses":{"200":{"description":"LULC classification result"},"401":{"description":"Missing or invalid API key."},"402":{"description":"Memory storage limit reached."}}}},"/api/tool/satellite/lulc/polygon":{"post":{"tags":["Geospatial tools"],"summary":"Analyze land use inside a polygon","description":"Samples points inside the given polygon and returns LULC classifications.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["coordinates"],"properties":{"coordinates":{"type":"array","items":{"type":"array","items":{"type":"number"}},"minItems":3,"description":"List of [lat, lon] pairs forming the polygon ring (at least 3)."},"sample_points":{"type":"integer","minimum":1,"maximum":100,"description":"Number of points to sample inside the polygon."}}},"example":{"coordinates":[[12.9,77.5],[12.9,77.6],[13,77.6],[13,77.5]],"sample_points":20}}}},"responses":{"200":{"description":"LULC classification result"},"401":{"description":"Missing or invalid API key."},"402":{"description":"Memory storage limit reached."}}}},"/api/tool/camera-stream/detections":{"post":{"tags":["Vision tools"],"summary":"Detections in camera feed","description":"Runs open-vocabulary object detection on a single frame. Exposes the same knobs as the Live Monitor config form: labels to detect (`prompts`), confidence cutoff, alert labels, and an optional natural-language question about the scene.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image_url":{"type":"string","format":"uri","description":"HTTPS URL of the image/frame to analyze."},"image_base64":{"type":"string","description":"Raw base64 image data or a data: URL."},"prompts":{"type":"array","items":{"type":"string"},"description":"Labels to detect (e.g. ['person','vehicle','fire']). Same as the form's Analysis Prompt."},"confidence_threshold":{"type":"number","minimum":0,"maximum":1,"description":"Drop detections below this score. 0.15 is a reasonable default."},"alert_triggers":{"type":"array","items":{"type":"string"},"description":"Labels that should be flagged as alerts. Matching detections come back with `is_alert: true` and also appear in a top-level `alerts[]` convenience list."},"ask_question":{"type":"string","description":"Optional natural-language question about the scene. When set, a VLM response is returned under `scene_analysis`."},"max_detections":{"type":"integer","description":"Advanced: cap on returned boxes."},"max_dimension":{"type":"integer","description":"Advanced: resize the input so the longer edge matches this."}}},"examples":{"basic":{"summary":"Basic detection","value":{"image_url":"https://example.com/frame.jpg","prompts":["person","car"]}},"withAlerts":{"summary":"With alerts","value":{"image_url":"https://example.com/frame.jpg","prompts":["person","fire","smoke","car"],"alert_triggers":["fire","smoke"],"confidence_threshold":0.25}},"withQuestion":{"summary":"With scene question","value":{"image_url":"https://example.com/frame.jpg","prompts":["person","vehicle"],"ask_question":"Is anything unusual happening in the frame?"}}}}}},"responses":{"200":{"description":"Detection result, optionally with `alerts[]` and `scene_analysis`."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Memory storage limit reached."}}}},"/api/world-model/verify":{"post":{"tags":["Verification"],"summary":"Verify any token or receipt","description":"One door for every token shape: `emem:fact:<cell64>:<cid>`, `emem:bundle:…`, `moment:<id>`, `card:<cid>`, `lineage:<kind>:<id>`, or a bare content id. Send `token` OR `receipt`, not both: a receipt cannot vouch for a token it does not carry, so the pair is refused with 400. Returns `matches` (the verdict), `checked` (whether a check actually ran), `value_verbatim`, `drift`, `signer` and `reason`. A pass is never painted on evidence that was not examined.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"A citation handle."},"receipt":{"type":"object","description":"An inline signed receipt."},"schema_cid":{"type":"string","description":"Required for an emem receipt."},"claimed_value":{"description":"Optional. Enables the drift check."}}}}}},"responses":{"200":{"description":"A verdict. `matches:null` with `checked:false` means the verifier was unreachable and nothing was checked."},"400":{"description":"Neither token nor receipt supplied, or both supplied and unrelated to each other."}}}},"/api/world-model/verify/receipt":{"post":{"tags":["Verification"],"summary":"Re-verify one signed receipt","description":"Checks a geo.qa ed25519 receipt against the published root of trust. The same check runs offline against https://geo.qa/.well-known/geoqa.json with no call to us at all.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"receipt":{"type":"object"}},"required":["receipt"]}}}},"responses":{"200":{"description":"{valid, reason, pubkey_b32}"}}}},"/api/world-model/verify/batch":{"post":{"tags":["Verification"],"summary":"Re-verify up to 256 receipts","description":"Over the limit is refused, never truncated: answering about the first 256 of 260 would read as a full pass to anyone comparing `valid` to `count`. The response carries `submitted` and `complete` for the same reason.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"receipts":{"type":"array","items":{"type":"object"},"maxItems":256}},"required":["receipts"]}}}},"responses":{"200":{"description":"{results[], count, valid, submitted, complete}"},"413":{"description":"More than 256 receipts. Split the set and call again."}}}},"/api/world-model/verify/log/sth":{"get":{"tags":["Verification"],"summary":"Signed tree head of the transparency log","description":"The anchor inclusion and consistency proofs are checked against. The signed message is the JSON canonicalization of `payload` with sorted keys and no whitespace; `payload_sha256` is an integrity aid, not the signed bytes.","security":[],"responses":{"200":{"description":"{available, log_id, sth}"}}}},"/api/world-model/verify/log/proof/{cid}":{"get":{"tags":["Verification"],"summary":"RFC 6962 inclusion proof for a content id","security":[],"parameters":[{"name":"cid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{found, leaf_index, tree_size, leaf_hash, audit_path[], root_sha256, sth}. `found:false` is a real answer, not an error."}}}},"/api/world-model/verify/log/consistency":{"get":{"tags":["Verification"],"summary":"Proof the log only ever appended","security":[],"parameters":[{"name":"first","in":"query","required":true,"schema":{"type":"integer"}},{"name":"second","in":"query","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"{first_size, second_size, first_root, second_root, consistency_path[], sth}"}}}},"/api/v1/object-detection":{"post":{"tags":["Open tools"],"summary":"Open-vocabulary object detection","description":"Needs no credential. Rate-limited per IP at 30 requests a minute. Give `image_url` or `image_base64` plus the labels to look for.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image_url":{"type":"string"},"image_base64":{"type":"string"},"prompts":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"{detections[], total_objects, image_width, image_height, model}"},"429":{"description":"Rate limit exceeded. Retry-After names the wait."}}}},"/api/mcp":{"post":{"tags":["Open tools"],"summary":"Model Context Protocol endpoint","description":"JSON-RPC 2.0 over Streamable HTTP. `initialize`, `ping` and `tools/list` need no credential; `tools/call detect_objects` does not either. The metered tools answer with the access ladder rather than a bare refusal. Read `tools/list` for the live tool set rather than trusting any list written in prose.","security":[],"responses":{"200":{"description":"A JSON-RPC response. A metered tool refused for credentials still returns 200 with the challenge as the tool result, and WWW-Authenticate on the response."},"429":{"description":"Rate limit exceeded. 120/min for reads, 30/min for tools/call, per IP."}}},"get":{"tags":["Open tools"],"summary":"MCP server descriptor","security":[],"responses":{"200":{"description":"Endpoint, tools, docs, payment status."}}}}},"security":[{"BearerAuth":[]}],"components":{"schemas":{"AgriChatMessage":{"properties":{"role":{"type":"string","title":"Role","description":"system | user | assistant"},"content":{"type":"string","title":"Content","description":"Message content"}},"type":"object","required":["role","content"],"title":"AgriChatMessage"},"AgriChatRequest":{"properties":{"messages":{"items":{"$ref":"#/components/schemas/AgriChatMessage"},"type":"array","title":"Messages","description":"Conversation history"},"latent_context":{"items":{"$ref":"#/components/schemas/AgriLatentContextVector"},"type":"array","title":"Latent Context","description":"Up to 32 retrieved 1270D vectors to ground the response"},"scenario":{"type":"string","title":"Scenario","description":"normal|drought|flood|urbanization|reforestation|irrigation|deforestation|climate_shift|auto","default":"auto"},"temperature":{"type":"number","maximum":2,"minimum":0,"title":"Temperature","default":0.4},"max_tokens":{"type":"integer","maximum":4096,"minimum":1,"title":"Max Tokens","default":1024},"stream":{"type":"boolean","title":"Stream","description":"Stream response via SSE","default":true}},"type":"object","required":["messages"],"title":"AgriChatRequest"},"AgriJepaAnomalyRequest":{"properties":{"state":{"items":{"type":"number"},"type":"array","title":"State","description":"1270D state under test"},"reference_memories":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Reference Memories","description":"Bank of 1270D vectors to score against"}},"type":"object","required":["state","reference_memories"],"title":"AgriJepaAnomalyRequest"},"AgriJepaPredictRequest":{"properties":{"state":{"items":{"type":"number"},"type":"array","title":"State","description":"Current 1270D state vector"},"scenarios":{"items":{"type":"string"},"type":"array","title":"Scenarios","description":"Scenarios to predict under"},"horizons":{"items":{"type":"number"},"type":"array","title":"Horizons","description":"Time horizons (abstract units)"},"reference_memories":{"anyOf":[{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},{"type":"null"}],"title":"Reference Memories","description":"Optional bank of 1270D memory vectors for nearest-match lookup"}},"type":"object","required":["state"],"title":"AgriJepaPredictRequest"},"AgriLatentContextVector":{"properties":{"embedding":{"items":{"type":"number"},"type":"array","title":"Embedding","description":"1270D latent vector"},"weight":{"type":"number","title":"Weight","description":"Relative weight for this vector","default":1},"memory_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Memory Id","description":"Client-side id for this memory"},"provenance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provenance","description":"e.g. memory | region | farm"}},"type":"object","required":["embedding"],"title":"AgriLatentContextVector"},"AgriMultisourceInput":{"properties":{"pixel_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pixel Id","description":"Optional client-side id for this pixel"},"geotessera":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Geotessera","description":"128 floats (GeoTessera)"},"alphaearth":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Alphaearth","description":"192 floats (AlphaEarth, 3yr × 64D)"},"sentinel2":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Sentinel2","description":"64 floats (Sentinel-2)"},"sentinel1":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Sentinel1","description":"64 floats (Sentinel-1)"},"spatial":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Spatial","description":"96 floats (spatial Fourier)"},"temporal":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Temporal","description":"64 floats (temporal encoding)"},"sam3_visual":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Sam3 Visual","description":"192 floats (SAM3 visual)"},"qwen_visual":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Qwen Visual","description":"192 floats (Qwen2-VL visual)"},"terrain_climate":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Terrain Climate","description":"32 floats (terrain + climate)"}},"type":"object","title":"AgriMultisourceInput"},"AgriMultisourceRequest":{"properties":{"inputs":{"items":{"$ref":"#/components/schemas/AgriMultisourceInput"},"type":"array","title":"Inputs","description":"Up to 256 pixels per request; any subset of slots per pixel"},"normalize":{"type":"boolean","title":"Normalize","description":"L2 normalise the output 1270D vectors","default":true}},"type":"object","required":["inputs"],"title":"AgriMultisourceRequest"},"AnnounceBody":{"properties":{"name":{"type":"string","title":"Name","description":"Peer's unique name, e.g. 'geoqa-ui'"},"role":{"type":"string","title":"Role","description":"backend | ui | other","default":"ui"},"base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Url","description":"Where this peer can be reached"},"manifest":{"additionalProperties":true,"type":"object","title":"Manifest","description":"Peer's own capability manifest"}},"type":"object","required":["name"],"title":"AnnounceBody"},"BiEncoderRequest":{"properties":{"texts":{"items":{"type":"string"},"type":"array","title":"Texts","description":"Texts to embed"},"model_name":{"type":"string","title":"Model Name","description":"Embedding model","default":"nomic-ai/nomic-embed-text-v1"},"max_context_length":{"type":"integer","title":"Max Context Length","description":"Max token length","default":512},"normalize_embeddings":{"type":"boolean","title":"Normalize Embeddings","description":"Normalize vectors","default":true},"text_type":{"type":"string","title":"Text Type","description":"'query' or 'passage'","default":"query"}},"type":"object","required":["texts"],"title":"BiEncoderRequest","description":"Text embedding request."},"Body_detect_masks_upload_detect_masks_upload_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"Image file to analyze"},"prompts":{"type":"string","title":"Prompts","description":"Comma-separated objects to detect","default":"building,road,vehicle,person,tree,water"}},"type":"object","required":["file"],"title":"Body_detect_masks_upload_detect_masks_upload_post"},"Body_detect_upload_detect_upload_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"Image file to analyze"},"prompts":{"type":"string","title":"Prompts","description":"Comma-separated objects to detect","default":"building,road,vehicle,person,tree,water"}},"type":"object","required":["file"],"title":"Body_detect_upload_detect_upload_post"},"Body_scene_upload_scene_upload_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"Image file to analyze"},"question":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Question","description":"Optional question about the image"}},"type":"object","required":["file"],"title":"Body_scene_upload_scene_upload_post"},"BoundingBoxRequest":{"properties":{"min_lat":{"type":"number","title":"Min Lat","description":"Minimum latitude (south)"},"min_lon":{"type":"number","title":"Min Lon","description":"Minimum longitude (west)"},"max_lat":{"type":"number","title":"Max Lat","description":"Maximum latitude (north)"},"max_lon":{"type":"number","title":"Max Lon","description":"Maximum longitude (east)"},"grid_size":{"type":"integer","maximum":20,"minimum":2,"title":"Grid Size","description":"Grid size (2-20 points per side)","default":5}},"type":"object","required":["min_lat","min_lon","max_lat","max_lon"],"title":"BoundingBoxRequest","description":"Bounding box area request."},"ContractCreate":{"properties":{"from_peer":{"type":"string","title":"From Peer","description":"Who is filing this (peer name)"},"to_role":{"type":"string","title":"To Role","description":"Who should act: backend | ui | any","default":"backend"},"kind":{"type":"string","title":"Kind","description":"need | offer | feature | bug | question","default":"need"},"title":{"type":"string","title":"Title","description":"Short imperative title"},"spec":{"additionalProperties":true,"type":"object","title":"Spec","description":"Structured detail: desired endpoint, shape, example, acceptance"},"priority":{"type":"string","title":"Priority","description":"low | normal | high | urgent","default":"normal"}},"type":"object","required":["from_peer","title"],"title":"ContractCreate"},"ContractPatch":{"properties":{"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"open|ack|in_progress|delivered|closed|rejected"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note","description":"Progress note appended to history"},"spec":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Spec","description":"Replace/augment the spec"},"priority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priority"},"actor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Actor","description":"Who is updating (peer name)"}},"type":"object","title":"ContractPatch"},"CrossEncoderRequest":{"properties":{"query":{"type":"string","title":"Query","description":"Query text"},"documents":{"items":{"type":"string"},"type":"array","title":"Documents","description":"Documents to rerank"},"model_name":{"type":"string","title":"Model Name","description":"Reranking model","default":"mixedbread-ai/mxbai-rerank-xsmall-v1"}},"type":"object","required":["query","documents"],"title":"CrossEncoderRequest","description":"Document reranking request."},"DatasetCreate":{"properties":{"name":{"type":"string","title":"Name"},"uri":{"type":"string","title":"Uri","description":"Path/URI to the dataset (tenant-namespaced JSONL)"},"schema_json":{"additionalProperties":true,"type":"object","title":"Schema Json","description":"Optional: {format: 'chat'|'prompt_completion'|'geo_cube'} for validation"},"dim":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dim","description":"Declared latent dim for geo cubes; validated at ingest"},"ingest":{"type":"boolean","title":"Ingest","description":"If true, an async worker validates+counts the JSONL and streams progress; else register metadata as ready","default":false}},"type":"object","required":["name","uri"],"title":"DatasetCreate"},"DetectionRequest":{"properties":{"image_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Base64","description":"Base64 encoded image"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url","description":"URL to fetch image from"},"prompts":{"items":{"type":"string"},"type":"array","title":"Prompts","description":"Objects to detect","default":["building","road","vehicle","person","tree","water"]}},"type":"object","title":"DetectionRequest","description":"Object detection request."},"GroundedChatReq":{"properties":{"messages":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Messages","description":"[{role,content}] conversation; or use `question`"},"question":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Question","description":"single-turn question (alt to messages)"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"},"cell64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cell64"},"alert_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alert Id","description":"ground on a specific SIGNED alert's evidence (e.g. an incident representative) — the answer explains that spike + cites the alert receipt"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"registry model id (default: the platform chat model)"},"max_tokens":{"type":"integer","maximum":2048,"minimum":1,"title":"Max Tokens","default":512},"temperature":{"type":"number","maximum":2,"minimum":0,"title":"Temperature","default":0.2},"stream":{"type":"boolean","title":"Stream","description":"SSE-stream the grounded answer (first event carries the signed facts)","default":false}},"type":"object","title":"GroundedChatReq","description":"Grounded conversational chat over a location's SIGNED facts, via the real serving stack."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"JobCreate":{"properties":{"family":{"type":"string","title":"Family","description":"qwen | gemma"},"base_model":{"type":"string","title":"Base Model","description":"HF base id, e.g. Qwen/Qwen2.5-7B-Instruct or google/gemma-4-E2B-it"},"model_id":{"type":"string","title":"Model Id","description":"Id to register the resulting finetuned model under"},"dataset_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dataset Id","description":"Dataset uuid (optional)"},"hyperparams":{"additionalProperties":true,"type":"object","title":"Hyperparams","description":"e.g. {epochs: 1, lr: 2e-4, phases: [3]}"}},"type":"object","required":["family","base_model","model_id"],"title":"JobCreate"},"LLMChatRequest":{"properties":{"messages":{"items":{"$ref":"#/components/schemas/LLMMessage"},"type":"array","title":"Messages","description":"Conversation messages"},"model":{"type":"string","title":"Model","description":"Registry model id (see GET /v1/models). Defaults to the platform default chat model."},"temperature":{"type":"number","maximum":2,"minimum":0,"title":"Temperature","description":"Sampling temperature","default":0.7},"max_tokens":{"type":"integer","maximum":32768,"minimum":1,"title":"Max Tokens","description":"Max tokens to generate","default":4096},"stream":{"type":"boolean","title":"Stream","description":"Stream the response as SSE","default":false}},"type":"object","required":["messages"],"title":"LLMChatRequest","description":"Chat completion request."},"LLMMessage":{"properties":{"role":{"type":"string","title":"Role","description":"Role: system, user, or assistant"},"content":{"type":"string","title":"Content","description":"Message content"}},"type":"object","required":["role","content"],"title":"LLMMessage","description":"A single chat message."},"LLMPromptRequest":{"properties":{"prompt":{"type":"string","title":"Prompt","description":"User prompt text"},"system":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System","description":"Optional system prompt"},"model":{"type":"string","title":"Model","description":"Registry model id (see GET /v1/models). Defaults to the platform default chat model."},"temperature":{"type":"number","maximum":2,"minimum":0,"title":"Temperature","default":0.7},"max_tokens":{"type":"integer","maximum":32768,"minimum":1,"title":"Max Tokens","default":4096}},"type":"object","required":["prompt"],"title":"LLMPromptRequest","description":"Simple prompt request."},"PolygonRequest":{"properties":{"coordinates":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","minItems":3,"title":"Coordinates","description":"List of [lat, lon] coordinates forming the polygon"},"sample_points":{"type":"integer","maximum":100,"minimum":4,"title":"Sample Points","description":"Number of sample points (4-100)","default":25}},"type":"object","required":["coordinates"],"title":"PolygonRequest","description":"Polygon area request."},"QueryAnalysisRequest":{"properties":{"query":{"type":"string","title":"Query","description":"Query to analyze"},"semantic_percent_threshold":{"type":"number","title":"Semantic Percent Threshold","default":0.5},"keyword_percent_threshold":{"type":"number","title":"Keyword Percent Threshold","default":0.5}},"type":"object","required":["query"],"title":"QueryAnalysisRequest","description":"Query analysis request."},"SceneRequest":{"properties":{"image_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Base64","description":"Base64 encoded image"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url","description":"URL to fetch image from"},"question":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Question","description":"Optional question about the image"}},"type":"object","title":"SceneRequest","description":"Scene understanding request."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WeatherSimulateRequest":{"properties":{"image":{"type":"string","title":"Image","description":"Base64-encoded JPEG or PNG tile"},"preset":{"type":"string","title":"Preset","description":"Weather preset: sunny, overcast, rain, night, fog, snow, dusk"},"tx":{"type":"integer","title":"Tx","description":"Tile X coordinate (noise seed)","default":0},"ty":{"type":"integer","title":"Ty","description":"Tile Y coordinate (noise seed)","default":0},"z":{"type":"integer","title":"Z","description":"Zoom level","default":17},"airport_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Airport Code","description":"Airport code for night lighting (e.g. 'BLR'). Falls back to generic glow if null."}},"type":"object","required":["image","preset"],"title":"WeatherSimulateRequest","description":"Weather simulation request for satellite imagery UI."},"WeatherTileRequest":{"properties":{"preset":{"type":"string","title":"Preset","description":"Weather preset: sunny, overcast, rain, night, fog, snow, dusk"},"airport_code":{"type":"string","title":"Airport Code","description":"Airport code for lighting maps","default":"MIA"},"z":{"type":"integer","title":"Z","description":"Zoom level","default":17},"x":{"type":"integer","title":"X","description":"Tile X coordinate","default":0},"y":{"type":"integer","title":"Y","description":"Tile Y coordinate","default":0},"tile_png":{"type":"string","title":"Tile Png","description":"256x256 PNG tile as base64"}},"type":"object","required":["preset","tile_png"],"title":"WeatherTileRequest","description":"Weather tile rendering request."}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"on_…","description":"Generate a key above. Use it as `Authorization: Bearer on_…`. Keys are scoped to the public API only — they cannot access admin endpoints."}}},"x-spec-source":"static-fallback"}