UTC --:--:--
Spot discovery

Find the best suitable spot in a region.

Rank suitable spots in a region before a customer chooses where to go. Give the engine an activity, a region and a window, and get back the top-K ranked sub-spots: calibrated per spot, safety-gated, each with the driver that set its rank. The endpoint behind 'best kitesurf near me this weekend' inside consumer apps and booking platforms.

01
Ranked results

One call · Tarifa · Saturday 10–16 UTC

A worked query for a kitesurf weekend on the Cádiz coast. The engine resolves five catalog sub-spots within 25km of the region centre, scores each across the six-hour window, drops the unsafe and not-feasible ones, and returns this ranked list. Every result uses the same scoring, safety and confidence rules as /v1/score.

Request
POST /v1/recommend-spot
{
 activity: "kitesurfing",
 regionCenter: { lat: 36.013, lng: -5.604 },
 radiusKm: 25,
 topK: 5,
 window: {
 from: "2026-08-28T10:00Z",
 to: "2026-08-28T16:00Z"
 }
}
resolver finds 5 catalog sub-spots in radius
5 spots scored on the same engine as /v1/score
unsafe / not-feasible dropped before ranking · none here
sorted + sliced · ~412ms p50
Response · ranked results5 of 5 returned
  1. 01
    Balneario0.3 km
    Steady 22kt cross-onshore, low gust
    87
  2. 02
    Valdevaqueros6.1 km
    Same wind, slightly choppier
    84
  3. 03
    Punta Paloma8.4 km
    Wind drops 4kt in lee
    79
  4. 04
    Los Lances Sur1.2 km
    Crowded · busy-spot penalty
    73
  5. 05
    Bolonia19.0 km
    Side-shore, gusty afternoon
    68
Reading the result · Balneario and Valdevaqueros both top 80 on the same wind regime, but Balneario wins on lower gust factor. Punta Paloma sits in the lee of the headland (4kt drop). Los Lances Sur is 0.9km closer to the centre, but the catalog tier marks it as crowded, so a busy-spot penalty drops it to fourth. The confidence detail on each row tells the consumer app whether to surface the rank or warn about uncertainty.

Coverage · Score works at any coordinate. Spot Discovery ranks catalogued sub-spots and is available in covered regions.

Check coverage for your region
02
What it's for

One call instead of N

Discovery answers "where should we go?" in a single request. Replace N client-side score calls with one ranked recommend. Discovery ranks trusted score results; it does not invent a separate recommendation model. Every result uses the same scoring, safety and confidence rules as /v1/score.

One call, not N. The engine enumerates the region for you, so the client makes a single request instead of scoring each candidate by hand.
Built for discovery. In-app "find a spot near me" search, region-and-activity result lists, and multi-day itinerary planning.
Per-spot explainability. Every ranked row carries the driver that set its position, so the UI can say why one spot beat another.
Fast and honest. A ranked region resolves in about 412ms p50, and coverage is declared up front so you always know where ranking is available.
03
Buyers

Three personas, one endpoint

Komoot · Strava · FATMAP · brand apps

Consumer discovery

Replace N client-side score calls with one ranked recommend.

25km · topK=5 · personalised
The 'find a spot near me' surface that today's weather apps don't have. Drop-in for existing 'check conditions' flows.
FareHarbor · Bookeo · vertical engines

Booking platforms

Powers region-and-activity search result lists.

50km · topK=10 · no personalisation
Sub-spot calibration means an intermediate-friendly bay outranks a big-wave reef when conditions favour learning, so the funnel converts on quality fit, not just proximity.
Much Better Adventures · Intrepid · enterprise

Travel + tour planners

Itinerary tooling. One call instead of an analyst with five tabs.

200km · topK=20 · counterfactual hints
Pro plan's 200km and topK=20 fit multi-day-route research; Scale's 1000km supports multi-country sweeps with binding-constraint annotations.
04
Safety

Unsafe dropped before ranking

Drop before rank, not after

A candidate that fails a hard gate — unsafe (lightning ≥0.85, hazardous AQI) or not_feasible (e.g. no rideable wind) — is removed before the sort, not filtered out of a ranked list afterwards. Neither an unsafe nor a not-feasible spot can ever surface as a recommendation, whatever its raw score.

When everything is gated

When all candidates are gated, Goable returns no recommendation plus the binding constraint — a danger (lightning, wind hazard, air-quality risk) or a feasibility limit (e.g. no rideable wind anywhere in radius) — so the app can tell the user why rather than showing an empty list.

05
Personalisation

Optional, pseudonymous, deletable

Anchored to fitness, not bias

Optional personalization refines recommendations within safety and physics-defined limits. Personalization is optional, pseudonymous and deletable by design. The exact blend limits and deletion mechanics are documented in Security and the endpoint reference.

06
Plan tiers

Caps scale with the use case

Radius and topK are tiered. Personalisation unlocks at Pro, counterfactual hints at Scale. Daily quota is separate from /v1/score: each recommend call fans out N internal scores, so the cap is independent and tighter. Starter includes 1,500 recommend calls/month, Pro 5,000; overage at €7.50/1k (Starter) and €4.00/1k (Pro).

Free
25km · top5
off
Single-spot operators, prototypes
Starter
50km · top10
off
Weekend planning, small school networks
Pro
200km · top20
personal blend
Regional planners, multi-spot brand apps
Scale
1000km · top50
personal + counterfactual hints
Travel agents, multi-country, insurance-adjacent
07
For engineering teams

Under the hood

The endpoint introduces no new physics and no new machine learning. It is orchestration of layers you already trust: spatial enumeration, per-spot scoring, safety filtering, ranking and persistence. Full detail is in the endpoint reference.

1

Resolve · R-tree

Catalog sub-spots looked up in microseconds against an in-memory R-tree built at boot.

2

Score each

Same physics, calibration and confidence pipeline as /v1/score, fanned out at concurrency 6 to spare upstream providers.

3

Drop no-gos

A verdict of unsafe (lightning ≥0.85, hazardous AQI, a safety gate) or not_feasible (e.g. no rideable wind — impossible, not dangerous) means the spot is dropped before ranking. allGated=true when every candidate fails.

4

Rank + tiebreak

Sorted descending by score; within ±0.5 the closer sub-spot wins. Top-K slice returned.

5

Persist + webhook

One audit row plus a recommendation.completed event (HMAC-signed, top-3 payload).

Every successful call writes one row to recommendation_runs (region centre as a PostGIS POINT, full top-K, latency, allGated flag), the primitive behind the upcoming search-heatmap analytics and the forecast-verification join.

Tenants subscribed to recommendation.completed receive an HMAC-signed webhook after each call; the payload trims to the top 3 while the full top-K stays in the audit DB. Personalization stores only a client-side hash plus model weights, and DELETE /v1/decision/user-data/:pseudonym scrubs every trace across the personalization, audit and recommendation stores in one call (GDPR Article 17).

webhook · HMAC-SHA-256 · 0 results in body
{
  "event": "recommendation.completed",
  "tenantId": "tn_...",
  "data": {
    "activity": "kitesurfing",
    "regionCenter": { "lat": 36.01, "lng": -5.6 },
    "radiusKm": 50, "topK": 5,
    "results": [
      { "rank": 1, "spotSlug": "kitesurfing-spot-tarifa-balneario",
        "effectiveScore": 87, "verdict": "excellent" },
      { "rank": 2, "spotSlug": "kitesurfing-spot-tarifa-valdevaqueros",
        "effectiveScore": 84, "verdict": "favorable" },
      { "rank": 3, "spotSlug": "kitesurfing-spot-tarifa-punta-paloma",
        "effectiveScore": 79, "verdict": "favorable" }
    ],
    "allGated": false, "latencyMs": 412
  }
}
08
Two decisions

One engine, two decisions

One engine for two decisions: validate a chosen spot or find the best one. Score a spot you already know. Search a region when the user has not chosen a spot yet. Same scoring curves, same hard gates, same confidence model. Two workflows, one consistent decision model.

/v1/score

Validate a spot you chose.

activity: "kitesurfing"
location: {lat:36.013, lng:-5.604}
window: {from:"…", to:"…"}
responsescore: 87 · excellent
/v1/recommend-spot

Find the best one in a region.

activity: "kitesurfing"
regionCenter: {lat:36.01, lng:-5.6}
radiusKm: 50
topK: 5
responsetop 5 ranked sub-spots