{
  "data": {
    "a": {
      "slug": "nextbillion",
      "name": "NextBillion.ai",
      "vendor": "NextBillion.ai Pte. Ltd.",
      "vendorUrl": "https://nextbillion.ai",
      "kind": "http-api",
      "category": "maps",
      "summary": "NextBillion.ai is a Singapore mapping and routing platform for fleets and logistics. Its REST APIs cover directions, distance matrices, route optimisation, navigation, geocoding and places, with a hosted MCP server for agents.",
      "url": "https://www.anchorterminal.com/tools/nextbillion",
      "markdownUrl": "https://www.anchorterminal.com/tools/nextbillion.md",
      "slimMarkdownUrl": "https://www.anchorterminal.com/tools/nextbillion.min.md",
      "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/nextbillion.json",
      "dns": "nextbillion.grade.anchorterminal.com",
      "repo": "https://github.com/nextbillion-ai/nextbillion-mcp",
      "transports": [
        "http",
        "streamable-http"
      ],
      "remoteUrl": "https://mcp.nextbillion.io",
      "packages": [],
      "auth": "mixed",
      "authNotes": "REST APIs take a 32-character key as the `key` query parameter, issued in the console at console.nextbillion.ai or by emailing support. Keys can carry an IP allowlist. The hosted MCP server is its own OAuth 2.1 authorisation server with PKCE: a sign-in page asks for the key once and seals it into the tokens. Scripts can send the key as a Bearer header to the MCP server instead.",
      "pricing": "paid",
      "pricingNotes": "By quote. Annual licences priced per order, per asset or per API call, paid monthly or yearly, with extra usage at a rate set in the plan. A 7-day free trial with an API key and no credit card.",
      "priceSummary": "Paid",
      "where": "hosted",
      "x402": {
        "level": "no",
        "evidence": "No x402, MPP or L402 in the docs, llms.txt, the MCP server source or the pricing page (checked 2026-11-06). Contracts are invoiced.",
        "endpoints": []
      },
      "toolCount": 27,
      "popularity": {
        "githubStars": null,
        "npmWeekly": null,
        "pypiWeekly": null,
        "asOf": "2026-11-06"
      },
      "docsUrl": "https://docs.nextbillion.ai/",
      "llmsTxt": "https://docs.nextbillion.ai/llms.txt",
      "capabilities": [
        "geo.routing",
        "geo.geocode",
        "geo.reverse",
        "geo.places",
        "geo.tiles"
      ],
      "tags": [
        "hosted",
        "mcp",
        "remote-mcp",
        "oauth",
        "api-key",
        "llms-txt",
        "official",
        "sales-led",
        "annual-contract",
        "free-trial",
        "no-card",
        "enterprise",
        "android",
        "ios",
        "closed-source"
      ],
      "lastRelease": "2026-10-30",
      "graded": true,
      "anchor": {
        "graded": true,
        "score": 55.4,
        "grade": "C",
        "agentReady": false,
        "rank": 874,
        "ranked": true,
        "rankOf": 1510,
        "categoryRank": 15,
        "methodology": "0.7",
        "run": "2026-10-01",
        "scores": {
          "ergonomics": 77,
          "maintenance": 73,
          "payments": 20,
          "reliability": 45,
          "schema": 73,
          "security": 46,
          "transparency": 58
        },
        "pending": [
          "performance",
          "tasks"
        ],
        "assessment": {
          "confidence": "medium",
          "date": "2026-11-06"
        },
        "negative": 0,
        "verdict": "NextBillion.ai covers routing, distance matrices, route optimisation, geocoding and places, and runs a hosted MCP server with 27 read-only annotated tools and OAuth sign-in. Pricing is by quote on annual licences, the REST API key travels in the query string, and no OpenAPI spec, API changelog or readable status history was found.",
        "bestFor": "Fleet and delivery routing, distance matrices and route optimisation with truck profiles, plus geocoding and POI search, for companies ready for an annual contract.",
        "strengths": [
          "Hosted MCP server at mcp.nextbillion.io with OAuth 2.1 and PKCE, and every API tool annotated read-only and idempotent",
          "Routing, distance matrix, isochrone, route optimisation, geocoding and places APIs under one key",
          "llms.txt, llms-full.txt and Markdown versions of the docs pages",
          "Documented rate limit of 2,400 queries a minute and a per-endpoint error table",
          "7-day free trial with no credit card"
        ],
        "weaknesses": [
          "Pricing is by quote on annual licences, with no public unit prices",
          "The REST APIs take the key only as a `key` query parameter",
          "No OpenAPI spec or API changelog found",
          "No security.txt or vulnerability disclosure policy, and no SLA",
          "The status page renders only in a browser, so its history couldn't be read"
        ],
        "agentNotes": [
          "Connect through https://mcp.nextbillion.io so the key stays in a Bearer header or OAuth token rather than in request URLs",
          "Use the geometry tools only for straight-line questions; use directions or distance_matrix for travel time",
          "Batch up to 100 geocodes with geocode_batch instead of one call per address",
          "On 429 the quota or the 2,400-a-minute limit is reached; slow down and tell the user if credits are spent",
          "Search the docs with the MCP documentation tools before guessing a parameter"
        ],
        "metrics": {
          "kind": "remote",
          "measured": false
        },
        "reviewCount": 0,
        "avgRating": 0,
        "history": [
          {
            "basis": "public evidence",
            "confidence": "medium",
            "grade": "C",
            "methodology": "0.7",
            "pending": [
              "performance",
              "tasks"
            ],
            "run": "2026-10-01",
            "runLabel": "October 2026 research run",
            "score": 55.4
          }
        ],
        "editorialScores": {
          "ergonomics": 77,
          "maintenance": 73,
          "payments": 20,
          "reliability": 45,
          "schema": 73,
          "security": 46,
          "transparency": 43
        },
        "provenanceScore": 73,
        "checked": {
          "categories": {
            "ergonomics": "2026-11-06",
            "maintenance": "2026-11-06",
            "payments": "2026-11-06",
            "reliability": "2026-11-06",
            "schema": "2026-11-06",
            "security": "2026-11-06",
            "transparency": "2026-11-06"
          },
          "last": "2026-11-06",
          "oldest": "2026-11-06",
          "stale": false,
          "staleAfterDays": 90
        }
      },
      "connect": {
        "http": "curl \"https://api.nextbillion.io/geocode?q=market\u0026at=40.720685,-74.044772\u0026in=countryCode:USA\u0026key=$NBAI_API_KEY\"",
        "claudeCode": "claude mcp add --transport http nextbillion https://mcp.nextbillion.io",
        "config": {
          "mcpServers": {
            "nextbillion": {
              "url": "https://mcp.nextbillion.io"
            }
          }
        }
      },
      "letme": {
        "capability": "https://letme.dev/geo.routing",
        "tool": "https://letme.dev/nextbillion"
      },
      "area": "everyday",
      "provenance": {
        "legalEntity": "NextBillion.ai Pte. Ltd.",
        "domain": "nextbillion.ai",
        "domainRegistered": "2019-08-07",
        "endpointOnVendorDomain": false,
        "terms": "https://nextbillion.ai/terms-of-service",
        "privacy": "https://nextbillion.ai/privacy",
        "statusPage": "https://status.nextbillion.io",
        "changelog": "https://github.com/nextbillion-ai/nextbillion-mcp/blob/main/CHANGELOG.md",
        "securityTxt": "none",
        "checked": "2026-11-06",
        "notes": [
          "The terms name NextBillion.ai Pte. Ltd. and choose Singapore law, with mediation first. The privacy policy names Nextbillion.AI Pte. Ltd. and its affiliates.",
          "The APIs and MCP server run on nextbillion.io, a second domain of the same company, while the site and docs are on nextbillion.ai.",
          "nextbillion.ai/.well-known/security.txt and /security return 404. No vulnerability disclosure policy was found.",
          "The changelog listed is the MCP server's; no changelog for the REST APIs was found.",
          "RDAP gives nextbillion.ai a registration date of 7 August 2019. robots.txt on nextbillion.ai and docs.nextbillion.ai allows these pages, and docs robots.txt allows /llms*.txt.",
          "The acceptable use clause bars reselling or making the services available to third parties. No clause on automated access to the website was found."
        ],
        "score": 73
      },
      "pageJsonUrl": "https://www.anchorterminal.com/tools/nextbillion.json",
      "live": {
        "slug": "nextbillion",
        "probe": {
          "target": "https://mcp.nextbillion.io",
          "method": "get",
          "lastAt": "2026-11-07T19:22:21.654883516Z",
          "lastOk": true,
          "lastStatus": 405,
          "lastMs": 407,
          "authRequired": false,
          "uptime24h": 100,
          "uptime30d": 100,
          "p50ms24h": 383,
          "p95ms24h": 503,
          "samples24h": 210,
          "samples30d": 210,
          "days": [
            {
              "date": "2026-11-06",
              "probes": 13,
              "ok": 13
            },
            {
              "date": "2026-11-07",
              "probes": 197,
              "ok": 197
            }
          ]
        },
        "vendorStatus": {
          "page": "https://status.nextbillion.io",
          "indicator": "unknown",
          "summary": "no machine-readable status found",
          "checkedAt": "2026-11-07T04:48:15.654905456Z"
        },
        "versions": [
          {
            "registry": "github",
            "name": "nextbillion-ai/nextbillion-mcp",
            "version": "v0.5.3",
            "released": "2026-10-30",
            "seenAt": "2026-11-06T23:49:07.315516581Z"
          }
        ],
        "githubStars": 0,
        "securityTxt": {
          "url": "https://nextbillion.ai/.well-known/security.txt",
          "state": "none",
          "checkedAt": "2026-11-07T16:00:46.65718407Z"
        },
        "llmsTxt": {
          "url": "https://docs.nextbillion.ai/llms.txt",
          "ok": true,
          "status": 200,
          "checkedAt": "2026-11-07T15:33:19.797741277Z"
        },
        "pages": [
          {
            "url": "https://raw.githubusercontent.com/nextbillion-ai/nextbillion-mcp/main/CHANGELOG.md",
            "kind": "changelog",
            "status": 200,
            "checkedAt": "2026-11-07T14:22:12.997536111Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "7a2ac2407039"
          },
          {
            "url": "https://nextbillion.ai/privacy",
            "kind": "privacy",
            "status": 200,
            "checkedAt": "2026-11-07T14:14:59.152376992Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "39ac967d5c22"
          },
          {
            "url": "https://nextbillion.ai/terms-of-service",
            "kind": "terms",
            "status": 200,
            "checkedAt": "2026-11-07T14:15:02.368911623Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "898d2ccdb595"
          }
        ],
        "mcpTools": {
          "url": "https://mcp.nextbillion.io",
          "checkedAt": "2026-11-07T01:46:25.213284458Z",
          "status": "ok",
          "protocol": "2026-07-28",
          "tools": [
            {
              "name": "autocomplete",
              "title": "Autocomplete",
              "description": "Complete a partial address or administrative-area prefix into full valid addresses (e.g. \"stat\" -\u003e \"State Capitol, ...\"). Use for prefix completion as the user types; use autosuggest for typo-tolerant fuzzy suggestions and geocode_forward for a full address. Parameters: query (required); optional near {latitude, longitude}, radius_m (with near), country_codes, bounding_box {west, south, east, north}, limit, language, view. Example: {\"query\": \"stat\", \"near\": {\"latitude\": 35.4769, \"longitude\": -97.4872}, \"limit\": 5}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Center of the search context; results are ranked around this point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "query": {
                    "description": "Free-text search query",
                    "minLength": 1,
                    "type": "string"
                  },
                  "radius_m": {
                    "description": "With `near`: hard-limit results to this radius in meters",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991,
                    "type": "integer"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "autosuggest",
              "title": "Autosuggest",
              "description": "Suggest address and place candidates from an incomplete or misspelled query (typo-tolerant, e.g. \"aqaurium\" still matches aquariums). Use for search-as-you-type; use autocomplete for strict prefix completion of valid addresses. Parameters: query (required); optional near {latitude, longitude}, radius_m (with near), country_codes, bounding_box {west, south, east, north}, limit, language, view. Example: {\"query\": \"aqauriums\", \"near\": {\"latitude\": 42.3501, \"longitude\": -71.0689}, \"limit\": 5}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Center of the search context; results are ranked around this point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "query": {
                    "description": "Free-text search query",
                    "minLength": 1,
                    "type": "string"
                  },
                  "radius_m": {
                    "description": "With `near`: hard-limit results to this radius in meters",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991,
                    "type": "integer"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "bbox",
              "title": "Bounding Box",
              "description": "The smallest latitude/longitude box around a set of points, a line or a polygon, optionally padded in metres — for example a viewport for static_map_image or a spatial filter. Handles shapes that straddle the antimeridian (reports crosses_antimeridian and the narrower box). Computed locally, no sign-in needed. Parameters: exactly one of points (array of {latitude, longitude}), line (array of points) or polygon (GeoJSON Polygon/MultiPolygon, isochrone Feature accepted); padding_meters (default 0). Returns min_latitude, min_longitude, max_latitude, max_longitude, crosses_antimeridian. Example: {\"points\": [{\"latitude\": 12.9716, \"longitude\": 77.5946}, {\"latitude\": 13.0827, \"longitude\": 80.2707}], \"padding_meters\": 500}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "line": {
                    "description": "A line as an array of {latitude, longitude} points (at least 2)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5000,
                    "minItems": 2,
                    "type": "array"
                  },
                  "padding_meters": {
                    "description": "Grow the box by this many metres on every side",
                    "maximum": 1000000,
                    "minimum": 0,
                    "type": "number"
                  },
                  "points": {
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "id": {
                          "description": "Optional label echoed back in the result",
                          "maxLength": 100,
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "polygon": {
                    "additionalProperties": {},
                    "description": "A GeoJSON Polygon or MultiPolygon geometry (coordinates in [longitude, latitude] order), or a Feature wrapping one — an isochrone contour can be passed as is",
                    "properties": {
                      "type": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  }
                },
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "buffer",
              "title": "Buffer Zone Around a Point, Line or Polygon",
              "description": "Build the zone within a given straight-line distance of a point (a circle), a line (a corridor, e.g. 1 km along a route) or a polygon (grown outward, or shrunk inward with a negative distance). Geodesic on WGS84, computed locally, no sign-in needed. Returns a GeoJSON Polygon or MultiPolygon (a shrunk shape may split) with its area; an empty result is returned, not an error. Parameters: exactly one of point ({latitude, longitude}), line (array of points) or polygon (GeoJSON Polygon/MultiPolygon, isochrone Feature accepted); distance (number, negative only for polygon); units (default meters); steps (points per circle, default 16); area_units; max_vertices (default 500). Example: {\"line\": [{\"latitude\": 12.9716, \"longitude\": 77.5946}, {\"latitude\": 12.99, \"longitude\": 77.62}], \"distance\": 1, \"units\": \"kilometers\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "area_units": {
                    "description": "Area unit (default square_meters)",
                    "enum": [
                      "square_meters",
                      "square_kilometers",
                      "hectares",
                      "acres",
                      "square_miles",
                      "square_feet"
                    ],
                    "type": "string"
                  },
                  "distance": {
                    "description": "Buffer distance; negative shrinks a polygon inward",
                    "type": "number"
                  },
                  "line": {
                    "description": "Buffer around a line (a corridor)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5000,
                    "minItems": 2,
                    "type": "array"
                  },
                  "max_vertices": {
                    "description": "Simplify the returned shape to at most this many vertices (default 500); the result says when it was simplified",
                    "maximum": 5000,
                    "minimum": 16,
                    "type": "integer"
                  },
                  "point": {
                    "additionalProperties": false,
                    "description": "Buffer around a point (a geodesic circle)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "polygon": {
                    "additionalProperties": {},
                    "description": "Buffer around or inside a polygon",
                    "properties": {
                      "type": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  },
                  "steps": {
                    "description": "Vertices per quarter... per full circle (default 16)",
                    "maximum": 64,
                    "minimum": 4,
                    "type": "integer"
                  },
                  "units": {
                    "description": "Distance unit (default meters)",
                    "enum": [
                      "meters",
                      "kilometers",
                      "miles",
                      "feet",
                      "nautical_miles"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "distance"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "centroid",
              "title": "Centroid and Label Point of a Polygon",
              "description": "The area-weighted centre of a polygon and a label point that is guaranteed to lie inside it (the centroid of a C- or ring-shaped area falls outside; the label point does not). Computed locally, no sign-in needed. Parameters: polygon (GeoJSON Polygon/MultiPolygon, or an isochrone Feature). Returns centroid, label_point ({latitude, longitude}) and centroid_inside. Example: {\"polygon\": {\"type\": \"Polygon\", \"coordinates\": [[[77.59, 12.97], [77.61, 12.97], [77.61, 12.99], [77.59, 12.99], [77.59, 12.97]]]}}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "polygon": {
                    "additionalProperties": {},
                    "description": "A GeoJSON Polygon or MultiPolygon geometry (coordinates in [longitude, latitude] order), or a Feature wrapping one — an isochrone contour can be passed as is",
                    "properties": {
                      "type": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "polygon"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "directions",
              "title": "Directions",
              "description": "Calculate a route between an origin and a destination with optional waypoints; returns distance (meters), duration (seconds) and an encoded polyline per route, which static_route_map can draw. Use distance_matrix for many pairs. Documentation for this API is available through search_documentation. Parameters: origin, destination {latitude, longitude} (required); optional waypoints (max 200), mode (car | truck | motorcycle | bike | walk), service (\"flexible\" default: all options; \"fast\": car/truck only, lower latency), route_type, departure_time, avoid (soft), exclude (strict), road_info, honor_restrictions, alternatives, steps (fast only), geometry (polyline | polyline6), cross_border; truck options: truck_size_cm, truck_weight_kg, truck_axle_load, hazmat_type, emission_class; freight network: prefer \"truck_route\" + truck_type (rigid_truck | semi_trailer | b_double | road_train | generic_truck) for roads legal for that truck class, require \"truck_route\" to stay on it. Example: {\"origin\": {\"latitude\": 37.7749, \"longitude\": -122.4194}, \"destination\": {\"latitude\": 34.0522, \"longitude\": -118.2437}, \"mode\": \"truck\", \"prefer\": \"truck_route\", \"truck_type\": [\"b_double\"]}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "alternatives": {
                    "description": "Return up to 3 alternative routes (only without waypoints)",
                    "type": "boolean"
                  },
                  "avoid": {
                    "description": "Road features to avoid when alternatives exist. Fast service supports only toll/ferry/highway",
                    "items": {
                      "enum": [
                        "toll",
                        "highway",
                        "ferry",
                        "sharp_turn",
                        "uturn",
                        "service_road",
                        "left_turn",
                        "right_turn",
                        "tunnel",
                        "none"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "cross_border": {
                    "description": "Allow the route to cross international borders (region-dependent, flexible service only)",
                    "type": "boolean"
                  },
                  "departure_time": {
                    "description": "Departure as a UNIX timestamp in seconds, for typical-traffic routing (flexible only)",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "destination": {
                    "additionalProperties": false,
                    "description": "Route end (must be a routable land location)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "emission_class": {
                    "description": "Engine emission class (EU regions, truck mode, flexible service only)",
                    "enum": [
                      "euro0",
                      "euro1",
                      "euro2",
                      "euro3",
                      "euro4",
                      "euro5",
                      "euro6",
                      "euro7",
                      "euro8",
                      "euro9"
                    ],
                    "type": "string"
                  },
                  "exclude": {
                    "description": "Strict filter: only routes that completely avoid these features are returned (error if none exists). Use `avoid` for a soft preference instead. Flexible service only",
                    "items": {
                      "enum": [
                        "toll",
                        "ferry",
                        "highway",
                        "service_road",
                        "uturn",
                        "sharp_turn",
                        "left_turn",
                        "right_turn"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "geometry": {
                    "description": "Route geometry encoding (default polyline, precision 5 — directly usable with static_route_map)",
                    "enum": [
                      "polyline",
                      "polyline6"
                    ],
                    "type": "string"
                  },
                  "hazmat_type": {
                    "description": "Hazardous cargo classes carried (truck mode, flexible service only)",
                    "items": {
                      "enum": [
                        "explosives",
                        "gas",
                        "flammable_liquid",
                        "flammable_gas",
                        "organic",
                        "toxic",
                        "radioactive",
                        "corrosive",
                        "other"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "honor_restrictions": {
                    "description": "When true, enforce restricted-area rules: no route is generated if origin, destination, or a waypoint is inside a restricted area. Default false: route anyway with a warning (flexible service only)",
                    "type": "boolean"
                  },
                  "mode": {
                    "description": "Travel mode (default car). Modes other than car/truck require service=flexible",
                    "enum": [
                      "car",
                      "truck",
                      "motorcycle",
                      "bike",
                      "walk"
                    ],
                    "type": "string"
                  },
                  "origin": {
                    "additionalProperties": false,
                    "description": "Route start (must be a routable land location)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "prefer": {
                    "description": "Prioritise designated freight network roads (flexible service, mode truck). truck_type takes effect only together with this",
                    "enum": [
                      "truck_route"
                    ],
                    "type": "string"
                  },
                  "require": {
                    "description": "Restrict the route to designated freight network roads; the API answers HTTP 422 when no such road is within 2 km of the origin, destination or a waypoint. Needs prefer: \"truck_route\"",
                    "enum": [
                      "truck_route"
                    ],
                    "type": "string"
                  },
                  "road_info": {
                    "description": "Extra per-segment information to return: max_speed, toll_distance, toll_cost, toll_info, truck_route, stop_sign, traffic_light (flexible service only)",
                    "items": {
                      "enum": [
                        "max_speed",
                        "toll_distance",
                        "toll_cost",
                        "toll_info",
                        "truck_route",
                        "stop_sign",
                        "traffic_light"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "route_type": {
                    "description": "Optimization objective (flexible only, default fastest)",
                    "enum": [
                      "fastest",
                      "shortest"
                    ],
                    "type": "string"
                  },
                  "service": {
                    "description": "API variant: \"flexible\" (default) supports all modes, departure_time, route_type, full avoid list and truck options; \"fast\" is lower latency but limited to car/truck and avoid toll/ferry/highway only",
                    "enum": [
                      "flexible",
                      "fast"
                    ],
                    "type": "string"
                  },
                  "steps": {
                    "description": "Include turn-by-turn steps (fast service only)",
                    "type": "boolean"
                  },
                  "truck_axle_load": {
                    "description": "Load per axle in tonnes (truck mode, flexible service only)",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "truck_size_cm": {
                    "additionalProperties": false,
                    "description": "Truck dimensions in cm (flexible + mode=truck only)",
                    "properties": {
                      "height": {
                        "type": "number"
                      },
                      "length": {
                        "type": "number"
                      },
                      "width": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "height",
                      "width",
                      "length"
                    ],
                    "type": "object"
                  },
                  "truck_type": {
                    "description": "Truck class(es) the route must be legal for on the designated freight network (rigid_truck, semi_trailer, b_double, road_train, generic_truck). Effective together with prefer: \"truck_route\" (flexible service, mode truck)",
                    "items": {
                      "enum": [
                        "rigid_truck",
                        "semi_trailer",
                        "b_double",
                        "road_train",
                        "generic_truck"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "truck_weight_kg": {
                    "description": "Truck gross weight in kg (flexible + mode=truck only)",
                    "maximum": 100000,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "waypoints": {
                    "description": "Intermediate stops visited in order (max 200)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 200,
                    "type": "array"
                  }
                },
                "required": [
                  "origin",
                  "destination"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "distance_matrix",
              "title": "Distance Matrix",
              "description": "Compute travel distance (meters) and duration (seconds) for every origin-to-destination pair in one call; one row per origin with one element per destination, in input order. Use it instead of repeated directions calls when several pairs are needed. Documentation for this API is available through search_documentation. Parameters: origins, destinations (arrays of {latitude, longitude}, required); optional mode, service (\"fast\" default: up to 1000x1000 points; \"flexible\": the options below, max 50x50), route_type, departure_time, avoid (soft), exclude (strict), honor_restrictions, route_failed_prompt (unroutable pairs return -1 instead of 0), truck options: truck_size_cm {height, width, length}, truck_weight_kg, truck_axle_load, hazmat_type, emission_class, cross_border, prefer \"truck_route\" + truck_type (roads legal for a truck class on the designated freight network). Example: {\"origins\": [{\"latitude\": 1.29, \"longitude\": 103.85}], \"destinations\": [{\"latitude\": 1.35, \"longitude\": 103.99}, {\"latitude\": 1.3, \"longitude\": 103.77}], \"route_failed_prompt\": true}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "avoid": {
                    "description": "Road features to avoid",
                    "items": {
                      "enum": [
                        "toll",
                        "highway",
                        "ferry",
                        "none"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "cross_border": {
                    "description": "Allow routes to cross international borders (region-dependent, flexible service only)",
                    "type": "boolean"
                  },
                  "departure_time": {
                    "description": "Departure as a UNIX timestamp in seconds, for typical-traffic results (flexible only)",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "destinations": {
                    "description": "End points (matrix columns)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "emission_class": {
                    "description": "Engine emission class (EU regions, truck mode, flexible service only)",
                    "enum": [
                      "euro0",
                      "euro1",
                      "euro2",
                      "euro3",
                      "euro4",
                      "euro5",
                      "euro6",
                      "euro7",
                      "euro8",
                      "euro9"
                    ],
                    "type": "string"
                  },
                  "exclude": {
                    "description": "Strict filter: only routes that completely avoid these features are returned (error if none exists). Use `avoid` for a soft preference instead. Flexible service only",
                    "items": {
                      "enum": [
                        "toll",
                        "ferry",
                        "highway",
                        "service_road",
                        "uturn",
                        "sharp_turn",
                        "left_turn",
                        "right_turn"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "hazmat_type": {
                    "description": "Hazardous cargo classes carried (truck mode, flexible service only)",
                    "items": {
                      "enum": [
                        "explosives",
                        "gas",
                        "flammable_liquid",
                        "flammable_gas",
                        "organic",
                        "toxic",
                        "radioactive",
                        "corrosive",
                        "other"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "honor_restrictions": {
                    "description": "When true, enforce restricted-area rules for origin/destination points instead of routing through with a warning (flexible service only)",
                    "type": "boolean"
                  },
                  "mode": {
                    "description": "Travel mode (default car). Modes other than car/truck require service=flexible",
                    "enum": [
                      "car",
                      "truck",
                      "motorcycle",
                      "bike",
                      "walk"
                    ],
                    "type": "string"
                  },
                  "origins": {
                    "description": "Start points (matrix rows)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "prefer": {
                    "description": "Prioritise designated freight network roads (flexible service, mode truck). truck_type takes effect only together with this",
                    "enum": [
                      "truck_route"
                    ],
                    "type": "string"
                  },
                  "route_failed_prompt": {
                    "description": "When true, unroutable origin/destination pairs return -1 instead of 0 so they can be told apart from zero-distance pairs",
                    "type": "boolean"
                  },
                  "route_type": {
                    "description": "Optimization objective (flexible only, default fastest)",
                    "enum": [
                      "fastest",
                      "shortest"
                    ],
                    "type": "string"
                  },
                  "service": {
                    "description": "API variant: \"fast\" (default) supports up to 1000x1000 points; \"flexible\" adds departure_time, route_type, truck options and more modes but is limited to 50x50 points within a ~8000 km area",
                    "enum": [
                      "fast",
                      "flexible"
                    ],
                    "type": "string"
                  },
                  "truck_axle_load": {
                    "description": "Load per axle in tonnes (truck mode, flexible service only)",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "truck_size_cm": {
                    "additionalProperties": false,
                    "description": "Truck dimensions in cm (flexible + mode=truck only)",
                    "properties": {
                      "height": {
                        "type": "number"
                      },
                      "length": {
                        "type": "number"
                      },
                      "width": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "height",
                      "width",
                      "length"
                    ],
                    "type": "object"
                  },
                  "truck_type": {
                    "description": "Truck class(es) the route must be legal for on the designated freight network (rigid_truck, semi_trailer, b_double, road_train, generic_truck). Effective together with prefer: \"truck_route\" (flexible service, mode truck)",
                    "items": {
                      "enum": [
                        "rigid_truck",
                        "semi_trailer",
                        "b_double",
                        "road_train",
                        "generic_truck"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "truck_weight_kg": {
                    "description": "Truck gross weight in kg (flexible + mode=truck only)",
                    "maximum": 100000,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  }
                },
                "required": [
                  "origins",
                  "destinations"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "geocode_batch",
              "title": "Batch Geocode",
              "description": "Forward-geocode up to 100 free-text queries in one request; returns one ranked result set per query, in input order. Use it instead of repeated geocode_forward calls when several addresses are needed: this endpoint has its own rate limit of 60 requests per minute, so larger batches per call stay within it. Parameters: queries (required array; each item: query (required), optional near {latitude, longitude}, radius_m, country_codes, bounding_box, limit, language, view, types); optional top-level types (houseNumber | addressBlock | street | intersection | place | area) as the default for all queries (a per-query types overrides it). Example: {\"queries\": [{\"query\": \"600-699 Golden Gate Ave, San Francisco, CA\", \"types\": [\"addressBlock\"]}, {\"query\": \"Empire State Building\", \"country_codes\": [\"USA\"]}]}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "queries": {
                    "description": "Up to 100 forward-geocode queries resolved in a single request",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "bounding_box": {
                          "additionalProperties": false,
                          "description": "Hard-limit results to this bounding box",
                          "properties": {
                            "east": {
                              "description": "Eastern longitude",
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "north": {
                              "description": "Northern latitude",
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "south": {
                              "description": "Southern latitude",
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "west": {
                              "description": "Western longitude",
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            }
                          },
                          "required": [
                            "west",
                            "south",
                            "east",
                            "north"
                          ],
                          "type": "object"
                        },
                        "country_codes": {
                          "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                          "items": {
                            "pattern": "^[A-Za-z]{3}$",
                            "type": "string"
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "language": {
                          "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                          "type": "string"
                        },
                        "limit": {
                          "description": "Maximum results (default 10)",
                          "maximum": 100,
                          "minimum": 1,
                          "type": "integer"
                        },
                        "near": {
                          "additionalProperties": false,
                          "description": "Center of the search context; results are ranked around this point",
                          "properties": {
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            }
                          },
                          "required": [
                            "latitude",
                            "longitude"
                          ],
                          "type": "object"
                        },
                        "query": {
                          "description": "Free-text search query for this entry",
                          "minLength": 1,
                          "type": "string"
                        },
                        "radius_m": {
                          "description": "With `near`: hard-limit results to this radius in meters",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991,
                          "type": "integer"
                        },
                        "types": {
                          "description": "Restrict results to these types: houseNumber (exact door point), addressBlock (address-range/segment match incl. interpolated numbers), street, intersection (only returned when requested), place (POI), area (city/district/postal/admin area)",
                          "items": {
                            "enum": [
                              "houseNumber",
                              "addressBlock",
                              "street",
                              "intersection",
                              "place",
                              "area"
                            ],
                            "type": "string"
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "view": {
                          "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                          "enum": [
                            "Unified",
                            "AR",
                            "IL",
                            "IN",
                            "MA",
                            "PK",
                            "RU",
                            "TR",
                            "CN",
                            "TW"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "query"
                      ],
                      "type": "object"
                    },
                    "maxItems": 100,
                    "minItems": 1,
                    "type": "array"
                  },
                  "types": {
                    "description": "Default result-type filter applied to every query that does not set its own `types` (houseNumber, addressBlock, street, intersection, place, area)",
                    "items": {
                      "enum": [
                        "houseNumber",
                        "addressBlock",
                        "street",
                        "intersection",
                        "place",
                        "area"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "queries"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "geocode_forward",
              "title": "Forward Geocode",
              "description": "Convert a free-text address, place name, locality or administrative area into coordinates and a full postal address; tolerates incomplete or partly wrong input. Use geocode_batch for many addresses, place_search for POIs/businesses, geocode_structured when the address components are already separated. Parameters: query (required); optional near {latitude, longitude} or country_codes (strongly recommended - landmark names rank poorly without a location bias), radius_m (with near), bounding_box {west, south, east, north}, limit, language, view, types (houseNumber | addressBlock | street | intersection | place | area). Example: {\"query\": \"1600 Pennsylvania Avenue NW, Washington DC\", \"country_codes\": [\"USA\"], \"limit\": 1}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Center of the search context; results are ranked around this point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "query": {
                    "description": "Free-text search query",
                    "minLength": 1,
                    "type": "string"
                  },
                  "radius_m": {
                    "description": "With `near`: hard-limit results to this radius in meters",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991,
                    "type": "integer"
                  },
                  "types": {
                    "description": "Restrict results to these types: houseNumber (exact door point), addressBlock (address-range/segment match incl. interpolated numbers), street, intersection (only returned when requested), place (POI), area (city/district/postal/admin area)",
                    "items": {
                      "enum": [
                        "houseNumber",
                        "addressBlock",
                        "street",
                        "intersection",
                        "place",
                        "area"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "geocode_reverse",
              "title": "Reverse Geocode",
              "description": "Find the nearest address for a coordinate; returns the full postal address, the matched position and a bounding box. Parameters: coordinate {latitude, longitude} (required); optional country_codes, bounding_box {west, south, east, north}, language, view. Example: {\"coordinate\": {\"latitude\": 48.8566, \"longitude\": 2.3522}}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "coordinate": {
                    "additionalProperties": false,
                    "description": "The location to reverse geocode",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "coordinate"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "geocode_structured",
              "title": "Structured Geocode",
              "description": "Geocode an address given as separate fields instead of one string; searches addresses and administrative areas only, never POIs. Use when the components are already known and precision matters; otherwise use geocode_forward. Parameters: country_code (required, ISO 3166-1 alpha-3) plus at least one of state, county, city, suburb, neighborhood, street, house_number, postal_code; optional near {latitude, longitude}, limit, types, view. Example: {\"country_code\": \"GBR\", \"city\": \"London\", \"street\": \"Baker Street\", \"house_number\": \"221B\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "city": {
                    "type": "string"
                  },
                  "country_code": {
                    "description": "Country of the address (required, ISO 3166-1 alpha-3, e.g. \"USA\")",
                    "pattern": "^[A-Za-z]{3}$",
                    "type": "string"
                  },
                  "county": {
                    "type": "string"
                  },
                  "house_number": {
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Search-context center for ranking",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "neighborhood": {
                    "type": "string"
                  },
                  "postal_code": {
                    "type": "string"
                  },
                  "state": {
                    "type": "string"
                  },
                  "street": {
                    "type": "string"
                  },
                  "suburb": {
                    "type": "string"
                  },
                  "types": {
                    "description": "Restrict results to these types: houseNumber (exact door point), addressBlock (address-range/segment match incl. interpolated numbers), street, intersection (only returned when requested), place (POI), area (city/district/postal/admin area)",
                    "items": {
                      "enum": [
                        "houseNumber",
                        "addressBlock",
                        "street",
                        "intersection",
                        "place",
                        "area"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "country_code"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "get_api_parameters",
              "title": "Get API Parameters",
              "description": "Get structured parameter details for a NextBillion REST API endpoint: type, required, default, allowed values, units and description. More precise than a prose search for questions about one specific parameter. Returns every matching API variant (e.g. directions/flexible and directions/fast), identified by heading_path. Empty units means the documentation does not state a unit. SDK methods are not covered. When the index is temporarily unavailable the result says so and names the public docs site.\nParameters:\n- endpoint (string, required unless doc_id given): API slug, optionally with variant, e.g. directions or directions/flexible; a tool name such as geocode_batch or a doc_id also resolves. An unknown endpoint returns found: false with similar endpoints.\n- doc_id (string, optional): page id instead of endpoint.\n- name (string, optional): one parameter name.\nExample: {\"endpoint\": \"directions\", \"name\": \"truck_weight\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "doc_id": {
                    "description": "Page id instead of endpoint",
                    "type": "string"
                  },
                  "endpoint": {
                    "description": "API slug with optional variant (directions, directions/flexible, geofence/create), a tool name (geocode_batch) or a doc_id",
                    "type": "string"
                  },
                  "name": {
                    "description": "One parameter name, e.g. truck_weight",
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "get_documentation",
              "title": "Get Documentation Page",
              "description": "Fetch the full text of one documentation page by its doc_id, as returned by search_documentation. Use when an excerpt is not enough to answer accurately. Pages over the size limit return truncated: true and a section list; a single section can be requested with section. Sample request and response bodies are omitted unless include_examples is true. An unknown doc_id or section returns found: false with similar ids or the section list. When the index is temporarily unavailable the result says so and names the public docs site.\nParameters:\n- doc_id (string, required): page id from search results.\n- section (string, optional): heading of one section to return.\n- include_examples (boolean, optional): default false.\nExample: {\"doc_id\": \"routing/directions-api/examples/legal-routes-for-a-given-truck-weight\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "doc_id": {
                    "description": "Page id from search_documentation or list_documentation_topics",
                    "minLength": 1,
                    "type": "string"
                  },
                  "include_examples": {
                    "description": "Include sample request/response code blocks (default false)",
                    "type": "boolean"
                  },
                  "section": {
                    "description": "Heading (or its anchor) of one section to return",
                    "type": "string"
                  }
                },
                "required": [
                  "doc_id"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "isochrone",
              "title": "Isochrone",
              "description": "Calculate the area reachable from a point within given travel times or distances; returns a GeoJSON FeatureCollection of contours (geometry coordinates are [longitude, latitude]). Each contour ring can be drawn with static_route_map by passing it as paths[].geojson_coordinates with a fill_color. Documentation for this API is available through search_documentation. Parameters: origin {latitude, longitude} (required); exactly one of contours_minutes (array, up to 4 values, max 40) or contours_meters (array, up to 4 values, max 60000); optional mode, polygons (true for Polygon geometry), denoise, generalize (meters), contours_colors (hex without #, one per contour), departure_time. Example: {\"origin\": {\"latitude\": 37.7749, \"longitude\": -122.4194}, \"contours_minutes\": [5, 10], \"polygons\": true}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "contours_colors": {
                    "description": "One hex color (without #) per contour, e.g. [\"ff0000\", \"00ff00\"]",
                    "items": {
                      "pattern": "^[0-9a-fA-F]{6}$",
                      "type": "string"
                    },
                    "maxItems": 4,
                    "type": "array"
                  },
                  "contours_meters": {
                    "description": "Travel distances in meters, one contour each (max 4 values, increasing, max 60000)",
                    "items": {
                      "maximum": 60000,
                      "minimum": 1,
                      "type": "integer"
                    },
                    "maxItems": 4,
                    "type": "array"
                  },
                  "contours_minutes": {
                    "description": "Travel times in minutes, one contour each (max 4 values, increasing, max 40)",
                    "items": {
                      "maximum": 40,
                      "minimum": 1,
                      "type": "integer"
                    },
                    "maxItems": 4,
                    "type": "array"
                  },
                  "denoise": {
                    "description": "Remove contours smaller than this fraction of the largest (default 1: largest only)",
                    "maximum": 1,
                    "minimum": 0,
                    "type": "number"
                  },
                  "departure_time": {
                    "description": "Departure as a UNIX timestamp in seconds, for typical-traffic analysis",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "generalize": {
                    "description": "Simplification tolerance in meters (Douglas-Peucker); omit for automatic",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "mode": {
                    "description": "Travel mode (default car)",
                    "enum": [
                      "car",
                      "truck",
                      "motorcycle",
                      "bike",
                      "walk"
                    ],
                    "type": "string"
                  },
                  "origin": {
                    "additionalProperties": false,
                    "description": "Starting point of the reachability analysis",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "polygons": {
                    "description": "Return contours as GeoJSON Polygons instead of LineStrings",
                    "type": "boolean"
                  }
                },
                "required": [
                  "origin"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "list_documentation_topics",
              "title": "List Documentation Topics",
              "description": "List the available documentation categories, APIs and pages, with index metadata. Useful before searching, when the right terms are not yet known, e.g. to see which APIs exist for a problem area. When the index is temporarily unavailable the result says so and names the public docs site.\nParameters:\n- category (string, optional): limit to one category.\n- sdk (string, optional): Android, iOS or Flutter.\nExample: {\"category\": \"Optimization\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "category": {
                    "description": "Only this category, e.g. Routing",
                    "type": "string"
                  },
                  "sdk": {
                    "description": "Only pages of this platform: Android, iOS, Flutter, Web",
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "measure",
              "title": "Measure Straight-Line Distance, Length, Area or Bearing",
              "description": "Measure straight-line (geodesic, WGS84) distance between two points, the length of a line, the area and perimeter of a polygon, or the bearing from one point to another. Straight-line (geodesic) geometry computed locally, not road distance or travel time: for those, directions or distance_matrix apply. No sign-in needed. Parameters: mode (distance | length | area | bearing); from and to ({latitude, longitude}) for distance and bearing; line (array of points) for length; polygon (GeoJSON Polygon or MultiPolygon, e.g. an isochrone contour) for area; units (meters, kilometers, miles, feet, nautical_miles; default meters); area_units (square_meters, square_kilometers, hectares, acres, square_miles, square_feet; default square_meters). Example: {\"mode\": \"distance\", \"from\": {\"latitude\": 12.9716, \"longitude\": 77.5946}, \"to\": {\"latitude\": 13.0827, \"longitude\": 80.2707}, \"units\": \"kilometers\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "area_units": {
                    "description": "Area unit (default square_meters)",
                    "enum": [
                      "square_meters",
                      "square_kilometers",
                      "hectares",
                      "acres",
                      "square_miles",
                      "square_feet"
                    ],
                    "type": "string"
                  },
                  "from": {
                    "additionalProperties": false,
                    "description": "Start point (distance, bearing)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "line": {
                    "description": "The line (length)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5000,
                    "minItems": 2,
                    "type": "array"
                  },
                  "mode": {
                    "description": "distance: between two points; length: of a line; area: of a polygon; bearing: from one point to another",
                    "enum": [
                      "distance",
                      "length",
                      "area",
                      "bearing"
                    ],
                    "type": "string"
                  },
                  "polygon": {
                    "additionalProperties": {},
                    "description": "The polygon (area)",
                    "properties": {
                      "type": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  },
                  "to": {
                    "additionalProperties": false,
                    "description": "End point (distance, bearing)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "units": {
                    "description": "Distance unit (default meters)",
                    "enum": [
                      "meters",
                      "kilometers",
                      "miles",
                      "feet",
                      "nautical_miles"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "mode"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "nearest",
              "title": "Nearest Point or Position on a Line",
              "description": "Find the candidate points nearest to a target as the crow flies (e.g. the closest depots to a customer), or snap the target onto a line and report the closest position on it. Straight-line (geodesic) distances, computed locally, no sign-in needed; distance_matrix gives travel time and road distance instead. Parameters: target ({latitude, longitude}); either candidates (array of {latitude, longitude, id?}) with k (default 1), or line (array of points); units (default meters). Returns ranked {id, point, distance} for candidates, or snapped_point, distance, segment_index and distance_along_line for a line. Example: {\"target\": {\"latitude\": 12.9716, \"longitude\": 77.5946}, \"candidates\": [{\"latitude\": 13.0827, \"longitude\": 80.2707, \"id\": \"Chennai\"}, {\"latitude\": 19.076, \"longitude\": 72.8777, \"id\": \"Mumbai\"}], \"k\": 1, \"units\": \"kilometers\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "candidates": {
                    "description": "Points to rank by straight-line distance from target",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "id": {
                          "description": "Optional label echoed back in the result",
                          "maxLength": 100,
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "k": {
                    "description": "How many nearest candidates to return (default 1)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "line": {
                    "description": "A line to snap the target onto",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5000,
                    "minItems": 2,
                    "type": "array"
                  },
                  "target": {
                    "additionalProperties": false,
                    "description": "The reference point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "units": {
                    "description": "Distance unit (default meters)",
                    "enum": [
                      "meters",
                      "kilometers",
                      "miles",
                      "feet",
                      "nautical_miles"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "target"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "place_browse",
              "title": "Browse Places by Category",
              "description": "List places of given categories around a location, ranked by distance, without a text query - e.g. all restaurants or schools near a point. Use place_search when the user describes what they want in words; use place_lookup to expand a result by id. Parameters: categories (required array of category names or ids); near {latitude, longitude} (recommended), radius_m (with near), country_codes, bounding_box {west, south, east, north}, limit, language, view. Example: {\"categories\": [\"restaurant\"], \"near\": {\"latitude\": 1.2839, \"longitude\": 103.8607}, \"radius_m\": 800, \"limit\": 10}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "categories": {
                    "description": "Category names or ids to browse; a place matching any of them is returned (e.g. [\"restaurant\"], [\"schools\"], [\"7376\"])",
                    "items": {
                      "minLength": 1,
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Center of the search context; results are ranked around this point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "radius_m": {
                    "description": "With `near`: hard-limit results to this radius in meters",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991,
                    "type": "integer"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "categories"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "place_lookup",
              "title": "Place Lookup",
              "description": "Fetch the full details of a place (address, position, access points, categories, contacts) by its unique id, as returned by place_search, geocode_forward, autosuggest, autocomplete or search_along_route. Parameters: id (required); optional view. Example: {\"id\": \"2EmBgAmFpR9dg0D89EBzNA\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "id": {
                    "description": "Unique place id, as returned by the other place/geocoding tools",
                    "minLength": 1,
                    "type": "string"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "id"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "place_search",
              "title": "Search Places",
              "description": "Search for places, points of interest and businesses with a free-text query (e.g. \"gas station\", \"coffee\"), ranked by relevance around a location. Use geocode_forward for plain address-to-coordinates conversion. Documentation for this API is available through search_documentation. Parameters: query (required); optional near {latitude, longitude} (recommended), radius_m (with near), country_codes, bounding_box {west, south, east, north}, limit, language, view. Example: {\"query\": \"coffee\", \"near\": {\"latitude\": 37.7749, \"longitude\": -122.4194}, \"radius_m\": 1000, \"limit\": 5}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Center of the search context; results are ranked around this point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "query": {
                    "description": "Free-text search query",
                    "minLength": 1,
                    "type": "string"
                  },
                  "radius_m": {
                    "description": "With `near`: hard-limit results to this radius in meters",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991,
                    "type": "integer"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "points_in_polygon",
              "title": "Points in Polygon",
              "description": "Geofencing: tell which of up to 1,000 points lie inside a polygon, for example which delivery addresses fall within an isochrone contour or a service area. Holes are respected; the test is done in map (flat degree) space, matching how polygons are drawn. Computed locally, no sign-in needed. Parameters: polygon (GeoJSON Polygon or MultiPolygon, or an isochrone Feature); points (array of {latitude, longitude, id?}); include_boundary (default true). Returns inside and outside lists (ids, or indexes when no id is given) with counts. Example: {\"polygon\": {\"type\": \"Polygon\", \"coordinates\": [[[77.59, 12.97], [77.61, 12.97], [77.61, 12.99], [77.59, 12.99], [77.59, 12.97]]]}, \"points\": [{\"latitude\": 12.98, \"longitude\": 77.6, \"id\": \"A\"}]}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "include_boundary": {
                    "description": "Count points exactly on the edge as inside (default true)",
                    "type": "boolean"
                  },
                  "points": {
                    "description": "Points to test, each optionally with an id",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "id": {
                          "description": "Optional label echoed back in the result",
                          "maxLength": 100,
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "polygon": {
                    "additionalProperties": {},
                    "description": "A GeoJSON Polygon or MultiPolygon geometry (coordinates in [longitude, latitude] order), or a Feature wrapping one — an isochrone contour can be passed as is",
                    "properties": {
                      "type": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "polygon",
                  "points"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "polygon_ops",
              "title": "Polygon Union, Intersection or Difference",
              "description": "Combine polygons: union (merge), intersect (overlap) or difference (first minus the others), for example the overlap of two isochrones or the part of a zone not covered by a depot area. Returns the resulting GeoJSON geometry (Polygon or MultiPolygon, or null when empty) with its geodesic area. Computed locally, no sign-in needed. Parameters: operation (union | intersect | difference); polygons (array of 2–20 GeoJSON Polygon/MultiPolygon geometries, isochrone Features accepted); area_units (default square_meters); max_vertices (default 500, result simplified to fit). Example: {\"operation\": \"intersect\", \"polygons\": [{\"type\": \"Polygon\", \"coordinates\": [[[77.59, 12.97], [77.61, 12.97], [77.61, 12.99], [77.59, 12.99], [77.59, 12.97]]]}, {\"type\": \"Polygon\", \"coordinates\": [[[77.6, 12.98], [77.62, 12.98], [77.62, 13.0], [77.6, 13.0], [77.6, 12.98]]]}], \"area_units\": \"hectares\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "area_units": {
                    "description": "Area unit (default square_meters)",
                    "enum": [
                      "square_meters",
                      "square_kilometers",
                      "hectares",
                      "acres",
                      "square_miles",
                      "square_feet"
                    ],
                    "type": "string"
                  },
                  "max_vertices": {
                    "description": "Simplify the returned shape to at most this many vertices (default 500); the result says when it was simplified",
                    "maximum": 5000,
                    "minimum": 16,
                    "type": "integer"
                  },
                  "operation": {
                    "description": "difference = first polygon minus all others",
                    "enum": [
                      "union",
                      "intersect",
                      "difference"
                    ],
                    "type": "string"
                  },
                  "polygons": {
                    "description": "Two or more polygons (GeoJSON Polygon/MultiPolygon or isochrone Features)",
                    "items": {
                      "additionalProperties": {},
                      "description": "A GeoJSON Polygon or MultiPolygon geometry (coordinates in [longitude, latitude] order), or a Feature wrapping one — an isochrone contour can be passed as is",
                      "properties": {
                        "type": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 2,
                    "type": "array"
                  }
                },
                "required": [
                  "operation",
                  "polygons"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "postcode_lookup",
              "title": "Postcode Lookup",
              "description": "Get the centroid and boundary polygon of a postal/ZIP code, or find the postal code that contains a coordinate; one lookup per call. Supported countries: USA, India, UK, Netherlands, Austria, Germany, Indonesia, France, Singapore, Philippines, Canada, Australia, New Zealand, Italy, Brazil, Mexico, Spain. Parameters: either postal_code plus country (name, alpha-2 or alpha-3 code), or coordinate {latitude, longitude}; optional geojson_boundary (true for a GeoJSON boundary). Example: {\"postal_code\": \"90011\", \"country\": \"USA\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "coordinate": {
                    "additionalProperties": false,
                    "description": "Find the postal code containing this location (alternative to `postal_code`)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "country": {
                    "description": "Country of the postal code — name, alpha-2, or alpha-3 ISO code. Required with `postal_code`",
                    "type": "string"
                  },
                  "geojson_boundary": {
                    "description": "Return the boundary polygon in GeoJSON format instead of the default point-list format",
                    "type": "boolean"
                  },
                  "postal_code": {
                    "description": "Postal/ZIP code to look up (requires `country`; do not combine with `coordinate`)",
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "search_along_route",
              "title": "Search Along Route",
              "description": "Find places matching a text query along a driving route, with the detour time and distance each stop adds - for \"find X on the way\" questions. Pass the route as an ordered list of waypoints, e.g. the origin, waypoints and destination used with directions. Parameters: route_points (array of {latitude, longitude}, at least 2, required), query (required); optional max_detour_seconds (default 900, max 3600), sort_by (detour_time | detour_offset), limit (max 20), view. Example: {\"route_points\": [{\"latitude\": 34.0493, \"longitude\": -118.2557}, {\"latitude\": 34.0415, \"longitude\": -118.231}], \"query\": \"gas station\", \"max_detour_seconds\": 600}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "limit": {
                    "description": "Maximum results (default 10, max 20)",
                    "maximum": 20,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "max_detour_seconds": {
                    "description": "Max driving time to reach a result after leaving the route (default 900 = 15 min)",
                    "maximum": 3600,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "query": {
                    "description": "What to find along the route, e.g. \"gas station\", \"coffee\"",
                    "minLength": 1,
                    "type": "string"
                  },
                  "route_points": {
                    "description": "Waypoints defining the route to search along, in travel order",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "minItems": 2,
                    "type": "array"
                  },
                  "sort_by": {
                    "description": "Order by detour driving time, or by distance of the detour point from route start",
                    "enum": [
                      "detour_time",
                      "detour_offset"
                    ],
                    "type": "string"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories (default: requester region or Unified)",
                    "enum": [
                      "Unified",
                      "AR",
                      "CN",
                      "IN",
                      "PK",
                      "MA",
                      "RU",
                      "RS",
                      "TW",
                      "TR"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "route_points",
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "search_documentation",
              "title": "Search Documentation",
              "description": "Search NextBillion's official API and SDK documentation. Use for any question about how NextBillion works: calling an API, what a parameter means, which API to use, or SDK setup. Answers come from an index of the official documentation, not from live API calls; when the index is temporarily unavailable the result says so and names the public docs site.\nQueries match best with the docs' own terms and exact parameter names (truck_weight, option=flexible) rather than everyday phrasing; when results are thin, other API terms may match. Results are excerpts: get_documentation returns a full page. Each result carries a source_url for citation and related_tools, the name of the tool that performs the operation.\nParameters:\n- query (string, required): search terms.\n- category (string, optional): e.g. Routing, Places.\n- api (string, optional): e.g. Directions.\n- sdk (string, optional): Android, iOS or Flutter.\n- limit (integer, optional): default 5, max 10.\n- include_examples (boolean, optional): default false.\nExample: {\"query\": \"truck_size truck_weight routing\", \"api\": \"Directions\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "api": {
                    "description": "Boost one API, e.g. Directions",
                    "type": "string"
                  },
                  "category": {
                    "description": "Boost one category, e.g. Routing, Places",
                    "type": "string"
                  },
                  "include_examples": {
                    "description": "Also return sample request/response code chunks (default false)",
                    "type": "boolean"
                  },
                  "limit": {
                    "description": "Number of results (default 5)",
                    "maximum": 10,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "query": {
                    "description": "Search terms, ideally the docs’ own vocabulary",
                    "minLength": 1,
                    "type": "string"
                  },
                  "sdk": {
                    "description": "Only pages of this platform: Android, iOS, Flutter, Web",
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "static_map_image",
              "title": "Static Map Image",
              "description": "Render a static map image centered on a location, with optional markers and line/polygon overlays; returns the image inline (path in the result text). For a map auto-fitted to a route or to overlays, use static_route_map. Parameters: center {latitude, longitude} and zoom (0-22) (required); optional markers (array of {latitude, longitude, color, icon_url, anchor, scale}), paths (array of {points [{latitude, longitude}] OR geojson_coordinates [[longitude, latitude], ...], stroke_color, stroke_width, fill_color for a filled polygon}), width, height (default 512), style (streets | light | dark | hybrid), format (png | jpg | webp), retina. Example: {\"center\": {\"latitude\": 48.8566, \"longitude\": 2.3522}, \"zoom\": 14, \"markers\": [{\"latitude\": 48.8584, \"longitude\": 2.2945, \"color\": \"red\"}], \"paths\": [{\"points\": [{\"latitude\": 48.85, \"longitude\": 2.29}, {\"latitude\": 48.86, \"longitude\": 2.30}], \"stroke_color\": \"green\"}]}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "center": {
                    "additionalProperties": false,
                    "description": "Center of the map view",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "format": {
                    "description": "Image format (default png)",
                    "enum": [
                      "png",
                      "jpg",
                      "webp"
                    ],
                    "type": "string"
                  },
                  "height": {
                    "description": "Image height in pixels (default 512)",
                    "maximum": 2048,
                    "minimum": 16,
                    "type": "integer"
                  },
                  "markers": {
                    "description": "Markers to draw, each with optional color or custom icon",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "anchor": {
                          "description": "Anchor point of a custom icon (default bottom)",
                          "enum": [
                            "top",
                            "left",
                            "bottom",
                            "right",
                            "center",
                            "topleft",
                            "bottomleft",
                            "topright",
                            "bottomright"
                          ],
                          "type": "string"
                        },
                        "color": {
                          "description": "Marker color, e.g. \"red\" or \"#0000ff\" (ignored when icon_url is set)",
                          "type": "string"
                        },
                        "icon_url": {
                          "description": "URL of a custom marker image (max 64 kB / 4096 px, e.g. 64x64 PNG)",
                          "format": "uri",
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        },
                        "scale": {
                          "description": "Custom icon scale factor (default 1)",
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "paths": {
                    "description": "Extra lines/polygons to draw (e.g. isochrone contours as filled polygons)",
                    "items": {
                      "additionalProperties": false,
                      "description": "A line or filled polygon overlay",
                      "properties": {
                        "fill_color": {
                          "description": "Fill color for a closed shape, e.g. \"rgba(255,0,0,0.3)\" or \"#ff000055\"; omit for a line",
                          "type": "string"
                        },
                        "geojson_coordinates": {
                          "description": "Vertices as GeoJSON [longitude, latitude] pairs - pass an isochrone or GeoJSON ring here unchanged",
                          "items": {
                            "prefixItems": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              }
                            ],
                            "type": "array"
                          },
                          "minItems": 2,
                          "type": "array"
                        },
                        "points": {
                          "description": "Vertices as {latitude, longitude} objects",
                          "items": {
                            "additionalProperties": false,
                            "properties": {
                              "latitude": {
                                "maximum": 90,
                                "minimum": -90,
                                "type": "number"
                              },
                              "longitude": {
                                "maximum": 180,
                                "minimum": -180,
                                "type": "number"
                              }
                            },
                            "required": [
                              "latitude",
                              "longitude"
                            ],
                            "type": "object"
                          },
                          "minItems": 2,
                          "type": "array"
                        },
                        "stroke_color": {
                          "description": "Line color (default blue)",
                          "type": "string"
                        },
                        "stroke_width": {
                          "description": "Line width in px (default 3)",
                          "maximum": 20,
                          "minimum": 1,
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    },
                    "maxItems": 10,
                    "type": "array"
                  },
                  "retina": {
                    "description": "Render at @2x resolution for high-DPI displays",
                    "type": "boolean"
                  },
                  "style": {
                    "description": "Map style id: \"streets\", \"light\", \"dark\", or \"hybrid\" (default streets)",
                    "type": "string"
                  },
                  "width": {
                    "description": "Image width in pixels (default 512)",
                    "maximum": 2048,
                    "minimum": 16,
                    "type": "integer"
                  },
                  "zoom": {
                    "description": "Zoom level (0 = world, ~10 = city, ~15 = streets; fractional values allowed)",
                    "maximum": 22,
                    "minimum": 0,
                    "type": "number"
                  }
                },
                "required": [
                  "center",
                  "zoom"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "static_route_map",
              "title": "Static Route Map",
              "description": "Render a static map auto-fitted to a route and/or overlays: a route from directions, and/or lines and filled polygons such as isochrone contours; very long geometry is simplified automatically to fit the map API URL limit (distances unaffected). Returns the image inline. Parameters: at least one of encoded_polyline (the geometry string from directions, preferred), route_points (array of {latitude, longitude}) or paths (array of {points OR geojson_coordinates [[longitude, latitude], ...], stroke_color, stroke_width, fill_color}); optional markers (array of {latitude, longitude, color, icon_url, anchor, scale}), stroke_color, stroke_width (route line), padding, width, height, style, format, retina. The example draws isochrone contours. Example: {\"paths\": [{\"geojson_coordinates\": [[-122.42, 37.77], [-122.40, 37.78], [-122.41, 37.79], [-122.42, 37.77]], \"fill_color\": \"rgba(29,78,216,0.35)\", \"stroke_color\": \"#1d4ed8\"}], \"markers\": [{\"latitude\": 37.7749, \"longitude\": -122.4194, \"color\": \"red\"}]}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "encoded_polyline": {
                    "description": "Route geometry as a Google encoded polyline (precision 5) — exactly what the directions tool returns with its default geometry setting",
                    "type": "string"
                  },
                  "format": {
                    "description": "Image format (default png)",
                    "enum": [
                      "png",
                      "jpg",
                      "webp"
                    ],
                    "type": "string"
                  },
                  "height": {
                    "description": "Image height in pixels (default 512)",
                    "maximum": 2048,
                    "minimum": 16,
                    "type": "integer"
                  },
                  "markers": {
                    "description": "Extra markers, e.g. origin and destination, with optional color or custom icon",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "anchor": {
                          "description": "Anchor point of a custom icon (default bottom)",
                          "enum": [
                            "top",
                            "left",
                            "bottom",
                            "right",
                            "center",
                            "topleft",
                            "bottomleft",
                            "topright",
                            "bottomright"
                          ],
                          "type": "string"
                        },
                        "color": {
                          "description": "Marker color, e.g. \"red\" or \"#0000ff\" (ignored when icon_url is set)",
                          "type": "string"
                        },
                        "icon_url": {
                          "description": "URL of a custom marker image (max 64 kB / 4096 px, e.g. 64x64 PNG)",
                          "format": "uri",
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        },
                        "scale": {
                          "description": "Custom icon scale factor (default 1)",
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "padding": {
                    "description": "Margin around the route as a fraction of image size (default 0.1)",
                    "maximum": 1,
                    "minimum": 0,
                    "type": "number"
                  },
                  "paths": {
                    "description": "Extra lines/polygons to draw (e.g. isochrone contours as filled polygons)",
                    "items": {
                      "additionalProperties": false,
                      "description": "A line or filled polygon overlay",
                      "properties": {
                        "fill_color": {
                          "description": "Fill color for a closed shape, e.g. \"rgba(255,0,0,0.3)\" or \"#ff000055\"; omit for a line",
                          "type": "string"
                        },
                        "geojson_coordinates": {
                          "description": "Vertices as GeoJSON [longitude, latitude] pairs - pass an isochrone or GeoJSON ring here unchanged",
                          "items": {
                            "prefixItems": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              }
                            ],
                            "type": "array"
                          },
                          "minItems": 2,
                          "type": "array"
                        },
                        "points": {
                          "description": "Vertices as {latitude, longitude} objects",
                          "items": {
                            "additionalProperties": false,
                            "properties": {
                              "latitude": {
                                "maximum": 90,
                                "minimum": -90,
                                "type": "number"
                              },
                              "longitude": {
                                "maximum": 180,
                                "minimum": -180,
                                "type": "number"
                              }
                            },
                            "required": [
                              "latitude",
                              "longitude"
                            ],
                            "type": "object"
                          },
                          "minItems": 2,
                          "type": "array"
                        },
                        "stroke_color": {
                          "description": "Line color (default blue)",
                          "type": "string"
                        },
                        "stroke_width": {
                          "description": "Line width in px (default 3)",
                          "maximum": 20,
                          "minimum": 1,
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    },
                    "maxItems": 10,
                    "type": "array"
                  },
                  "retina": {
                    "description": "Render at @2x resolution for high-DPI displays",
                    "type": "boolean"
                  },
                  "route_points": {
                    "description": "Alternative to encoded_polyline: the route as an ordered list of coordinates",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "minItems": 2,
                    "type": "array"
                  },
                  "stroke_color": {
                    "description": "Route line color (e.g. \"blue\", \"#ff0000\"; default blue)",
                    "type": "string"
                  },
                  "stroke_width": {
                    "description": "Route line width in pixels (default 4)",
                    "maximum": 20,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "style": {
                    "description": "Map style id: \"streets\", \"light\", \"dark\", or \"hybrid\" (default streets)",
                    "type": "string"
                  },
                  "width": {
                    "description": "Image width in pixels (default 512)",
                    "maximum": 2048,
                    "minimum": 16,
                    "type": "integer"
                  }
                },
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            }
          ],
          "schemaTokens": 17777,
          "changedAt": "2026-11-07T01:46:25.213284458Z",
          "check": {
            "checker": "anchor-check/1.0",
            "totalTokens": 17777,
            "counts": {
              "error": 0,
              "note": 1,
              "warn": 6
            },
            "findings": [
              {
                "rule": "TC11",
                "severity": "warn",
                "tool": "bbox",
                "message": "3 parameters without a description: points, points[].latitude, points[].longitude",
                "fix": "Describe each one: format, units, an example, and what happens when it's left out."
              },
              {
                "rule": "TC11",
                "severity": "warn",
                "tool": "geocode_structured",
                "message": "8 parameters without a description: city, county, house_number, neighborhood, postal_code, state and 2 more",
                "fix": "Describe each one: format, units, an example, and what happens when it's left out."
              },
              {
                "rule": "TC13",
                "severity": "warn",
                "tool": "static_map_image",
                "message": "paths[].geojson_coordinates[] (array with no items)",
                "fix": "Declare the properties (or additionalProperties with a schema) and the array's items."
              },
              {
                "rule": "TC13",
                "severity": "warn",
                "tool": "static_route_map",
                "message": "paths[].geojson_coordinates[] (array with no items)",
                "fix": "Declare the properties (or additionalProperties with a schema) and the array's items."
              },
              {
                "rule": "TC22",
                "severity": "warn",
                "tool": "directions",
                "message": "the definition is about 1,699 tokens",
                "fix": "Trim the description and parameter docs, or split the tool."
              },
              {
                "rule": "TC23",
                "severity": "warn",
                "message": "27 tools, about 17,789 tokens of definitions",
                "fix": "Split the server by job, or offer a smaller default toolset (a read-only set, or a search-then-call pattern)."
              },
              {
                "rule": "TC24",
                "severity": "note",
                "message": "27 of 27 tools have no outputSchema",
                "fix": "Declare outputSchema for tools that return structured data, and return structuredContent that matches it."
              }
            ]
          }
        },
        "updatedAt": "2026-11-07T19:22:21.654883516Z"
      }
    },
    "answer": "NextBillion.ai scores 55.4 (C) on agent readiness against Radar's 53.3 (D), and leads in 4 of 7 scored categories. Radar leads on reliability and security \u0026 auth.",
    "b": {
      "slug": "radar",
      "name": "Radar",
      "vendor": "Radar Labs",
      "vendorUrl": "https://radar.com",
      "kind": "http-api",
      "category": "maps",
      "summary": "Radar is a location platform from Radar Labs with REST APIs for forward, reverse and IP geocoding, address autocomplete and validation, places search, distance, matrix, directions and route optimisation, plus geofencing, trip tracking and base maps.",
      "url": "https://www.anchorterminal.com/tools/radar",
      "markdownUrl": "https://www.anchorterminal.com/tools/radar.md",
      "slimMarkdownUrl": "https://www.anchorterminal.com/tools/radar.min.md",
      "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/radar.json",
      "dns": "radar.grade.anchorterminal.com",
      "repo": "https://github.com/radarlabs/radar-sdk-js",
      "license": "Proprietary service under Radar's Terms of Use. The web SDK in radarlabs/radar-sdk-js is Apache-2.0",
      "transports": [
        "http"
      ],
      "remoteUrl": "https://api.radar.io/v1",
      "packages": [
        {
          "registry": "npm",
          "name": "radar-sdk-js"
        }
      ],
      "auth": "api-key",
      "authNotes": "API key in the `Authorization` header, with no query-string option documented. Each project has four keys, test and live, publishable and secret. Publishable keys reach 16 of the 38 documented operations (4 November 2026), including all geocoding, search and routing calls, and can be restricted by website domain or mobile app identifier. Secret keys reach the rest and can read or write any data. Keys come from the dashboard. Whether sign-up is self-serve was not established, because dashboard.radar.com's robots.txt closes every path.",
      "pricing": "paid",
      "pricingNotes": "Core Maps (forward, reverse and IP geocoding, autocomplete, static maps, distance, directions, matrix) starts at $0.50 per 1,000 API calls and Premium Maps (address validation, places search, route matching, route optimisation, satellite maps) at $2.00. Matrix bills per element. Every plan is an annual commitment with a monthly quota, at a rate Radar sets by quote. The pricing page says there is no free tier, and that teams can start with a technical validation period arranged with sales (https://radar.com/pricing).",
      "priceSummary": "$0.50 / 1k req",
      "where": "hosted",
      "x402": {
        "level": "no",
        "evidence": "No x402, MPP or L402 in the API reference, the docs index or the pricing page (checked 2026-10-09).",
        "endpoints": []
      },
      "toolCount": null,
      "popularity": {
        "githubStars": null,
        "npmWeekly": null,
        "pypiWeekly": null,
        "asOf": "2026-10-09"
      },
      "docsUrl": "https://docs.radar.com/api",
      "llmsTxt": "https://docs.radar.com/llms.txt",
      "capabilities": [
        "geo.geocode",
        "geo.reverse",
        "geo.places",
        "geo.routing",
        "geo.tiles"
      ],
      "tags": [
        "hosted",
        "api-key",
        "llms-txt",
        "status-page",
        "sales-led",
        "annual-contract",
        "soc2",
        "closed-source"
      ],
      "lastRelease": "2026-10-13",
      "graded": true,
      "anchor": {
        "graded": true,
        "score": 53.3,
        "grade": "D",
        "agentReady": false,
        "rank": 955,
        "ranked": true,
        "rankOf": 1510,
        "categoryRank": 16,
        "methodology": "0.7",
        "run": "2026-10-01",
        "scores": {
          "ergonomics": 65,
          "maintenance": 77,
          "payments": 10,
          "reliability": 70,
          "schema": 50,
          "security": 56,
          "transparency": 55
        },
        "pending": [
          "performance",
          "tasks"
        ],
        "assessment": {
          "confidence": "medium",
          "date": "2026-11-04"
        },
        "negative": -2,
        "negativeNotes": [
          "9 October 2026, re-read 4 November 2026. The Maps product page still says the geocoding APIs come with 'the right to store, reuse, and export results freely' (https://radar.com/product/maps), while section 2(d) of the Terms of Use forbids storing address or point-of-interest data from the geocoding, autocomplete or place search APIs for more than 30 days (https://radar.com/terms) and the geocoding docs repeat the 30-day limit (https://docs.radar.com/maps/geocoding.md). 2 points for a claim the published terms contradict. A quoted enterprise agreement may differ and is not published."
        ],
        "verdict": "Radar documents 38 REST operations in Markdown with a rate limit on each, and its status feed shows two API incidents of elevated errors or latency in 90 days. Access is sales-led. The pricing page says there is no free tier, every plan is an annual commitment, and no OpenAPI description or API changelog was found.",
        "bestFor": "A company that already has a Radar contract, or wants geofencing and trip tracking with geocoding and routing on one key.",
        "strengths": [
          "Each of the 38 documented operations states its key level and a default rate limit, from 10 to 100 requests a second",
          "docs.radar.com publishes llms.txt and a Markdown twin of every page, including the whole API reference in one file",
          "Statuspage history lists two API incidents in the 90 days to 4 November 2026, about an hour of errors and about three hours of latency",
          "Publishable keys are limited to 16 client-safe operations and can be restricted by website domain or mobile app identifier",
          "The DPA names two sub-processors (AWS and MongoDB) and the FAQ states default retention periods"
        ],
        "weaknesses": [
          "The pricing page says Radar has no free tier and every plan is an annual commitment set by quote",
          "No OpenAPI description and no API changelog were found in the docs index",
          "The terms cap storage of geocoding, autocomplete and place results at 30 days, while the Maps product page claims a right to store results freely",
          "The terms of 24 May 2023 let Radar change or stop the services without notice, and still describe a free version",
          "A secret key can read or write any project data, with no scopes found",
          "The terms forbid using the services to develop or test other geocoding, autocomplete or place search APIs, which matters before any probe is run"
        ],
        "agentNotes": [
          "Send the key in the `Authorization` header with no `Bearer` prefix, and call `https://api.radar.io/v1`, not radar.com",
          "Use a publishable key for geocoding, search and routing. Keep the secret key for users, trips, geofences and beacons",
          "Call `/v1/search/autocomplete` for partial addresses and place names. `/v1/geocode/forward` is documented as best for complete addresses",
          "Set `units=metric` on routing calls. The default is imperial, with distances in feet",
          "Treat 429 as one of three things (rate limit, no state change or selective throttling) and 402 as usage exceeded. No Retry-After header is documented",
          "Do not keep geocoding, autocomplete or place results for more than 30 days"
        ],
        "metrics": {
          "kind": "remote",
          "measured": false
        },
        "reviewCount": 0,
        "avgRating": 0,
        "history": [
          {
            "basis": "public evidence",
            "confidence": "medium",
            "grade": "D",
            "methodology": "0.7",
            "pending": [
              "performance",
              "tasks"
            ],
            "run": "2026-10-01",
            "runLabel": "October 2026 research run",
            "score": 53.3
          }
        ],
        "editorialScores": {
          "ergonomics": 65,
          "maintenance": 77,
          "payments": 10,
          "reliability": 70,
          "schema": 50,
          "security": 56,
          "transparency": 51
        },
        "provenanceScore": 59,
        "checked": {
          "categories": {
            "ergonomics": "2026-11-04",
            "maintenance": "2026-11-04",
            "payments": "2026-11-04",
            "reliability": "2026-11-04",
            "schema": "2026-11-04",
            "security": "2026-11-04",
            "transparency": "2026-11-04"
          },
          "last": "2026-11-04",
          "oldest": "2026-11-04",
          "stale": false,
          "staleAfterDays": 90
        }
      },
      "connect": {
        "install": "npm install radar-sdk-js",
        "http": "curl \"https://api.radar.io/v1/geocode/forward?query=20+jay+st+brooklyn+ny\" -H \"Authorization: $RADAR_PUBLISHABLE_KEY\""
      },
      "letme": {
        "capability": "https://letme.dev/geo.geocode",
        "tool": "https://letme.dev/radar"
      },
      "area": "everyday",
      "unitPrices": [
        {
          "item": "Core Maps API calls, starting price",
          "unit": "1k-requests",
          "usd": 0.5,
          "note": "Geocoding, autocomplete, static maps, distance, directions, matrix (per element). Annual commitment, rate set by quote"
        },
        {
          "item": "Premium Maps API calls, starting price",
          "unit": "1k-requests",
          "usd": 2,
          "note": "Address validation, places search, route matching, route optimisation, satellite maps. Annual commitment, rate set by quote"
        }
      ],
      "provenance": {
        "legalEntity": "Radar Labs, Inc.",
        "domain": "radar.com",
        "domainRegistered": "1994-12-16",
        "endpointOnVendorDomain": false,
        "terms": "https://radar.com/terms",
        "privacy": "https://radar.com/privacy",
        "statusPage": "https://status.radar.com",
        "changelog": "",
        "securityTxt": "none",
        "checked": "2026-11-04",
        "notes": [
          "The privacy notice (last updated 13 May 2025) names Radar Labs, Inc., a Delaware corporation in New York, per the 9 October 2026 check.",
          "The Terms of Use (last updated 24 May 2023, re-read 4 November 2026) cover the SDK and Radar's APIs and incorporate the DPA at radar.com/dpa. They describe a free version, which the pricing page says Radar does not have. They contain no clause on automated access to the website. Paid plans are by quote, and no enterprise agreement is published.",
          "The API answers at api.radar.io, a second domain. Nothing was sent to it, and its registrant was not checked.",
          "radar.com/.well-known/security.txt answers 404 (4 November 2026). The FAQ gives security@radar.com for reports.",
          "No API changelog was found in the docs index (4 November 2026). The SDK repositories have dated release tags.",
          "RDAP gave 16 December 1994 as the registration date of radar.com on 9 October 2026 (not re-read; RDAP is a JSON service).",
          "robots.txt on 4 November 2026. radar.com 200 with a sitemap line only. docs.radar.com 200 for all agents, /cdn-cgi/ and /_next/ disallowed, Content-Signal ai-train=yes, search=yes, ai-input=yes. status.radar.com 200 disallowing /api/ and /embed/. dashboard.radar.com disallowed every path on 9 October (not re-read)."
        ],
        "score": 59
      },
      "pageJsonUrl": "https://www.anchorterminal.com/tools/radar.json",
      "live": {
        "slug": "radar",
        "probe": {
          "target": "https://api.radar.io/v1",
          "method": "get",
          "lastAt": "2026-11-07T19:22:28.638139376Z",
          "lastOk": true,
          "lastStatus": 404,
          "lastMs": 132,
          "authRequired": false,
          "uptime24h": 100,
          "uptime30d": 99.93,
          "p50ms24h": 127,
          "p95ms24h": 229,
          "samples24h": 238,
          "samples30d": 7215,
          "days": [
            {
              "date": "2026-10-09",
              "probes": 85,
              "ok": 85
            },
            {
              "date": "2026-10-10",
              "probes": 247,
              "ok": 247
            },
            {
              "date": "2026-10-11",
              "probes": 247,
              "ok": 247
            },
            {
              "date": "2026-10-12",
              "probes": 247,
              "ok": 247
            },
            {
              "date": "2026-10-13",
              "probes": 248,
              "ok": 248
            },
            {
              "date": "2026-10-14",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-10-15",
              "probes": 253,
              "ok": 253
            },
            {
              "date": "2026-10-16",
              "probes": 252,
              "ok": 252
            },
            {
              "date": "2026-10-17",
              "probes": 253,
              "ok": 253
            },
            {
              "date": "2026-10-18",
              "probes": 256,
              "ok": 256
            },
            {
              "date": "2026-10-19",
              "probes": 255,
              "ok": 255
            },
            {
              "date": "2026-10-20",
              "probes": 252,
              "ok": 252
            },
            {
              "date": "2026-10-21",
              "probes": 253,
              "ok": 253
            },
            {
              "date": "2026-10-22",
              "probes": 253,
              "ok": 253
            },
            {
              "date": "2026-10-23",
              "probes": 248,
              "ok": 248
            },
            {
              "date": "2026-10-24",
              "probes": 251,
              "ok": 251
            },
            {
              "date": "2026-10-25",
              "probes": 250,
              "ok": 250
            },
            {
              "date": "2026-10-26",
              "probes": 252,
              "ok": 252
            },
            {
              "date": "2026-10-27",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-10-28",
              "probes": 250,
              "ok": 250
            },
            {
              "date": "2026-10-29",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-10-30",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-10-31",
              "probes": 251,
              "ok": 251
            },
            {
              "date": "2026-11-01",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-11-02",
              "probes": 250,
              "ok": 250
            },
            {
              "date": "2026-11-03",
              "probes": 248,
              "ok": 243
            },
            {
              "date": "2026-11-04",
              "probes": 246,
              "ok": 246
            },
            {
              "date": "2026-11-05",
              "probes": 185,
              "ok": 185
            },
            {
              "date": "2026-11-06",
              "probes": 241,
              "ok": 241
            },
            {
              "date": "2026-11-07",
              "probes": 197,
              "ok": 197
            }
          ],
          "outages": [
            {
              "start": "2026-11-03T11:49:09.103056402Z",
              "end": "2026-11-03T12:18:34.21468377Z",
              "note": "timed out"
            }
          ]
        },
        "vendorStatus": {
          "page": "https://status.radar.com",
          "indicator": "none",
          "summary": "All Systems Operational",
          "checkedAt": "2026-11-07T19:23:33.704456906Z"
        },
        "versions": [
          {
            "registry": "github",
            "name": "radarlabs/radar-sdk-js",
            "version": "maps-v1.2.0",
            "released": "2026-10-15",
            "seenAt": "2026-11-07T00:00:04.44338016Z"
          },
          {
            "registry": "npm",
            "name": "radar-sdk-js",
            "version": "5.2.0",
            "seenAt": "2026-11-07T00:00:02.395906253Z"
          }
        ],
        "githubStars": 52,
        "npmWeekly": 127337,
        "securityTxt": {
          "url": "https://radar.com/.well-known/security.txt",
          "state": "none",
          "checkedAt": "2026-11-07T16:01:06.937447505Z"
        },
        "llmsTxt": {
          "url": "https://docs.radar.com/llms.txt",
          "ok": true,
          "status": 200,
          "checkedAt": "2026-11-07T15:33:43.359883875Z"
        },
        "domain": {
          "domain": "radar.com",
          "registered": "1994-12-16",
          "source": "https://rdap.verisign.com/com/v1/domain/radar.com",
          "checkedAt": "2026-11-01T14:26:44.033610339Z"
        },
        "pages": [
          {
            "url": "https://radar.com/pricing",
            "kind": "pricing",
            "status": 200,
            "checkedAt": "2026-11-07T14:17:52.554845922Z",
            "changedAt": "2026-11-06T13:39:31.015729856Z",
            "fingerprint": "34830dec8146"
          },
          {
            "url": "https://radar.com/privacy",
            "kind": "privacy",
            "status": 200,
            "checkedAt": "2026-11-07T14:17:54.663856655Z",
            "changedAt": "2026-11-06T13:39:33.138157539Z",
            "fingerprint": "3c21c931b16e"
          },
          {
            "url": "https://radar.com/terms",
            "kind": "terms",
            "status": 200,
            "checkedAt": "2026-11-07T14:17:56.689904287Z",
            "changedAt": "2026-11-06T13:39:35.353975966Z",
            "fingerprint": "854a0ce74930"
          }
        ],
        "github": {
          "repo": "radarlabs/radar-sdk-js",
          "checkedAt": "2026-11-02T09:20:06.168958113Z",
          "stars": 52,
          "archived": false,
          "issuesEnabled": true,
          "pushedAt": "2026-10-29T20:13:29Z",
          "openIssues": 4,
          "openPRs": 30,
          "issuesOpened90d": 0,
          "issuesClosed90d": 0,
          "prsMerged90d": 9,
          "ci": {
            "branch": "master",
            "runs": 23,
            "success": 23,
            "failure": 0,
            "other": 0,
            "latest": "success",
            "latestAt": "2026-10-28T22:18:51Z"
          },
          "replies": {
            "sampled": 22,
            "unanswered": 4,
            "medianDays": 96.4
          }
        },
        "updatedAt": "2026-11-07T19:23:33.704456906Z"
      }
    },
    "edges": [
      {
        "by": 25,
        "category": "reliability",
        "leads": "radar",
        "name": "Reliability",
        "reasons": {
          "a": "Hosted lines, for the REST APIs at api.nextbillion.io and the hosted MCP server. A status page at status.nextbillion.io, 'NextBillion.AI API Status', renders only in a browser, and its Statuspage-style JSON paths return 404, so we couldn't see its components (10) or read any history. That's our limit, not a finding, and the rubric gives 5 (5). The API reference states 2,400 queries a minute, or 40 a second, for continuous requests (15). Each endpoint's error table lists 429 as 'QPM or API request count quota reached', with no Retry-After or backoff guidance (5). No SLA found; the terms say access isn't warranted to be uninterrupted (0). The REST APIs are GA. The MCP server is at version 0.5.3 (10). 10+5+15+5+0+10 = 45.",
          "b": "Read with the hosted lines. status.radar.com is a Statuspage site with components for the Geocoding, Search, Routing, Maps, Track and Trips APIs among others (20). Its history feed lists two incidents in the 90 days to 4 November 2026. Elevated API errors on 27 August from 19:31 to 20:34 EDT, and elevated API latencies on 23 October from 11:52 to 14:57 EDT, traced to a Cloudflare incident. Neither states the share of failed requests, and this run reads \"elevated\" errors or latencies as partial, so both are minor (20). Each operation states a default rate limit, 100 requests a second for geocoding down to 10 for matrix and the data operations (15). 429 is documented with three meanings, with no Retry-After header or backoff guidance found, and PUT upserts keyed on `tag` and `externalId` make geofence writes repeatable (5, partial kept). No SLA is published (0). The APIs carry no beta label (10). 20 + 20 + 15 + 5 + 0 + 10 = 70."
        },
        "scores": {
          "a": 45,
          "b": 70
        }
      },
      {
        "by": 23,
        "category": "schema",
        "leads": "nextbillion",
        "name": "Schema \u0026 documentation",
        "reasons": {
          "a": "No OpenAPI document for the REST APIs was found in llms.txt or the docs. The hosted MCP server's 27 tools are defined with Zod schemas, so they carry typed JSON Schema inputs (15 of 25). llms.txt, llms-full.txt and a Markdown file for each docs page (10). Endpoint pages explain each parameter, and MCP tool descriptions say when not to use a tool, such as the geometry tools being straight-line rather than road distance (16). Parameter tables give types, allowed values and defaults, such as `types` and `limit` (default 10), though `in` packs several filters into one string (12). curl examples and a per-endpoint error table with causes (13). The MCP server has a dated changelog. No API changelog or versioned path was found (7). 15+10+16+12+13+7 = 73.",
          "b": "No OpenAPI description or other machine-readable contract was found in the docs index (0). docs.radar.com publishes llms.txt and a Markdown twin of each page, with the whole API reference in one Markdown file of about 154 KB (10). Descriptions say what an operation is for and sometimes when to use another, for example forward geocoding for complete addresses and autocomplete for partial ones (14). Parameters are listed with type, required or optional, ranges and allowed values, though coordinate lists travel as pipe-delimited strings and there is no schema to validate against (11). Every operation has a sample request and response, and there is one list of 12 response codes with one sample error (11). Paths carry `/v1`, and no API changelog was found (4). 0 + 10 + 14 + 11 + 11 + 4 = 50."
        },
        "scores": {
          "a": 73,
          "b": 50
        }
      },
      {
        "by": 12,
        "category": "ergonomics",
        "leads": "nextbillion",
        "name": "Agent ergonomics",
        "reasons": {
          "a": "MCP reading, since the hosted server is the agent surface. 27 tools, four of them for documentation and seven local geometry tools, with shapes simplified to a 500-vertex budget to save context (18). limit, types, country, bbox and circle filters, and batch geocoding of up to 100 queries (16). The error table explains each code, and the MCP masks the key in error text (15). Every API tool is marked readOnlyHint, idempotentHint and not destructive in the source (18). Few required parameters and explicit latitude and longitude objects, but no official server-side SDK, only mobile and web map SDKs (10). 18+16+15+18+10 = 77.",
          "b": "Read as an API. `limit` on search operations (1 to 100), `layers` and `country` filters on geocoding, and optional `geometry` on route optimisation size a response, with no field selection (14). List operations page with `limit` up to 1,000 and date cursors such as `updatedBefore` (16). Errors are JSON with `code`, `param` and `message`, and every response carries `X-Radar-Request-ID` (15). The maps operations only read. Geofence and beacon writes are PUT upserts by external ID, and no idempotency key was found for trip or user creation (10). Most maps calls need one parameter. Official SDKs cover web, iOS, Android and five cross-platform frameworks, all client-side, with no server library found (10). 14 + 16 + 15 + 10 + 10 = 65."
        },
        "scores": {
          "a": 77,
          "b": 65
        }
      },
      {
        "by": 10,
        "category": "security",
        "leads": "radar",
        "name": "Security \u0026 auth",
        "reasons": {
          "a": "The REST APIs take a single `key` query parameter, so a plain key that travels in URLs, which earns 20 less 10. The MCP server adds OAuth 2.1 with PKCE, seals the key into tokens with AES-256-GCM, accepts a Bearer header and stores nothing server-side, so 5 back (15). Every tool is read-only, and keys can carry an IP allowlist (12). Places results are POI and address text with no prompt-injection guidance (7). Usage alerts at 50, 75 and 90 per cent of credits, per the pricing FAQ. No per-call log found (5). /.well-known/security.txt returns 404, and we found no disclosure policy or bug bounty. The about page says the company follows ISO 27001 standards, without naming a certificate (7). 15+12+7+5+7 = 46.",
          "b": "Four keys a project, test and live, publishable and secret, sent in the `Authorization` header only. A secret key can read or write any data and no scopes were found. Key rotation was not read (20). Publishable keys reach only 16 of the 38 documented operations and can be restricted by website domain or mobile app identifier, and dashboard accounts have read, write, admin and owner roles. No confirmation step for deletes (10). Results are addresses and place names from open and commercial datasets, with no prompt-injection guidance (6). Audit logs cover dashboard requests on enterprise plans, and each API response has a request ID (7). security.txt answers 404 (4 November 2026). The FAQ gives a disclosure address, and the DPA states SOC 2 Type II, a yearly third-party penetration test and a bug bounty, with the report on request. The trust centre is script-drawn and was not read (13). 20 + 10 + 6 + 7 + 13 = 56."
        },
        "scores": {
          "a": 46,
          "b": 56
        }
      },
      {
        "by": 10,
        "category": "payments",
        "leads": "nextbillion",
        "name": "Payments \u0026 pricing",
        "reasons": {
          "a": "No x402, MPP or L402 (0). Pricing is by quote, with annual licences per order, asset or API call and no published unit price (0). A 7-day free trial with an API key and 'No credit card required' (20). A person signs up through the console or emails support for a key (0). 0+0+20+0 = 20.",
          "b": "No x402, MPP or L402 (0). The pricing page publishes starting prices without a login, $0.50 per 1,000 calls for Core Maps and $2.00 for Premium Maps, but every plan is an annual commitment at a rate set by quote (10). The pricing page says \"Radar does not currently offer a free tier\", and the technical validation period goes through sales (0). Keys come from a dashboard account, and the sign-up page was closed to us by robots.txt on 9 October, so no programmatic route was found (0). 0 + 10 + 0 + 0 = 10."
        },
        "scores": {
          "a": 20,
          "b": 10
        }
      }
    ],
    "facts": [
      {
        "a": "HTTP API",
        "b": "HTTP API",
        "name": "Kind"
      },
      {
        "a": "NextBillion.ai Pte. Ltd.",
        "b": "Radar Labs",
        "name": "Vendor"
      },
      {
        "a": "https://mcp.nextbillion.io",
        "b": "https://api.radar.io/v1",
        "name": "Hosted endpoint"
      },
      {
        "a": "HTTP, Streamable HTTP",
        "b": "HTTP",
        "name": "Transports"
      },
      {
        "a": "OAuth or key",
        "b": "API key",
        "name": "Auth"
      },
      {
        "a": "Paid",
        "b": "Paid",
        "name": "Pricing"
      },
      {
        "a": "no",
        "b": "no",
        "name": "x402"
      },
      {
        "a": "none",
        "b": "Proprietary service under Radar's Terms of Use. The web SDK in radarlabs/radar-sdk-js is Apache-2.0",
        "name": "Licence"
      },
      {
        "a": "27",
        "b": "none",
        "name": "Tools exposed"
      },
      {
        "a": "yes",
        "b": "no",
        "name": "Read-only variant documented"
      },
      {
        "a": "yes",
        "b": "yes",
        "name": "llms.txt"
      },
      {
        "a": "2026-10-30",
        "b": "2026-10-13",
        "name": "Last release"
      },
      {
        "a": "no date given",
        "b": "2023-05-24",
        "name": "Terms last updated"
      },
      {
        "a": "no date given",
        "b": "2025-05-13",
        "name": "Privacy policy last updated"
      },
      {
        "a": "not found in the text",
        "b": "not found in the text",
        "name": "Customer content may train models"
      },
      {
        "a": "not found in the text",
        "b": "not found in the text",
        "name": "Terms restrict automated access"
      },
      {
        "a": "not found in the text",
        "b": "yes",
        "name": "Terms restrict benchmarking"
      },
      {
        "a": "not found in the text",
        "b": "yes",
        "name": "Terms or service can change without notice"
      },
      {
        "a": "not found in the text",
        "b": "yes",
        "name": "Arbitration or class-action waiver"
      }
    ],
    "faq": [
      {
        "answer": "NextBillion.ai scores 55.4 (C) on agent readiness against Radar's 53.3 (D), and leads in 4 of 7 scored categories. Radar leads on reliability and security \u0026 auth.",
        "question": "Which is better for AI agents, NextBillion.ai or Radar?"
      },
      {
        "answer": "NextBillion.ai takes an API key or an OAuth sign-in. Radar needs an API key.",
        "question": "Do NextBillion.ai and Radar need an API key?"
      },
      {
        "answer": "Yes. NextBillion.ai has a hosted endpoint at https://mcp.nextbillion.io and Radar at https://api.radar.io/v1.",
        "question": "Can an agent call NextBillion.ai and Radar without installing anything?"
      }
    ],
    "goodFor": [
      {
        "aheadOn": [
          "Schema \u0026 documentation, 73 against 50",
          "Agent ergonomics, 77 against 65",
          "Payments \u0026 pricing, 20 against 10"
        ],
        "also": [
          "Free to start without a card"
        ],
        "goodFor": "Fleet and delivery routing, distance matrices and route optimisation with truck profiles, plus geocoding and POI search, for companies ready for an annual contract.",
        "slug": "nextbillion",
        "watchFor": "Pricing is by quote on annual licences, with no public unit prices"
      },
      {
        "aheadOn": [
          "Reliability, 70 against 45",
          "Security \u0026 auth, 56 against 46"
        ],
        "also": null,
        "goodFor": "A company that already has a Radar contract, or wants geofencing and trip tracking with geocoding and routing on one key.",
        "slug": "radar",
        "watchFor": "The pricing page says Radar has no free tier and every plan is an annual commitment set by quote"
      }
    ],
    "history": null,
    "job": {
      "capability": "geo.routing",
      "name": "Geo routing"
    },
    "others": [
      {
        "json": "https://www.anchorterminal.com/compare/amazon-location-vs-nextbillion.json",
        "title": "Amazon Location Service vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/amazon-location-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/amazon-location-vs-radar.json",
        "title": "Amazon Location Service vs Radar",
        "url": "https://www.anchorterminal.com/compare/amazon-location-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-nextbillion.json",
        "title": "ArcGIS Location Platform vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-radar.json",
        "title": "ArcGIS Location Platform vs Radar",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/azure-maps-vs-nextbillion.json",
        "title": "Azure Maps vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/azure-maps-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/azure-maps-vs-radar.json",
        "title": "Azure Maps vs Radar",
        "url": "https://www.anchorterminal.com/compare/azure-maps-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/geoapify-vs-nextbillion.json",
        "title": "Geoapify Location Platform + MCP vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/geoapify-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/geoapify-vs-radar.json",
        "title": "Geoapify Location Platform + MCP vs Radar",
        "url": "https://www.anchorterminal.com/compare/geoapify-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/geocodio-vs-nextbillion.json",
        "title": "Geocodio vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/geocodio-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/geocodio-vs-radar.json",
        "title": "Geocodio vs Radar",
        "url": "https://www.anchorterminal.com/compare/geocodio-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/google-maps-platform-vs-nextbillion.json",
        "title": "Google Maps Platform + Grounding Lite MCP vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/google-maps-platform-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/google-maps-platform-vs-radar.json",
        "title": "Google Maps Platform + Grounding Lite MCP vs Radar",
        "url": "https://www.anchorterminal.com/compare/google-maps-platform-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/here-location-services-vs-nextbillion.json",
        "title": "HERE Location Services vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/here-location-services-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/here-location-services-vs-radar.json",
        "title": "HERE Location Services vs Radar",
        "url": "https://www.anchorterminal.com/compare/here-location-services-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/locationiq-vs-nextbillion.json",
        "title": "LocationIQ vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/locationiq-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/locationiq-vs-radar.json",
        "title": "LocationIQ vs Radar",
        "url": "https://www.anchorterminal.com/compare/locationiq-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/mapbox-vs-nextbillion.json",
        "title": "Mapbox APIs + MCP vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/mapbox-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/mapbox-vs-radar.json",
        "title": "Mapbox APIs + MCP vs Radar",
        "url": "https://www.anchorterminal.com/compare/mapbox-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/mapquest-vs-nextbillion.json",
        "title": "MapQuest vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/mapquest-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/mapquest-vs-radar.json",
        "title": "MapQuest vs Radar",
        "url": "https://www.anchorterminal.com/compare/mapquest-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/maptiler-vs-nextbillion.json",
        "title": "MapTiler Cloud vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/maptiler-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/maptiler-vs-radar.json",
        "title": "MapTiler Cloud vs Radar",
        "url": "https://www.anchorterminal.com/compare/maptiler-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nextbillion-vs-nominatim.json",
        "title": "NextBillion.ai vs Nominatim",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-nominatim"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nextbillion-vs-opencage.json",
        "title": "NextBillion.ai vs OpenCage Geocoding API",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-opencage"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nominatim-vs-radar.json",
        "title": "Nominatim vs Radar",
        "url": "https://www.anchorterminal.com/compare/nominatim-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/opencage-vs-radar.json",
        "title": "OpenCage Geocoding API vs Radar",
        "url": "https://www.anchorterminal.com/compare/opencage-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/radar-vs-stadia-maps.json",
        "title": "Radar vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/radar-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/radar-vs-tomtom.json",
        "title": "Radar vs TomTom Maps APIs + MCP",
        "url": "https://www.anchorterminal.com/compare/radar-vs-tomtom"
      },
      {
        "json": "https://www.anchorterminal.com/compare/radar-vs-woosmap.json",
        "title": "Radar vs Woosmap",
        "url": "https://www.anchorterminal.com/compare/radar-vs-woosmap"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nextbillion-vs-stadia-maps.json",
        "title": "NextBillion.ai vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nextbillion-vs-tomtom.json",
        "title": "NextBillion.ai vs TomTom Maps APIs + MCP",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-tomtom"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nextbillion-vs-woosmap.json",
        "title": "NextBillion.ai vs Woosmap",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-woosmap"
      }
    ],
    "panel": null,
    "scores": [
      {
        "by": 25,
        "edge": "radar",
        "key": "reliability",
        "name": "Reliability",
        "nextbillion": 45,
        "radar": 70,
        "weight": 16
      },
      {
        "key": "performance",
        "name": "Performance",
        "pending": true,
        "weight": 10
      },
      {
        "by": 23,
        "edge": "nextbillion",
        "key": "schema",
        "name": "Schema \u0026 documentation",
        "nextbillion": 73,
        "radar": 50,
        "weight": 13
      },
      {
        "by": 12,
        "edge": "nextbillion",
        "key": "ergonomics",
        "name": "Agent ergonomics",
        "nextbillion": 77,
        "radar": 65,
        "weight": 13
      },
      {
        "by": 10,
        "edge": "radar",
        "key": "security",
        "name": "Security \u0026 auth",
        "nextbillion": 46,
        "radar": 56,
        "weight": 14
      },
      {
        "by": 10,
        "edge": "nextbillion",
        "key": "payments",
        "name": "Payments \u0026 pricing",
        "nextbillion": 20,
        "radar": 10,
        "weight": 10
      },
      {
        "key": "tasks",
        "name": "Task success",
        "pending": true,
        "weight": 10
      },
      {
        "by": 4,
        "edge": "radar",
        "key": "maintenance",
        "name": "Maintenance \u0026 community",
        "nextbillion": 73,
        "radar": 77,
        "weight": 7
      },
      {
        "by": 3,
        "edge": "nextbillion",
        "key": "transparency",
        "name": "Transparency \u0026 trust",
        "nextbillion": 58,
        "radar": 55,
        "weight": 7
      }
    ],
    "summary": "NextBillion.ai scores 55.4 (C) on agent readiness against Radar's 53.3 (D), and leads in 4 of 7 scored categories. Radar leads on reliability and security \u0026 auth. Both do geo routing.",
    "tasks": null,
    "tutorials": [],
    "verdicts": {
      "nextbillion": "NextBillion.ai covers routing, distance matrices, route optimisation, geocoding and places, and runs a hosted MCP server with 27 read-only annotated tools and OAuth sign-in. Pricing is by quote on annual licences, the REST API key travels in the query string, and no OpenAPI spec, API changelog or readable status history was found.",
      "radar": "Radar documents 38 REST operations in Markdown with a rate limit on each, and its status feed shows two API incidents of elevated errors or latency in 90 days. Access is sales-led. The pricing page says there is no free tier, every plan is an annual commitment, and no OpenAPI description or API changelog was found."
    }
  },
  "kind": "anchor.page",
  "links": {
    "api": "https://www.anchorterminal.com/api/v1/index.json",
    "html": "https://www.anchorterminal.com/compare/nextbillion-vs-radar",
    "json": "https://www.anchorterminal.com/compare/nextbillion-vs-radar.json",
    "llms": "https://www.anchorterminal.com/llms.txt",
    "markdown": "https://www.anchorterminal.com/compare/nextbillion-vs-radar.md",
    "mcp": "https://www.anchorterminal.com/mcp",
    "slim": "https://www.anchorterminal.com/compare/nextbillion-vs-radar.min.md"
  },
  "markdown": "NextBillion.ai scores 55.4 (C) on agent readiness against Radar's 53.3 (D), and leads in 4 of 7 scored categories. Radar leads on reliability and security \u0026 auth. Both do geo routing.\n\n- NextBillion.ai: grade C, 55.4/100, rank #874 of 1510. Markdown https://www.anchorterminal.com/tools/nextbillion.md · JSON https://www.anchorterminal.com/api/v1/tools/nextbillion.json\n- Radar: grade D, 53.3/100, rank #955 of 1510. Markdown https://www.anchorterminal.com/tools/radar.md · JSON https://www.anchorterminal.com/api/v1/tools/radar.json\n- Best maps, geocoding and places APIs for AI agents: https://www.anchorterminal.com/best/maps/index.md\n- All 153 maps comparisons: https://www.anchorterminal.com/compare/maps/index.md\n\n## Which one, for what\n\n### NextBillion.ai (C)\n\nGood for: Fleet and delivery routing, distance matrices and route optimisation with truck profiles, plus geocoding and POI search, for companies ready for an annual contract.\n\nAhead on:\n- Schema \u0026 documentation, 73 against 50\n- Agent ergonomics, 77 against 65\n- Payments \u0026 pricing, 20 against 10\n\nAlso in its favour:\n- Free to start without a card\n\nWatch for: Pricing is by quote on annual licences, with no public unit prices\n\n### Radar (D)\n\nGood for: A company that already has a Radar contract, or wants geofencing and trip tracking with geocoding and routing on one key.\n\nAhead on:\n- Reliability, 70 against 45\n- Security \u0026 auth, 56 against 46\n\nWatch for: The pricing page says Radar has no free tier and every plan is an annual commitment set by quote\n\n\n## Why the edge\n\n### Reliability: Radar +25\n\n- NextBillion.ai (45): Hosted lines, for the REST APIs at api.nextbillion.io and the hosted MCP server. A status page at status.nextbillion.io, 'NextBillion.AI API Status', renders only in a browser, and its Statuspage-style JSON paths return 404, so we couldn't see its components (10) or read any history. That's our limit, not a finding, and the rubric gives 5 (5). The API reference states 2,400 queries a minute, or 40 a second, for continuous requests (15). Each endpoint's error table lists 429 as 'QPM or API request count quota reached', with no Retry-After or backoff guidance (5). No SLA found; the terms say access isn't warranted to be uninterrupted (0). The REST APIs are GA. The MCP server is at version 0.5.3 (10). 10+5+15+5+0+10 = 45.\n- Radar (70): Read with the hosted lines. status.radar.com is a Statuspage site with components for the Geocoding, Search, Routing, Maps, Track and Trips APIs among others (20). Its history feed lists two incidents in the 90 days to 4 November 2026. Elevated API errors on 27 August from 19:31 to 20:34 EDT, and elevated API latencies on 23 October from 11:52 to 14:57 EDT, traced to a Cloudflare incident. Neither states the share of failed requests, and this run reads \"elevated\" errors or latencies as partial, so both are minor (20). Each operation states a default rate limit, 100 requests a second for geocoding down to 10 for matrix and the data operations (15). 429 is documented with three meanings, with no Retry-After header or backoff guidance found, and PUT upserts keyed on `tag` and `externalId` make geofence writes repeatable (5, partial kept). No SLA is published (0). The APIs carry no beta label (10). 20 + 20 + 15 + 5 + 0 + 10 = 70.\n\n### Schema \u0026 documentation: NextBillion.ai +23\n\n- NextBillion.ai (73): No OpenAPI document for the REST APIs was found in llms.txt or the docs. The hosted MCP server's 27 tools are defined with Zod schemas, so they carry typed JSON Schema inputs (15 of 25). llms.txt, llms-full.txt and a Markdown file for each docs page (10). Endpoint pages explain each parameter, and MCP tool descriptions say when not to use a tool, such as the geometry tools being straight-line rather than road distance (16). Parameter tables give types, allowed values and defaults, such as `types` and `limit` (default 10), though `in` packs several filters into one string (12). curl examples and a per-endpoint error table with causes (13). The MCP server has a dated changelog. No API changelog or versioned path was found (7). 15+10+16+12+13+7 = 73.\n- Radar (50): No OpenAPI description or other machine-readable contract was found in the docs index (0). docs.radar.com publishes llms.txt and a Markdown twin of each page, with the whole API reference in one Markdown file of about 154 KB (10). Descriptions say what an operation is for and sometimes when to use another, for example forward geocoding for complete addresses and autocomplete for partial ones (14). Parameters are listed with type, required or optional, ranges and allowed values, though coordinate lists travel as pipe-delimited strings and there is no schema to validate against (11). Every operation has a sample request and response, and there is one list of 12 response codes with one sample error (11). Paths carry `/v1`, and no API changelog was found (4). 0 + 10 + 14 + 11 + 11 + 4 = 50.\n\n### Agent ergonomics: NextBillion.ai +12\n\n- NextBillion.ai (77): MCP reading, since the hosted server is the agent surface. 27 tools, four of them for documentation and seven local geometry tools, with shapes simplified to a 500-vertex budget to save context (18). limit, types, country, bbox and circle filters, and batch geocoding of up to 100 queries (16). The error table explains each code, and the MCP masks the key in error text (15). Every API tool is marked readOnlyHint, idempotentHint and not destructive in the source (18). Few required parameters and explicit latitude and longitude objects, but no official server-side SDK, only mobile and web map SDKs (10). 18+16+15+18+10 = 77.\n- Radar (65): Read as an API. `limit` on search operations (1 to 100), `layers` and `country` filters on geocoding, and optional `geometry` on route optimisation size a response, with no field selection (14). List operations page with `limit` up to 1,000 and date cursors such as `updatedBefore` (16). Errors are JSON with `code`, `param` and `message`, and every response carries `X-Radar-Request-ID` (15). The maps operations only read. Geofence and beacon writes are PUT upserts by external ID, and no idempotency key was found for trip or user creation (10). Most maps calls need one parameter. Official SDKs cover web, iOS, Android and five cross-platform frameworks, all client-side, with no server library found (10). 14 + 16 + 15 + 10 + 10 = 65.\n\n### Security \u0026 auth: Radar +10\n\n- NextBillion.ai (46): The REST APIs take a single `key` query parameter, so a plain key that travels in URLs, which earns 20 less 10. The MCP server adds OAuth 2.1 with PKCE, seals the key into tokens with AES-256-GCM, accepts a Bearer header and stores nothing server-side, so 5 back (15). Every tool is read-only, and keys can carry an IP allowlist (12). Places results are POI and address text with no prompt-injection guidance (7). Usage alerts at 50, 75 and 90 per cent of credits, per the pricing FAQ. No per-call log found (5). /.well-known/security.txt returns 404, and we found no disclosure policy or bug bounty. The about page says the company follows ISO 27001 standards, without naming a certificate (7). 15+12+7+5+7 = 46.\n- Radar (56): Four keys a project, test and live, publishable and secret, sent in the `Authorization` header only. A secret key can read or write any data and no scopes were found. Key rotation was not read (20). Publishable keys reach only 16 of the 38 documented operations and can be restricted by website domain or mobile app identifier, and dashboard accounts have read, write, admin and owner roles. No confirmation step for deletes (10). Results are addresses and place names from open and commercial datasets, with no prompt-injection guidance (6). Audit logs cover dashboard requests on enterprise plans, and each API response has a request ID (7). security.txt answers 404 (4 November 2026). The FAQ gives a disclosure address, and the DPA states SOC 2 Type II, a yearly third-party penetration test and a bug bounty, with the report on request. The trust centre is script-drawn and was not read (13). 20 + 10 + 6 + 7 + 13 = 56.\n\n### Payments \u0026 pricing: NextBillion.ai +10\n\n- NextBillion.ai (20): No x402, MPP or L402 (0). Pricing is by quote, with annual licences per order, asset or API call and no published unit price (0). A 7-day free trial with an API key and 'No credit card required' (20). A person signs up through the console or emails support for a key (0). 0+0+20+0 = 20.\n- Radar (10): No x402, MPP or L402 (0). The pricing page publishes starting prices without a login, $0.50 per 1,000 calls for Core Maps and $2.00 for Premium Maps, but every plan is an annual commitment at a rate set by quote (10). The pricing page says \"Radar does not currently offer a free tier\", and the technical validation period goes through sales (0). Keys come from a dashboard account, and the sign-up page was closed to us by robots.txt on 9 October, so no programmatic route was found (0). 0 + 10 + 0 + 0 = 10.\n\n## Score by category\n\n| Category | Weight | NextBillion.ai | Radar | Edge |\n| --- | --- | --- | --- | --- |\n| Reliability | 16% (20 this run) | 45 | 70 | Radar +25 |\n| Performance | 10%, pending | pending | pending | not scored in this run |\n| Schema \u0026 documentation | 13% (16.2 this run) | 73 | 50 | NextBillion.ai +23 |\n| Agent ergonomics | 13% (16.2 this run) | 77 | 65 | NextBillion.ai +12 |\n| Security \u0026 auth | 14% (17.5 this run) | 46 | 56 | Radar +10 |\n| Payments \u0026 pricing | 10% (12.5 this run) | 20 | 10 | NextBillion.ai +10 |\n| Task success | 10%, pending | pending | pending | not scored in this run |\n| Maintenance \u0026 community | 7% (8.8 this run) | 73 | 77 | Radar +4 |\n| Transparency \u0026 trust | 7% (8.8 this run) | 58 | 55 | NextBillion.ai +3 |\n| Negative events | ≤15 | 0 | -2 | |\n| **Total** | | **55.4 · C** | **53.3 · D** | |\n\n## Facts side by side\n\n| Fact | NextBillion.ai | Radar |\n| --- | --- | --- |\n| Kind | HTTP API | HTTP API |\n| Vendor | NextBillion.ai Pte. Ltd. | Radar Labs |\n| Hosted endpoint | `https://mcp.nextbillion.io` | `https://api.radar.io/v1` |\n| Transports | HTTP, Streamable HTTP | HTTP |\n| Auth | OAuth or key | API key |\n| Pricing | Paid | Paid |\n| x402 | no | no |\n| Licence | none | Proprietary service under Radar's Terms of Use. The web SDK in radarlabs/radar-sdk-js is Apache-2.0 |\n| Tools exposed | 27 | none |\n| Read-only variant documented | yes | no |\n| llms.txt | yes | yes |\n| Last release | 2026-10-30 | 2026-10-13 |\n| Terms last updated | no date given | 2023-05-24 |\n| Privacy policy last updated | no date given | 2025-05-13 |\n| Customer content may train models | not found in the text | not found in the text |\n| Terms restrict automated access | not found in the text | not found in the text |\n| Terms restrict benchmarking | not found in the text | yes |\n| Terms or service can change without notice | not found in the text | yes |\n| Arbitration or class-action waiver | not found in the text | yes |\n\n## Verdicts\n\n**NextBillion.ai.** NextBillion.ai covers routing, distance matrices, route optimisation, geocoding and places, and runs a hosted MCP server with 27 read-only annotated tools and OAuth sign-in. Pricing is by quote on annual licences, the REST API key travels in the query string, and no OpenAPI spec, API changelog or readable status history was found.\n\n**Radar.** Radar documents 38 REST operations in Markdown with a rate limit on each, and its status feed shows two API incidents of elevated errors or latency in 90 days. Access is sales-led. The pricing page says there is no free tier, every plan is an annual commitment, and no OpenAPI description or API changelog was found.\n\n## Before you call either\n\n### NextBillion.ai\n\n1. Connect through https://mcp.nextbillion.io so the key stays in a Bearer header or OAuth token rather than in request URLs\n2. Use the geometry tools only for straight-line questions; use directions or distance_matrix for travel time\n3. Batch up to 100 geocodes with geocode_batch instead of one call per address\n4. On 429 the quota or the 2,400-a-minute limit is reached; slow down and tell the user if credits are spent\n5. Search the docs with the MCP documentation tools before guessing a parameter\n\n### Radar\n\n1. Send the key in the `Authorization` header with no `Bearer` prefix, and call `https://api.radar.io/v1`, not radar.com\n2. Use a publishable key for geocoding, search and routing. Keep the secret key for users, trips, geofences and beacons\n3. Call `/v1/search/autocomplete` for partial addresses and place names. `/v1/geocode/forward` is documented as best for complete addresses\n4. Set `units=metric` on routing calls. The default is imperial, with distances in feet\n5. Treat 429 as one of three things (rate limit, no state change or selective throttling) and 402 as usage exceeded. No Retry-After header is documented\n6. Do not keep geocoding, autocomplete or place results for more than 30 days\n\n## Questions\n\n### Which is better for AI agents, NextBillion.ai or Radar?\n\nNextBillion.ai scores 55.4 (C) on agent readiness against Radar's 53.3 (D), and leads in 4 of 7 scored categories. Radar leads on reliability and security \u0026 auth.\n\n### Do NextBillion.ai and Radar need an API key?\n\nNextBillion.ai takes an API key or an OAuth sign-in. Radar needs an API key.\n\n### Can an agent call NextBillion.ai and Radar without installing anything?\n\nYes. NextBillion.ai has a hosted endpoint at https://mcp.nextbillion.io and Radar at https://api.radar.io/v1.\n\n\n## For agents\n\n- This comparison as JSON: https://www.anchorterminal.com/compare/nextbillion-vs-radar.json, and with the fewest tokens: https://www.anchorterminal.com/compare/nextbillion-vs-radar.min.md\n- Over MCP at https://www.anchorterminal.com/mcp (no key): `compare_tools {\"a\": \"nextbillion\", \"b\": \"radar\"}`. From a terminal: `anchor compare nextbillion radar`\n- Each listing in full: https://www.anchorterminal.com/api/v1/tools/nextbillion.json and https://www.anchorterminal.com/api/v1/tools/radar.json\n\n## Other comparisons with NextBillion.ai or Radar\n\n- [Amazon Location Service vs NextBillion.ai](https://www.anchorterminal.com/compare/amazon-location-vs-nextbillion.md)\n- [Amazon Location Service vs Radar](https://www.anchorterminal.com/compare/amazon-location-vs-radar.md)\n- [ArcGIS Location Platform vs NextBillion.ai](https://www.anchorterminal.com/compare/arcgis-vs-nextbillion.md)\n- [ArcGIS Location Platform vs Radar](https://www.anchorterminal.com/compare/arcgis-vs-radar.md)\n- [Azure Maps vs NextBillion.ai](https://www.anchorterminal.com/compare/azure-maps-vs-nextbillion.md)\n- [Azure Maps vs Radar](https://www.anchorterminal.com/compare/azure-maps-vs-radar.md)\n- [Geoapify Location Platform + MCP vs NextBillion.ai](https://www.anchorterminal.com/compare/geoapify-vs-nextbillion.md)\n- [Geoapify Location Platform + MCP vs Radar](https://www.anchorterminal.com/compare/geoapify-vs-radar.md)\n- [Geocodio vs NextBillion.ai](https://www.anchorterminal.com/compare/geocodio-vs-nextbillion.md)\n- [Geocodio vs Radar](https://www.anchorterminal.com/compare/geocodio-vs-radar.md)\n- [Google Maps Platform + Grounding Lite MCP vs NextBillion.ai](https://www.anchorterminal.com/compare/google-maps-platform-vs-nextbillion.md)\n- [Google Maps Platform + Grounding Lite MCP vs Radar](https://www.anchorterminal.com/compare/google-maps-platform-vs-radar.md)\n- [HERE Location Services vs NextBillion.ai](https://www.anchorterminal.com/compare/here-location-services-vs-nextbillion.md)\n- [HERE Location Services vs Radar](https://www.anchorterminal.com/compare/here-location-services-vs-radar.md)\n- [LocationIQ vs NextBillion.ai](https://www.anchorterminal.com/compare/locationiq-vs-nextbillion.md)\n- [LocationIQ vs Radar](https://www.anchorterminal.com/compare/locationiq-vs-radar.md)\n- [Mapbox APIs + MCP vs NextBillion.ai](https://www.anchorterminal.com/compare/mapbox-vs-nextbillion.md)\n- [Mapbox APIs + MCP vs Radar](https://www.anchorterminal.com/compare/mapbox-vs-radar.md)\n- [MapQuest vs NextBillion.ai](https://www.anchorterminal.com/compare/mapquest-vs-nextbillion.md)\n- [MapQuest vs Radar](https://www.anchorterminal.com/compare/mapquest-vs-radar.md)\n- [MapTiler Cloud vs NextBillion.ai](https://www.anchorterminal.com/compare/maptiler-vs-nextbillion.md)\n- [MapTiler Cloud vs Radar](https://www.anchorterminal.com/compare/maptiler-vs-radar.md)\n- [NextBillion.ai vs Nominatim](https://www.anchorterminal.com/compare/nextbillion-vs-nominatim.md)\n- [NextBillion.ai vs OpenCage Geocoding API](https://www.anchorterminal.com/compare/nextbillion-vs-opencage.md)\n- [Nominatim vs Radar](https://www.anchorterminal.com/compare/nominatim-vs-radar.md)\n- [OpenCage Geocoding API vs Radar](https://www.anchorterminal.com/compare/opencage-vs-radar.md)\n- [Radar vs Stadia Maps](https://www.anchorterminal.com/compare/radar-vs-stadia-maps.md)\n- [Radar vs TomTom Maps APIs + MCP](https://www.anchorterminal.com/compare/radar-vs-tomtom.md)\n- [Radar vs Woosmap](https://www.anchorterminal.com/compare/radar-vs-woosmap.md)\n- [NextBillion.ai vs Stadia Maps](https://www.anchorterminal.com/compare/nextbillion-vs-stadia-maps.md)\n- [NextBillion.ai vs TomTom Maps APIs + MCP](https://www.anchorterminal.com/compare/nextbillion-vs-tomtom.md)\n- [NextBillion.ai vs Woosmap](https://www.anchorterminal.com/compare/nextbillion-vs-woosmap.md)\n",
  "meta": {
    "attribution": "Anchor Terminal (https://www.anchorterminal.com)",
    "attributionRequired": true,
    "credit": "CC BY 4.0, credit Anchor Terminal and link the page or API address you took it from (https://www.anchorterminal.com/terms/#data)",
    "docs": "https://www.anchorterminal.com/docs/",
    "generatedAt": "2026-11-07",
    "license": "CC-BY-4.0",
    "method": "https://www.anchorterminal.com/benchmark/",
    "methodology": "0.7",
    "openapi": "https://www.anchorterminal.com/openapi.json",
    "preview": false,
    "run": "2026-10-01",
    "runLabel": "October 2026 research run",
    "terms": "https://www.anchorterminal.com/terms/#data"
  },
  "page": {
    "breadcrumbs": [
      {
        "name": "Home",
        "url": "https://www.anchorterminal.com/"
      },
      {
        "name": "Compare",
        "url": "https://www.anchorterminal.com/compare/"
      },
      {
        "name": "NextBillion.ai vs Radar",
        "url": ""
      }
    ],
    "description": "NextBillion.ai scores 55.4 (C) to Radar's 53.3 (D) for geo routing. Prices, MCP, x402, uptime and agent notes side by side.",
    "facts": [
      "NextBillion.ai C 55.4",
      "Radar D 53.3",
      "scores"
    ],
    "h1": "NextBillion.ai vs Radar",
    "image": "https://www.anchorterminal.com/assets/og/default.png",
    "path": "/compare/nextbillion-vs-radar",
    "published": "2026-10-01",
    "section": "tools",
    "title": "NextBillion.ai vs Radar for AI agents in 2026: scores and prices",
    "toc": null,
    "updated": "2026-11-07",
    "url": "https://www.anchorterminal.com/compare/nextbillion-vs-radar"
  },
  "tokens": {
    "markdown": 4500,
    "slim": 2480
  },
  "version": 1
}
