Geo Service

Mushu Geo provides location services for building location-aware features: timezone lookup, place autocomplete, and reverse geocoding.

Endpoints Overview

MethodEndpointAuthPriceDescription
POST/location/timezoneNoneFreeGet timezone from coordinates
POST/location/autocompleteAPI Key$0.001Place/address autocomplete
POST/location/reverseAPI Key$0.001Coordinates to address

Timezone Lookup

Free endpoint. No authentication or API key required.

Get the IANA timezone and current UTC offset for any coordinates:

curl -X POST https://geo.mushucorp.com/location/timezone \
  -H "Content-Type: application/json" \
  -d '{
    "lat": 37.7749,
    "lng": -122.4194
  }'

Response:

{
  "timezone": "America/Los_Angeles",
  "utc_offset_hours": -8.0
}

The timezone lookup uses a local database (no external API calls), making it fast and free. Works for any land coordinates worldwide.

Place Autocomplete

Requires API key. Billed at $0.001 per search.

Search for places and addresses with autocomplete suggestions:

curl -X POST https://geo.mushucorp.com/location/autocomplete \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key" \
  -d '{
    "query": "starbucks san francisco",
    "lat": 37.7749,
    "lng": -122.4194,
    "limit": 5
  }'

Response:

{
  "suggestions": [
    {
      "place_name": "Starbucks, 123 Market St, San Francisco, CA 94103",
      "text": "Starbucks",
      "place_type": ["poi"],
      "lat": 37.7751,
      "lng": -122.4180,
      "context": {
        "place": "San Francisco",
        "region": "California",
        "country": "United States"
      }
    }
  ],
  "cached": false
}

Parameters

FieldTypeRequiredDescription
querystringYesSearch query (1-200 chars)
latnumberNoBias results near this latitude
lngnumberNoBias results near this longitude
limitintegerNoMax results (1-10, default 5)
languagestringNoLanguage code (default "en")

Reverse Geocoding

Requires API key. Billed at $0.001 per lookup.

Convert coordinates to human-readable addresses:

curl -X POST https://geo.mushucorp.com/location/reverse \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key" \
  -d '{
    "lat": 37.7749,
    "lng": -122.4194
  }'

Response:

{
  "locations": [
    {
      "place_name": "123 Main St, San Francisco, CA 94105, USA",
      "text": "123 Main St",
      "place_type": ["address"],
      "address": "123",
      "city": "San Francisco",
      "region": "California",
      "country": "United States",
      "postal_code": "94105"
    }
  ],
  "cached": false
}

Caching

Autocomplete and reverse geocoding results are cached for 7 days to reduce costs. The cached field indicates whether the response came from cache. You are billed the same rate regardless of cache status.


Use Cases

  • Timezone handling - Display local times for users based on their coordinates
  • Address search - Let users search for places with autocomplete
  • Location display - Show human-readable addresses for coordinates

Geo Search

A geo-indexed datastore for text + location search. Store items with coordinates and search by "running groups near me" - combining full-text search with geo proximity in a single query.

Hosted at geosearch.mushucorp.com - A separate service optimized for geo queries.

Geo Search Endpoints

MethodEndpointPriceDescription
GET/{collection}FreeList items (paginated)
PUT/{collection}/{id}$0.0001Create/update item
GET/{collection}/{id}FreeGet single item
DELETE/{collection}/{id}FreeDelete item
POST/{collection}/search$0.0005Text + geo + tag search
POST/{collection}/nearest$0.0005Nearest N items

Store an Item

curl -X PUT https://geosearch.mushucorp.com/groups/group-123 \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key" \
  -d '{
    "name": "SF Running Club",
    "description": "Weekly runs in Golden Gate Park",
    "tags": ["running", "fitness", "outdoor"],
    "lat": 37.7694,
    "lng": -122.4862,
    "data": {
      "members": 42,
      "schedule": "Saturdays 9am"
    }
  }'

Response:

{
  "id": "group-123",
  "collection": "groups",
  "status": "ok"
}

List Items

List all items in a collection with cursor-based pagination:

curl -X GET "https://geosearch.mushucorp.com/groups?limit=100" \
  -H "X-API-Key: your_api_key"

Response:

{
  "items": [...],
  "count": 100,
  "next_cursor": "eyJsYXN0X2lkIjoiZ3JvdXAtMTAwIn0="
}

To fetch the next page, pass the cursor:

curl -X GET "https://geosearch.mushucorp.com/groups?limit=100&cursor=eyJsYXN0X2lkIjoiZ3JvdXAtMTAwIn0=" \
  -H "X-API-Key: your_api_key"

Search Items

Search by text, location, and/or tags:

curl -X POST https://geosearch.mushucorp.com/groups/search \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key" \
  -d '{
    "lat": 37.7749,
    "lng": -122.4194,
    "radius_km": 10,
    "text": "running",
    "tags": ["outdoor"],
    "limit": 20
  }'

Response:

{
  "items": [
    {
      "id": "group-123",
      "collection": "groups",
      "name": "SF Running Club",
      "description": "Weekly runs in Golden Gate Park",
      "tags": ["running", "fitness", "outdoor"],
      "lat": 37.7694,
      "lng": -122.4862,
      "distance_km": 3.21,
      "data": {"members": 42, "schedule": "Saturdays 9am"}
    }
  ],
  "count": 1,
  "next_cursor": null
}

Search Parameters

FieldTypeRequiredDescription
latnumberYesSearch center latitude
lngnumberYesSearch center longitude
radius_kmnumberYesSearch radius in km (max 20,000)
textstringNoFull-text search query
tagsarrayNoFilter by tags (AND - all must match)
tags_anyarrayNoFilter by tags (OR - any must match)
limitintegerNoMax results (default 20, max 1000)

Tag Filtering Examples

AND filtering - items must have all specified tags:

{"tags": ["outdoor", "fitness"]} // matches items with BOTH tags

OR filtering - items must have at least one tag:

{"tags_any": ["running", "cycling"]} // matches items with EITHER tag

Combined - AND and OR together:

{"tags": ["outdoor"], "tags_any": ["running", "cycling"]}
// matches: outdoor AND (running OR cycling)

Nearest N Items

Get the closest items to a point (no radius limit). Supports the same tag filtering as search:

curl -X POST https://geosearch.mushucorp.com/groups/nearest \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key" \
  -d '{
    "lat": 37.7749,
    "lng": -122.4194,
    "tags": ["outdoor"],
    "limit": 5
  }'

Item Fields

FieldTypeRequiredDescription
latnumberYesLatitude (-90 to 90)
lngnumberYesLongitude (-180 to 180)
namestringNoItem name (searchable)
descriptionstringNoItem description (searchable)
tagsarrayNoTags for filtering (searchable)
dataobjectNoAdditional JSON data

Python SDK

import mushu
from mushu.geo_search.api.items import put_item, list_items
from mushu.geo_search.api.search import search_items, nearest_items
from mushu.geo_search.models import PutItemRequest, SearchRequest

client = mushu.client("geo_search", api_key="your_api_key")

# Store an item
put_item.sync_detailed(
    collection="groups",
    id="group-123",
    client=client,
    body=PutItemRequest(
        name="SF Running Club",
        lat=37.7694,
        lng=-122.4862,
        tags=["running", "fitness", "outdoor"]
    )
)

# Search nearby with tag filtering
response = search_items.sync_detailed(
    collection="groups",
    client=client,
    body=SearchRequest(
        lat=37.7749,
        lng=-122.4194,
        radius_km=10.0,
        text="running",
        tags=["outdoor"]  # AND: all must match
    )
)

if response.parsed:
    for item in response.parsed.items:
        print(f"{item.name}: {item.distance_km:.2f} km away")

Install the SDK:

pip install mushu

API Reference

Location service: geo.mushucorp.com/docs
Geo search service: geosearch.mushucorp.com