LocaMapHQLocaMapHQ

API Documentation

The LocaMapHQ public API finds local business leads by city and industry. Use it from scripts, agents, or any HTTP client to search, list, and export leads within your credit balance. Prefer a terminal workflow instead of raw HTTP calls? The LocaMapHQ CLI wraps this same API for city and industry searches, saved leads, and CSV export.

Authentication

All endpoints except /health and /meta require a Bearer API key.

http
Authorization: Bearer lmhq_live_YOUR_KEY_HERE

Create a key at /dashboard/settings/api-keys. The raw key is shown exactly once on creation and cannot be recovered later. Give it a name so you can identify it, and revoke it if it is ever compromised.

Credits

Search costs 1 credit per business returned. The charge is based on what is actually found, up to your requested limit. A search that returns no results, or that fails upstream, charges nothing.

All other endpoints are free: health, metadata, balance check, listing saved leads, and CSV export.

Before running a search, call GET /api/public/v1/credits to check the balance. The balance is a guide, not an exact quote, since the final charge depends on how many businesses are found.

Add credits

Purchase credit packs at /pricing. See current pack sizes and prices in the GET /api/public/v1/meta response.

Rate limits

Limits are per API key. On serverless deployments with multiple concurrent instances, effective limits may be higher because each instance maintains its own counters.

GroupLimitApplies to
permissiveEffectively open/health, /meta
general60 / minute/credits, /leads/saved
search10 / minute/leads/search
export20 / minute/leads/export

When a limit is exceeded the response is 429 with a Retry-After header giving seconds until the window resets.

Endpoints

GET/api/public/v1/health
No keyFree

Liveness check.

GET/api/public/v1/meta
No keyFree

Service metadata, pricing, and onboarding URLs.

GET/api/public/v1/credits
Requires keyFree

Current credit balance.

GET/api/public/v1/leads/saved
Requires keyFree

List stored leads, paginated.

POST/api/public/v1/leads/search
Requires key1 credit per result

Find local businesses by city and trade.

GET/api/public/v1/leads/export
Requires keyFree

Export a search as CSV.

POST /api/public/v1/leads/search

Find local businesses by city and trade. Returns business name, category, address, phone, rating, review-volume signal, and whether the business has a website. Charges 1 credit per result actually found.

Request body

json
{
  "city":     "Austin",      // required
  "industry": "plumber",     // required
  "limit":    25,            // optional, one of 10 / 25 / 50 / 100, default 10
  "country":  "US",          // optional, default "US"
  "name":     "My search"    // optional label
}

Response (200)

json
{
  "search_id":         "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "prospects_found":   23,
  "credits_used":      23,
  "remaining_credits": 227
}

Retrieve results with GET /api/public/v1/leads/saved?search_id=<id>.

GET /api/public/v1/leads/saved

Returns stored prospects paginated. Pass ?search_id= to filter to one search.

Query parameters

ParamDefaultNotes
limit20Max 100.
offset0Pagination offset.
search_id--UUID. Filter to a specific search.

Code examples

All examples use the placeholder key lmhq_live_YOUR_KEY_HERE. Replace it with your actual key from the dashboard.

Search -- curl

bash
curl -X POST https://www.locamaphq.com/api/public/v1/leads/search \
  -H "Authorization: Bearer lmhq_live_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"city":"Austin","industry":"plumber","limit":25}'

Search -- JavaScript

js
const response = await fetch(
  'https://www.locamaphq.com/api/public/v1/leads/search',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer lmhq_live_YOUR_KEY_HERE',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ city: 'Austin', industry: 'plumber', limit: 25 }),
  }
);

const data = await response.json();
console.log(
  `Found ${data.prospects_found} leads, used ${data.credits_used} credits.`
);

// Retrieve the actual results
const results = await fetch(
  `https://www.locamaphq.com/api/public/v1/leads/saved?search_id=${data.search_id}`,
  { headers: { 'Authorization': 'Bearer lmhq_live_YOUR_KEY_HERE' } }
);
const { prospects } = await results.json();

Search -- Python

python
import requests

API_KEY = "lmhq_live_YOUR_KEY_HERE"
BASE = "https://www.locamaphq.com/api/public/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# Run a search
response = requests.post(
    f"{BASE}/leads/search",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"city": "Austin", "industry": "plumber", "limit": 25},
)
data = response.json()
print(f"Found {data['prospects_found']} leads, used {data['credits_used']} credits.")

# Retrieve results
results = requests.get(
    f"{BASE}/leads/saved",
    headers=HEADERS,
    params={"search_id": data["search_id"]},
)
for p in results.json()["prospects"]:
    website = p["website_url"] or "(no website)"
    print(f"{p['business_name']} -- {p['phone']} -- {website}")

Error codes

All errors return JSON in the standard envelope:

json
{ "error": { "code": "rate_limited", "message": "Rate limit exceeded. Retry after the window resets." } }
CodeHTTPWhen
unauthorized401Authorization header missing or malformed.
invalid_api_key401Key not found in the database.
revoked_api_key401Key was revoked. Create a new key.
invalid_request400Missing or invalid request parameter.
insufficient_credits402Not enough credits for the requested search.
rate_limited429Too many requests. Check the Retry-After header.
provider_unavailable503Search provider is temporarily unavailable. No credits charged.
internal_error500Unexpected server error. No credits charged if no results were saved.
LocaMapHQ AI