Open Places API

Blog

Give your AI agent local search

· Open Places API

An abstract AI agent node calling a places API tool and receiving real map pins.

Ask an LLM what’s near 40.71, -74.00 and it will hallucinate a plausible coffee shop. Models don’t know what’s at a coordinate. Agents, though, are excellent at calling tools that do, and place search is close to the ideal agent tool: one GET request, small JSON in, small JSON out, no state.

Here are three ways to wire it up, from zero-code to fully custom.

Option 1: the hosted MCP server

If your agent speaks MCP (Model Context Protocol), like Claude Desktop, Claude Code, and a growing list of others, the fastest path is our hosted MCP server at https://app.openplacesapi.com/mcp. Nothing to install: it exposes one tool, search_places, and authenticates with the same API key the REST endpoint uses.

For Claude Code, it’s one command:

claude mcp add --transport http openplacesapi https://app.openplacesapi.com/mcp \
  --header "Authorization: Bearer opa_live_..."

For clients configured with JSON:

{
  "mcpServers": {
    "openplacesapi": {
      "type": "http",
      "url": "https://app.openplacesapi.com/mcp",
      "headers": { "Authorization": "Bearer opa_live_..." }
    }
  }
}

That’s the whole integration. Your agent can now answer “find a late-night pharmacy near the hotel” with real places, real distances, and real addresses instead of confident fiction.

Option 2: a tool definition for any LLM

No MCP? Most mainstream LLM APIs support tool use with a JSON schema. Describe the endpoint once and let the model fill in the parameters:

{
  "name": "search_places",
  "description": "Search real-world places (businesses, landmarks, venues) near a coordinate. Returns names, addresses, categories, and distances in miles. Coverage: US, CA, MX, GB, IE, DE, FR, IT, ES, JP, KR, SG, MY, DO, CR, PR, JM, and BS.",
  "input_schema": {
    "type": "object",
    "properties": {
      "q": { "type": "string", "description": "What to search for, e.g. 'pharmacy', 'ramen', 'hardware store'. At least 3 characters." },
      "lat": { "type": "number", "description": "Latitude of the search center." },
      "lon": { "type": "number", "description": "Longitude of the search center." },
      "radius_mi": { "type": "number", "description": "Search radius in miles, max 50. Default 25." },
      "limit": { "type": "integer", "description": "Max results, 1-20. Default 10." }
    },
    "required": ["q", "lat", "lon"]
  }
}

When the model calls the tool, your code forwards it:

async function searchPlaces({ q, lat, lon, radius_mi = 25, limit = 10 }) {
  const url = new URL("https://api.openplacesapi.com/v1/places");
  url.search = new URLSearchParams({ q, lat, lon, radius_mi, limit }).toString();
  const response = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.OPEN_PLACES_API_KEY}` },
  });
  const body = await response.json();
  if (!response.ok) return { error: body?.error?.code ?? "search_failed" };
  return body.results;
}

Return the JSON straight back to the model. Results are small and structured, which is exactly what models reason over well.

Option 3: plain HTTP from any framework

LangChain, agent loops, cron-driven workflows: anything that can make an HTTP request can use the API directly. There’s no SDK to wrap because there’s nothing to wrap. One endpoint, bearer auth, JSON back. The API reference and OpenAPI contract cover every parameter, and the error codes are stable and machine-readable, which matters more for agents than for humans.

Teach the agent the failure modes

Agents retry. Tell yours what the errors mean so it retries intelligently instead of hammering:

A sentence in the tool description like “if you receive quota_exhausted, stop and tell the user” saves a surprising amount of grief.

Why flat caps matter for agents specifically

An agent in a retry loop is the most expensive customer usage-based billing ever met. On a per-call platform, a misbehaving loop turns into an invoice; you find out at the end of the month. Here, every plan has a hard cap. The loop hits a 402, the API stops serving, and your bill stays exactly what it said it would be. We stop at the cap, not your invoice. For autonomous systems that’s not a pricing preference, it’s a safety property.

Is this the right tool for your agent?

The tool does proximity search (“what’s near this point”) across 39 million places in 18 countries and territories. It won’t geocode street addresses, autocomplete partial queries, or answer global searches without a coordinate. If your agent needs a location, get it from the user, the device, or a geocoder first, then hand the coordinate to the search.

Try it without a key on the homepage demo, or create a free key: 10,000 searches a month is a lot of agent curiosity.