# geolith demo > A public live demo of the geolith cloud geocoding API. Type an address or a place anywhere in the world and see it on a map; click the map for reverse geocoding. Each request shows its URL, the time measured in the browser and the raw JSON answer. geolith cloud is hosted geocoding and vector tiles on Cloudflare's edge. Its data comes from OpenStreetMap and Overture Maps only. Attribution is required: "© OpenStreetMap contributors (ODbL), Overture Maps Foundation". Results may be stored permanently. ## What the demo does - Autocomplete on every keystroke (`/v1/autocomplete`), full search on Enter (`/v1/search`). - Click the map: the nearest places (`/v1/reverse`). - Select a result: the map flies to it and draws its outline when it has one (`/v1/place?geometry=true`). - Filters: rank near the map centre (`focus.point.lat`, `focus.point.lon`), one country (`boundary.country`, ISO 3166-1 alpha-2), one layer (`layers`). - Copy-paste code for the current request (fetch or curl). ## The API - Base URL: https://api.geolith.app - Key: `?api_key=` or `Authorization: Bearer`. Publishable keys are locked to allowed origins (browser use); secret keys are for servers. - `GET /v1/search?text=` forward geocoding - `GET /v1/autocomplete?text=` search as you type - `GET /v1/reverse?point.lat=&point.lon=` nearest places to a point - `GET /v1/place?ids=` places by id; `geometry=true` returns the place outline - Optional: `focus.point.lat`, `focus.point.lon`, `boundary.country`, `layers` (venue, address, street, locality, county, region, country), `size` - Answers are GeoJSON FeatureCollections; each feature has `gid`, `name`, `label`, `layer` and address parts in `properties`. ## Plans - Free: $0, 100,000 requests a month, commercial use with attribution - Starter: $19 a month, 1,000,000 requests - Growth: $99 a month, 7,500,000 requests - Scale: $299 a month, 25,000,000 requests - Over quota, requests stop (429) until the month ends or you upgrade. ## For agents - [How to geocode with geolith](https://demo.geolith.app/.well-known/agent-skills/geolith-geocoding/SKILL.md): REST, MCP and A2A - [MCP server](https://api.geolith.app/mcp): Streamable HTTP; [server card](https://demo.geolith.app/.well-known/mcp/server-card.json) - [A2A agent](https://api.geolith.app/a2a): [agent card](https://demo.geolith.app/.well-known/agent-card.json) - [auth.md](https://console.geolith.app/auth.md): register an agent with OAuth 2.1 - WebMCP: this page registers `search_places`, `reverse_geocode` and `get_place` tools for in-browser agents. ## Links - [Get a free API key](https://console.geolith.app/signup) - [API documentation](https://docs.search.geolith.app) - [geolith](https://geolith.app) --- --- name: geolith-geocoding description: Geocode with geolith — turn place names and addresses into coordinates, coordinates into addresses, and fetch place outlines, over REST or MCP. Use when a task needs latitude/longitude for a place, the address at a point, or a place's polygon. --- # Geocode with geolith geolith answers forward geocoding, autocomplete, structured address search, reverse geocoding and place lookup over OpenStreetMap and Overture Maps data. Answers are GeoJSON FeatureCollections (`features[].geometry.coordinates` is `[lon, lat]`; `properties.label` is a display string; `properties.gid` identifies the place). ## 1. Get a credential Either: - **API key** — sign up at https://console.geolith.app/signup, then create a key at https://console.geolith.app/dashboard/keys. Send it as `Authorization: Bearer gc_sk_…` or `?api_key=gc_sk_…`. - **OAuth 2.1** — register as a client and get an access token for resource `https://api.geolith.app/mcp` (MCP) or `https://api.geolith.app` (REST) with scope `geocode`. The steps are in https://console.geolith.app/auth.md. The Free plan allows 100,000 requests a month. Every geocoding call or tool call counts as one request. `X-Quota-Remaining` reports what is left. ## 2a. REST | Task | Request | | --- | --- | | Search | `GET https://api.geolith.app/v1/search?text=gateway+of+india&size=3` | | Autocomplete | `GET https://api.geolith.app/v1/autocomplete?text=koramang` | | Structured | `GET https://api.geolith.app/v1/search/structured?locality=pune&country=IN` | | Reverse | `GET https://api.geolith.app/v1/reverse?point.lat=18.5195&point.lon=73.8553` | | Place + outline | `GET https://api.geolith.app/v1/place?ids=&geometry=true` | Common filters: `size` (1–40), `layers` (venue, address, street, neighbourhood, locality, county, region, country…), `boundary.country` (ISO alpha-2), `focus.point.lat` / `focus.point.lon`. Full reference: https://docs.search.geolith.app/openapi.json (OpenAPI 3.1) and https://docs.search.geolith.app. ```bash curl -H "Authorization: Bearer $GEOLITH_KEY" "https://api.geolith.app/v1/search?text=india+gate&size=1" ``` ## 2b. MCP Remote MCP server (Streamable HTTP): `https://api.geolith.app/mcp`. Authenticate with the same API key (`Authorization: Bearer gc_sk_…`) or an OAuth access token; an unauthenticated request gets a 401 whose `WWW-Authenticate` header points at the OAuth metadata. Tools: `search`, `autocomplete`, `structured_search`, `reverse`, `place` (set `geometry: true` for outlines). Each returns the FeatureCollection as `structuredContent` and as JSON text. ## 2c. A2A A2A 1.0 agent (JSON-RPC): `https://api.geolith.app/a2a`, card at `https://api.geolith.app/.well-known/agent-card.json`. Send `SendMessage` with a text part (a place name, or `"lat, lon"` to reverse-geocode) or a data part `{ "operation": "search", "params": { "text": "…" } }`. ## Rules - Show "© OpenStreetMap contributors, Overture Maps Foundation" wherever results appear. - Storing results permanently is allowed on every plan. - Errors: 401 missing or invalid credential, 403 origin not allowed (publishable keys) or missing scope, 429 rate limit (`Retry-After`) or monthly quota used up. --- # geolith auth.md You are an agent. This service supports **agentic registration**: discover → register → authorize (a person claims you) → exchange the code for an access token → call the API → handle revocation. Follow the steps in order; do not skip ahead. The resource server is `https://api.geolith.app` (REST at `/v1/*`, MCP at `/mcp`, A2A at `/a2a`). The authorization server is `https://console.geolith.app`. ## Step 1 — Discover A request without a credential gets a 401 with `WWW-Authenticate: Bearer resource_metadata="https://api.geolith.app/.well-known/oauth-protected-resource/mcp", scope="geocode"`. 1. Fetch the Protected Resource Metadata (RFC 9728): `https://api.geolith.app/.well-known/oauth-protected-resource/mcp` for MCP, `https://api.geolith.app/.well-known/oauth-protected-resource` for REST. `authorization_servers` is `["https://console.geolith.app"]`. 2. Fetch the Authorization Server metadata (RFC 8414): `https://console.geolith.app/.well-known/oauth-authorization-server`. Its `agent_auth` block carries this skill (`skill`), the registration endpoint (`register_uri`), `identity_types_supported: ["anonymous"]`, and `anonymous.claim_uri`. ## Step 2 — Register Dynamic Client Registration (RFC 7591). POST your client metadata to `register_uri` (`https://console.geolith.app/api/auth/oauth2/register`); no initial access token is needed: ```http POST https://console.geolith.app/api/auth/oauth2/register Content-Type: application/json {"client_name": "My agent", "redirect_uris": ["http://127.0.0.1:33418/callback"], "token_endpoint_auth_method": "none", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "scope": "openid offline_access geocode"} ``` Keep the returned `client_id`. Public clients (`token_endpoint_auth_method: "none"`) must use PKCE. ## Step 3 — Authorize (claim) Send the person who owns the geolith account to the authorization endpoint with PKCE (S256) and the resource you will call: ``` https://console.geolith.app/api/auth/oauth2/authorize?response_type=code&client_id=&redirect_uri=&scope=openid%20offline_access%20geocode&resource=https%3A%2F%2Fapi.geolith.app%2Fmcp&code_challenge=&code_challenge_method=S256&state= ``` They sign in (or create a free account) at https://console.geolith.app and approve your client on the consent screen. This claims your anonymous registration for their account; usage then counts against their monthly quota. They can see and revoke approved agents at https://console.geolith.app/dashboard/settings (the `claim_uri`). ## Step 4 — Exchange POST the code to the token endpoint `https://console.geolith.app/api/auth/oauth2/token`: ``` grant_type=authorization_code&code=&redirect_uri=&client_id=&code_verifier=&resource=https%3A%2F%2Fapi.geolith.app%2Fmcp ``` The access token is a JWT (one hour) signed with the keys at `https://console.geolith.app/api/auth/jwks`; `offline_access` also returns a refresh token. Use `resource=https://api.geolith.app` instead for the REST API. ## Step 5 — Use the access token Call the API with `Authorization: Bearer ` (or `DPoP` with a proof if you bound the token): - MCP: `POST https://api.geolith.app/mcp` (Streamable HTTP; tools `search`, `autocomplete`, `structured_search`, `reverse`, `place`). - REST: `GET https://api.geolith.app/v1/search?text=…` (OpenAPI: https://docs.search.geolith.app/openapi.json). Every call counts as one request against the account's monthly quota; `429` means the rate limit (see `Retry-After`) or the quota is used up. To read the account's plan and this month's usage, ask for scope `usage` with `resource=https://console.geolith.app` and call `GET https://console.geolith.app/api/v1/usage` (metadata: `https://console.geolith.app/.well-known/oauth-protected-resource`). ## Alternative — API key A person can create an API key at https://console.geolith.app/dashboard/keys and give it to you. Send it as `Authorization: Bearer gc_sk_…`. Keys work for REST, MCP and A2A. ## Revocation Revoke tokens at the revocation endpoint (RFC 7009): `POST https://console.geolith.app/api/auth/oauth2/revoke` with `token` and `client_id`. When a person revokes your client at https://console.geolith.app/dashboard/settings, refreshing fails; access tokens already issued expire within an hour. Start again at Step 3 if you get `401 invalid_token`.