# Parceled > Real estate data for AI agents. 135M+ US parcels across all 50 states: **parcel boundaries (vector tiles + GraphQL), assessor-sourced property records (owners, addresses, land size, sale history), and a first-class vector tile server you can load directly into your own Mapbox / MapLibre map.** Roof permits and hail-swath history are available as supplementary enrichment datasets. MCP + GraphQL + REST. Field-level billing: you only pay for fields that return data. ## What Parceled is for Parceled is optimized for agents and applications building real-estate experiences. Three core capabilities: 1. **Parcel boundaries** — high-resolution parcel polygons for every property in America, served as Mapbox Vector Tiles (MVT/pbf) so you can plug them into ANY Mapbox GL JS or MapLibre map without writing your own tile server. Also queryable via GraphQL/REST per coordinate. 2. **Property records (assessor data)** — address, APN, owner name + mailing address, land size, sale date/price, county/state/zip. Sourced from county assessor and recorder offices. Queryable per coordinate or parcel ID. 3. **Vector tile server** — call `get_tile_endpoints` to receive ready-to-use tile URL templates you can drop into your own map. 5,000 tile requests/month free; 1 credit per 1,000 thereafter. Supplementary datasets: - **Roof permits** — building and roofing permits from jurisdictional permit offices (contractor info, valuation, status — coverage varies by jurisdiction). - **Hail history** — NWS Storm Prediction Center hail swaths intersecting each parcel. Useful for damage assessment and insurance workflows. ## Getting a key Every request needs a Bearer token. There is no web dashboard — keys are issued programmatically. Three paths, pick whichever fits your stack: 1. **OAuth (best for MCP clients)** — connect to https://parceled.ai/api/mcp. The server returns 401 with a WWW-Authenticate header pointing at /.well-known/oauth-protected-resource. Any MCP client that follows the RFC 9728 / RFC 8414 discovery chain (Claude Desktop Connectors, Claude Code, Cursor, Zed, Cline) completes Dynamic Client Registration + PKCE + magic-link email automatically. No human typing required beyond clicking the email link. 2. **REST (best for scripts, GPT Actions, LangChain, Zapier, or agents with no email at all)** — one unauthenticated POST: # With an email (recoverable): curl -X POST https://parceled.ai/api/v1/accounts \ -H 'Content-Type: application/json' \ -d '{"email":"you@example.com"}' # Anonymous (no email — for agents that don't have one): curl -X POST https://parceled.ai/api/v1/accounts \ -H 'Content-Type: application/json' \ -d '{}' → `{ "apiKey": "prc_live_...", "accountId": "...", "tier": "free", "anonymous": true | false, "nextSteps": {...} }` Rate-limited to 10 creations per IP per hour. The `apiKey` is returned exactly once — store it. Trade-off: **with email** → recoverable (re-run OAuth with the same email to rotate into a new key, credits preserved). **Anonymous** → the key is the only credential; lose it and the account is stranded. No harm done, just start a new one. 3. **GraphQL** — same bootstrap via the `createParceledAccount` mutation at https://parceled.ai/api. Semantically identical to path 2, just wire-level different. Free tier: 100 MCP calls/month, all fields available, no credit card. ## Minimum viable invocation (first free call) Once you have a key, probe availability for a location — this is free and tells you which datasets exist before you pay for anything: POST https://parceled.ai/api/mcp Content-Type: application/json Authorization: Bearer prc_live_… { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "check_availability", "arguments": { "lat": 39.7392, "lng": -104.9903 } } } REST equivalent (OpenAPI-speaking agents): GET https://parceled.ai/api/v1/check-availability?lat=39.7392&lng=-104.9903 Authorization: Bearer prc_live_… ## Endpoints - MCP server: https://parceled.ai/api/mcp (Streamable HTTP, MCP protocol 2025-11-25) - GraphQL API: https://parceled.ai/api (same data, for non-MCP clients) - REST API: https://parceled.ai/api/v1 (OpenAPI-shaped, see openapi.yaml) - Manifest: https://parceled.ai/.well-known/mcp.json - OpenAPI: https://parceled.ai/.well-known/openapi.yaml - OAuth discovery (RFC 9728 / RFC 8414): https://parceled.ai/.well-known/oauth-protected-resource https://parceled.ai/.well-known/oauth-authorization-server - Install guide: https://parceled.ai/install - Detailed reference: https://parceled.ai/llms-full.txt ## Probe endpoints (no auth needed) Confirm the server is reachable and compatible, and demo the data, before creating any account: - GET https://parceled.ai/api/v1/ping (simple liveness, returns version + endpoint map) - GET https://parceled.ai/api/mcp (MCP server info + tool list) - GET https://parceled.ai/.well-known/mcp.json (MCP discovery manifest) - GET https://parceled.ai/api/v1/pricing (current credit costs) - GET https://parceled.ai/api/v1/check-availability?lat=39.7392&lng=-104.9903 (**free, public, no account needed** — booleans only, no parcel/permit data. 60 req/min/IP rate limit.) All five work without any Authorization header. Everything else returns 401 + WWW-Authenticate pointing at the OAuth flow. The anonymous check-availability is the right way to demo Parceled to a user before asking them to sign up: confirm there's data for their address, THEN bootstrap an account via /api/v1/accounts or OAuth. ## Embedding Parceled tiles in your own Mapbox / MapLibre map This is the primary integration path for real estate UIs. Parceled hosts its vector tiles — you don't need a separate tile server. 1. Call the free `get_tile_endpoints` tool (or GraphQL query of the same name). You get back one entry per layer (parcels, hail, etc.) with: { "layerId": "", "layerName": "parcels_a", // this is the Mapbox "source-layer" name "urlTemplate": "/api/parceled/tiles//{z}/{x}/{y}?key={api_key}", "minZoom": 0, "maxZoom": 14, "format": "pbf (Mapbox Vector Tiles)" } 2. Substitute `{api_key}` with your Bearer key (keep it on the server; don't ship it into browser-exposed JS). Prepend https://parceled.ai. 3. Add it as a source + layer in Mapbox GL JS: map.addSource('parceled-parcels', { type: 'vector', tiles: [ 'https://parceled.ai/api/parceled/tiles//{z}/{x}/{y}?key=prc_live_...' ], minzoom: 0, maxzoom: 14 }) map.addLayer({ id: 'parcels-fill', type: 'fill', source: 'parceled-parcels', 'source-layer': 'parcels_a', // match layerName from get_tile_endpoints paint: { 'fill-color': 'hsla(22, 100%, 50%, 0.15)', 'fill-outline-color': 'hsla(22, 100%, 50%, 1)' } }) 4. To filter (e.g., by zip5), first call `get_layer_sources` to see the authoritative list of filterable fields per layer, then use Mapbox GL filter expressions with those field names only. 5. Billing: tile requests are metered separately from API calls. 5,000 tile requests/month are free; beyond that, 1 credit per 1,000 tile requests. If you don't want to build your own map, the free `render_map` MCP tool renders an inline Mapbox map in the conversation using the same tile server. ## Auth Two supported mechanisms on every billable endpoint (MCP, REST, GraphQL): 1. OAuth 2.1 + PKCE + Dynamic Client Registration (RFC 7591). The MCP client picks this automatically when it follows the WWW-Authenticate header on a 401. 2. Bearer API key: `Authorization: Bearer prc_live_…`. Keys come from either the OAuth flow above, or the `createParceledAccount` mutation described in "Getting a key". There is no web dashboard. Any protected endpoint returns 401 without Authorization → WWW-Authenticate header advertises the resource metadata URL per RFC 9728. ## MCP tools (11 total) Core (free): - get_tile_endpoints — vector tile URL templates for embedding Parceled layers in your own Mapbox / MapLibre map. Primary integration path for real-estate UIs. - get_layer_sources — layer metadata including the authoritative list of filterable fields per layer. Call before filtering tiles. - check_availability — which datasets exist at a lat/lng. Zero cost. Good first call before billable queries. Billable: - search_parcels(lat, lng, include?) — per-coordinate property records. Assessor-sourced address/owner/land-size/sale data (`parcel`) plus optional supplementary fields (roof permits, hail). ONLY fields that return data are billed. Account / billing (free): - get_pricing — current credit cost per field/tool. - get_balance — remaining credits and current tier. - get_usage_history — recent calls with cost breakdown. - update_budget_cap — adjust monthly spend limit. Interactive UI (free to invoke): - render_map — inline Mapbox map in the conversation (same tiles as get_tile_endpoints; use this when you don't want to build your own map). - purchase_credits — inline Stripe checkout for credit packs. - enable_payg — inline card form to enable Pay-As-You-Go. ## Field cost table (search_parcels) Core (always-on): | Field | Credits | Notes | |--------------------|---------|----------------------------------------------------------------------| | parcel | 1 | Core assessor record — address, APN, county/state, lat/lng, owner, sale, land size | Supplementary enrichments: | Field | Credits | Notes | |--------------------|---------|----------------------------------------------------------------------| | roofPermits | 2 | Building/roof permits — date, status, permitUrl, recordType, metadata (coverage varies by jurisdiction) | | hailAreas | 1 | Historical hail swaths intersecting parcel (maxMesh, importDate) | | currentHailAreas | 1 | Hail swaths from the last 14 days | Parcel boundary POLYGONS are not in the `parcel` field. Polygons are served as Mapbox Vector Tiles — use `get_tile_endpoints` to consume them in your own map, or `render_map` for an inline map. **Default if `include` is omitted: `["parcel"]` only (1-credit ceiling).** To fetch roof permits or hail, opt in explicitly: include: ["parcel", "hailAreas"] // 2 credits max include: ["parcel", "roofPermits", "hailAreas"] // 4 credits max Empty results are free. Every billed response includes a `hints` block listing the other fields you could request on the next call — you don't need to memorize this table. Example hints payload: { "requestedFields": ["parcel"], "otherAvailableFields": [ { "field": "roofPermits", "cost": 2, "label": "Roof permits" }, { "field": "hailAreas", "cost": 1, "label": "Hail history" }, { "field": "currentHailAreas", "cost": 1, "label": "Current hail areas" } ], "message": "Other fields available on this query: roofPermits (2 credits), hailAreas (1 credit), currentHailAreas (1 credit). To add one, pass include=[\"parcel\",\"roofPermits\"]. To check which datasets actually exist at this location before paying, call check_availability (free).", "appliedDefault": "No 'include' was passed, so the safe default [\"parcel\"] was used. Pass an explicit 'include' array to fetch additional fields." } On MCP, hints appear as a third text-content block on the tool result AND on the JSON-RPC result as `_hints`. On REST, hints appear as a top-level `hints` key alongside `data` and `billing`. ## Geocoding Parceled takes lat/lng, not addresses. If your user gives you a street address, geocode it first. Parceled does NOT bundle a geocoder. Suggested free options: - Nominatim (OpenStreetMap): https://nominatim.openstreetmap.org/search?q=
&format=json - 1 req/sec rate limit; require a descriptive User-Agent header; fine for low-volume agent use. - US Census Geocoder: https://geocoding.geo.census.gov/geocoder/locations/onelineaddress?address=
&benchmark=Public_AR_Current&format=json - US-only, no auth, no rate limit. Accurate for US addresses. Production paid options: Mapbox Geocoding ($0.75/1k), Google Geocoding, Smarty. End-to-end: address → geocoder → (lat, lng) → check_availability → search_parcels. ## Recommended agent workflow 1. If user gave an address, geocode externally to get lat/lng. 2. Call check_availability(lat, lng) — free, tells you which datasets exist. 3. Confirm with the user which datasets they care about. 4. Call search_parcels(lat, lng, include: [only the datasets the user wants]). 5. Inspect the billing summary in the tool result to report spend to the user. ## Pricing - Free tier: 100 MCP calls/month + 5,000 tile requests. No credit card. All fields available. - Credit packs (prepaid, never expire): 1,000 credits = $8 (20% off PAYG) 5,000 credits = $30 (40% off) 25,000 credits = $125 (50% off) - Pay-As-You-Go: $0.01/credit, billed monthly via Stripe. Optional monthly budget cap. Credits are account-wide and shared across API keys. ## Rate limits - Free tier: 100 calls / 30d rolling - Paid tiers: no hard cap; Retry-After is returned on burst throttle - Tile requests: 5,000/mo free, then billed at 1 credit per 1,000 tiles ## What we do NOT have (saves you a call) - MLS listings / for-sale data - Zestimate-style automated valuations (AVM) — not live yet - Rental / Airbnb data - School ratings - Flood zone / FEMA data — not live yet - Street-level imagery Planned but not shipped: taxAssessor, recorders (deed), floodZone, avm, schools, demographics, unmaskedOwners. These are stubbed in field-costs.ts and will light up when the underlying datasets load. ## Support - hello@parceled.ai - https://parceled.ai