ALL SYSTEMS · NOMINAL
UTC --:--:--
Score

Is this spot good?

The predicate-query side of the engine. Hand the engine an activity, a location, and a time window — get back a 0-100 verdict with the full physics breakdown, per-dimension scores, and a confidence block. The booking-platform endpoint that decides whether tomorrow's session opens or closes.

01
Two questions, one engine

The flip-side of /v1/recommend-spot

One physics engine, two question shapes. The predicate path (this page) validates a chosen spot. The inverse path enumerates a region. Same calibrated curves, same hard gates, same confidence model. Two buyers, one bill.

/v1/score

Is this spot good?

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

Where should I go?

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

One call · Tarifa Balneario · Saturday 10–16 UTC

A real-world predicate call for a kitesurf weekend at a known spot. The engine scores six physics dimensions independently against the kitesurfing profile's calibrated curves, then folds them into the 0-100 verdict the booking flow consumes.

Request
POST /v1/score
{
 activity: "kitesurfing",
 location: { lat: 36.0133, lng: -5.6044 },
 window: {
 from: "2026-07-15T10:00Z",
 to: "2026-07-15T16:00Z"
 }
}
skill-weighted provider fetch
6 dimensions evaluated independently
hard gates checked · none triggered
verdict + confidence · ~180ms p50
Response · per-dimension breakdownscore 87 · favorable
  1. Wind speed22 kt @ 270°
    Cross-onshore, ideal for intermediate kitesurfing
    94
  2. Wind gust factor1.18 (low)
    Steady wind, gust just 18% above mean
    91
  3. Wave height1.5 m, period 10s
    Manageable chop for intermediates, not flat-water
    78
  4. Air temperature22 °C apparent
    Comfortable session-length window
    88
  5. Lightning proximityCAPE 280 J/kg
    No convective activity in 50km radius
    100
  6. Visibility25 km
    Clear sightlines, no fog
    96
Reading the result · Wind is the dominant favorable signal (94) — 22kt cross-onshore is textbook intermediate kitesurfing. Wave height (78) is the lowest per-dim because Balneario carries chop at this swell direction; some riders prefer it, profile curve says workable. Lightning gate at 100 means no convective threat. The fold: 0.4×94 + 0.2×91 + 0.15×78 + 0.1×88 + 0.1×100 + 0.05×96 ≈ 87. Verdict cutoffs come from the catalog, not hard-coded — kitesurfing's "favorable" band is ≥75.
03
How it works

Physics first, black-box ML last

Every coefficient traces to a peer-reviewed formula. ML appears ONLY in two places — provider skill weights and curve calibration. Both train against real outcomes, never replace the physics. The verdict you read in production has a paper trail back to oceanography journals.

1

Provider chain

Skill-weighted blend of Open-Meteo + Stormglass + CMEMS — per-cell weights refit nightly against real outcomes.

2

Physics layer

25+ peer-reviewed formulas across 20 namespaces (wind, wave, tide, atmosphere, snow, lightning, AQI, ...).

3

Calibration

Hierarchical Bayesian shrinkage along the 5-level catalog (base → region → cluster → sub-spot). Curves tighten as cohort outcomes accumulate.

4

Hard gates

Lightning ≥0.85 or hazardous AQI → verdict=unsafe regardless of other dimensions. Safety first.

5

Verdict + confidence

0-100 score + verdict (favorable/workable/poor/unsafe) + confidence detail (forecast / historical / climate mode).

04
Buyers

Three personas, one endpoint

FareHarbor · Bookeo · Checkfront

Booking platforms

Validate booking-flow conditions before the customer pays.

1 spot · 3-day window · single score
The customer is about to confirm a kitesurf school slot for Saturday. The engine returns 'favorable' or 'unsafe' with the full breakdown — the booking flow auto-cancels-and-refunds when conditions degrade. Reduces no-show + bad-experience cost on the operator side.
Vertical PMS for kite/sail/dive schools

School OS · gestionali noleggi

Daily 'open or close' decision for the school.

10-20 spot polling · daily cron · multi-window
School director checks tomorrow's conditions at 18:00 the night before, decides which spots to open. Replaces 'check the forecast app' with one structured call per spot — operator confidence is the value, not the score number itself.
Adventure travel, expedition planners

Tour operators · guides

Per-day go/no-go on a multi-day itinerary.

5-15 spots · 7-day window · weekly batch
Guide planning a kite safari Tarifa → Essaouira: scores each candidate beach for each day of the trip, surfaces the optimal route. Replaces an analyst with five browser tabs.
05
Plan tiers

Calls scale with the use case

Score calls are metered per-event via Stripe. Free hard-caps at the included quota (no surprise bill). Starter/Pro overflow at the published rate. Scale runs on a contracted ceiling.

PlanIncludedOverageTypical buyer
Free1,000 / monthHard capPrototype, single-spot test
Starter50,000 / month€1.50 / 1k overSingle operator, weekend traffic
Pro500,000 / month€0.80 / 1k overMulti-spot brand, ensemble + AI explain
ScaleUnlimitedContractedUnderwriting, climate, multi-country
06
Confidence

Every score carries a confidence block

The confidence detail decomposes the scalar confidence into four interpretable factors. Booking flows can gate UX decisions on the SUB-factor they care about (e.g., "warn user when providerSkill < 0.7 for their region").

The block shape adapts to the call: mode is forecast for /v1/score (today's call), historical for /v1/score/historical (parametric underwriting), climate for /v1/projections (multi-decadal). Same envelope, different content.

4 sub-factors · same shape across forecast / historical / climate
{
  "session_id": "a7b2...",
  "score": 87,
  "verdict": "favorable",
  "confidence": 0.84,
  "confidenceDetail": {
    "mode": "forecast",
    "providerSkill": 0.91,
    "ensembleSpread": 0.78,
    "profileMaturity": 0.85,
    "hierarchicalCalibration": 0.95
  },
  "breakdown": [
    { "dim": "wind",     "score": 94 },
    { "dim": "wave",     "score": 78 },
    { "dim": "lightning","score": 100 }
  ],
  "eco": { "carbonNeutral": true, "energyClass": "A" }
}
07
Calibration

Close the loop with outcomes

POST /v1/score/:session_id/outcome

Booking flow reports back: "did the session actually happen? was it cancelled? was the customer happy?". Each outcome feeds the calibration loop — curves tighten when reality disagrees with the engine's predictions.

The data primitive

(forecast × outcome) pairs are what unlock the next horizons — parametric underwriting needs them (T2) and the open research dataset publishes them with k≥10 anonymisation (Stream F, CC BY 4.0).

08
Try it

Build with it today