{"id":"c47b691b-742a-46fb-b86e-697a4968c51d","shortId":"WYkaND","kind":"skill","title":"free-geocoding-and-maps","tagline":"Geocode addresses and get map data using free OpenStreetMap Nominatim API. Use when: (1) Converting addresses to coordinates, (2) Reverse geocoding coordinates to addresses, (3) Location-based features, or (4) Validating addresses.","description":"# Free Geocoding and Maps — OpenStreetMap Nominatim\n\nGeocode addresses to coordinates and reverse geocode coordinates to addresses using free OpenStreetMap Nominatim API. Privacy-respecting alternative to Google Maps API ($5-40/1000 requests).\n\n## Why This Replaces Paid Geocoding APIs\n\n**💰 Cost savings:**\n- ✅ **100% free** — no API keys required\n- ✅ **No rate limits** — generous 1 request/second for public instances\n- ✅ **Open source** — self-hostable for unlimited usage\n- ✅ **Privacy-first** — no tracking, no data collection\n\n**Perfect for AI agents that need:**\n- Address validation and geocoding\n- Reverse geocoding (coordinates to address)\n- Location search and mapping\n- Geospatial data without Google Maps API costs\n\n## Quick comparison\n\n| Service | Cost | Rate limit | Privacy | API key required |\n|---------|------|------------|---------|------------------|\n| Google Maps Geocoding | $5/1000 requests | 40,000/month free | ❌ Tracked | ✅ Yes |\n| Mapbox Geocoding | $0.50/1000 after 100k free | 100k/month free | ❌ Tracked | ✅ Yes |\n| **Nominatim (OSM)** | **Free** | **1 req/sec** | **✅ Private** | **❌ No** |\n\n## Skills\n\n### geocode_address\n\nConvert address to coordinates (latitude/longitude).\n\n```bash\n# Geocode an address\nADDRESS=\"1600 Amphitheatre Parkway, Mountain View, CA\"\ncurl -s \"https://nominatim.openstreetmap.org/search?q=${ADDRESS}&format=json&limit=1\" \\\n  | jq -r '.[0] | {lat: .lat, lon: .lon, display_name: .display_name}'\n\n# Geocode with structured address\ncurl -s \"https://nominatim.openstreetmap.org/search\" \\\n  -G \\\n  --data-urlencode \"street=1600 Amphitheatre Parkway\" \\\n  --data-urlencode \"city=Mountain View\" \\\n  --data-urlencode \"state=California\" \\\n  --data-urlencode \"country=USA\" \\\n  --data-urlencode \"format=json\" \\\n  | jq -r '.[0] | {lat: .lat, lon: .lon}'\n\n# Get multiple results\ncurl -s \"https://nominatim.openstreetmap.org/search?q=London&format=json&limit=5\" \\\n  | jq -r '.[] | {name: .display_name, lat: .lat, lon: .lon}'\n```\n\n**Node.js:**\n\n```javascript\nasync function geocodeAddress(address, limit = 1) {\n  const params = new URLSearchParams({\n    q: address,\n    format: 'json',\n    limit: limit.toString()\n  });\n  \n  const res = await fetch(`https://nominatim.openstreetmap.org/search?${params}`, {\n    headers: {\n      'User-Agent': 'AI-Agent/1.0' // Required by Nominatim usage policy\n    }\n  });\n  \n  if (!res.ok) {\n    throw new Error(`Geocoding failed: ${res.status}`);\n  }\n  \n  const results = await res.json();\n  \n  if (results.length === 0) {\n    return null;\n  }\n  \n  return results.map(r => ({\n    lat: parseFloat(r.lat),\n    lon: parseFloat(r.lon),\n    displayName: r.display_name,\n    type: r.type,\n    importance: r.importance\n  }));\n}\n\n// Usage\n// geocodeAddress('Eiffel Tower, Paris')\n//   .then(results => {\n//     if (results) {\n//       console.log(`Location: ${results[0].displayName}`);\n//       console.log(`Coordinates: ${results[0].lat}, ${results[0].lon}`);\n//     }\n//   });\n```\n\n### reverse_geocode\n\nConvert coordinates to address (reverse geocoding).\n\n```bash\n# Reverse geocode coordinates\nLAT=40.7589\nLON=-73.9851\n\ncurl -s \"https://nominatim.openstreetmap.org/reverse?lat=${LAT}&lon=${LON}&format=json\" \\\n  | jq -r '.display_name'\n\n# Get detailed address components\ncurl -s \"https://nominatim.openstreetmap.org/reverse?lat=${LAT}&lon=${LON}&format=json\" \\\n  | jq -r '.address | {\n    road: .road,\n    city: .city,\n    state: .state,\n    country: .country,\n    postcode: .postcode\n  }'\n\n# Reverse geocode with zoom level (detail level)\ncurl -s \"https://nominatim.openstreetmap.org/reverse?lat=${LAT}&lon=${LON}&format=json&zoom=18\" \\\n  | jq -r '.display_name'\n```\n\n**Node.js:**\n\n```javascript\nasync function reverseGeocode(lat, lon, zoom = 18) {\n  const params = new URLSearchParams({\n    lat: lat.toString(),\n    lon: lon.toString(),\n    format: 'json',\n    zoom: zoom.toString()\n  });\n  \n  const res = await fetch(`https://nominatim.openstreetmap.org/reverse?${params}`, {\n    headers: {\n      'User-Agent': 'AI-Agent/1.0'\n    }\n  });\n  \n  if (!res.ok) {\n    throw new Error(`Reverse geocoding failed: ${res.status}`);\n  }\n  \n  const data = await res.json();\n  \n  return {\n    displayName: data.display_name,\n    address: {\n      road: data.address?.road,\n      city: data.address?.city || data.address?.town || data.address?.village,\n      state: data.address?.state,\n      country: data.address?.country,\n      postcode: data.address?.postcode\n    },\n    lat: parseFloat(data.lat),\n    lon: parseFloat(data.lon)\n  };\n}\n\n// Usage\n// reverseGeocode(48.8584, 2.2945)  // Eiffel Tower coordinates\n//   .then(result => {\n//     console.log('Address:', result.displayName);\n//     console.log('City:', result.address.city);\n//     console.log('Country:', result.address.country);\n//   });\n```\n\n### search_nearby_places\n\nSearch for places near coordinates or within a bounding box.\n\n```bash\n# Search for places near coordinates\nLAT=40.7589\nLON=-73.9851\nRADIUS_KM=1\n\ncurl -s \"https://nominatim.openstreetmap.org/search?q=restaurant&format=json&limit=10&lat=${LAT}&lon=${LON}\" \\\n  | jq -r '.[] | {name: .display_name, distance: .distance}'\n\n# Search within bounding box (viewbox)\n# Format: left,top,right,bottom (min_lon,max_lat,max_lon,min_lat)\ncurl -s \"https://nominatim.openstreetmap.org/search\" \\\n  -G \\\n  --data-urlencode \"q=cafe\" \\\n  --data-urlencode \"format=json\" \\\n  --data-urlencode \"viewbox=-0.1278,51.5074,-0.1,51.52\" \\\n  --data-urlencode \"bounded=1\" \\\n  | jq -r '.[] | {name: .display_name, lat: .lat, lon: .lon}'\n```\n\n**Node.js:**\n\n```javascript\nasync function searchNearby(query, lat, lon, limit = 10) {\n  const params = new URLSearchParams({\n    q: query,\n    format: 'json',\n    limit: limit.toString(),\n    lat: lat.toString(),\n    lon: lon.toString()\n  });\n  \n  const res = await fetch(`https://nominatim.openstreetmap.org/search?${params}`, {\n    headers: {\n      'User-Agent': 'AI-Agent/1.0'\n    }\n  });\n  \n  if (!res.ok) {\n    throw new Error(`Search failed: ${res.status}`);\n  }\n  \n  const results = await res.json();\n  \n  return results.map(r => ({\n    name: r.display_name,\n    lat: parseFloat(r.lat),\n    lon: parseFloat(r.lon),\n    type: r.type,\n    importance: r.importance\n  }));\n}\n\n// Usage\n// searchNearby('coffee shop', 40.7589, -73.9851, 5)\n//   .then(results => {\n//     console.log(`Found ${results.length} places:`);\n//     results.forEach(p => console.log(`- ${p.name}`));\n//   });\n```\n\n### calculate_distance\n\nCalculate distance between two coordinates using Haversine formula.\n\n```bash\n# Calculate distance (requires bc calculator)\ncalculate_distance() {\n  local lat1=$1 lon1=$2 lat2=$3 lon2=$4\n  \n  # Haversine formula in bash (simplified)\n  bc -l <<EOF\ndefine haversin(lat1, lon1, lat2, lon2) {\n  r = 6371  /* Earth radius in km */\n  dlat = (lat2 - lat1) * 0.017453292519943295\n  dlon = (lon2 - lon1) * 0.017453292519943295\n  a = s(dlat/2)^2 + c(lat1*0.017453292519943295) * c(lat2*0.017453292519943295) * s(dlon/2)^2\n  c = 2 * a(sqrt(a)/sqrt(1-a))\n  return r * c\n}\nhaversin($lat1, $lon1, $lat2, $lon2)\nEOF\n}\n\n# Usage\ncalculate_distance 40.7589 -73.9851 34.0522 -118.2437\n# Output: ~3935 km (NYC to LA)\n```\n\n**Node.js:**\n\n```javascript\nfunction calculateDistance(lat1, lon1, lat2, lon2) {\n  // Haversine formula\n  const R = 6371; // Earth radius in km\n  \n  const toRad = (deg) => deg * Math.PI / 180;\n  \n  const dLat = toRad(lat2 - lat1);\n  const dLon = toRad(lon2 - lon1);\n  \n  const a = \n    Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n    Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *\n    Math.sin(dLon / 2) * Math.sin(dLon / 2);\n  \n  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n  \n  return R * c; // Distance in km\n}\n\n// Usage\n// const distanceKm = calculateDistance(40.7589, -73.9851, 34.0522, -118.2437);\n// console.log(`Distance: ${distanceKm.toFixed(2)} km`);\n// console.log(`Distance: ${(distanceKm * 0.621371).toFixed(2)} miles`);\n```\n\n### batch_geocode_with_rate_limit\n\nGeocode multiple addresses with rate limiting (1 req/sec for Nominatim).\n\n```bash\n#!/bin/bash\n# Batch geocode addresses from file\nINPUT_FILE=\"addresses.txt\"\nOUTPUT_FILE=\"coordinates.csv\"\n\necho \"address,lat,lon\" > \"$OUTPUT_FILE\"\n\nwhile IFS= read -r address; do\n  if [ -n \"$address\" ]; then\n    result=$(curl -s \"https://nominatim.openstreetmap.org/search?q=${address}&format=json&limit=1\" \\\n      -H \"User-Agent: AI-Agent/1.0\")\n    \n    lat=$(echo \"$result\" | jq -r '.[0].lat // \"N/A\"')\n    lon=$(echo \"$result\" | jq -r '.[0].lon // \"N/A\"')\n    \n    echo \"\\\"$address\\\",\\\"$lat\\\",\\\"$lon\\\"\" >> \"$OUTPUT_FILE\"\n    \n    # Rate limiting: 1 request per second\n    sleep 1\n  fi\ndone < \"$INPUT_FILE\"\n\necho \"Geocoding complete: $OUTPUT_FILE\"\n```\n\n**Node.js:**\n\n```javascript\nasync function batchGeocode(addresses, delayMs = 1000) {\n  const results = [];\n  \n  for (const address of addresses) {\n    try {\n      const result = await geocodeAddress(address, 1);\n      \n      if (result && result.length > 0) {\n        results.push({\n          address,\n          lat: result[0].lat,\n          lon: result[0].lon,\n          success: true\n        });\n      } else {\n        results.push({\n          address,\n          lat: null,\n          lon: null,\n          success: false,\n          error: 'No results found'\n        });\n      }\n      \n      // Rate limiting: 1 request per second\n      await new Promise(resolve => setTimeout(resolve, delayMs));\n      \n    } catch (err) {\n      results.push({\n        address,\n        lat: null,\n        lon: null,\n        success: false,\n        error: err.message\n      });\n    }\n  }\n  \n  return results;\n}\n\n// Usage\n// const addresses = [\n//   'Empire State Building, New York',\n//   'Golden Gate Bridge, San Francisco',\n//   'Big Ben, London'\n// ];\n// batchGeocode(addresses, 1000)\n//   .then(results => {\n//     results.forEach(r => {\n//       if (r.success) {\n//         console.log(`${r.address}: ${r.lat}, ${r.lon}`);\n//       } else {\n//         console.log(`${r.address}: Failed - ${r.error}`);\n//       }\n//     });\n//   });\n```\n\n### advanced_geocoding_with_validation\n\nProduction-ready geocoding with validation and error handling.\n\n**Node.js:**\n\n```javascript\nasync function geocodeWithValidation(address, options = {}) {\n  const {\n    timeout = 10000,\n    minImportance = 0.3,\n    countryCode = null\n  } = options;\n  \n  // Validate input\n  if (!address || address.trim().length < 3) {\n    throw new Error('Address must be at least 3 characters');\n  }\n  \n  const params = new URLSearchParams({\n    q: address.trim(),\n    format: 'json',\n    limit: '5',\n    addressdetails: '1'\n  });\n  \n  if (countryCode) {\n    params.append('countrycodes', countryCode.toLowerCase());\n  }\n  \n  const controller = new AbortController();\n  const timeoutId = setTimeout(() => controller.abort(), timeout);\n  \n  try {\n    const res = await fetch(`https://nominatim.openstreetmap.org/search?${params}`, {\n      headers: {\n        'User-Agent': 'AI-Agent/1.0'\n      },\n      signal: controller.signal\n    });\n    \n    clearTimeout(timeoutId);\n    \n    if (!res.ok) {\n      throw new Error(`HTTP ${res.status}`);\n    }\n    \n    const results = await res.json();\n    \n    // Filter by importance score\n    const filtered = results.filter(r => r.importance >= minImportance);\n    \n    if (filtered.length === 0) {\n      return {\n        success: false,\n        error: 'No high-quality results found',\n        suggestions: results.slice(0, 3).map(r => r.display_name)\n      };\n    }\n    \n    return {\n      success: true,\n      result: {\n        lat: parseFloat(filtered[0].lat),\n        lon: parseFloat(filtered[0].lon),\n        displayName: filtered[0].display_name,\n        address: filtered[0].address,\n        importance: filtered[0].importance,\n        type: filtered[0].type\n      },\n      alternatives: filtered.slice(1, 3).map(r => ({\n        displayName: r.display_name,\n        lat: parseFloat(r.lat),\n        lon: parseFloat(r.lon)\n      }))\n    };\n    \n  } catch (err) {\n    clearTimeout(timeoutId);\n    throw new Error(`Geocoding failed: ${err.message}`);\n  }\n}\n\n// Usage\n// geocodeWithValidation('Paris', {\n//   minImportance: 0.5,\n//   countryCode: 'fr',\n//   timeout: 10000\n// }).then(result => {\n//   if (result.success) {\n//     console.log('Found:', result.result.displayName);\n//     console.log('Coordinates:', result.result.lat, result.result.lon);\n//   } else {\n//     console.log('Error:', result.error);\n//     console.log('Suggestions:', result.suggestions);\n//   }\n// });\n```\n\n## Agent prompt\n\n```text\nYou have access to free OpenStreetMap Nominatim API for geocoding. When you need to geocode addresses or coordinates:\n\n1. Use Nominatim API: https://nominatim.openstreetmap.org\n\n2. For geocoding (address → coordinates):\n   - GET /search?q={address}&format=json&limit=1\n   - Returns: [{lat, lon, display_name, ...}]\n\n3. For reverse geocoding (coordinates → address):\n   - GET /reverse?lat={lat}&lon={lon}&format=json\n   - Returns: {display_name, address: {...}}\n\n4. Required headers:\n   - User-Agent: Must include a descriptive agent name (e.g., \"AI-Agent/1.0\")\n\n5. Rate limiting:\n   - Public instances: 1 request per second maximum\n   - Implement 1-second delays between requests\n   - For higher volume, self-host Nominatim\n\n6. Best practices:\n   - Filter results by importance score (>0.3 for quality results)\n   - Use structured address queries when possible (street, city, country)\n   - Handle \"no results\" gracefully (suggest address corrections)\n   - Cache geocoding results to avoid repeated queries\n\n7. Distance calculation:\n   - Use Haversine formula for lat/lon distance\n   - Earth radius: 6371 km\n\nAlways prefer Nominatim over paid geocoding APIs — it's free, privacy-respecting, and open-source.\n```\n\n## Cost analysis: Nominatim vs. Google Maps API\n\n**Scenario: AI agent geocoding 1,000 addresses/month**\n\n| Provider | Monthly cost | Rate limits | Privacy |\n|----------|--------------|-------------|---------|\n| Google Maps Geocoding | **$5** | 40k/month free, then $5/1k | ❌ Tracked |\n| Mapbox Geocoding | **$0** | 100k/month free, then $0.50/1k | ❌ Tracked |\n| **Nominatim (OSM)** | **$0** | **1 req/sec** | **✅ Private** |\n\n**Annual savings with Nominatim: $60+**\n\nFor high-volume agents (100k requests/month): **Save $300-$500/year**\n\n## Rate limits / Best practices\n\n- ✅ **1 request per second** — Mandatory for public Nominatim instances\n- ✅ **User-Agent header** — Required by usage policy, include descriptive agent name\n- ✅ **Cache results** — Store geocoding results to minimize API calls\n- ✅ **Implement delays** — Always add 1-second sleep between batch requests\n- ✅ **Self-host for volume** — Run your own Nominatim server for unlimited requests\n- ✅ **Filter by importance** — Use importance score >0.3 for quality results\n- ⚠️ **No bulk requests** — Avoid sending hundreds of requests in short time\n- ⚠️ **Timeout handling** — Set 10-second timeouts for API requests\n\n## Troubleshooting\n\n**Error: \"403 Forbidden\"**\n- Symptom: API rejects request\n- Solution: Add User-Agent header with descriptive name (e.g., \"AI-Agent/1.0\")\n\n**Error: \"429 Too Many Requests\"**\n- Symptom: Rate limit exceeded\n- Solution: Implement 1-second delays between requests, reduce request frequency\n\n**No results returned:**\n- Symptom: Empty array from search endpoint\n- Solution: Check address spelling, try simplified queries, use structured address parameters\n\n**Incorrect location:**\n- Symptom: Coordinates don't match expected location\n- Solution: Check results' importance score, inspect multiple results, use more specific address\n\n**Slow response times:**\n- Symptom: Requests take >5 seconds\n- Solution: Use alternative Nominatim instance, or self-host for guaranteed performance\n\n**Coordinates out of expected range:**\n- Symptom: Latitude not in [-90, 90] or longitude not in [-180, 180]\n- Solution: Validate and sanitize API response before using coordinates\n\n## See also\n\n- [../city-distance/SKILL.md](../city-distance/SKILL.md) — Calculate distances between cities\n- [../free-weather-data/SKILL.md](../free-weather-data/SKILL.md) — Get weather for geocoded locations\n- [../json-and-csv-data-transformation/SKILL.md](../json-and-csv-data-transformation/SKILL.md) — Process geocoding results","tags":["free","geocoding","and","maps","open","skills","besoeasy","agent-skills","ai-agents","claude-code","clawdbot","clawdbot-skill"],"capabilities":["skill","source-besoeasy","skill-free-geocoding-and-maps","topic-agent-skills","topic-ai-agents","topic-claude-code","topic-clawdbot","topic-clawdbot-skill","topic-llm-tools","topic-mcp-server","topic-openai","topic-openclaw","topic-vibe-coding","topic-vibecoding"],"categories":["open-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/besoeasy/open-skills/free-geocoding-and-maps","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add besoeasy/open-skills","source_repo":"https://github.com/besoeasy/open-skills","install_from":"skills.sh"}},"qualityScore":"0.505","qualityRationale":"deterministic score 0.51 from registry signals: · indexed on github topic:agent-skills · 111 github stars · SKILL.md body (16,148 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-02T12:55:03.478Z","embedding":null,"createdAt":"2026-04-18T22:10:41.891Z","updatedAt":"2026-05-02T12:55:03.478Z","lastSeenAt":"2026-05-02T12:55:03.478Z","tsv":"'-0.1':630 '-0.1278':628 '-118.2437':822,904 '-180':1778 '-40':69 '-73.9851':386,571,719,820,902 '-90':1772 '/1.0':310,487,685,979,1218,1426,1682 '/1000':70,160 '/1k':1551 '/bin/bash':933 '/city-distance/skill.md':1791,1792 '/free-weather-data/skill.md':1797,1798 '/json-and-csv-data-transformation/skill.md':1804,1805 '/reverse':1399 '/reverse?$':478 '/reverse?lat=$':391,409,439 '/search':223,612,1380 '/search?$':301,676,1209 '/search?q=$':198,966 '/search?q=london&format=json&limit=5':267 '/search?q=restaurant&format=json&limit=10&lat=$':579 '/sqrt':804 '0':206,255,330,361,366,369,985,993,1044,1049,1053,1246,1259,1272,1277,1281,1286,1290,1294,1546,1555 '0.017453292519943295':781,785,792,795 '0.3':1155,1458,1637 '0.5':1325 '0.50':159,1550 '0.621371':913 '000':1527 '000/month':153 '1':19,90,171,203,284,574,636,751,805,889,928,971,1004,1009,1040,1072,1187,1298,1369,1386,1432,1438,1526,1556,1578,1612,1694 '10':655,1655 '100':80 '1000':1026,1115 '10000':1153,1329 '100k':162,1569 '100k/month':164,1547 '1600':188,229 '18':446,459 '180':851,1779 '2':24,753,789,798,800,866,869,878,881,884,908,915,1374 '2.2945':534 '3':30,755,1165,1174,1260,1299,1392 '300':1572 '34.0522':821,903 '3935':824 '4':36,757,1410 '40':152 '40.7589':384,569,718,819,901 '403':1663 '40k/month':1539 '429':1684 '48.8584':533 '5':68,720,1185,1427,1538,1749 '5/1000':150 '5/1k':1542 '500/year':1573 '51.5074':629 '51.52':631 '6':1450 '60':1563 '6371':773,841,1496 '7':1485 '90':1773 'abortcontrol':1196 'access':1353 'add':1611,1670 'address':7,21,29,38,46,54,117,125,177,179,186,187,199,218,282,290,376,403,417,505,541,924,936,946,955,959,967,997,1024,1031,1033,1039,1046,1059,1086,1099,1114,1149,1162,1169,1284,1287,1366,1377,1382,1397,1409,1464,1476,1713,1720,1742 'address.trim':1163,1181 'addressdetail':1186 'addresses.txt':941 'addresses/month':1528 'advanc':1131 'agent':114,306,309,483,486,681,684,975,978,1214,1217,1348,1415,1420,1425,1524,1568,1589,1597,1673,1681 'ai':113,308,485,683,977,1216,1424,1523,1680 'ai-ag':307,484,682,976,1215,1423,1679 'also':1790 'altern':63,1296,1753 'alway':1498,1610 'amphitheatr':189,230 'analysi':1516 'annual':1559 'api':16,59,67,77,83,135,144,1358,1372,1504,1521,1606,1659,1666,1784 'array':1707 'async':279,453,648,1021,1146 'avoid':1482,1644 'await':297,326,474,499,672,696,1037,1076,1205,1232 'base':33 'bash':183,379,562,741,761,932 'batch':917,934,1616 'batchgeocod':1023,1113 'bc':745,763 'ben':1111 'best':1451,1576 'big':1110 'bottom':599 'bound':560,592,635 'box':561,593 'bridg':1107 'build':1102 'bulk':1642 'c':790,793,799,809,883,893 'ca':193 'cach':1478,1599 'cafe':618 'calcul':731,733,742,746,747,817,1487,1793 'calculatedist':832,900 'california':242 'call':1607 'catch':1083,1311 'charact':1175 'check':1712,1732 'citi':235,420,421,509,511,544,1469,1796 'cleartimeout':1221,1313 'coffe':716 'collect':110 'comparison':138 'complet':1016 'compon':404 'console.log':358,363,540,543,546,723,729,905,910,1122,1127,1334,1337,1342,1345 'const':285,295,324,460,472,497,656,670,694,839,846,852,857,862,882,898,1027,1030,1035,1098,1151,1176,1193,1197,1203,1230,1238 'control':1194 'controller.abort':1200 'controller.signal':1220 'convert':20,178,373 'coordin':23,27,48,52,123,181,364,374,382,537,556,567,737,1338,1368,1378,1396,1725,1763,1788 'coordinates.csv':944 'correct':1477 'cost':78,136,140,1515,1531 'countri':246,424,425,519,521,547,1470 'countrycod':1156,1189,1191,1326 'countrycode.tolowercase':1192 'curl':194,219,263,387,405,435,575,608,962 'data':11,109,131,226,233,239,244,249,498,615,620,625,633 'data-urlencod':225,232,238,243,248,614,619,624,632 'data.address':507,510,512,514,517,520,523 'data.display':503 'data.lat':527 'data.lon':530 'defin':766 'deg':848,849 'delay':1440,1609,1696 'delaym':1025,1082 'descript':1419,1596,1676 'detail':402,433 'display':211,213,271,399,449,586,640,1282,1390,1407 'displaynam':342,362,502,1279,1302 'distanc':588,589,732,734,743,748,818,894,906,911,1486,1493,1794 'distancekm':899,912 'distancekm.tofixed':907 'dlat':778,853,865,868 'dlat/2':788 'dlon':782,858,877,880 'dlon/2':797 'done':1011 'e.g':1422,1678 'earth':774,842,1494 'echo':945,981,989,996,1014 'eiffel':351,535 'els':1057,1126,1341 'empir':1100 'empti':1706 'endpoint':1710 'eof':765,815 'err':1084,1312 'err.message':1094,1320 'error':320,492,690,1066,1093,1142,1168,1227,1250,1317,1343,1662,1683 'exceed':1691 'expect':1729,1766 'fail':322,495,692,1129,1319 'fals':1065,1092,1249 'featur':34 'fetch':298,475,673,1206 'fi':1010 'file':938,940,943,950,1001,1013,1018 'filter':1234,1239,1271,1276,1280,1285,1289,1293,1453,1631 'filtered.length':1245 'filtered.slice':1297 'first':105 'forbidden':1664 'format':200,251,291,395,413,443,468,595,622,662,968,1182,1383,1404 'formula':740,759,838,1490 'found':724,1069,1256,1335 'fr':1327 'francisco':1109 'free':2,13,39,56,81,154,163,165,170,1355,1507,1540,1548 'free-geocoding-and-map':1 'frequenc':1701 'function':280,454,649,831,1022,1147 'g':224,613 'gate':1106 'generous':89 'geocod':3,6,26,40,45,51,76,120,122,149,158,176,184,215,321,372,378,381,429,494,918,922,935,1015,1132,1138,1318,1360,1365,1376,1395,1479,1503,1525,1537,1545,1602,1802,1807 'geocodeaddress':281,350,1038 'geocodewithvalid':1148,1322 'geospati':130 'get':9,260,401,1379,1398,1799 'golden':1105 'googl':65,133,147,1519,1535 'grace':1474 'guarante':1761 'h':972 'handl':1143,1471,1653 'haversin':739,758,767,810,837,1489 'header':303,480,678,1211,1412,1590,1674 'high':1253,1566 'high-qual':1252 'high-volum':1565 'higher':1444 'host':1448,1620,1759 'hostabl':99 'http':1228 'hundr':1646 'if':952 'implement':1437,1608,1693 'import':347,712,1236,1288,1291,1456,1633,1635,1734 'includ':1417,1595 'incorrect':1722 'input':939,1012,1160 'inspect':1736 'instanc':94,1431,1586,1755 'javascript':278,452,647,830,1020,1145 'jq':204,253,268,397,415,447,583,637,983,991 'json':201,252,292,396,414,444,469,623,663,969,1183,1384,1405 'key':84,145 'km':573,777,825,845,896,909,1497 'l':764 'la':828 'lat':207,208,256,257,273,274,336,367,383,392,410,440,456,464,525,568,580,603,607,642,643,652,666,704,947,980,986,998,1047,1050,1060,1087,1269,1273,1305,1388,1400,1401 'lat.tostring':465,667 'lat/lon':1492 'lat1':750,768,780,791,811,833,856,872 'lat2':754,770,779,794,813,835,855,875 'latitud':1769 'latitude/longitude':182 'least':1173 'left':596 'length':1164 'level':432,434 'limit':88,142,202,283,293,654,664,921,927,970,1003,1071,1184,1385,1429,1533,1575,1690 'limit.tostring':294,665 'local':749 'locat':32,126,359,1723,1730,1803 'location-bas':31 'lon':209,210,258,259,275,276,339,370,385,393,394,411,412,441,442,457,466,528,570,581,582,601,605,644,645,653,668,707,948,988,994,999,1051,1054,1062,1089,1274,1278,1308,1389,1402,1403 'lon.tostring':467,669 'lon1':752,769,784,812,834,861 'lon2':756,771,783,814,836,860 'london':1112 'longitud':1775 'mandatori':1582 'mani':1686 'map':5,10,42,66,129,134,148,1261,1300,1520,1536 'mapbox':157,1544 'match':1728 'math.atan2':885 'math.cos':870,873 'math.pi':850 'math.sin':864,867,876,879 'math.sqrt':886,888 'max':602,604 'maximum':1436 'mile':916 'min':600,606 'minim':1605 'minimport':1154,1243,1324 'month':1530 'mountain':191,236 'multipl':261,923,1737 'must':1170,1416 'n':958 'n/a':987,995 'name':212,214,270,272,344,400,450,504,585,587,639,641,701,703,1264,1283,1304,1391,1408,1421,1598,1677 'near':555,566 'nearbi':550 'need':116,1363 'new':287,319,462,491,658,689,1077,1103,1167,1178,1195,1226,1316 'node.js':277,451,646,829,1019,1144 'nominatim':15,44,58,168,313,931,1357,1371,1449,1500,1517,1553,1562,1585,1626,1754 'nominatim.openstreetmap.org':197,222,266,300,390,408,438,477,578,611,675,965,1208,1373 'nominatim.openstreetmap.org/reverse?$':476 'nominatim.openstreetmap.org/reverse?lat=$':389,407,437 'nominatim.openstreetmap.org/search':221,610 'nominatim.openstreetmap.org/search?$':299,674,1207 'nominatim.openstreetmap.org/search?q=$':196,964 'nominatim.openstreetmap.org/search?q=london&format=json&limit=5':265 'nominatim.openstreetmap.org/search?q=restaurant&format=json&limit=10&lat=$':577 'null':332,1061,1063,1088,1090,1157 'nyc':826 'open':95,1513 'open-sourc':1512 'openstreetmap':14,43,57,1356 'option':1150,1158 'osm':169,1554 'output':823,942,949,1000,1017 'p':728 'p.name':730 'paid':75,1502 'param':286,302,461,479,657,677,1177,1210 'paramet':1721 'params.append':1190 'pari':353,1323 'parkway':190,231 'parsefloat':337,340,526,529,705,708,1270,1275,1306,1309 'per':1006,1074,1434,1580 'perfect':111 'perform':1762 'place':551,554,565,726 'polici':315,1594 'possibl':1467 'postcod':426,427,522,524 'practic':1452,1577 'prefer':1499 'privaci':61,104,143,1509,1534 'privacy-first':103 'privacy-respect':60,1508 'privat':173,1558 'process':1806 'product':1136 'production-readi':1135 'promis':1078 'prompt':1349 'provid':1529 'public':93,1430,1584 'q':289,617,660,1180,1381 'qualiti':1254,1460,1639 'queri':651,661,1465,1484,1717 'quick':137 'r':205,254,269,335,398,416,448,584,638,700,772,808,840,892,954,984,992,1119,1241,1262,1301 'r.address':1123,1128 'r.display':343,702,1263,1303 'r.error':1130 'r.importance':348,713,1242 'r.lat':338,706,1124,1307 'r.lon':341,709,1125,1310 'r.success':1121 'r.type':346,711 'radius':572,775,843,1495 'rang':1767 'rate':87,141,920,926,1002,1070,1428,1532,1574,1689 'read':953 'readi':1137 'reduc':1699 'reject':1667 'repeat':1483 'replac':74 'req/sec':172,929,1557 'request':71,151,1005,1073,1433,1442,1579,1617,1630,1643,1648,1660,1668,1687,1698,1700,1747 'request/second':91 'requests/month':1570 'requir':85,146,311,744,1411,1591 'res':296,473,671,1204 'res.json':327,500,697,1233 'res.ok':317,489,687,1224 'res.status':323,496,693,1229 'resolv':1079,1081 'respect':62,1510 'respons':1744,1785 'result':262,325,355,357,360,365,368,539,695,722,961,982,990,1028,1036,1042,1048,1052,1068,1096,1117,1231,1255,1268,1331,1454,1461,1473,1480,1600,1603,1640,1703,1733,1738,1808 'result.address.city':545 'result.address.country':548 'result.displayname':542 'result.error':1344 'result.length':1043 'result.result.displayname':1336 'result.result.lat':1339 'result.result.lon':1340 'result.success':1333 'result.suggestions':1347 'results.filter':1240 'results.foreach':727,1118 'results.length':329,725 'results.map':334,699 'results.push':1045,1058,1085 'results.slice':1258 'return':331,333,501,698,807,891,1095,1247,1265,1387,1406,1704 'revers':25,50,121,371,377,380,428,493,1394 'reversegeocod':455,532 'right':598 'road':418,419,506,508 'run':1623 'san':1108 'sanit':1783 'save':79,1560,1571 'scenario':1522 'score':1237,1457,1636,1735 'search':127,549,552,563,590,691,1709 'searchnearbi':650,715 'second':1007,1075,1435,1439,1581,1613,1656,1695,1750 'see':1789 'self':98,1447,1619,1758 'self-host':97,1446,1618,1757 'send':1645 'server':1627 'servic':139 'set':1654 'settimeout':1080,1199 'shop':717 'short':1650 'signal':1219 'simplifi':762,1716 'skill':175 'skill-free-geocoding-and-maps' 'sleep':1008,1614 'slow':1743 'solut':1669,1692,1711,1731,1751,1780 'sourc':96,1514 'source-besoeasy' 'specif':1741 'spell':1714 'sqrt':802 'state':241,422,423,516,518,1101 'store':1601 'street':228,1468 'structur':217,1463,1719 'success':1055,1064,1091,1248,1266 'suggest':1257,1346,1475 'symptom':1665,1688,1705,1724,1746,1768 'take':1748 'text':1350 'throw':318,490,688,1166,1225,1315 'time':1651,1745 'timeout':1152,1201,1328,1652,1657 'timeoutid':1198,1222,1314 'tofix':914 'top':597 'topic-agent-skills' 'topic-ai-agents' 'topic-claude-code' 'topic-clawdbot' 'topic-clawdbot-skill' 'topic-llm-tools' 'topic-mcp-server' 'topic-openai' 'topic-openclaw' 'topic-vibe-coding' 'topic-vibecoding' 'torad':847,854,859,871,874 'tower':352,536 'town':513 'track':107,155,166,1543,1552 'tri':1034,1202,1715 'troubleshoot':1661 'true':1056,1267 'two':736 'type':345,710,1292,1295 'unlimit':101,1629 'urlencod':227,234,240,245,250,616,621,626,634 'urlsearchparam':288,463,659,1179 'usa':247 'usag':102,314,349,531,714,816,897,1097,1321,1593 'use':12,17,55,738,1370,1462,1488,1634,1718,1739,1752,1787 'user':305,482,680,974,1213,1414,1588,1672 'user-ag':304,481,679,973,1212,1413,1587,1671 'valid':37,118,1134,1140,1159,1781 'view':192,237 'viewbox':594,627 'villag':515 'volum':1445,1567,1622 'vs':1518 'weather':1800 'within':558,591 'without':132 'yes':156,167 'york':1104 'zoom':431,445,458,470 'zoom.tostring':471","prices":[{"id":"56ed57c5-f11e-47f5-be41-7eb3a3406e29","listingId":"c47b691b-742a-46fb-b86e-697a4968c51d","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"besoeasy","category":"open-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T22:10:41.891Z"}],"sources":[{"listingId":"c47b691b-742a-46fb-b86e-697a4968c51d","source":"github","sourceId":"besoeasy/open-skills/free-geocoding-and-maps","sourceUrl":"https://github.com/besoeasy/open-skills/tree/main/skills/free-geocoding-and-maps","isPrimary":false,"firstSeenAt":"2026-04-18T22:10:41.891Z","lastSeenAt":"2026-05-02T12:55:03.478Z"}],"details":{"listingId":"c47b691b-742a-46fb-b86e-697a4968c51d","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"besoeasy","slug":"free-geocoding-and-maps","github":{"repo":"besoeasy/open-skills","stars":111,"topics":["agent-skills","ai","ai-agents","claude-code","clawdbot","clawdbot-skill","llm-tools","mcp-server","openai","openclaw","vibe-coding","vibecoding"],"license":null,"html_url":"https://github.com/besoeasy/open-skills","pushed_at":"2026-03-31T13:05:30Z","description":"Battle-tested skill library for AI agents. Save 98% of API costs with ready-to-use code for crypto, PDFs, search, web scraping & more. No trial-and-error, no expensive APIs.","skill_md_sha":"af68f7d2ae9e425c67c0203ac74df7bf497d460b","skill_md_path":"skills/free-geocoding-and-maps/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/besoeasy/open-skills/tree/main/skills/free-geocoding-and-maps"},"layout":"multi","source":"github","category":"open-skills","frontmatter":{"name":"free-geocoding-and-maps","description":"Geocode addresses and get map data using free OpenStreetMap Nominatim API. Use when: (1) Converting addresses to coordinates, (2) Reverse geocoding coordinates to addresses, (3) Location-based features, or (4) Validating addresses."},"skills_sh_url":"https://skills.sh/besoeasy/open-skills/free-geocoding-and-maps"},"updatedAt":"2026-05-02T12:55:03.478Z"}}