Nearest for developers · Invite-only beta

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.

Coverage keeps growing. A listed category is not a guarantee of coverage in every area. Check current coverage for your area before integrating.

Your first request

  1. Request an invitation. Requests are reviewed; there is no public key or invite minting endpoint.
  2. Sign in with your verified invited email, accept the token, and create your developer project.
  3. Create a key with discovery:read. Copy it once into a server secret store. Add usage:read if the key needs to inspect its own usage.
  4. 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 pathPurpose
/v1/categoriesAll stable category IDs and capability information
/v1/places/nearbyNearest eligible places around a centre or within a bounded box
/v1/places/searchBounded text and category search
/v1/places/{id}A place and its permitted facts
/v1/locations/searchLocality-name search with explicit precision
/v1/locations/reverseNearest locality; not an address or proof of administrative containment
/v1/coverageCurrent coverage by area and category, with limitations
/v1/attributionsCredits, licence links and notices
/v1/developer/usageThe 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.

HeaderMeaning
RateLimit-Limit / RemainingEffective minute allowance and remaining requests, constrained by both key and project.
RateLimit-ResetSeconds until the fixed minute window resets.
RateLimit-PolicyMinute policy, with window expressed as w=60.
X-Quota-Day-Limit / Remaining / ResetDaily allowance, remaining units and reset as a Unix timestamp in seconds.
X-Quota-Month-Limit / Remaining / ResetMonthly allowance, remaining units and reset as a Unix timestamp in seconds.
Retry-AfterDelay 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 IDDatabase status
restaurantsIn the Nearest database; coverage varies by area
cafesIn the Nearest database; coverage varies by area
groceriesIn the Nearest database; coverage varies by area
pharmaciesIn the Nearest database; coverage varies by area
atmsIn the Nearest database; coverage varies by area
washroomsLimited database coverage; mostly community reports for now
parkingIn the Nearest database; coverage varies by area
gas_stationsIn the Nearest database; coverage varies by area
ev_chargingIn the Nearest database; coverage varies by area
public_wifiCommunity Wi-Fi reports; not loaded from Overture
drinking_waterNot loaded from Overture; community submissions may appear
librariesIn the Nearest database; coverage varies by area
shopsIn the Nearest database; coverage varies by area
attractionsIn the Nearest database; coverage varies by area
parksIn the Nearest database; coverage varies by area
gymsIn the Nearest database; coverage varies by area
coworkingNot loaded from Overture; community submissions may appear
liquor_storesIn 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.

Redistribution exclusions: Apache-licensed Overture records are withheld until their release-specific full Foursquare NOTICE is verified. Unknown or missing provenance is excluded. Commercial enrichment and basemap data are not included.

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.

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.

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.