API Documentation
Integrate GeoSeer's geolocation API for media analysis and text-only event analysis, with support for single and batch request shapes.
Quick Start
Choose the request shape that matches your input: media upload, media URL, or text-only event analysis.
# Single file: image or video
curl -X POST https://geoseeer.com/api/v1/analyze \
-H "X-API-Key: YOUR_API_KEY" \
-F "file=@/path/to/media.jpg" \
-F "analysis_mode=fast"Response Format
Canonical success responses return locations plus API_Requests_remaining.
{
"status": "success",
"locations": [
{
"latitude": 48.8584,
"longitude": 2.2945,
"confidence": 0.95,
"address": "Eiffel Tower, Paris, France",
"reasoning": "The image shows the Eiffel Tower from Trocadero gardens..."
},
{
"latitude": 48.853,
"longitude": 2.3499,
"confidence": 0.72,
"address": "Notre-Dame, Paris, France",
"reasoning": "Gothic cathedral architecture and urban layout align with Notre-Dame..."
}
],
"processing_time": "45.2s",
"API_Requests_remaining": 67
}Streaming Format
Set stream: true for real-time Server-Sent Events (SSE) updates during analysis.
Event Types
processingProgress updates during analysisbranch_pointParallel branch creation (mostly agent mode, usually absent in fast mode)branch_updateBranch status update (mostly agent mode, usually absent in fast mode)completedFinal result with locations and API_Requests_remainingerrorError occurred during processingSSE application frames use id, event, and data. Keepalive frames are an exception and appear as : keepalive.
Example SSE Events
Show SSE sample
: keepalive
id: 101
event: processing
data: {"type":"progress","message":"Running fast analysis","branch_id":"Satellite Agent","last_event_id":"101"}
id: 102
event: branch_point
data: {"type":"branch_point","branch_point":{"fork_id":"candidate_search_methods","fork_label":"Candidate Search Methods","branches":[{"branch_id":"Search Agent","label":"Web Search","status":"processing"},{"branch_id":"Satellite Agent","label":"Satellite","status":"processing"}]},"last_event_id":"102"}
id: 103
event: branch_update
data: {"type":"branch_update","branch_id":"Search Agent","status":"completed","message":"Found 2 candidates","last_event_id":"103"}
id: 104
event: completed
data: {"type":"complete","result":{"status":"success","locations":[{"latitude":25.7735,"longitude":-80.2859,"address":"Miami, United States","confidence":0.6,"reasoning":"Visual clues suggest a likely match in this region."}],"processing_time":"24.9s","API_Requests_remaining":67},"last_event_id":"104"}: keepalive
id: 101
event: processing
data: {"type":"progress","message":"Running fast analysis","branch_id":"Satellite Agent","last_event_id":"101"}
id: 102
event: branch_point
data: {"type":"branch_point","branch_point":{"fork_id":"candidate_search_methods","fork_label":"Candidate Search Methods","branches":[{"branch_id":"Search Agent","label":"Web Search","status":"processing"},{"branch_id":"Satellite Agent","label":"Satellite","status":"processing"}]},"last_event_id":"102"}
id: 103
event: branch_update
data: {"type":"branch_update","branch_id":"Search Agent","status":"completed","message":"Found 2 candidates","last_event_id":"103"}
id: 104
event: completed
data: {"type":"complete","result":{"status":"success","locations":[{"latitude":25.7735,"longitude":-80.2859,"address":"Miami, United States","confidence":0.6,"reasoning":"Visual clues suggest a likely match in this region."}],"processing_time":"24.9s","API_Requests_remaining":67},"last_event_id":"104"}Implementation Examples
Show implementation sample
import json
import requests
API_KEY = "YOUR_API_KEY"
def analyze_with_streaming(url):
response = requests.post(
"https://geoseeer.com/api/v1/analyze",
headers={
"X-API-Key": API_KEY,
"Content-Type": "application/json"
},
json={"url": url, "analysis_mode": "fast", "stream": True},
stream=True
)
event_type = None
for raw_line in response.iter_lines(decode_unicode=True):
if not raw_line:
continue
if raw_line.startswith("event: "):
event_type = raw_line[7:]
continue
if not raw_line.startswith("data: "):
continue
payload = json.loads(raw_line[6:])
if event_type == "processing":
print(payload.get("message", "Processing"))
elif event_type == "completed":
result = payload.get("result", {})
print(result["locations"][0]["address"])
print("Remaining:", result.get("API_Requests_remaining"))
return result
elif event_type == "error":
raise RuntimeError(payload.get("error", "Streaming error"))import json
import requests
API_KEY = "YOUR_API_KEY"
def analyze_with_streaming(url):
response = requests.post(
"https://geoseeer.com/api/v1/analyze",
headers={
"X-API-Key": API_KEY,
"Content-Type": "application/json"
},
json={"url": url, "analysis_mode": "fast", "stream": True},
stream=True
)
event_type = None
for raw_line in response.iter_lines(decode_unicode=True):
if not raw_line:
continue
if raw_line.startswith("event: "):
event_type = raw_line[7:]
continue
if not raw_line.startswith("data: "):
continue
payload = json.loads(raw_line[6:])
if event_type == "processing":
print(payload.get("message", "Processing"))
elif event_type == "completed":
result = payload.get("result", {})
print(result["locations"][0]["address"])
print("Remaining:", result.get("API_Requests_remaining"))
return result
elif event_type == "error":
raise RuntimeError(payload.get("error", "Streaming error"))Contract Guarantees
API Key
Get your API key from the dashboard to start making requests.
Request Parameters
Contract Guarantees
Supported Formats
Max media items per request: 3.
Max upload size: 10MB.
Use file for a single image or video upload.
Use repeated files fields for multi-image analysis.
URL input keys are url and urls.
Event mode uses event_text only and does not accept media input.
Endpoints
Base URL
https://geoseeer.com/api/v1/analyzeAnalyze media input or text-only event input. Use stream=true for SSE updates and stream=false for a single response.
Error Codes
400Invalid request401Unauthorized402Usage limit reached403Free plan fast mode only413File too large429Queue full500Server error