Discovery API, version 1.
One API for the Nearest worldwide places database and locality search. Invite-only access, explicit limits and attribution on every response.
Your first request
- Request an invitation. Requests are reviewed; there is no public key or invite minting endpoint.
- Sign in with your verified invited email, accept the token, and create your developer project.
- Create a key with
discovery:read. Copy it once into a server secret store. Addusage:readif the key needs to inspect its own usage. - Send every request to
https://api.neare.st.
curl
# Set these in your server environment. Never commit your key. # The API origin is https://api.neare.st curl --fail-with-body --get "https://api.neare.st/v1/places/nearby" \ --header "Authorization: Bearer $NEAREST_API_KEY" \ --data-urlencode 'lat=51.5074' \ --data-urlencode 'lon=-0.1278' \ --data-urlencode 'radius_m=2000' \ --data-urlencode 'categories=cafes' \ --data-urlencode 'limit=20'
Coordinates are illustrative query inputs, not an assertion that matching records are loaded there. Do not use verbose request logging or put keys in query strings.
TypeScript with generated contract types
The monorepo exports OpenAPI-generated paths from @nearest/contracts. External projects can generate equivalent types from the published OpenAPI document; the workspace package is not published to npm. This is a typed fetch example, not a generated runtime client.
// Server-side TypeScript; types generated from OpenAPI 3.1.
import type { paths } from '@nearest/contracts';
type Nearby = paths['/v1/places/nearby']['get'];
type Result = Nearby['responses'][200]['content']['application/json'];
export async function nearby(origin: string, key: string): Promise<Result> {
const url = new URL('/v1/places/nearby', origin);
url.search = new URLSearchParams({
lat: '51.5074', lon: '-0.1278', radius_m: '2000', categories: 'cafes'
}).toString();
const response = await fetch(url, {
headers: { Authorization: 'Bearer ' + key },
cache: 'no-store', redirect: 'error', signal: AbortSignal.timeout(10000)
});
if (!response.ok) {
// Handle error.code and Retry-After. Do not log request headers.
throw new Error('Nearest request failed: HTTP ' + response.status);
}
return await response.json() as Result;
}Keep response attribution and capability metadata alongside the returned records.
Read endpoints
| GET path | Purpose |
|---|---|
/v1/categories | All stable category IDs and capability information |
/v1/places/nearby | Nearest eligible places around a centre or within a bounded box |
/v1/places/search | Bounded text and category search |
/v1/places/{id} | A place and its permitted facts |
/v1/locations/search | Locality-name search with explicit precision |
/v1/locations/reverse | Nearest locality; not an address or proof of administrative containment |
/v1/coverage | Current coverage by area and category, with limitations |
/v1/attributions | Credits, licence links and notices |
/v1/developer/usage | The caller key’s recorded usage over a time window |
Discovery uses discovery:read; usage uses usage:read. API keys do not authorize consumer lists, account information, contributions, photos or administration.
Place searches require a centre or bounded box. Radius defaults to 5,000 m and is capped at 50,000 m. Limit defaults to 20 and is capped at 50. Text is at most 200 characters. Bboxes are west,south,east,north and at most 10,000 km²; an east value below west crosses the antimeridian. Distances are approximate straight-line metres, never travel times. Current discovery is bounded first-page retrieval; do not assume pagination.
Canonical specification: GET /v1/openapi.json on the API origin. This site exposes a same-origin copy at /api/v1/openapi.json. Breaking changes require a new major path, such as /v2; they will never replace /v1 in place.
Limits, metering and errors
Your invitation sets the project’s minute, UTC-day and UTC-month ceilings. Keys have ceilings of their own and share the project ceilings. Creating or rotating keys cannot increase the project allowance. See assigned limits in your portal. These are beta guardrails, not measured commercial capacity or a performance SLA.
One admitted, validated discovery attempt consumes one quota unit, including cache hits, empty results and requests that subsequently fail. Authentication, validation and rate/quota rejections consume no discovery quota. Usage reads consume no discovery quota. Request history includes failures and rejections, so its total may differ from quota consumption.
| Header | Meaning |
|---|---|
RateLimit-Limit / Remaining | Effective minute allowance and remaining requests, constrained by both key and project. |
RateLimit-Reset | Seconds until the fixed minute window resets. |
RateLimit-Policy | Minute policy, with window expressed as w=60. |
X-Quota-Day-Limit / Remaining / Reset | Daily allowance, remaining units and reset as a Unix timestamp in seconds. |
X-Quota-Month-Limit / Remaining / Reset | Monthly allowance, remaining units and reset as a Unix timestamp in seconds. |
Retry-After | Delay in seconds for 429 responses and applicable 503 errors. Wait before retrying. |
Limits are returned when a key can be identified and its counters evaluated. Invalid credentials cannot receive private quota details. Respect HTTP 429 and do not rotate keys to evade a limit.
{
"error": {
"code": "QUOTA_EXCEEDED",
"message": "…",
"request_id": "…",
"retry_after_seconds": 60
}
}The error above illustrates the envelope; its delay is not a promised quota reset. Branch on the stable error.code, not the human message. RATE_LIMITED and QUOTA_EXCEEDED use 429. Validation is 400, invalid authentication 401, missing scope 403, absent record 404, conflict 409, and unavailable capability/service 503. A request ID supports debugging without sharing your key or location query.
Coverage and data limits
The Nearest database grows every day as we add new data and community reports. The table follows the currently active API catalog; a listed category is not proof of local coverage.
| Stable category ID | Database status |
|---|---|
restaurants | In the Nearest database; coverage varies by area |
cafes | In the Nearest database; coverage varies by area |
groceries | In the Nearest database; coverage varies by area |
pharmacies | In the Nearest database; coverage varies by area |
atms | In the Nearest database; coverage varies by area |
washrooms | Limited database coverage; mostly community reports for now |
parking | In the Nearest database; coverage varies by area |
gas_stations | In the Nearest database; coverage varies by area |
ev_charging | In the Nearest database; coverage varies by area |
public_wifi | Community Wi-Fi reports; not loaded from Overture |
drinking_water | Not loaded from Overture; community submissions may appear |
libraries | In the Nearest database; coverage varies by area |
shops | In the Nearest database; coverage varies by area |
attractions | In the Nearest database; coverage varies by area |
parks | In the Nearest database; coverage varies by area |
gyms | In the Nearest database; coverage varies by area |
coworking | Not loaded from Overture; community submissions may appear |
liquor_stores | In the Nearest database; coverage varies by area |
If returned, Overture lake and private_lodging records are point features. A point may be a feature centre or private residence, not a public entrance, area boundary or proof of access.
Locality lookup covers cities and towns worldwide. There is no worldwide street-address, rooftop, postcode or administrative-boundary service yet. A nearest locality is not an address. Missing access, Wi-Fi, water potability, hours, prices and other attributes remain unknown. There is no live occupancy, charging availability, fuel-price or routing promise.
Do not interpret an empty response as proof that no real facility exists. Coverage varies by area and keeps growing. Coverage counts may include records that are not eligible for redistribution through the API. See current coverage.
Licences & attribution
Preserve meta.attributions, each record’s source_ids, attribution_ids, source_attributions, modifications, database_licence and normalized_at. Resolve every attribution ID against the response metadata, and display the credit, source/licence links, change indications and database release offer wherever you show the corresponding data. Follow the response’s attribution link for source notices, including on errors or non-record responses.
Some records in the Nearest database carry third-party licence terms, resolved per contributing dataset. Preserve licence identifiers, dataset names and Nearest’s normalization timestamp. Redistributed CDLA data must carry the agreement text. Locality data from GeoNames requires attribution, its CC BY 4.0 licence and applicable source credits. As the database adds data sources, their terms appear in the attributions endpoint.
- CDLA Permissive 2.0 licence text
- CC0 1.0 licence text
- Creative Commons Attribution 4.0 licence text
- GeoNames source credits
Only redistribution-approved records and fields are eligible for the developer API. API access grants no basemap or tile-resale entitlement: bring your own permitted map. OpenStreetMap-derived database redistribution remains gated by its source review and distribution obligations.
Current attribution and licence notices · Privacy and contribution terms
Measured community signals
GET /v1/community/signals?place_id=PLACE_ID returns approved, unexpired observations. Alternatively use lat and lon for reports at an exact coordinate. Developer keys use the existing discovery read scope and quotas. Keep every signal’s report count, most recent time and individual evidence (author, report time, expiry) with its reported status. Never turn one report into a statement of fact. author is the reporter’s @handle when they chose a public profile, otherwise anonymous; contributor carries the same public handle and picture, or null.
Freshness windows from server receipt: washroom 4 hours, charger 1 hour, parking 30 minutes, café 2 hours, outlet 7 days, Wi-Fi 1 day. Approval does not reset the clock. Disputed reports are removed after moderation accepts the dispute. Clients must stop displaying evidence at its expiry, including while a page remains open.
Confidence is an evidence weight: min(1, sum(1 − age/window) / 5), using recent reports from distinct contributors. It depends only on sample size and recency, and is not a probability or a claim about availability. Conflicting statuses remain separate. No wait-time, occupancy or busyness prediction exists.
Coverage for washrooms and similar gaps is only as good as the community reports received so far. No report is unknown. Community reports are counted separately from database place counts. Contributions and disputes use authenticated, moderated POST /v1/contributions; developer keys cannot write them.
Location input
/v1/locations/search accepts decimal latitude/longitude, DMS, DMM and coordinate-bearing OpenStreetMap and Google Maps URLs. Coordinate input returns type=coordinate, match_type=exact_input and source_ids=["user_input"]. It is the caller’s supplied point, not a verified address. Other input retains locality search. Shortened map links, plus codes and geohashes are not supported coordinate formats.
Try a request
Use your own key. An admitted discovery request consumes quota, even if it returns no results. Your key stays in this page’s memory until you clear it or leave; it is sent only to the Nearest API boundary.
Version 1 beta changelog
Milestone 6 adds measured, expiring community signals and direct coordinate resolution. Milestone 5 adds invite-only developer accounts, project/key limits, revocation, usage summaries and the authenticated explorer. Discovery continues through the existing /v1 handlers. Billing, subscriptions and automatic overages are unavailable.