Documentation
A 5-minute introduction to the POIscore API.
Quickstart
- Create an account.
- Mint a key in /keys (the secret is shown once — copy it).
- Optionally save a scoring profile in /profiles and attach it to the key.
- Call the API with
Authorization: Bearer sk_live_*.
cURL
# Sign up + create a key first (admin UI), then: curl 'https://api.poiscore.com/v1/pois/nearby?lat=48.8584&lng=2.2945&radius_m=2000&limit=10' \ -H 'Authorization: Bearer sk_live_...' \ -H 'Accept: application/json'
JavaScript
const res = await fetch(
'https://api.poiscore.com/v1/pois/nearby?lat=48.8584&lng=2.2945&radius_m=2000',
{ headers: { Authorization: 'Bearer sk_live_...' } },
);
const { data, meta } = await res.json();
data.forEach((p, i) => console.log(`#${i + 1} ${p.name} (${p.scores.final.toFixed(2)})`));Endpoints
| Method | Path | What it does | Auth |
|---|---|---|---|
| GET | /v1/pois/nearby | POIs within radius_m, ranked by tunable scoring | Bearer or session |
| GET | /v1/pois/:id | Single POI by id | Bearer or session |
| GET | /v1/destinations | List seeded destinations with pipeline status | Bearer or session |
| GET | /v1/destinations/:id | Single destination | Bearer or session |
| GET | /v1/keys | List your API keys | Session |
| POST | /v1/keys | Mint a new sk_live_* (secret returned once) | Session |
| DEL | /v1/keys/:id | Revoke a key | Session |
| GET | /v1/profiles | List your scoring profiles | Session |
| POST | /v1/profiles | Create a profile | Session |
| PUT | /v1/profiles/:id | Update profile | Session |
| DEL | /v1/profiles/:id | Delete profile | Session |
| GET | /v1/usage/me | Today + month totals, per-key, recent calls | Session |
Scoring formula
final = tier_weight[tier]
× category_boost[category] (defaults to 1.0)
× (base_offset + w_fame · fame_score + w_quality · osm_quality)
× exp(−ST_Distance(loc, target) / τ)Every coefficient is configurable per request (via query params), per key (via a saved profile), or at run-time (default values from the blueprint). The closer a POI is to your target, the higher its multiplier — but with a long enough τ even far-away iconic POIs surface.
Tiers
| Tier | Default weight | What it covers | Examples |
|---|---|---|---|
| S | 5 | Heritage / iconic (UNESCO, heritage tag, or admin override) | Tour Eiffel, Notre-Dame, Westminster Abbey |
| A | 3 | Major attractions, museums, historic, parks | Musée Grévin, Brasserie Lipp (heritage) |
| B | 1.5 | Restaurants, cafes, theatres, viewpoints, shopping | Cafés, brasseries, smaller museums |
| C | 0.8 | Transport, cinemas | Métro stations, bus stations |
Categories
All POIs are mapped from OSM tags to one of these canonical categories. Boost or exclude them per profile.
attractionmuseumhistoricparkbeachrestaurantcafenightlifetheatrecinemareligioustheme_parkzooviewpointshoppingtransport
Rate limiting
Each key has a per-day budget (1,000 in dev). Every response carries X-RateLimit-* headers. Past the limit you get an RFC 7807 429.
Errors
All errors follow RFC 7807 (type, title, status, detail, instance). 400 for validation, 401 for missing/invalid auth, 404 for not-found, 429 for quota.