LocalProspects

Find local businesses on Google Maps with owner names, business emails, phone line types and social profiles, and export leads from your AI agent.

Hosted MCP Server

npx add-mcp 'https://localprospects.ai/api/mcp'

Installs into Claude Code, Codex, Cursor and more

Documentation

API Referencev2.0

Local Prospects API

Search for local businesses, enrich them by domain, and get back public emails, phone carrier data, owner names, social profiles, and website intelligence.

Quick Start

For searches across multiple areas, use a campaign. The direct search example below is for a one-off or deliberately small single-location search. Replace the API key with yours from the dashboard.

1. Find a location code

curl "https://localprospects.ai/api/v1/locations?q=denver" \
  -H "x-api-key: lp_your_key"
# Returns: { locations: [{ location_code: 1012938, full_name: "Denver, Colorado, US", ... }] }

2. Search for businesses

curl -X POST https://localprospects.ai/api/v1/search \
  -H "Content-Type: application/json" \
  -H "x-api-key: lp_your_key" \
  -d '{"keyword": "electrician", "location_code": 1012938, "depth": 300}'

3. Poll until enrichment completes

curl https://localprospects.ai/api/v1/job/<job_id> \
  -H "x-api-key: lp_your_key"
# Poll every 5s until status === "completed"

Or enrich leads you already have

curl -X POST https://localprospects.ai/api/v1/enrich \
  -H "Content-Type: application/json" \
  -H "x-api-key: lp_your_key" \
  -d '{"leads": [{"domain": "brightlineelectric.com"}]}'

Authentication

Search, campaign, location, and enrichment requests require an API key via the x-api-key header. Category lookup is public. Get your key from the dashboard.

curl -H "x-api-key: lp_your_key" https://localprospects.ai/api/v1/...

MCP Server

Connect ChatGPT, Claude, GoHighLevel, Cursor, Codex or any AI that supports MCP. It can search and enrich local businesses, run campaigns across many cities and export leads as a CSV, using your lead credits.

https://localprospects.ai/api/mcp

Sign in (ChatGPT, claude.ai, GoHighLevel): add the URL with no key. You sign in to LocalProspects and click Allow.

API key (Claude Code, Cursor, Codex): send your key as Authorization: Bearer YOUR_API_KEY. Your key is on your dashboard.

Connect your AI

Instructions for ChatGPT

Paste this into ChatGPT. It connects with your LocalProspects login, no API key needed.

Connect to LocalProspects so you can find, enrich and export local business leads for me.

Add the LocalProspects MCP server in ChatGPT:
- Plugins → Add → Add custom MCP server
- URL: https://localprospects.ai/api/mcp
- Sign in with LocalProspects and click Allow

Use these as well:
- REST API: https://localprospects.ai/docs (send your API key as x-api-key; it's on https://localprospects.ai/dashboard)
- Skill file: https://localprospects.ai/localprospects-skill.md

To pull leads for a niche in a city: find_location, then search_businesses, then search_status until it's done, then get_results. For many cities, run a campaign and export it as a CSV. Tell me the credit cost before searching, enriching or starting a campaign.

Leads tools

check_creditsLead credits left and your plan.
find_locationTurns a city like "Irvine, CA" into the location code a search needs.
search_businessesFinds and enriches businesses for a niche in one city. One credit per business found, up to the depth you pick (100 to 700). Unused credits are refunded.
search_statusProgress of a search, and the credits it used.
get_resultsThe enriched leads: owner (with first name, last name and title), emails, phones with line type, socials, website status, rating and address. Filter to leads with a website, email, phone or mobile.
enrich_domainsEnriches websites you already have, up to 10 at a time. One credit per domain.

Campaigns tools

find_campaign_locationsFinds the states and cities a campaign can cover.
preview_campaignHow many cities a campaign would search and the most credits it could use. Saves nothing.
create_campaignSaves a campaign for one niche across many cities. Uses no credits until it starts.
start_campaign / resume_campaignStarts a campaign, or resumes a paused one. One credit per business found, until it covers every city, reaches its lead cap or runs out of credits.
pause_campaign / stop_campaignPauses a campaign so it can be resumed, or stops it for good.
list_campaigns / get_campaignYour campaigns with their status, progress, leads found and credits used.
update_campaignChanges a campaign's area, lead cap or name.
get_campaign_leadsA campaign's leads, a page at a time, with text search.
export_campaign / get_exportBuilds a CSV of every lead (Simple, Advanced, GoHighLevel, Instantly or 1ClickWebsite format) and returns a download link.
add_search_to_campaignAdds a finished search's leads to a campaign.
  • Your AI can only see and use your own account.
  • Searches, enrichment and campaigns use the same lead credits as the dashboard and the API. Ask your AI to confirm the cost before it spends any.
  • Export download links last 24 hours. You can also find every export in Downloads on your dashboard.

Agent Skill

Paste this skill file into Claude Code, Codex, Manus, or any other agent platform to search and enrich leads autonomously. Using ChatGPT, Claude or GoHighLevel? Connect the MCP server instead.

Loading skill…

Look Up Locations

GET /api/v1/locations?q=:query

Fuzzy search for cities and regions. Returns location_code values required by the search endpoint. No credits consumed.

Parameters

ParameterTypeDescription
qstringCity name to search (min 2 characters). e.g. miami, denver co, austin texas

Request

curl "https://localprospects.ai/api/v1/locations?q=miami" \
  -H "x-api-key: lp_your_key"

Response

Returns up to 8 matching locations, sorted by relevance (US cities first).

{
  "locations": [
    { "location_code": 1015116, "name": "Miami", "region": "Florida", "country": "US", "type": "City", "full_name": "Miami, Florida, US" },
    { "location_code": 1015117, "name": "Miami Beach", "region": "Florida", "country": "US", "type": "City", "full_name": "Miami Beach, Florida, US" },
    { "location_code": 9052425, "name": "Miami Gardens", "region": "Florida", "country": "US", "type": "City", "full_name": "Miami Gardens, Florida, US" },
    { "location_code": 1013446, "name": "Miami", "region": "Arizona", "country": "US", "type": "City", "full_name": "Miami, Arizona, US" }
  ]
}

GET /api/search/categories?q=:query

Find primary business categories for exact category search. This public endpoint needs no API key and consumes no lead credits.

Parameters

ParameterTypeDescription
qstringCategory name to search (2–80 characters). Returns up to 3 matches; an exact name comes first, then matches are ordered by business count.

Request

curl "https://localprospects.ai/api/search/categories?q=designer"

Response

{
  "categories": [
    { "category_key": "website_designer", "display_name": "Website designer" },
    { "category_key": "graphic_designer", "display_name": "Graphic designer" },
    { "category_key": "interior_designer", "display_name": "Interior designer" }
  ]
}

An API search automatically uses exact primary category matching when its keyword matches a category name, ignoring case. You can also send just its category_key as exact_category_key with a location; the API fills in the category name as the search term. Send exact_category_key: null to search broadly for a category name.

Search for Businesses

POST /api/v1/search

Find businesses by niche and location. Requires a location_code from the locations endpoint. Returns a job ID — enrichment runs async in the background.

Parameters

ParameterTypeDescription
keywordstringBusiness type (e.g. electrician, dentist, roofer). Optional when exact_category_key is supplied.
location_codeintegerLocation ID from GET /v1/locations (required)
depthintegerMaximum provider results: 100, 300, 500, or 700 (optional; default 300)
exact_category_keystring | nullOmit to auto-match an exact category name (case-insensitive). Send a category key with or without a keyword to require it, or null to search broadly. Only primary category matches are kept in exact mode.

For example, keyword: "Dentist" selects the Dentist category automatically. A non-category term such as "WordPress designer" stays a free text search. To search broadly for dentists, send exact_category_key: null.

Request

curl -X POST https://localprospects.ai/api/v1/search \
  -H "Content-Type: application/json" \
  -H "x-api-key: lp_your_key" \
  -d '{"keyword": "electrician", "location_code": 1012938, "depth": 300}'

To search by category alone, omit keyword:

curl -X POST https://localprospects.ai/api/v1/search \
  -H "Content-Type: application/json" \
  -H "x-api-key: lp_your_key" \
  -d '{"exact_category_key": "dentist", "location_code": 1026201, "depth": 100}'

Response

The selected depth is reserved before provider work begins. The response reports the final charge and refund; a failed search refunds the full reservation. Use the job ID to poll for enrichment progress and fetch results.

{
  "job_id": "a3f8c21d-7b04-4e19-9c6a-d42e8f1b5a07",
  "status": "enriching",
  "keyword": "electrician",
  "exact_category_key": "electrician",
  "cities_searched": 1,
  "cities_missing": [],
  "total_raw": 52,
  "total_unique": 52,
  "total_enrichable": 41,
  "credits_reserved": 300,
  "leads_charged": 52,
  "credits_refunded": 248,
  "leads_remaining": 948,
  "timings": {
    "geocode_ms": 142,
    "search_ms": 2103,
    "dedup_ms": 0,
    "total_ms": 3100
  },
  "search_details": [
    { "city": "location_1012938", "results": 274, "elapsed_ms": 10843 }
  ],
  "businesses": [
    {
      "name": "Brightline Electric",
      "phone": "1720-555-0391",
      "website": "https://www.brightlineelectric.com/",
      "address": "4820 Elm St Suite 200, Denver, CO 80216",
      "city": "Denver",
      "state": "Colorado",
      "country_iso_code": "US",
      "rating": 4.7,
      "reviews": 178,
      "rating_distribution": { "1": 3, "2": 1, "3": 4, "4": 12, "5": 158 },
      "cid": "8827364519203847561",
      "google_cid": "8827364519203847561",
      "place_id": "ChIJ_example_brightline",
      "category": "Electrician",
      "latitude": 39.7508,
      "longitude": -104.9490,
      "is_claimed": true,
      "rank_group": 1,
      "rank_absolute": 3,
      "main_image": "https://lh3.googleusercontent.com/gps-cs-s/...",
      "total_photos": 14,
      "snippet": "4820 Elm St Suite 200, Denver, CO 80216",
      "price_level": null,
      "book_online_url": null,
      "searched_city": "Denver CO"
    }
  ]
}

Insufficient credits

A 100-depth search can use a final balance of 1–99 credits and returns no more leads than it reserves. Deeper searches must reserve their full selected depth. The request returns 429 before provider work begins when the account cannot make that reservation.

{
  "error": "Not enough lead credits -- 300 required to search",
  "code": "insufficient_credits",
  "required_credits": 300,
  "available_credits": 100
}

Search Campaigns

POST /api/v1/campaigns

Create a resumable multi-location search. Campaigns are available on every plan and use the same lead-credit balance as ordinary searches. Each location searches up to 100 leads, and a Google Maps CID is charged only once within the same campaign. A campaign can use a final balance of 1–99 credits for one more location, then pauses at zero until credits are added.

Create a campaign

ParameterTypeDescription
keywordstringOne business niche for this campaign; optional when exact_category_key is supplied
exact_category_keystring | nullOmit to auto-match an exact category name; send a key with or without a keyword to require it, or null for a broad search
campaign_idUUIDOptional client-generated idempotency key; safely reuse it when retrying create
namestringOptional display name
max_leadsintegerOptional campaign-wide stopping limit for charged unique leads
scope.includeinteger[]Ordered country, region, or city location codes
scope.excludeinteger[]Descendants to omit from an included area
scope.default_depthintegerOptional; campaign searches are always normalized to 100
scope.depth_overridesobjectAccepted for compatibility but ignored; campaigns always use 100
curl -X POST https://localprospects.ai/api/v1/campaigns \
  -H "Content-Type: application/json" \
  -H "x-api-key: lp_your_key" \
  -d '{
    "name": "California plumbers",
    "keyword": "plumber",
    "max_leads": 5000,
    "scope": {
      "include": [21137],
      "exclude": [1014369],
      "default_depth": 100
    }
  }'

Use POST /api/v1/campaigns/preview with the same body to resolve and review the plan without saving it.

Lifecycle and results

FieldDescription
GET /api/v1/campaignsList campaigns for the API key owner
GET /api/v1/campaigns/:idCampaign, ordered plan, child searches, stats, and activity
PATCH /api/v1/campaigns/:idEdit a draft or paused plan; the active location is locked
POST /api/v1/campaigns/:id/actions/startStart a ready campaign
POST /api/v1/campaigns/:id/actions/pausePrevent another location from starting
POST /api/v1/campaigns/:id/actions/resumeContinue a paused or attention-needed campaign
POST /api/v1/campaigns/:id/actions/stopPermanently stop future searches
GET /api/v1/campaigns/:id/leadsPaginated, cross-search deduplicated campaign leads
GET /api/v1/campaigns/:id/planPaginate large frozen execution plans
GET /api/v1/campaigns/:id/exportDownload the deduplicated campaign pool as CSV
POST /api/v1/campaigns/:id/searchesAttach an existing same-keyword search with { job_id }
GET /api/v1/campaign-locationsBrowse countries, regions, and cities for scope codes

Each child is a normal search job with a campaign_id. Campaign searches reserve 100 credits, or the full positive balance when fewer than 100 remain, then settle as soon as that location finishes. New CIDs are charged once per campaign; repeated CIDs and unused credits are refunded immediately. Searches without a CID are charged normally, and standalone searches use the same final-balance rule.

Poll Job Status

GET /api/v1/job/:jobId

Poll every 5 seconds until status is completed, then call the results endpoint to get enriched data.

Request

curl https://localprospects.ai/api/v1/job/a3f8c21d-7b04-4e19-9c6a-d42e8f1b5a07 \
  -H "x-api-key: lp_your_key"

Response (in progress)

{
  "job_id": "a3f8c21d-7b04-4e19-9c6a-d42e8f1b5a07",
  "status": "enriching",
  "keyword": "electrician",
  "total_businesses": 41,
  "enriched_count": 28,
  "failed_count": 5,
  "progress": 80,
  "created_at": "2026-03-15T14:22:00.000000+00:00",
  "completed_at": null
}

Response (completed)

{
  "job_id": "a3f8c21d-7b04-4e19-9c6a-d42e8f1b5a07",
  "status": "completed",
  "keyword": "electrician",
  "total_businesses": 41,
  "enriched_count": 36,
  "failed_count": 5,
  "progress": 100,
  "created_at": "2026-03-15T14:22:00.000000+00:00",
  "completed_at": "2026-03-15T14:23:38.000000+00:00"
}

Get Enriched Results

GET /api/v1/job/:jobId/results

Fetch the full enriched business data for a completed job. Each business includes promoted best-match email, GBP phone, mobile number when found, grouped sections for contact, reputation, services, and web/tech data.

Request

curl https://localprospects.ai/api/v1/job/a3f8c21d-7b04-4e19-9c6a-d42e8f1b5a07/results \
  -H "x-api-key: lp_your_key"

Optional filters

Add any of these boolean query parameters to narrow the returned businesses. Use true to require the data or false to require it to be absent. Omitted filters do not change results, and combined filters use AND logic. Filters apply to JSON and every CSV format.

ParameterTypeDescription
has_websitebooleanBusiness has a website URL
has_emailbooleanBusiness has at least one discovered email
has_phonebooleanBusiness has at least one phone of any known type
has_mobile_phonebooleanBusiness has at least one phone classified as mobile
# Businesses with both an email and any phone
curl "https://localprospects.ai/api/v1/job/a3f8c21d-7b04-4e19-9c6a-d42e8f1b5a07/results?has_email=true&has_phone=true" \
  -H "x-api-key: lp_your_key"

# Businesses without a website that have a mobile phone
curl "https://localprospects.ai/api/v1/job/a3f8c21d-7b04-4e19-9c6a-d42e8f1b5a07/results?has_website=false&has_mobile_phone=true" \
  -H "x-api-key: lp_your_key"

Response formats

The endpoint returns the existing JSON structure by default. Add the optional format query parameter to download a CSV using the same export presets available in the dashboard. Choosing a representation does not rerun the search or consume additional credits.

FieldDescription
jsonDefault. Returns { businesses: [...] } using the full structured API response
simpleCompact outreach CSV with core business, contact, reputation, and website content columns
advancedFull enrichment CSV with Google CID, Place ID, primary fields, discovered emails, phones, website content, and crawled page links
ghlGoHighLevel-ready contact CSV with owner, business, contact, source, and category fields
instantlyInstantly-ready lead CSV with predefined contact and personalization fields; businesses without an email are omitted
1cw1ClickWebsite Lead Gen CSV with business name, phone, email, address, color, and logo

CSV examples

# Advanced CSV
curl "https://localprospects.ai/api/v1/job/a3f8c21d-7b04-4e19-9c6a-d42e8f1b5a07/results?format=advanced" \
  -H "x-api-key: lp_your_key" \
  -o leads-advanced.csv

# GoHighLevel CSV
curl "https://localprospects.ai/api/v1/job/a3f8c21d-7b04-4e19-9c6a-d42e8f1b5a07/results?format=ghl" \
  -H "x-api-key: lp_your_key" \
  -o leads-ghl.csv

# Instantly CSV
curl "https://localprospects.ai/api/v1/job/a3f8c21d-7b04-4e19-9c6a-d42e8f1b5a07/results?format=instantly" \
  -H "x-api-key: lp_your_key" \
  -o leads-instantly.csv

CSV responses use text/csv and include attachment, result-format, and result-count headers. Unsupported format or filter values return 400 with the valid options.

JSON response

Showing 1 business. Best email, GBP phone, and mobile number are promoted to the top level. Full lists in contact.all_emails[] and contact.all_phones[].

{
  "businesses": [
    {
      "id": "b7e2a9f1-...",
      "name": "Brightline Electric",
      "category": "Electrician",
      "website": "https://www.brightlineelectric.com/",
      "website_status": "ok",
      "logo": "https://www.brightlineelectric.com/logo.png",
      "rank": 3,
      "owner": "Terrence Hayes",
      "owner_first_name": "Terrence",
      "owner_last_name": "Hayes",
      "owner_title": "Owner",
      "owner_verified": true,
      "owner_email": "terrence@brightlineelectric.com",
      "contacts": [
        { "name": "Terrence Hayes", "title": "Owner", "sources": ["website", "bbb"], "email": "terrence@brightlineelectric.com" },
        { "name": "Dana Hayes", "title": "Office Manager", "sources": ["bbb"], "email": null }
      ],
      "contact_2_name": "Dana Hayes",
      "contact_2_title": "Office Manager",
      "contact_3_name": null,
      "contact_3_title": null,
      "email_contact_name": null,
      "bbb": {
        "url": "https://www.bbb.org/us/co/denver/profile/electrician/brightline-electric-1296-90012345",
        "rating": "A+",
        "accredited": true,
        "business_started": "3/14/2011",
        "entity_type": "LLC"
      },
      "summary": null,
      "email": "info@brightlineelectric.com",
      "phone": "(720) 555-0391",
      "phone_type": "mobile",
      "mobile_number": "(720) 555-0391",

      "contact": {
        "address": "4820 Elm St Suite 200, Denver, CO 80216",
        "city": "Denver",
        "state": "Colorado",
        "state_code": "CO",
        "country": "US",
        "lat": 39.7508,
        "lng": -104.9490,
        "all_emails": [
          {
            "email": "info@brightlineelectric.com",
            "is_role_based": true,
            "is_free_provider": false
          },
          {
            "email": "terrence@brightlineelectric.com",
            "is_role_based": false,
            "is_free_provider": false
          }
        ],
        "all_phones": [
          { "number": "(720) 555-0391", "line_type": "mobile", "carrier": "T-MOBILE USA" },
          { "number": "(303) 555-0842", "line_type": "landline", "carrier": "QWEST CORPORATION" }
        ]
      },

      "reputation": {
        "rating": 4.7,
        "reviews": 178,
        "rating_distribution": { "1": 3, "2": 1, "3": 4, "4": 12, "5": 158 },
        "is_claimed": true
      },

      "services": {
        "list": [],
        "specialties": [],
        "areas": [],
        "selling_points": [],
        "customer_types": null,
        "year_established": null,
        "employees": null
      },

      "web": {
        "tech": {
          "cms": "wordpress", "cdn": "cloudflare", "server": "nginx",
          "chat": null, "analytics": ["google_analytics"], "frameworks": ["jquery"], "other": ["schema_org", "recaptcha"]
        },
        "socials": { "facebook": "https://facebook.com/brightlineelectric", "yelp": "https://yelp.com/biz/brightline-electric-denver" },
        "has_blog": true,
        "meta_description": "Denver's trusted electrician since 2012. Panel upgrades, EV chargers, and commercial electrical...",
        "pages_crawled": 4,
        "website_content": "Brightline Electric is Denver's licensed electrician for panel upgrades, EV chargers, and commercial work...",
        "pages": [
          { "url": "https://brightlineelectric.com/", "title": "Denver Electrician | Brightline Electric", "meta_description": "Denver's trusted electrician since 2012..." }
        ]
      },

      "created_at": "2026-03-15T14:23:12.000000+00:00"
    }
  ]
}

Enrich by Domain

POST /api/v1/enrich

Already have leads? Pass an array of domains and get back the full enrichment pipeline — no search required. Each lead costs 1 lead credit. Failed enrichments are refunded automatically.

Parameters

ParameterTypeDescription
leadsarrayArray of lead objects (max 10)
leads[].domainstringBusiness domain (required)
leads[].business_namestringImproves enrichment accuracy (optional)
leads[].citystringCity name (optional)
leads[].statestringState code or name, e.g. CA (optional)

Request

curl -X POST https://localprospects.ai/api/v1/enrich \
  -H "Content-Type: application/json" \
  -H "x-api-key: lp_your_key" \
  -d '{
    "leads": [
      { "domain": "summitridgeplumbing.com", "business_name": "Summit Ridge Plumbing", "city": "Austin", "state": "TX" },
      { "domain": "goldencrust.co" }
    ]
  }'

Response

Same structured shape as search results, minus Maps-only fields (no reputation, rank, main_image). Page text truncated below.

{
  "total": 1,
  "succeeded": 1,
  "failed": 0,
  "results": [
    {
      "domain": "summitridgeplumbing.com",
      "status": "success",
      "result": {
        "id": "d9c4e7a2-...",
        "name": "Summit Ridge Plumbing",
        "category": "Plumber",
        "website": "https://summitridgeplumbing.com",
        "website_status": "ok",
        "logo": "https://summitridgeplumbing.com/images/logo.png",
        "owner": "Marco Delgado",
        "owner_first_name": "Marco",
        "owner_last_name": "Delgado",
        "owner_title": "Founder",
        "owner_verified": false,
        "owner_email": "marco@summitridgeplumbing.com",
        "contacts": [
          { "name": "Marco Delgado", "title": "Founder", "sources": ["website"], "email": "marco@summitridgeplumbing.com" }
        ],
        "contact_2_name": null,
        "contact_2_title": null,
        "contact_3_name": null,
        "contact_3_title": null,
        "email_contact_name": "Marco",
        "bbb": null,
        "summary": null,
        "email": "marco@summitridgeplumbing.com",
        "phone": "(512) 555-0147",
        "phone_type": "mobile",
        "mobile_number": "(512) 555-0147",

        "contact": {
          "address": "782 Riverside Dr, Austin, TX 78704",
          "city": "Austin",
          "state": "Texas",
          "state_code": "TX",
          "country": "US",
          "lat": null,
          "lng": null,
          "all_emails": [
            { "email": "marco@summitridgeplumbing.com", "is_role_based": false, "is_free_provider": false }
          ],
          "all_phones": [
            { "number": "(512) 555-0147", "line_type": "mobile", "carrier": "T-MOBILE USA" }
          ]
        },

        "services": {
          "list": [],
          "specialties": [],
          "areas": [],
          "selling_points": [],
          "customer_types": null,
          "year_established": null,
          "employees": "5-10"
        },

        "web": {
          "tech": { "cms": "wordpress", "cdn": "cloudflare", "server": "nginx", "analytics": ["google_analytics"] },
          "socials": { "facebook": "https://facebook.com/summitridgeplumbing" },
          "has_blog": true,
          "pages_crawled": 3,
          "website_content": "Summit Ridge Plumbing provides water heater, drain, and repiping service across Austin...",
          "pages": [{ "url": "https://summitridgeplumbing.com/", "title": "Summit Ridge Plumbing | Austin TX", "meta_description": null }]
        },

        "created_at": "2026-03-15T16:30:00.000Z"
      }
    }
  ],
  "usage": { "leads_charged": 1, "leads_refunded": 0, "leads_remaining": 4999 }
}

Demo Endpoints

Use these endpoints to test integrations with fake local-business data. They do not require an API key, do not call the search or enrichment workers, and never consume credits.

GET /api/v1/demo/locations?q=:query

Returns sample location codes for client-side location lookup flows.

curl "https://localprospects.ai/api/v1/demo/locations?q=irvine"

POST /api/v1/demo/search

Returns a fake search response with job_id, raw business listings, timings, and enrichable counts.

curl -X POST https://localprospects.ai/api/v1/demo/search \
  -H "Content-Type: application/json" \
  -d '{"keyword": "plumber", "location_code": 1013883}'

GET /api/v1/demo/job/:jobId

Returns a fake job status. Add ?status=enriching to test polling UI while a job is still running.

curl https://localprospects.ai/api/v1/demo/job/demo-job-plumbers-irvine
curl "https://localprospects.ai/api/v1/demo/job/demo-job-plumbers-irvine?status=enriching"

GET /api/v1/demo/job/:jobId/results

Returns fake enriched search results in the same transformed shape as the production results endpoint. The same format values and optional result filters are supported for testing integrations.

curl https://localprospects.ai/api/v1/demo/job/demo-job-plumbers-irvine/results
curl "https://localprospects.ai/api/v1/demo/job/demo-job-plumbers-irvine/results?has_mobile_phone=true"
curl "https://localprospects.ai/api/v1/demo/job/demo-job-plumbers-irvine/results?has_email=true&format=ghl" -o demo-ghl.csv

POST /api/v1/demo/enrich

Returns fake enrichment data for supplied domains. /api/v1/demo/enhance is available as an alias.

curl -X POST https://localprospects.ai/api/v1/demo/enrich \
  -H "Content-Type: application/json" \
  -d '{
    "leads": [
      { "domain": "harborpipe.example", "business_name": "Harbor Pipe & Drain", "city": "Irvine", "state": "CA" }
    ]
  }'

Example Response Marker

Every demo response includes demo: true, so SDKs and test suites can assert they are using fixture data.

{
  "job_id": "demo-job-plumbers-irvine",
  "status": "enriching",
  "keyword": "plumber",
  "location_code": 1013883,
  "total_unique": 2,
  "total_enrichable": 2,
  "demo": true
}

Data Fields

Every enriched business includes these fields. Null when data is unavailable.

Vitals (top-level)

FieldDescription
nameBusiness name
categoryBusiness category (Plumber, Dentist, etc.)
websiteWebsite URL
website_statusWebsite health: ok, no_website (the listing links to a Facebook, Yelp or directory page instead of a site), parked, empty, blocked, down, dead, ssl_error, not_found, not_html, timeout, invalid_url, error. Null when there is no website or for leads enriched before this field existed
gbp_urlGoogle Business Profile URL
google_cidGoogle Maps CID
place_idGoogle Place ID
logoLogo image URL
ownerPrimary owner's full name, from the website and the BBB profile. When both list people, the strongest title wins (owner or founder, then president or CEO, then partner, then manager), and the website wins a tie
owner_first_nameOwner's first name, without titles like Dr. (for personalization)
owner_last_nameOwner's last name, without suffixes like Jr. or DDS
owner_titleOwner's stated role: Owner, Founder, President, Lead Pastor...
owner_verifiedTrue when the website and the BBB profile both name this owner
owner_emailThe owner's personal email when one matches their name (mike@, mmellado@, mike.mellado@)
contacts[]Everyone named on the website or BBB profile, owner first, with duplicates merged (Mike and Michael V. match Mike Varela)
contacts[].nameFull name
contacts[].titleStated role, or null
contacts[].sourcesWhere the person was found: website, bbb, or both
contacts[].emailTheir personal email when one matches their name
contact_2_name / contact_2_titleThe second person in contacts, for spreadsheets
contact_3_name / contact_3_titleThe third person in contacts
email_contact_nameA person's name read from a personal email address on the site (jacob@...). Useful when no owner is named
summaryBusiness summary (reserved for future use)
emailBest-match email (promoted from all_emails)
phoneGBP phone when available, otherwise best available discovered phone
phone_typeLine type of phone (mobile, landline, voip, toll_free)
mobile_numberFirst mobile phone found; may duplicate phone when the GBP phone is mobile
rankSearch rank position (search results only)

BBB

US and Canadian businesses are matched to their Better Business Bureau profile by phone, then by name and city. Leads without a website are looked up too. Null when there is no match.

FieldDescription
bbb.urlBBB profile URL
bbb.ratingBBB letter rating (A+ to F)
bbb.accreditedTrue when the business is BBB accredited
bbb.business_startedDate the business started, as listed on BBB
bbb.entity_typeLegal entity: LLC, Corporation, Sole Proprietorship...

Contact

FieldDescription
contact.addressFull street address
contact.cityCity
contact.stateState name
contact.state_codeState code (CA, TX, etc.)
contact.countryCountry ISO code
contact.latLatitude
contact.lngLongitude
contact.all_emails[]All discovered emails
contact.all_emails[].emailEmail address
contact.all_emails[].is_role_basedTrue for info@, admin@, support@, etc.
contact.all_emails[].is_free_providerTrue for gmail.com, yahoo.com, etc.
contact.all_phones[]All discovered phones
contact.all_phones[].numberPhone number
contact.all_phones[].line_typelandline, mobile, voip, or toll_free
contact.all_phones[].carrierCarrier name (AT&T, Verizon, etc.)

Reputation (search results only)

FieldDescription
reputation.ratingGoogle Maps star rating (1-5)
reputation.reviewsTotal review count
reputation.rating_distributionBreakdown by star: {1: n, 2: n,...}
reputation.is_claimedWhether the listing is claimed by the owner

Services (reserved)

These fields are present in the response shape but currently return empty values. They are reserved for a future release.

FieldDescription
services.listArray of services offered (currently empty)
services.specialtiesKey specialties (currently empty)
services.areasGeographic service areas (currently empty)
services.selling_pointsKey differentiators (currently empty)
services.customer_typesresidential, commercial, or both (currently null)
services.year_establishedYear founded (currently null)
services.employeesEmployee count (currently null)

Web

FieldDescription
web.tech.cmsContent management system (wordpress, squarespace, etc.)
web.tech.cdnCDN provider (cloudflare, etc.)
web.tech.serverWeb server
web.tech.analyticsAnalytics tools array
web.tech.frameworksFrontend frameworks array
web.socialsSocial profile URLs (facebook, instagram, etc.)
web.has_blogWhether site has a blog
web.meta_descriptionPage meta description
web.pages_crawledNumber of pages analyzed
web.website_contentUp to about 1,000 characters of the website's text, homepage first
web.pages[]Crawled pages with url, title, meta_description

Plans

Free

$0

300 leads

Starter

$39/mo

10,000 leads/mo, or $29/mo billed yearly

Agency

$97/mo

50,000 leads/mo, or $79/mo billed yearly

Scale

$297/mo

200,000 leads/mo, or $229/mo billed yearly

All plans return identical data. Lead credits reset monthly, including yearly subscriptions.

Errors

FieldDescription
400Invalid request (missing params, bad domain)
401Missing or invalid API key
429Credit limit or rate limit exceeded
500Internal server error
{ "error": "Search limit reached", "usage": 100, "limit": 100 }

Questions? Use our support chat in the bottom left.