## Quick Start for AI Agents Point your agent to: https://gmapsscraper.io/llms.txt Or install a skill: npx skills add gmapsscraper/google-maps-agent-skills/google-maps-scraper All skills: https://github.com/gmapsscraper/google-maps-agent-skills --- # GMaps Scraper API Documentation # Base URL: https://gmapsscraper.io/api/v1 ## Authentication All requests require a Bearer token: Authorization: Bearer gmaps_sk_your_key_here Get your free API key at: https://gmapsscraper.io/dashboard (API Keys tab) Free accounts include 10 credits (5 searches). --- ## Endpoints ### POST /api/v1/scrape Create a new Google Maps scraping job. Costs 2 credits. Request: curl -X POST https://gmapsscraper.io/api/v1/scrape \ -H "Authorization: Bearer gmaps_sk_your_key_here" \ -H "Content-Type: application/json" \ -d '{"keywords":["coffee shop in new york"],"email":true,"depth":2}' Parameters: keywords (required) — Array of search terms, e.g. ["dentist in Austin TX"] name (optional) — Job name for reference lang (optional) — Language code, default "en" zoom (optional) — Map zoom 1-21, default 15 depth (optional) — Search depth 1-3, default 2. Higher = more results lat (optional) — Center latitude (auto-geocoded from keywords if omitted) lon (optional) — Center longitude (auto-geocoded from keywords if omitted) radius (optional) — Search radius in meters, default 20000 email (optional) — Ask the scraper for emails Google exposes, default false. Returns almost none on its own; use POST /api/v1/enrich for emails. fast_mode (optional) — Skip deep website crawling, default true max_time (optional) — Max job duration in seconds, default 3600 proxy_url (optional) — Your own proxy URL, e.g. "http://user:pass@host:port". Routes scraping through your proxy instead of the shared server IP. Supports HTTP, HTTPS, and SOCKS5. Recommended for high-volume usage to avoid Google rate limiting. area (optional) — Set to true for Area Search. Runs 5 grid-point sub-searches around the target location for 3-5x more leads. Costs 10 credits instead of 2. Results are automatically merged and deduplicated by business ID. Requires lat/lon (auto-geocoded from keywords if omitted). Response (201 Created): { "id": "6f0c1af8-3c4e-4742-84bb-590938ae8930", "credits_remaining": 8 } --- ### GET /api/v1/jobs/:id Check job status. Poll until status is "complete" or "failed". A running job tells you when to come back, in a Retry-After header and a "retry_after" field (seconds). Honour it instead of polling on a fixed timer: it starts at 10s and widens as the job ages, so a long scrape is checked about once a minute rather than 200 times. Our SDKs do this for you. Request: curl https://gmapsscraper.io/api/v1/jobs/6f0c1af8-3c4e-4742-84bb-590938ae8930 \ -H "Authorization: Bearer gmaps_sk_your_key_here" Response (still running): { "id": "6f0c1af8-3c4e-4742-84bb-590938ae8930", "status": "running", "name": "coffee shop in new york", "retry_after": 20 } Response (finished): { "id": "6f0c1af8-3c4e-4742-84bb-590938ae8930", "status": "complete", "name": "coffee shop in new york" } Status values: "running", "complete", "failed". "retry_after" appears on running jobs only. --- ### GET /api/v1/jobs/:id/download Download results as CSV when job is complete. Request: curl https://gmapsscraper.io/api/v1/jobs/6f0c1af8-3c4e-4742-84bb-590938ae8930/download \ -H "Authorization: Bearer gmaps_sk_your_key_here" \ --output results.csv Response: CSV file with columns: title, address, phone, website, email, rating, reviews_count, category, latitude, longitude, google_maps_url, opening_hours --- ### POST /api/v1/enrich Crawl business websites for contact details. This is where emails come from: the scrape itself returns only what Google exposes, which is almost never an email address. Feed it the website column from the download. Request: curl -X POST https://gmapsscraper.io/api/v1/enrich \ -H "Authorization: Bearer gmaps_sk_your_key_here" \ -H "Content-Type: application/json" \ -d '{"urls":["flemingdonparkgolfclub.ca","https://example.com"]}' Parameters: urls (required) — array of website URLs, up to 50 per request. Scheme optional; duplicates are removed. Response: { "results": [ { "url": "flemingdonparkgolfclub.ca", "emails": ["info@fpgc.ca"], "socials": {"facebook": "https://facebook.com/..."} } ], "requested": 2, "with_email": 1, "daily_limit": 25000, "daily_used": 2 } Notes: - Spends no credits and no daily scrape quota. - Rate limit: 20 requests/minute per key (up to 1,000 sites a minute). - Daily ceiling, counted in sites rather than calls, and separate from the scrape limit so enriching never eats into what you can scrape: Starter ($19/mo): 25,000 sites/day Pro ($49/mo): 125,000 sites/day Advanced ($399/yr): 125,000 sites/day No subscription: 500 sites/day Each paid ceiling is a full day of that plan's scrapes at the maximum batch size, so it will not stop you before your scrape limit does. Every response reports daily_limit and daily_used. Resets 00:00 UTC. - Each site is crawled for up to 3 pages: the homepage, plus contact pages when the homepage carries no address. - A site that is unreachable or publishes no address returns empty arrays rather than an error, so a batch never fails as a whole. --- ### GET /api/v1/credits Check your remaining credit balance. Request: curl https://gmapsscraper.io/api/v1/credits \ -H "Authorization: Bearer gmaps_sk_your_key_here" Response: { "credits": 8 } --- ## Error Codes 401 — Invalid or missing API key 402 — Insufficient credits. Purchase more at https://gmapsscraper.io/#pricing 422 — Invalid request parameters 429 — Daily scrape limit reached (resets 00:00 UTC), more than 10 jobs pending, or on /enrich: 20 requests/minute or the daily site ceiling 502 — Scraping backend temporarily unavailable 500 — Internal server error Error response format: { "error": "Human-readable error message" } --- ## Rate Limits - Daily limits count scrapes started. Status polls, downloads and balance checks are unmetered, so a job costs one unit however long you poll it. Starter ($19/mo): 500/day Pro ($49/mo): 2,500/day Advanced ($399/yr): 2,500/day No subscription: 100/day - Each ceiling is sized to what that plan's monthly credits buy, so the daily limit won't stop you before your credits do. - Max 10 concurrent (pending) jobs per account - Standard scrape: 2 credits; Area Search (area: true): 10 credits - Status checks and downloads cost no credits and no daily quota - Completed results are saved to your account history and can be re-downloaded from the dashboard - For high-volume usage, pass proxy_url to avoid shared IP rate limits from Google --- ## Complete Example: Scrape → Poll → Download # 1. Start a scrape job JOB=$(curl -s -X POST https://gmapsscraper.io/api/v1/scrape \ -H "Authorization: Bearer gmaps_sk_your_key_here" \ -H "Content-Type: application/json" \ -d '{"keywords":["plumber in chicago"],"email":true}') JOB_ID=$(echo $JOB | jq -r '.id') # 2. Poll until complete, waiting as long as the API asks while true; do JOB_STATE=$(curl -s https://gmapsscraper.io/api/v1/jobs/$JOB_ID \ -H "Authorization: Bearer gmaps_sk_your_key_here") STATUS=$(echo $JOB_STATE | jq -r '.status') echo "Status: $STATUS" if [ "$STATUS" = "complete" ] || [ "$STATUS" = "failed" ]; then break; fi sleep $(echo $JOB_STATE | jq -r '.retry_after // 10') done # 3. Download results curl -s https://gmapsscraper.io/api/v1/jobs/$JOB_ID/download \ -H "Authorization: Bearer gmaps_sk_your_key_here" \ --output plumbers_chicago.csv # 4. Attach emails — batch the website column 50 at a time. # Free: no credits, no daily quota. csvcut -c website plumbers_chicago.csv | tail -n +2 | grep . | \ while mapfile -t -n 50 BATCH && [ ${#BATCH[@]} -gt 0 ]; do printf '%s\n' "${BATCH[@]}" | jq -R . | jq -sc '{urls: .}' | \ curl -s -X POST https://gmapsscraper.io/api/v1/enrich \ -H "Authorization: Bearer gmaps_sk_your_key_here" \ -H "Content-Type: application/json" --data-binary @- \ | jq -r '.results[] | select(.emails|length>0) | [.url, .emails[0]] | @csv' sleep 3 # stay under 20 requests/minute done > emails.csv --- ## Area Search Example (3-5x more leads) # Area Search fans out 5 sub-searches in a grid. 10 credits, ~100+ leads. JOB=$(curl -s -X POST https://gmapsscraper.io/api/v1/scrape \ -H "Authorization: Bearer gmaps_sk_your_key_here" \ -H "Content-Type: application/json" \ -d '{"keywords":["plumber in chicago"],"email":true,"area":true}') JOB_ID=$(echo $JOB | jq -r '.id') # Poll and download — same as standard workflow. # Results are merged and deduplicated automatically. --- ## Tips - Use multiple keywords in one request for broader coverage (same credit cost) - For emails, run POST /api/v1/enrich over the website column after downloading - Be specific with location: "dentist in downtown Austin TX" > "dentist in Texas" - Save your CSV — you can re-process it anytime without spending credits - Location is auto-geocoded from keywords — no need to provide lat/lon manually ## Pricing - Free: 10 credits (5 searches) - Starter: $19/month — 30,000 credits - Pro: $49/month — 150,000 credits - Advanced: $399/year — 1,800,000 credits Details: https://gmapsscraper.io/#pricing