{
  "data": {
    "a": {
      "slug": "arcgis",
      "name": "ArcGIS Location Platform",
      "vendor": "Esri",
      "vendorUrl": "https://location.arcgis.com",
      "kind": "http-api",
      "category": "maps",
      "summary": "Esri's pay-as-you-go location services for developers. REST APIs cover geocoding, reverse and batch geocoding, place search, routing, basemap tiles, static maps, elevation and demographic enrichment, with an Esri-hosted MCP server in beta.",
      "url": "https://www.anchorterminal.com/tools/arcgis",
      "markdownUrl": "https://www.anchorterminal.com/tools/arcgis.md",
      "slimMarkdownUrl": "https://www.anchorterminal.com/tools/arcgis.min.md",
      "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/arcgis.json",
      "dns": "arcgis.grade.anchorterminal.com",
      "repo": "https://github.com/Esri/arcgis-rest-js",
      "license": "Proprietary service under the ArcGIS Location Platform Agreement. The ArcGIS REST JS client library is Apache-2.0",
      "transports": [
        "http",
        "streamable-http"
      ],
      "remoteUrl": "https://geocode-api.arcgis.com",
      "packages": [
        {
          "registry": "npm",
          "name": "@esri/arcgis-rest-geocoding"
        },
        {
          "registry": "npm",
          "name": "@esri/arcgis-rest-request"
        },
        {
          "registry": "pypi",
          "name": "arcgis"
        }
      ],
      "auth": "mixed",
      "authNotes": "Self-serve. A free ArcGIS Location Platform account created in a browser issues API key credentials with selected privileges, an expiry date of up to one year, optional referrer limits and two tokens for rotation. OAuth 2.0 user authentication and app authentication (client ID and secret, short-lived tokens) are also supported. Requests take the token as a `token` parameter or in an `X-Esri-Authorization` or `Authorization` header. Accounts are for one person and may not be shared.",
      "pricing": "freemium",
      "pricingNotes": "Usage-based in US dollars with a monthly free tier and no contract. Free each month are 20,000 unstored geocodes, 20,000 routes, 500 place searches, 2 million basemap tiles, 1,000 static maps and 50,000 elevation points. A payment method (card, purchase order or voucher) is needed only to turn on pay-as-you-go, which services without a free tier, among them stored geocodes, require. The sign-up form is drawn by script and we couldn't read whether it asks for a card.",
      "priceSummary": "$0.50 / 1k req",
      "where": "hosted",
      "x402": {
        "level": "no",
        "evidence": "No x402, MPP or L402 on the pricing page, the billing help or the REST and MCP documentation (checked 2026-10-08).",
        "endpoints": []
      },
      "toolCount": 9,
      "popularity": {
        "githubStars": 392,
        "npmWeekly": 65286,
        "pypiWeekly": 32974,
        "asOf": "2026-10-08"
      },
      "docsUrl": "https://developers.arcgis.com/rest/location-based-services/",
      "capabilities": [
        "geo.geocode",
        "geo.reverse",
        "geo.places",
        "geo.routing",
        "geo.tiles"
      ],
      "tags": [
        "hosted",
        "maps",
        "geocoding",
        "routing",
        "places",
        "api-key",
        "oauth",
        "mcp",
        "beta-mcp",
        "free-tier",
        "usage-priced",
        "sla",
        "status-page",
        "typescript",
        "python"
      ],
      "lastRelease": "2026-10-27",
      "graded": true,
      "anchor": {
        "graded": true,
        "score": 66.1,
        "grade": "B",
        "agentReady": false,
        "rank": 380,
        "ranked": true,
        "rankOf": 1486,
        "categoryRank": 7,
        "methodology": "0.7",
        "run": "2026-10-01",
        "scores": {
          "ergonomics": 78,
          "maintenance": 83,
          "payments": 40,
          "reliability": 70,
          "schema": 61,
          "security": 64,
          "transparency": 69
        },
        "pending": [
          "performance",
          "tasks"
        ],
        "assessment": {
          "confidence": "medium",
          "date": "2026-11-02"
        },
        "negative": 0,
        "verdict": "Per-unit prices are public for every service, with a monthly free tier of 20,000 geocodes and 20,000 routes, keys limited to chosen privileges and a 99.9 per cent SLA. No rate limits or OpenAPI description were found, results may not be stored unless the dearer stored geocode is bought, and the agreement bars benchmarking without written permission.",
        "bestFor": "Organisations already on Esri software, and work that needs demographic enrichment, service areas or fleet routing beside geocoding.",
        "strengths": [
          "Every service has a public unit price and most have a monthly free tier, such as 20,000 geocodes, 20,000 routes and 2 million basemap tiles (https://location.arcgis.com/pricing/).",
          "API key credentials carry selected privileges, an expiry date of up to one year, optional referrer limits and two tokens for rotation. OAuth 2.0 user and app authentication are also supported.",
          "A published SLA commits to 99.9 per cent monthly uptime for ten services, with credits of 10 or 20 per cent of the monthly bill for the affected service (document G632a, 23 December 2025).",
          "The agreement promises 90 days' notice for deprecations of SDKs, APIs and location services (ArcGIS Location Platform Agreement, revised 21 November 2025, section 4.1).",
          "An Esri-hosted MCP server at `https://location-services-mcp.arcgis.com/beta/mcp` has nine tools, filters them by the token's privileges and adds no charge on top of service rates."
        ],
        "weaknesses": [
          "The agreement bars benchmarking availability, performance or functionality, and publishing benchmark results, without prior written permission from Esri and its licensors (sections 3.1.b.6 and 3.1.c.6.F).",
          "No request rate limits, 429 behaviour or retry guidance were found in the geocoding, places or routing reference pages we read.",
          "No OpenAPI description or llms.txt was found. `/llms.txt` returns 404 on developers.arcgis.com and location.arcgis.com.",
          "Storing a geocode needs `forStorage=true` at $4 per 1,000 with no free tier, against $0.50 per 1,000 for results that may not be kept.",
          "The MCP server is a beta under an Early Access programme, and the SLA excludes beta, evaluation and free services. Technical support is sold separately."
        ],
        "agentNotes": [
          "Send the token in an `X-Esri-Authorization: Bearer` or `Authorization` header. The docs' examples put it in a `token` parameter, which Esri's own best-practice page calls less secure.",
          "Set `forStorage=true` on `findAddressCandidates` or `reverseGeocode` only when results will be kept. It needs pay-as-you-go and the Geocode (stored) privilege, and costs eight times the unstored rate.",
          "Cap geocoding output with `maxLocations` (default and maximum 50) and `outFields`, because billing counts results returned and the default returns every field.",
          "Page place searches with `pageSize` (maximum 20) and `offset`. A nearby or extent search costs $8 per 1,000 requests after 500 free a month.",
          "Check the JSON body for an `error` object with `code`, `message` and `details`. Code 499 means the token is missing and 403 means it lacks the privilege."
        ],
        "metrics": {
          "kind": "remote",
          "measured": false
        },
        "reviewCount": 4,
        "avgRating": 3.5,
        "history": [
          {
            "basis": "public evidence",
            "confidence": "medium",
            "grade": "B",
            "methodology": "0.7",
            "pending": [
              "performance",
              "tasks"
            ],
            "run": "2026-10-01",
            "runLabel": "October 2026 research run",
            "score": 66.1
          }
        ],
        "editorialScores": {
          "ergonomics": 78,
          "maintenance": 83,
          "payments": 40,
          "reliability": 70,
          "schema": 61,
          "security": 64,
          "transparency": 54
        },
        "provenanceScore": 83,
        "checked": {
          "categories": {
            "ergonomics": "2026-11-02",
            "maintenance": "2026-11-02",
            "payments": "2026-11-02",
            "reliability": "2026-11-02",
            "schema": "2026-11-02",
            "security": "2026-11-02",
            "transparency": "2026-11-02"
          },
          "last": "2026-11-02",
          "lastMoved": "2026-11-02",
          "oldest": "2026-11-02",
          "stale": false,
          "staleAfterDays": 90
        }
      },
      "connect": {
        "install": "npm install @esri/arcgis-rest-request @esri/arcgis-rest-geocoding",
        "http": "curl https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates \\\n  -d \"f=pjson\" \\\n  -d \"address=1600 Pennsylvania Ave NW, DC\" \\\n  -d \"token=\u003cACCESS_TOKEN\u003e\"",
        "config": {
          "servers": {
            "mcpArcGISLocationServices": {
              "headers": {
                "Authorization": "Bearer ${input:esriApiKey}"
              },
              "type": "http",
              "url": "https://location-services-mcp.arcgis.com/beta/mcp"
            }
          }
        }
      },
      "letme": {
        "capability": "https://letme.dev/geo.geocode",
        "tool": "https://letme.dev/arcgis"
      },
      "area": "everyday",
      "unitPrices": [
        {
          "item": "Geocodes, not stored (after 20,000 free a month)",
          "unit": "1k-requests",
          "usd": 0.5
        },
        {
          "item": "Geocodes, stored (`forStorage=true`, no free tier)",
          "unit": "1k-requests",
          "usd": 4
        },
        {
          "item": "Places nearby and extent search (after 500 free a month)",
          "unit": "1k-requests",
          "usd": 8
        },
        {
          "item": "Routes (after 20,000 free a month)",
          "unit": "1k-requests",
          "usd": 0.5
        },
        {
          "item": "Routes, stop-optimised (no free tier)",
          "unit": "1k-requests",
          "usd": 50
        },
        {
          "item": "Service areas (after 5,000 free a month)",
          "unit": "1k-requests",
          "usd": 50
        },
        {
          "item": "Basemap tiles (after 2 million free a month)",
          "unit": "1k-requests",
          "usd": 0.15
        },
        {
          "item": "Static maps (after 1,000 free a month)",
          "unit": "1k-requests",
          "usd": 0.9
        },
        {
          "item": "Elevation, per 1,000 points (after 50,000 free a month)",
          "unit": "1k-requests",
          "usd": 1
        }
      ],
      "provenance": {
        "legalEntity": "Environmental Systems Research Institute, Inc.",
        "domain": "arcgis.com",
        "domainRegistered": "1999-06-09",
        "endpointOnVendorDomain": true,
        "terms": "https://www.esri.com/content/dam/esrisites/en-us/media/legal/platform/platform-legal.pdf",
        "privacy": "https://www.esri.com/en-us/privacy/privacy-statements/privacy-statement",
        "statusPage": "https://status.location.arcgis.com",
        "changelog": "https://location.arcgis.com/help/release-notes/2026-09/",
        "securityTxt": "none",
        "checked": "2026-11-02",
        "notes": [
          "The ArcGIS Location Platform Agreement (E204 Platform Legal, revised 21 November 2025) is between the customer and Environmental Systems Research Institute, Inc., a California corporation at 380 New York Street, Redlands, California 92373-8100.",
          "The privacy statement (revised 31 July 2026) is the one the product's pages link. Esri also publishes a Products \u0026 Services Privacy Statement Supplement (9 September 2025) and a Data Processing Addendum (12 March 2024). Neither names ArcGIS Location Platform. The agreement's section 11.5 points to the addendum.",
          "The services answer on arcgis.com subdomains, among them geocode-api.arcgis.com, places-api.arcgis.com and location-services-mcp.arcgis.com.",
          "`/.well-known/security.txt` returns 404 on www.esri.com, developers.arcgis.com, location.arcgis.com and www.arcgis.com (developers and location re-read on 2 November 2026). The trust centre takes reports through a form, with a PGP key and a safe harbour statement.",
          "RDAP gives 1999-06-09 for arcgis.com and 1990-04-18 for esri.com, both registered through MarkMonitor Inc.",
          "The status page is Esri's own. Its event history is drawn by script, so we read the platform's RSS feed (all.rss, titled ArcGIS Location Platform Services Status), whose newest entry on 2 November 2026 is still dated 16 June 2026. The page's \"all services RSS feed\" link points at location_platform.rss, which answered 404 that day.",
          "The platform release notes moved on to a September 2026 page (Static Maps polygon and overlay endpoints, the MCP service, pay-as-you-go moved to the payment methods page, a fix for an API key validation bug in geocoding and routing)."
        ],
        "score": 83
      },
      "pageJsonUrl": "https://www.anchorterminal.com/tools/arcgis.json",
      "live": {
        "slug": "arcgis",
        "probe": {
          "target": "https://geocode-api.arcgis.com",
          "method": "get",
          "lastAt": "2026-11-07T18:20:10.912928956Z",
          "lastOk": true,
          "lastStatus": 200,
          "lastMs": 217,
          "authRequired": false,
          "uptime24h": 100,
          "uptime30d": 100,
          "p50ms24h": 154,
          "p95ms24h": 283,
          "samples24h": 239,
          "samples30d": 7420,
          "days": [
            {
              "date": "2026-10-08",
              "probes": 50,
              "ok": 50
            },
            {
              "date": "2026-10-09",
              "probes": 250,
              "ok": 250
            },
            {
              "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": 251,
              "ok": 251
            },
            {
              "date": "2026-10-29",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-10-30",
              "probes": 248,
              "ok": 248
            },
            {
              "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": 248
            },
            {
              "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": 187,
              "ok": 187
            }
          ]
        },
        "vendorStatus": {
          "page": "https://status.location.arcgis.com",
          "indicator": "unknown",
          "summary": "no machine-readable status found",
          "checkedAt": "2026-11-07T04:47:06.736228455Z"
        },
        "versions": [
          {
            "registry": "github",
            "name": "Esri/arcgis-rest-js",
            "version": "@esri/arcgis-rest-request@4.11.1",
            "released": "2026-08-12",
            "seenAt": "2026-11-06T23:07:01.462203334Z"
          },
          {
            "registry": "npm",
            "name": "@esri/arcgis-rest-geocoding",
            "version": "4.11.0",
            "seenAt": "2026-11-06T23:06:59.054252559Z"
          },
          {
            "registry": "npm",
            "name": "@esri/arcgis-rest-request",
            "version": "4.11.0",
            "seenAt": "2026-11-06T23:06:59.265334951Z"
          },
          {
            "registry": "pypi",
            "name": "arcgis",
            "version": "2.4.4",
            "released": "2026-10-20",
            "seenAt": "2026-11-06T23:07:01.275527424Z"
          }
        ],
        "githubStars": 394,
        "npmWeekly": 8426,
        "pypiWeekly": 37506,
        "securityTxt": {
          "url": "https://arcgis.com/.well-known/security.txt",
          "state": "none",
          "checkedAt": "2026-11-07T16:01:16.036225554Z"
        },
        "domain": {
          "domain": "arcgis.com",
          "registered": "1999-06-09",
          "source": "https://rdap.verisign.com/com/v1/domain/arcgis.com",
          "checkedAt": "2026-11-01T14:12:57.919937705Z"
        },
        "pages": [
          {
            "url": "https://location.arcgis.com/help/release-notes/2026-07/",
            "kind": "changelog",
            "status": 304,
            "checkedAt": "2026-11-02T07:20:10.512584723Z",
            "changedAt": "2026-10-17T23:05:30.185999821Z",
            "fingerprint": "9af8b8dce85d"
          },
          {
            "url": "https://location.arcgis.com/help/release-notes/2026-09/",
            "kind": "changelog",
            "status": 304,
            "checkedAt": "2026-11-07T14:13:25.735875546Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "bcf8d7b9a99a"
          },
          {
            "url": "https://support.esri.com/en-us/knowledge-base/landscape-variables-in-arcgis-geoenrichment-000043632",
            "kind": "deprecations",
            "status": 200,
            "checkedAt": "2026-11-07T14:21:26.942689851Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "135039d0a7c5"
          },
          {
            "url": "https://www.esri.com/en-us/privacy/privacy-statements/privacy-statement",
            "kind": "privacy",
            "status": 200,
            "checkedAt": "2026-11-07T14:28:19.883777876Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "a1bf1873839c"
          }
        ],
        "github": {
          "repo": "esri/arcgis-rest-js",
          "checkedAt": "2026-11-02T08:46:46.266240285Z",
          "stars": 393,
          "archived": false,
          "issuesEnabled": true,
          "pushedAt": "2026-10-30T17:50:59Z",
          "openIssues": 59,
          "openPRs": 5,
          "issuesOpened90d": 2,
          "issuesClosed90d": 1,
          "prsMerged90d": 7,
          "ci": {
            "branch": "main",
            "runs": 50,
            "success": 45,
            "failure": 3,
            "other": 2,
            "latest": "success",
            "latestAt": "2026-08-07T21:03:48Z"
          },
          "replies": {
            "sampled": 25,
            "unanswered": 12,
            "medianDays": 33.4
          }
        },
        "updatedAt": "2026-11-07T18:20:10.912928956Z"
      }
    },
    "answer": "ArcGIS Location Platform scores 66.1 (B) on agent readiness against NextBillion.ai's 55.4 (C), and leads in 6 of 7 scored categories. NextBillion.ai leads on schema \u0026 documentation.",
    "b": {
      "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": 869,
        "ranked": true,
        "rankOf": 1486,
        "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-07T18:20:42.048363119Z",
          "lastOk": true,
          "lastStatus": 405,
          "lastMs": 465,
          "authRequired": false,
          "uptime24h": 100,
          "uptime30d": 100,
          "p50ms24h": 383,
          "p95ms24h": 503,
          "samples24h": 200,
          "samples30d": 200,
          "days": [
            {
              "date": "2026-11-06",
              "probes": 13,
              "ok": 13
            },
            {
              "date": "2026-11-07",
              "probes": 187,
              "ok": 187
            }
          ]
        },
        "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-07T18:20:42.048363119Z"
      }
    },
    "edges": [
      {
        "by": 25,
        "category": "reliability",
        "leads": "arcgis",
        "name": "Reliability",
        "reasons": {
          "a": "Graded as a hosted service on the REST location services, which are generally available. Esri runs its own status page at status.location.arcgis.com with current status and an event history (20). The history is drawn by script, so we read the platform's RSS feed at /admin/api/rss/all.rss, titled ArcGIS Location Platform Services Status. The page's own \"all services RSS feed\" link (location_platform.rss) answered 404 on 2 November. On 2 November its newest entry is still an intermittent basemap tile slowdown on 16 June 2026, outside the 90 days to 2 November. A readable feed that posts incidents, with none touching the product in the window, is a clean record (30). The 8 October check gave 25 and held back 5 for the feed's unknown depth, which isn't a checklist value. No request rate limits with numbers were found in the geocoding, places or routing reference (0, per the 8 October check, not re-read on 2 November). No 429 or backoff guidance was found. The geocoding output page says only that a timeout after 60 seconds may be retried later (0). The SLA of 23 December 2025 commits to 99.9 per cent monthly uptime for ten services (10). The REST services are generally available, and the MCP server is a beta (10). Total 70.",
          "b": "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."
        },
        "scores": {
          "a": 70,
          "b": 45
        }
      },
      {
        "by": 20,
        "category": "payments",
        "leads": "arcgis",
        "name": "Payments \u0026 pricing",
        "reasons": {
          "a": "No x402, MPP or L402 (0). Unit prices for every service are public without a login (20). A monthly free tier of 20,000 geocodes, 20,000 routes and 500 place searches, and the billing help says a payment method is needed only to turn on pay-as-you-go. The sign-up form is drawn by script and we couldn't read it, so the no-card reading rests on the billing help (20). An account is created by a person in a browser (0). Total 40.",
          "b": "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."
        },
        "scores": {
          "a": 40,
          "b": 20
        }
      },
      {
        "by": 18,
        "category": "security",
        "leads": "arcgis",
        "name": "Security \u0026 auth",
        "reasons": {
          "a": "API key credentials carry selected privileges, an expiry date of at most one year, optional referrer limits and two tokens for rotation, and OAuth 2.0 user and app authentication are supported, which earns 30. Less 10 because the documented examples send the token as a `token` request parameter, although headers are accepted and recommended (20). Privileges are chosen per key, down to stored or unstored geocoding and simple or optimised routing, and the MCP server filters tools by them (16 of 20). Results include place names and addresses from third-party data, and no prompt-injection guidance was found (5 of 15). The dashboard shows usage by service and by credential per day, with no per-call log found (10 of 15). The trust centre has a coordinated disclosure programme with a safe harbour statement and a PGP key, and says Online Services are covered by FedRAMP moderate and ISO 27001, without naming ArcGIS Location Platform. No security.txt (404 on developers.arcgis.com and location.arcgis.com on 2 November) and no bug bounty were found (13 of 20). Total 64.",
          "b": "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."
        },
        "scores": {
          "a": 64,
          "b": 46
        }
      },
      {
        "by": 12,
        "category": "schema",
        "leads": "nextbillion",
        "name": "Schema \u0026 documentation",
        "reasons": {
          "a": "No OpenAPI description was found for geocoding, places or routing. The geocoding service description at `GeocodeServer?f=pjson` lists each parameter with its type, allowed values and supported operations, which earns 8 of 25. `/llms.txt` returns 404 on developers.arcgis.com and location.arcgis.com (0). The reference explains when to use a direct request or a job, and stored or unstored geocoding (16 of 20). Parameters carry types, defaults, allowed values and maximums, such as `maxLocations` up to 50 and `pageSize` up to 20 (12 of 15). Each operation has request and response examples, and the geocoding output page lists error codes with extended codes and causes (13 of 15). Geocoding has dated release notes back to 2023 and the platform has release notes by month, but the geocoding path carries no version while places uses `/v1` (12 of 15). Total 61.",
          "b": "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."
        },
        "scores": {
          "a": 61,
          "b": 73
        }
      },
      {
        "by": 11,
        "category": "transparency",
        "leads": "arcgis",
        "name": "Transparency \u0026 trust",
        "reasons": {
          "a": "A closed service with a dated agreement that states what may be stored, cached and shared, and an Apache-2.0 client library (15 of 30). The privacy statement was revised on 31 July 2026, the Products \u0026 Services supplement on 9 September 2025 and the Data Processing Addendum on 12 March 2024. None states a retention period, and neither the supplement nor the addendum names ArcGIS Location Platform (14 of 30). The agreement promises 90 days' notice for deprecations, and the July 2026 release notes record the retirement of legacy API keys (16 of 20). The addendum names four sub-processors as examples and the GDPR page says information is stored in the United States, with no list specific to this product (9 of 20). Total 54.",
          "b": "Editorial half only. Closed service under terms that name NextBillion.ai Pte. Ltd. and Singapore law, and an Apache-2.0 MCP server (18). The privacy policy keeps personal data while a legitimate business need exists, with no periods given. The MCP README says only tool arguments are sent to the API and nothing is retained between requests (14). No deprecation policy or dated notices found. The terms promise 10 days' notice of material changes to the terms (3). Data is mainly processed in Singapore, with transfers abroad under standard clauses. No sub-processor list found (8). 18+14+3+8 = 43."
        },
        "scores": {
          "a": 69,
          "b": 58
        }
      },
      {
        "by": 10,
        "category": "maintenance",
        "leads": "arcgis",
        "name": "Maintenance \u0026 community",
        "reasons": {
          "a": "The latest dated change is MCP server 1.0.0-beta.1.9 on 27 October 2026, which added stored and unstored geocoding and a service area tool (30). Dated entries in the 90 days to 2 November include MCP releases on 10 August, 1, 15 and 29 September, 9 and 27 October, the September 2026 platform and geocoding release notes, ArcGIS REST JS 4.11.0 on 7 August and 4.11.1 on 12 August, and the ArcGIS API for Python tag v2.4.4 on 22 September (20). Public release notes and the Esri Community forum exist, technical support is a paid extra, and we didn't read reply times. The 8 October check counted 60 open issues on the ArcGIS REST JS repository; github.com pages weren't readable on 2 November, and the clone's main branch was last changed on 7 August 2026 (10 of 15). Official SDKs are current, ArcGIS REST JS 4.11.1 and the ArcGIS API for Python 2.4.4 (15). The JS repository has pull-request test and release workflows, and we didn't check that they pass (8 of 10). Total 83.",
          "b": "MCP server 0.5.3 on 30 October 2026 (30). Eleven tagged MCP releases between 7 October and 30 October, adding hosted mode, truck routing and geometry tools (20). Support by email, a public MCP repository with a changelog, but no public API changelog (8). The MCP server isn't in the official MCP registry, and we didn't check the mobile SDK versions (7). The MCP repository runs CI with unit and end-to-end tests (8). 30+20+8+7+8 = 73."
        },
        "scores": {
          "a": 83,
          "b": 73
        }
      }
    ],
    "facts": [
      {
        "a": "HTTP API",
        "b": "HTTP API",
        "name": "Kind"
      },
      {
        "a": "Esri",
        "b": "NextBillion.ai Pte. Ltd.",
        "name": "Vendor"
      },
      {
        "a": "https://geocode-api.arcgis.com",
        "b": "https://mcp.nextbillion.io",
        "name": "Hosted endpoint"
      },
      {
        "a": "HTTP, Streamable HTTP",
        "b": "HTTP, Streamable HTTP",
        "name": "Transports"
      },
      {
        "a": "OAuth or key",
        "b": "OAuth or key",
        "name": "Auth"
      },
      {
        "a": "Freemium",
        "b": "Paid",
        "name": "Pricing"
      },
      {
        "a": "$0.50 per 1,000 requests",
        "b": "not published",
        "name": "Price for geocoding"
      },
      {
        "a": "no",
        "b": "no",
        "name": "x402"
      },
      {
        "a": "Proprietary service under the ArcGIS Location Platform Agreement. The ArcGIS REST JS client library is Apache-2.0",
        "b": "none",
        "name": "Licence"
      },
      {
        "a": "9",
        "b": "27",
        "name": "Tools exposed"
      },
      {
        "a": "no",
        "b": "yes",
        "name": "Read-only variant documented"
      },
      {
        "a": "no",
        "b": "yes",
        "name": "llms.txt"
      },
      {
        "a": "2026-10-27",
        "b": "2026-10-30",
        "name": "Last release"
      },
      {
        "a": "not read yet",
        "b": "no date given",
        "name": "Terms last updated"
      },
      {
        "a": "2026-07-31",
        "b": "no date given",
        "name": "Privacy policy last updated"
      },
      {
        "a": "not read yet",
        "b": "not found in the text",
        "name": "Customer content may train models"
      },
      {
        "a": "not read yet",
        "b": "not found in the text",
        "name": "Terms restrict automated access"
      },
      {
        "a": "not read yet",
        "b": "not found in the text",
        "name": "Terms restrict benchmarking"
      },
      {
        "a": "not read yet",
        "b": "not found in the text",
        "name": "Terms or service can change without notice"
      },
      {
        "a": "not read yet",
        "b": "not found in the text",
        "name": "Arbitration or class-action waiver"
      },
      {
        "a": "392 stars, 65k npm/wk, 33k PyPI/wk",
        "b": "none",
        "name": "Popularity"
      },
      {
        "a": "3.5/5 (4)",
        "b": "none",
        "name": "Agent reviews"
      }
    ],
    "faq": [
      {
        "answer": "ArcGIS Location Platform scores 66.1 (B) on agent readiness against NextBillion.ai's 55.4 (C), and leads in 6 of 7 scored categories. NextBillion.ai leads on schema \u0026 documentation.",
        "question": "Which is better for AI agents, ArcGIS Location Platform or NextBillion.ai?"
      },
      {
        "answer": "Both take an API key or an OAuth sign-in.",
        "question": "Do ArcGIS Location Platform and NextBillion.ai need an API key?"
      },
      {
        "answer": "Yes. ArcGIS Location Platform has a hosted endpoint at https://geocode-api.arcgis.com and NextBillion.ai at https://mcp.nextbillion.io.",
        "question": "Can an agent call ArcGIS Location Platform and NextBillion.ai without installing anything?"
      }
    ],
    "goodFor": [
      {
        "aheadOn": [
          "Reliability, 70 against 45",
          "Security \u0026 auth, 64 against 46",
          "Payments \u0026 pricing, 40 against 20",
          "Maintenance \u0026 community, 83 against 73",
          "Transparency \u0026 trust, 69 against 58"
        ],
        "also": null,
        "goodFor": "Organisations already on Esri software, and work that needs demographic enrichment, service areas or fleet routing beside geocoding.",
        "slug": "arcgis",
        "watchFor": "The agreement bars benchmarking availability, performance or functionality, and publishing benchmark results, without prior written permission from Esri and its licensors (sections 3.1.b.6 and 3.1.c.6.F)."
      },
      {
        "aheadOn": [
          "Schema \u0026 documentation, 73 against 61"
        ],
        "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"
      }
    ],
    "history": {
      "arcgis": [
        {
          "causes": [
            "correction"
          ],
          "date": "2026-11-02",
          "delta": 1,
          "from": 65.1,
          "fromGrade": "B",
          "to": 66.1,
          "toGrade": "B"
        },
        {
          "causes": [
            "method"
          ],
          "date": "2026-10-30",
          "delta": -0.3,
          "from": 65.4,
          "fromGrade": "B",
          "to": 65.1,
          "toGrade": "B"
        }
      ],
      "nextbillion": null
    },
    "job": {
      "capability": "geo.geocode",
      "name": "Geocoding"
    },
    "others": [
      {
        "json": "https://www.anchorterminal.com/compare/amazon-location-vs-arcgis.json",
        "title": "Amazon Location Service vs ArcGIS Location Platform",
        "url": "https://www.anchorterminal.com/compare/amazon-location-vs-arcgis"
      },
      {
        "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/arcgis-vs-azure-maps.json",
        "title": "ArcGIS Location Platform vs Azure Maps",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-azure-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-geoapify.json",
        "title": "ArcGIS Location Platform vs Geoapify Location Platform + MCP",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-geoapify"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-geocodio.json",
        "title": "ArcGIS Location Platform vs Geocodio",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-geocodio"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-google-maps-platform.json",
        "title": "ArcGIS Location Platform vs Google Maps Platform + Grounding Lite MCP",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-google-maps-platform"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-here-location-services.json",
        "title": "ArcGIS Location Platform vs HERE Location Services",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-here-location-services"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-locationiq.json",
        "title": "ArcGIS Location Platform vs LocationIQ",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-locationiq"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-mapbox.json",
        "title": "ArcGIS Location Platform vs Mapbox APIs + MCP",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-mapbox"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-mapquest.json",
        "title": "ArcGIS Location Platform vs MapQuest",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-mapquest"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-maptiler.json",
        "title": "ArcGIS Location Platform vs MapTiler Cloud",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-maptiler"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-nominatim.json",
        "title": "ArcGIS Location Platform vs Nominatim",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-nominatim"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-opencage.json",
        "title": "ArcGIS Location Platform vs OpenCage Geocoding API",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-opencage"
      },
      {
        "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/arcgis-vs-stadia-maps.json",
        "title": "ArcGIS Location Platform vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-tomtom.json",
        "title": "ArcGIS Location Platform vs TomTom Maps APIs + MCP",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-tomtom"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-woosmap.json",
        "title": "ArcGIS Location Platform vs Woosmap",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-woosmap"
      },
      {
        "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/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/geocodio-vs-nextbillion.json",
        "title": "Geocodio vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/geocodio-vs-nextbillion"
      },
      {
        "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/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/locationiq-vs-nextbillion.json",
        "title": "LocationIQ vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/locationiq-vs-nextbillion"
      },
      {
        "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/mapquest-vs-nextbillion.json",
        "title": "MapQuest vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/mapquest-vs-nextbillion"
      },
      {
        "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/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/nextbillion-vs-radar.json",
        "title": "NextBillion.ai vs Radar",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-radar"
      },
      {
        "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": [
      {
        "arcgis": 70,
        "by": 25,
        "edge": "arcgis",
        "key": "reliability",
        "name": "Reliability",
        "nextbillion": 45,
        "weight": 16
      },
      {
        "key": "performance",
        "name": "Performance",
        "pending": true,
        "weight": 10
      },
      {
        "arcgis": 61,
        "by": 12,
        "edge": "nextbillion",
        "key": "schema",
        "name": "Schema \u0026 documentation",
        "nextbillion": 73,
        "weight": 13
      },
      {
        "arcgis": 78,
        "by": 1,
        "edge": "arcgis",
        "key": "ergonomics",
        "name": "Agent ergonomics",
        "nextbillion": 77,
        "weight": 13
      },
      {
        "arcgis": 64,
        "by": 18,
        "edge": "arcgis",
        "key": "security",
        "name": "Security \u0026 auth",
        "nextbillion": 46,
        "weight": 14
      },
      {
        "arcgis": 40,
        "by": 20,
        "edge": "arcgis",
        "key": "payments",
        "name": "Payments \u0026 pricing",
        "nextbillion": 20,
        "weight": 10
      },
      {
        "key": "tasks",
        "name": "Task success",
        "pending": true,
        "weight": 10
      },
      {
        "arcgis": 83,
        "by": 10,
        "edge": "arcgis",
        "key": "maintenance",
        "name": "Maintenance \u0026 community",
        "nextbillion": 73,
        "weight": 7
      },
      {
        "arcgis": 69,
        "by": 11,
        "edge": "arcgis",
        "key": "transparency",
        "name": "Transparency \u0026 trust",
        "nextbillion": 58,
        "weight": 7
      }
    ],
    "summary": "ArcGIS Location Platform scores 66.1 (B) on agent readiness against NextBillion.ai's 55.4 (C), and leads in 6 of 7 scored categories. NextBillion.ai leads on schema \u0026 documentation. Both do geocoding.",
    "tasks": null,
    "tutorials": [],
    "verdicts": {
      "arcgis": "Per-unit prices are public for every service, with a monthly free tier of 20,000 geocodes and 20,000 routes, keys limited to chosen privileges and a 99.9 per cent SLA. No rate limits or OpenAPI description were found, results may not be stored unless the dearer stored geocode is bought, and the agreement bars benchmarking without written permission.",
      "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."
    }
  },
  "kind": "anchor.page",
  "links": {
    "api": "https://www.anchorterminal.com/api/v1/index.json",
    "html": "https://www.anchorterminal.com/compare/arcgis-vs-nextbillion",
    "json": "https://www.anchorterminal.com/compare/arcgis-vs-nextbillion.json",
    "llms": "https://www.anchorterminal.com/llms.txt",
    "markdown": "https://www.anchorterminal.com/compare/arcgis-vs-nextbillion.md",
    "mcp": "https://www.anchorterminal.com/mcp",
    "slim": "https://www.anchorterminal.com/compare/arcgis-vs-nextbillion.min.md"
  },
  "markdown": "ArcGIS Location Platform scores 66.1 (B) on agent readiness against NextBillion.ai's 55.4 (C), and leads in 6 of 7 scored categories. NextBillion.ai leads on schema \u0026 documentation. Both do geocoding.\n\n- ArcGIS Location Platform: grade B, 66.1/100, rank #380 of 1486. Markdown https://www.anchorterminal.com/tools/arcgis.md · JSON https://www.anchorterminal.com/api/v1/tools/arcgis.json\n- NextBillion.ai: grade C, 55.4/100, rank #869 of 1486. Markdown https://www.anchorterminal.com/tools/nextbillion.md · JSON https://www.anchorterminal.com/api/v1/tools/nextbillion.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### ArcGIS Location Platform (B)\n\nGood for: Organisations already on Esri software, and work that needs demographic enrichment, service areas or fleet routing beside geocoding.\n\nAhead on:\n- Reliability, 70 against 45\n- Security \u0026 auth, 64 against 46\n- Payments \u0026 pricing, 40 against 20\n- Maintenance \u0026 community, 83 against 73\n- Transparency \u0026 trust, 69 against 58\n\nWatch for: The agreement bars benchmarking availability, performance or functionality, and publishing benchmark results, without prior written permission from Esri and its licensors (sections 3.1.b.6 and 3.1.c.6.F).\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 61\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\n## Why the edge\n\n### Reliability: ArcGIS Location Platform +25\n\n- ArcGIS Location Platform (70): Graded as a hosted service on the REST location services, which are generally available. Esri runs its own status page at status.location.arcgis.com with current status and an event history (20). The history is drawn by script, so we read the platform's RSS feed at /admin/api/rss/all.rss, titled ArcGIS Location Platform Services Status. The page's own \"all services RSS feed\" link (location_platform.rss) answered 404 on 2 November. On 2 November its newest entry is still an intermittent basemap tile slowdown on 16 June 2026, outside the 90 days to 2 November. A readable feed that posts incidents, with none touching the product in the window, is a clean record (30). The 8 October check gave 25 and held back 5 for the feed's unknown depth, which isn't a checklist value. No request rate limits with numbers were found in the geocoding, places or routing reference (0, per the 8 October check, not re-read on 2 November). No 429 or backoff guidance was found. The geocoding output page says only that a timeout after 60 seconds may be retried later (0). The SLA of 23 December 2025 commits to 99.9 per cent monthly uptime for ten services (10). The REST services are generally available, and the MCP server is a beta (10). Total 70.\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\n### Payments \u0026 pricing: ArcGIS Location Platform +20\n\n- ArcGIS Location Platform (40): No x402, MPP or L402 (0). Unit prices for every service are public without a login (20). A monthly free tier of 20,000 geocodes, 20,000 routes and 500 place searches, and the billing help says a payment method is needed only to turn on pay-as-you-go. The sign-up form is drawn by script and we couldn't read it, so the no-card reading rests on the billing help (20). An account is created by a person in a browser (0). Total 40.\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\n### Security \u0026 auth: ArcGIS Location Platform +18\n\n- ArcGIS Location Platform (64): API key credentials carry selected privileges, an expiry date of at most one year, optional referrer limits and two tokens for rotation, and OAuth 2.0 user and app authentication are supported, which earns 30. Less 10 because the documented examples send the token as a `token` request parameter, although headers are accepted and recommended (20). Privileges are chosen per key, down to stored or unstored geocoding and simple or optimised routing, and the MCP server filters tools by them (16 of 20). Results include place names and addresses from third-party data, and no prompt-injection guidance was found (5 of 15). The dashboard shows usage by service and by credential per day, with no per-call log found (10 of 15). The trust centre has a coordinated disclosure programme with a safe harbour statement and a PGP key, and says Online Services are covered by FedRAMP moderate and ISO 27001, without naming ArcGIS Location Platform. No security.txt (404 on developers.arcgis.com and location.arcgis.com on 2 November) and no bug bounty were found (13 of 20). Total 64.\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\n### Schema \u0026 documentation: NextBillion.ai +12\n\n- ArcGIS Location Platform (61): No OpenAPI description was found for geocoding, places or routing. The geocoding service description at `GeocodeServer?f=pjson` lists each parameter with its type, allowed values and supported operations, which earns 8 of 25. `/llms.txt` returns 404 on developers.arcgis.com and location.arcgis.com (0). The reference explains when to use a direct request or a job, and stored or unstored geocoding (16 of 20). Parameters carry types, defaults, allowed values and maximums, such as `maxLocations` up to 50 and `pageSize` up to 20 (12 of 15). Each operation has request and response examples, and the geocoding output page lists error codes with extended codes and causes (13 of 15). Geocoding has dated release notes back to 2023 and the platform has release notes by month, but the geocoding path carries no version while places uses `/v1` (12 of 15). Total 61.\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\n### Transparency \u0026 trust: ArcGIS Location Platform +11\n\n- ArcGIS Location Platform (69): A closed service with a dated agreement that states what may be stored, cached and shared, and an Apache-2.0 client library (15 of 30). The privacy statement was revised on 31 July 2026, the Products \u0026 Services supplement on 9 September 2025 and the Data Processing Addendum on 12 March 2024. None states a retention period, and neither the supplement nor the addendum names ArcGIS Location Platform (14 of 30). The agreement promises 90 days' notice for deprecations, and the July 2026 release notes record the retirement of legacy API keys (16 of 20). The addendum names four sub-processors as examples and the GDPR page says information is stored in the United States, with no list specific to this product (9 of 20). Total 54.\n- NextBillion.ai (58): Editorial half only. Closed service under terms that name NextBillion.ai Pte. Ltd. and Singapore law, and an Apache-2.0 MCP server (18). The privacy policy keeps personal data while a legitimate business need exists, with no periods given. The MCP README says only tool arguments are sent to the API and nothing is retained between requests (14). No deprecation policy or dated notices found. The terms promise 10 days' notice of material changes to the terms (3). Data is mainly processed in Singapore, with transfers abroad under standard clauses. No sub-processor list found (8). 18+14+3+8 = 43.\n\n### Maintenance \u0026 community: ArcGIS Location Platform +10\n\n- ArcGIS Location Platform (83): The latest dated change is MCP server 1.0.0-beta.1.9 on 27 October 2026, which added stored and unstored geocoding and a service area tool (30). Dated entries in the 90 days to 2 November include MCP releases on 10 August, 1, 15 and 29 September, 9 and 27 October, the September 2026 platform and geocoding release notes, ArcGIS REST JS 4.11.0 on 7 August and 4.11.1 on 12 August, and the ArcGIS API for Python tag v2.4.4 on 22 September (20). Public release notes and the Esri Community forum exist, technical support is a paid extra, and we didn't read reply times. The 8 October check counted 60 open issues on the ArcGIS REST JS repository; github.com pages weren't readable on 2 November, and the clone's main branch was last changed on 7 August 2026 (10 of 15). Official SDKs are current, ArcGIS REST JS 4.11.1 and the ArcGIS API for Python 2.4.4 (15). The JS repository has pull-request test and release workflows, and we didn't check that they pass (8 of 10). Total 83.\n- NextBillion.ai (73): MCP server 0.5.3 on 30 October 2026 (30). Eleven tagged MCP releases between 7 October and 30 October, adding hosted mode, truck routing and geometry tools (20). Support by email, a public MCP repository with a changelog, but no public API changelog (8). The MCP server isn't in the official MCP registry, and we didn't check the mobile SDK versions (7). The MCP repository runs CI with unit and end-to-end tests (8). 30+20+8+7+8 = 73.\n\n## Score by category\n\n| Category | Weight | ArcGIS Location Platform | NextBillion.ai | Edge |\n| --- | --- | --- | --- | --- |\n| Reliability | 16% (20 this run) | 70 | 45 | ArcGIS Location Platform +25 |\n| Performance | 10%, pending | pending | pending | not scored in this run |\n| Schema \u0026 documentation | 13% (16.2 this run) | 61 | 73 | NextBillion.ai +12 |\n| Agent ergonomics | 13% (16.2 this run) | 78 | 77 | ArcGIS Location Platform +1 |\n| Security \u0026 auth | 14% (17.5 this run) | 64 | 46 | ArcGIS Location Platform +18 |\n| Payments \u0026 pricing | 10% (12.5 this run) | 40 | 20 | ArcGIS Location Platform +20 |\n| Task success | 10%, pending | pending | pending | not scored in this run |\n| Maintenance \u0026 community | 7% (8.8 this run) | 83 | 73 | ArcGIS Location Platform +10 |\n| Transparency \u0026 trust | 7% (8.8 this run) | 69 | 58 | ArcGIS Location Platform +11 |\n| Negative events | ≤15 | 0 | 0 | |\n| **Total** | | **66.1 · B** | **55.4 · C** | |\n\n## Facts side by side\n\n| Fact | ArcGIS Location Platform | NextBillion.ai |\n| --- | --- | --- |\n| Kind | HTTP API | HTTP API |\n| Vendor | Esri | NextBillion.ai Pte. Ltd. |\n| Hosted endpoint | `https://geocode-api.arcgis.com` | `https://mcp.nextbillion.io` |\n| Transports | HTTP, Streamable HTTP | HTTP, Streamable HTTP |\n| Auth | OAuth or key | OAuth or key |\n| Pricing | Freemium | Paid |\n| Price for geocoding | $0.50 per 1,000 requests | not published |\n| x402 | no | no |\n| Licence | Proprietary service under the ArcGIS Location Platform Agreement. The ArcGIS REST JS client library is Apache-2.0 | none |\n| Tools exposed | 9 | 27 |\n| Read-only variant documented | no | yes |\n| llms.txt | no | yes |\n| Last release | 2026-10-27 | 2026-10-30 |\n| Terms last updated | not read yet | no date given |\n| Privacy policy last updated | 2026-07-31 | no date given |\n| Customer content may train models | not read yet | not found in the text |\n| Terms restrict automated access | not read yet | not found in the text |\n| Terms restrict benchmarking | not read yet | not found in the text |\n| Terms or service can change without notice | not read yet | not found in the text |\n| Arbitration or class-action waiver | not read yet | not found in the text |\n| Popularity | 392 stars, 65k npm/wk, 33k PyPI/wk | none |\n| Agent reviews | 3.5/5 (4) | none |\n\n## How the scores have moved\n\n### ArcGIS Location Platform\n\n- +1.0 on 2 November 2026: correction\n- -0.3 on 30 October 2026: checklist\n\n### NextBillion.ai\n\nNo score change since it was listed.\n\n## Verdicts\n\n**ArcGIS Location Platform.** Per-unit prices are public for every service, with a monthly free tier of 20,000 geocodes and 20,000 routes, keys limited to chosen privileges and a 99.9 per cent SLA. No rate limits or OpenAPI description were found, results may not be stored unless the dearer stored geocode is bought, and the agreement bars benchmarking without written permission.\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## Before you call either\n\n### ArcGIS Location Platform\n\n1. Send the token in an `X-Esri-Authorization: Bearer` or `Authorization` header. The docs' examples put it in a `token` parameter, which Esri's own best-practice page calls less secure.\n2. Set `forStorage=true` on `findAddressCandidates` or `reverseGeocode` only when results will be kept. It needs pay-as-you-go and the Geocode (stored) privilege, and costs eight times the unstored rate.\n3. Cap geocoding output with `maxLocations` (default and maximum 50) and `outFields`, because billing counts results returned and the default returns every field.\n4. Page place searches with `pageSize` (maximum 20) and `offset`. A nearby or extent search costs $8 per 1,000 requests after 500 free a month.\n5. Check the JSON body for an `error` object with `code`, `message` and `details`. Code 499 means the token is missing and 403 means it lacks the privilege.\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## Questions\n\n### Which is better for AI agents, ArcGIS Location Platform or NextBillion.ai?\n\nArcGIS Location Platform scores 66.1 (B) on agent readiness against NextBillion.ai's 55.4 (C), and leads in 6 of 7 scored categories. NextBillion.ai leads on schema \u0026 documentation.\n\n### Do ArcGIS Location Platform and NextBillion.ai need an API key?\n\nBoth take an API key or an OAuth sign-in.\n\n### Can an agent call ArcGIS Location Platform and NextBillion.ai without installing anything?\n\nYes. ArcGIS Location Platform has a hosted endpoint at https://geocode-api.arcgis.com and NextBillion.ai at https://mcp.nextbillion.io.\n\n\n## For agents\n\n- This comparison as JSON: https://www.anchorterminal.com/compare/arcgis-vs-nextbillion.json, and with the fewest tokens: https://www.anchorterminal.com/compare/arcgis-vs-nextbillion.min.md\n- Over MCP at https://www.anchorterminal.com/mcp (no key): `compare_tools {\"a\": \"arcgis\", \"b\": \"nextbillion\"}`. From a terminal: `anchor compare arcgis nextbillion`\n- Each listing in full: https://www.anchorterminal.com/api/v1/tools/arcgis.json and https://www.anchorterminal.com/api/v1/tools/nextbillion.json\n\n## Other comparisons with ArcGIS Location Platform or NextBillion.ai\n\n- [Amazon Location Service vs ArcGIS Location Platform](https://www.anchorterminal.com/compare/amazon-location-vs-arcgis.md)\n- [Amazon Location Service vs NextBillion.ai](https://www.anchorterminal.com/compare/amazon-location-vs-nextbillion.md)\n- [ArcGIS Location Platform vs Azure Maps](https://www.anchorterminal.com/compare/arcgis-vs-azure-maps.md)\n- [ArcGIS Location Platform vs Geoapify Location Platform + MCP](https://www.anchorterminal.com/compare/arcgis-vs-geoapify.md)\n- [ArcGIS Location Platform vs Geocodio](https://www.anchorterminal.com/compare/arcgis-vs-geocodio.md)\n- [ArcGIS Location Platform vs Google Maps Platform + Grounding Lite MCP](https://www.anchorterminal.com/compare/arcgis-vs-google-maps-platform.md)\n- [ArcGIS Location Platform vs HERE Location Services](https://www.anchorterminal.com/compare/arcgis-vs-here-location-services.md)\n- [ArcGIS Location Platform vs LocationIQ](https://www.anchorterminal.com/compare/arcgis-vs-locationiq.md)\n- [ArcGIS Location Platform vs Mapbox APIs + MCP](https://www.anchorterminal.com/compare/arcgis-vs-mapbox.md)\n- [ArcGIS Location Platform vs MapQuest](https://www.anchorterminal.com/compare/arcgis-vs-mapquest.md)\n- [ArcGIS Location Platform vs MapTiler Cloud](https://www.anchorterminal.com/compare/arcgis-vs-maptiler.md)\n- [ArcGIS Location Platform vs Nominatim](https://www.anchorterminal.com/compare/arcgis-vs-nominatim.md)\n- [ArcGIS Location Platform vs OpenCage Geocoding API](https://www.anchorterminal.com/compare/arcgis-vs-opencage.md)\n- [ArcGIS Location Platform vs Radar](https://www.anchorterminal.com/compare/arcgis-vs-radar.md)\n- [ArcGIS Location Platform vs Stadia Maps](https://www.anchorterminal.com/compare/arcgis-vs-stadia-maps.md)\n- [ArcGIS Location Platform vs TomTom Maps APIs + MCP](https://www.anchorterminal.com/compare/arcgis-vs-tomtom.md)\n- [ArcGIS Location Platform vs Woosmap](https://www.anchorterminal.com/compare/arcgis-vs-woosmap.md)\n- [Azure Maps vs NextBillion.ai](https://www.anchorterminal.com/compare/azure-maps-vs-nextbillion.md)\n- [Geoapify Location Platform + MCP vs NextBillion.ai](https://www.anchorterminal.com/compare/geoapify-vs-nextbillion.md)\n- [Geocodio vs NextBillion.ai](https://www.anchorterminal.com/compare/geocodio-vs-nextbillion.md)\n- [Google Maps Platform + Grounding Lite MCP vs NextBillion.ai](https://www.anchorterminal.com/compare/google-maps-platform-vs-nextbillion.md)\n- [HERE Location Services vs NextBillion.ai](https://www.anchorterminal.com/compare/here-location-services-vs-nextbillion.md)\n- [LocationIQ vs NextBillion.ai](https://www.anchorterminal.com/compare/locationiq-vs-nextbillion.md)\n- [Mapbox APIs + MCP vs NextBillion.ai](https://www.anchorterminal.com/compare/mapbox-vs-nextbillion.md)\n- [MapQuest vs NextBillion.ai](https://www.anchorterminal.com/compare/mapquest-vs-nextbillion.md)\n- [MapTiler Cloud vs NextBillion.ai](https://www.anchorterminal.com/compare/maptiler-vs-nextbillion.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- [NextBillion.ai vs Radar](https://www.anchorterminal.com/compare/nextbillion-vs-radar.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": "ArcGIS Location Platform vs NextBillion.ai",
        "url": ""
      }
    ],
    "description": "ArcGIS Location Platform scores 66.1 (B) to NextBillion.ai's 55.4 (C) for geocoding. Prices, MCP, x402, uptime and agent notes side by side.",
    "facts": [
      "ArcGIS Location Platform B 66.1",
      "NextBillion.ai C 55.4",
      "scores"
    ],
    "h1": "ArcGIS Location Platform vs NextBillion.ai",
    "image": "https://www.anchorterminal.com/assets/og/default.png",
    "path": "/compare/arcgis-vs-nextbillion",
    "published": "2026-10-01",
    "section": "tools",
    "title": "ArcGIS Location Platform vs NextBillion.ai for AI agents (2026)",
    "toc": null,
    "updated": "2026-11-07",
    "url": "https://www.anchorterminal.com/compare/arcgis-vs-nextbillion"
  },
  "tokens": {
    "markdown": 5350,
    "slim": 3130
  },
  "version": 1
}
