API Overview

The Geog API provides vector tile serving and geo-constrained places search, deployed at the edge for global distribution.

Base URL

https://api.geog.dev

Authentication

All API requests (except health check and JWKS) require a Bearer JWT token:

curl -X POST "https://api.geog.dev/v1/places/search" \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{"location": {"lat": 37.7749, "lon": -122.4194}, "radius": 5000, "query": "coffee shop"}'

API tokens are self-issued JWTs created in the GEOG console. For frontend applications, exchange long-lived tokens for short-lived access tokens via the Token Exchange endpoint.

Rate Limiting

Free tier organizations have daily rate limits:

Endpoint TypeDaily Limit
Vector Tiles2,000
Places API1,000

Limits reset daily at 00:00 UTC. Paid plans have no rate limits.

Rate limit headers are included on free tier responses:

X-RateLimit-Tiles-Limit: 2000
X-RateLimit-Tiles-Remaining: 1999
X-RateLimit-Tiles-Reset: 2025-01-02T00:00:00.000Z

Endpoints

Places API

Search Places

POST/v1/places/search

Geo-constrained hybrid text and geographic search. Requires places:read scope.

Request Body (JSON):

  • location (required) — Geographic center point: { "lat": number, "lon": number }
  • radius (optional) — Search radius in meters (1–100,000, default: 5000)
  • query (optional) — Text search query (e.g., "coffee shops")
  • categories (optional) — Filter by categories: ["restaurant", "cafe"]
  • limit (optional) — Results limit (1–1,000, default: 20)
  • offset (optional) — Pagination offset (default: 0)
  • weights (optional) — Scoring weights: { "text": 0.6, "geo": 0.4 }

Get Place by ID

GET/v1/places/{placeId}

Get detailed information about a specific place. Requires places:read scope.

Vector Tiles API

Get Tile

GET/v1/tiles/{tileset}/{z}/{x}/{y}.{ext}

Retrieve vector tiles in MVT/PBF format. Requires tiles:read scope.

Parameters:

  • tileset — Tileset identifier (currently basemap)
  • z — Zoom level
  • x — Tile column
  • y — Tile row
  • ext — Format: mvt or pbf

Get Tileset Metadata

GET/v1/tiles/{tileset}/metadata

Returns TileJSON metadata for the tileset. Requires tiles:read scope.

Token Exchange

POST/v1/auth/token

Exchange a long-lived API token for a short-lived access token (1s–4 hours) for secure frontend use.

Rate Limit Usage

GET/v1/rate-limit/usage

Check current rate limit usage for your organization.

Response Format

{
	"results": [
		{
			"id": "8529a1003ffffff_n456789012",
			"name": "Blue Bottle Coffee",
			"categories": ["cafe", "coffee_shop"],
			"location": { "lat": 37.7849, "lon": -122.4088 },
			"address": {
				"housenumber": "66",
				"street": "Mint St",
				"city": "San Francisco",
				"state": "California",
				"postcode": "94103"
			},
			"contact": { "phone": "+14158438220", "website": "https://bluebottlecoffee.com" },
			"brand": { "name": "Blue Bottle Coffee" },
			"score": 0.95,
			"distance": 1250,
			"confidence": 0.98,
			"scores": { "text": 0.92, "geo": 0.98 }
		}
	],
	"total": 245,
	"executionTime": 42,
	"metadata": { "shardsSearched": 3, "cacheHit": false },
	"queryStats": { "pruningEfficiency": 0.85, "cellsSearched": 3 }
}

Error Response

{
	"error": "invalid_request",
	"message": "Missing required parameter: location",
	"code": "GEO_CONSTRAINT_REQUIRED"
}

HTTP Status Codes

  • 200 — Success
  • 204 — No Content (empty tile)
  • 400 — Bad Request (invalid parameters)
  • 401 — Unauthorized (missing or invalid token)
  • 403 — Forbidden (insufficient scope or wrong organization)
  • 404 — Not Found
  • 429 — Rate Limit Exceeded (free tier)
  • 500 — Internal Server Error
  • 503 — Service Unavailable

See Also