API reference
Locomint API
Base URL https://api.locomint.io/v1. JSON in, JSON out, UTF-8 everywhere. One header to authenticate. Every response carries a request ID and your rate-limit headers.
Quickstart
Search for dentists in Lisbon, then fetch one record in full, enrichment included:
curl "https://api.locomint.io/v1/places/search?q=dentist&location=Lisbon,%20Portugal&limit=5" \ -H "X-API-Key: $LOCOMINT_KEY" curl "https://api.locomint.io/v1/places/ChIJjxN4B_tDXz4RLrBrwzc9Qew" \ -H "X-API-Key: $LOCOMINT_KEY"
Always add the country to the location. “Warsaw” alone can resolve to Warsaw, Indiana. “Warsaw, Poland” cannot.
Authentication
Send your key in the X-API-Key header on every request. Create a free key on the signup page; it works immediately with 200 credits a month. Free keys look like lm_free_…, paid keys like lm_live_…. A missing or unknown key returns 401.
Programmatic signup: POST/v1/signup with { "email", "name", "company" } returns { "api_key", "plan", "monthly_quota", "rate_per_minute" }. One key per email; three signups per network per day.
GET/places/search
Keyword + location → a page of places with the core fields.
| Parameter | Type | Notes |
|---|---|---|
q | string, required | Keyword or category: dentist, coffee shop, car rental |
location | string | Free text, geocoded server-side: Dubai Marina, Lagos, Nigeria |
lat, lng, radius | number, number, int (m) | Coordinate search instead of location. Default radius 5000 m |
limit | int, default 20, max 50 | Places per page |
page | int, default 1 | Deep pages that drift outside the area are cut off automatically |
language | BCP-47, default en | Names and categories come back localised |
fields | comma list | Return only these summary fields |
Response: { "data": [PlaceSummary…], "pagination": { "page", "limit", "has_more" }, "meta": { "request_id", "credits_used", "source" } }. Costs one credit per place returned.
GET/places/{place_id}
The full record: everything in the summary plus description, all seven days of opening hours, plus code, timezone, photos, attributes — and enrichment, fetched from the business website on first request and cached per site for 30 days.
| Parameter | Type | Notes |
|---|---|---|
place_id | path | Locomint place ID (ChIJ…) or a numeric CID |
refresh | bool, default false | Re-crawl the website now (+1 credit) |
language | BCP-47 |
Costs one credit; unknown IDs return 404 and cost nothing.
GET/places/{place_id}/reviews
The latest reviews for a place with the rating summary. Reviewer identity is off by default; pass include_author=true to get the public display name. limit up to 100; one credit per 10 reviews. Only the latest page is available — paging further would require defeating a protection measure, which we do not do.
GET/places/count
Estimate how many places match a query before you pay for them. Free, cached for 24 hours per query, capped per key per day.
POST/emails/verify
Verify up to 100 addresses per call without sending a message. One credit per address.
curl -X POST "https://api.locomint.io/v1/emails/verify" \
-H "X-API-Key: $LOCOMINT_KEY" -H "Content-Type: application/json" \
-d '{"emails": ["info@acme.example", "nobody@gmail.com"]}'
Each row carries status (deliverable, undeliverable, invalid, disposable, risky for catch-all domains, unknown when the server would not answer), a reason, a 0–100 score, and every check that ran: syntax_valid, mx_found, mx_host, disposable, free_provider, role_account, catch_all, smtp_checked, smtp_code. Set "smtp_check": false for domain-level checks only.
POST/websites/extract
Readable text plus contact details for up to 20 page URLs per call. One credit per page.
curl -X POST "https://api.locomint.io/v1/websites/extract" \
-H "X-API-Key: $LOCOMINT_KEY" -H "Content-Type: application/json" \
-d '{"urls": ["https://acme.example/"], "output": "markdown", "max_chars": 20000}'
Each row: status (ok, thin for client-side rendered pages, parked, http_error, not_html, unreachable, blocked, refused), title, description, language, headings, content, word_count, and with include_contacts (default true) the emails, socials, whatsapp, contact_form_url and tech_stack. Pass "include_links": true for up to 500 outgoing links per page.
Status & usage
GET/status — public, no key. The daily canary result: status (operational / degraded / outage), success_rate, latencies, checked_at. Shown live at /status.
GET/usage — credits used in the current billing period for your key.
The Place record
| Field | Description |
|---|---|
place_id | Stable identifier, shared with official sources. Use it to diff runs. |
name, categories[] | As listed, localised by language |
address | full, street, city, region, postal_code, country_code (ISO 3166-1) |
location | lat, lng |
phone, website | International format; website as listed |
rating, reviews_count, price_level | |
status | open, temporarily_closed, permanently_closed |
hours | Per weekday, list of { open, close } in HH:MM; 24:00 allowed |
service_area_business | True when the business has no storefront address |
description, plus_code, timezone, photos[], attributes[] | Details only |
enrichment | emails[] (role mailboxes only), socials{}, whatsapp, contact_form_url, tech_stack[], website_status, crawled_at |
source, fetched_at | Which data path answered, and when |
Errors
Every error is { "error": { "code", "message", "request_id" } }.
| Status | Code | Meaning |
|---|---|---|
| 400 | bad_request | Missing or invalid parameter |
| 401 | unauthorized | Missing or unknown API key |
| 402 | quota_exceeded | The request would exceed your monthly quota. Nothing charged. |
| 404 | not_found | Unknown place ID |
| 429 | rate_limited | Too many requests this minute. Honour Retry-After. |
| 503 | source_unavailable | The data path is degraded; retry after Retry-After. Check /status. |
Limits & credits
- Rate limit: 60 requests per minute per key. Headers:
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset. - Quota: checked before any work using the request’s estimated cost; a request that would exceed it is refused with 402 and costs nothing.
- Credits: 1 per place in search, 1 per details call, +1 for
refresh=true, 1 per 10 reviews, 1 per email verified, 1 per page extracted.countandstatusare free. - Request ID: every response carries
X-Request-Id. Quote it when you write to us.
Removal requests
Any business can ask to be removed from our results via the removal form or POST/removal-requests. Removals take effect within 7 days and are honoured across the API and the actors.