API Documentation
Complete reference for authentication, endpoints, request parameters, and JSON responses.
Base URL
https://www.looscout.com/api
Route compatibility note
Public API paths remain /api/toilets and /api/toilets/{id_or_hash} for backward compatibility. In product copy and docs, these represent submissions.
Latest API changes
Recently published: 2026.2.5 — Developer update with advanced endpoint examples, request patterns, and result payloads.
Authentication
Most routes require API key auth. Create credentials from Profile Settings in API Access.
User limit
1 active key
Moderator limit
3 active keys
Admin limit
Unlimited
Header-based auth
X-API-Key: tmk_xxxxxxxxxxxxx X-API-Token: your_token_value_once
You can send Authorization: Bearer your_token instead of X-API-Token.
Quick Start
Use this request to list approved submissions around a point.
curl -s "https://www.looscout.com/api/toilets?limit=20&offset=0&lat=51.5074&lng=-0.1278&radius_km=2&accessible=1" \ -H "X-API-Key: tmk_xxx" \ -H "X-API-Token: yyy"
Example result
{
"data": [
{
"id": 842,
"route_hash": "lc3k9f",
"name": "City Library Ground Floor",
"address": "1 Central Ave, London",
"lat": 51.50762,
"lng": -0.12751,
"status": "approved",
"is_accessible": 1,
"gender": "all genders",
"hours": "06:00-22:00",
"floor_level": "Ground",
"amenities": "soap, dryer",
"image_url": null,
"notes": "Inside main foyer",
"created_at": "2026-02-20 09:12:44",
"updated_at": "2026-02-20 09:12:44"
}
],
"meta": {
"limit": 20,
"offset": 0,
"count": 1,
"api_key_id": 14
}
}
Endpoint Reference
GET /api
Health and route index. Useful for integration checks.
Result
{
"name": "LooScout API",
"version": "1",
"status": "ok",
"routes": [
"/api/auth/keys",
"/api/toilets",
"/api/toilets/{id_or_hash}",
"/api/locations",
"/api/statistics"
]
}
GET /api/toilets
Returns approved submissions only.
| Query param | Type | Notes |
|---|---|---|
| limit | int | Default 50, max 200 |
| offset | int | Default 0 |
| accessible | 0/1 | Set to 1 for accessible submissions only |
| gender | string | Exact DB value, e.g. all genders, male, female |
| lat,lng | float | Center point for bbox filtering |
| radius_km | float | Used with lat/lng, defaults to 2.0 km |
Example request
curl -s "https://www.looscout.com/api/toilets?limit=20&offset=0&accessible=1&gender=all%20genders&lat=51.5074&lng=-0.1278&radius_km=2" \ -H "X-API-Key: tmk_xxx" -H "X-API-Token: yyy"
Example result
{
"data": [
{
"id": 842,
"route_hash": "lc3k9f",
"name": "City Library Ground Floor",
"address": "1 Central Ave, London",
"lat": 51.50762,
"lng": -0.12751,
"status": "approved",
"is_accessible": 1,
"gender": "all genders",
"hours": "06:00-22:00",
"floor_level": "Ground",
"amenities": "soap, dryer",
"image_url": null,
"notes": "Inside main foyer",
"created_at": "2026-02-20 09:12:44",
"updated_at": "2026-02-20 09:12:44"
}
],
"meta": {
"limit": 20,
"offset": 0,
"count": 1,
"api_key_id": 14
}
}
GET /api/toilets/{id_or_hash}
Returns one approved submission by numeric id or route hash, plus review statistics.
curl -s "https://www.looscout.com/api/toilets/lc3k9f" -H "X-API-Key: tmk_xxx" -H "X-API-Token: yyy"
Example result
{
"data": {
"id": 842,
"route_hash": "lc3k9f",
"name": "City Library Ground Floor",
"status": "approved",
"is_accessible": 1,
"gender": "all genders",
"hours": "06:00-22:00"
},
"statistics": {
"reviews_count": 18,
"average_rating": 4.28
}
}
GET /api/locations
Returns configured map locations with nearby submission and review stats.
Optional query: delta (float, clamped to 0.05–1.0).
curl -s "https://www.looscout.com/api/locations?delta=0.2" -H "X-API-Key: tmk_xxx" -H "X-API-Token: yyy"
Example result
{
"data": [
{
"slug": "london",
"label": "London",
"lat": 51.5074,
"lng": -0.1278,
"zoom": 13,
"toilets_count": 126,
"reviews_count": 882,
"average_rating": 4.17
}
],
"meta": {
"delta": 0.2
}
}
GET /api/statistics
Returns totals and top contributors. Use include_locations=1 to include location stats.
curl -s "https://www.looscout.com/api/statistics?include_locations=1" -H "X-API-Key: tmk_xxx" -H "X-API-Token: yyy"
Example result
{
"data": {
"users_total": 307,
"toilets_total": 912,
"toilets_approved": 802,
"toilets_pending": 69,
"toilets_rejected": 41,
"reviews_total": 4026,
"average_rating": 4.11,
"visited_total": 1674,
"top_contributors": [
{
"id": 12,
"username": "maphelper",
"display_name": "Map Helper",
"approved_toilets": 95
}
]
}
}
Session-protected Key Management Routes
These routes are intended for the web app and require signed-in session auth. For write actions, include CSRF token.
GET /api/auth/keys
List your API keys.
Result
{
"data": [
{
"id": 14,
"name": "Production dashboard",
"api_key": "tmk_12ab34cd...",
"token_last4": "5f9a",
"rate_limit_per_minute": null,
"is_active": 1,
"last_used_at": "2026-02-28 00:19:02",
"expires_at": null,
"created_at": "2026-02-20 08:11:45"
}
]
}
POST /api/auth/keys
Create a key/token pair. Token appears once only.
Example JSON body
{
"name": "Analytics export",
"rate_limit_per_minute": 90,
"expires_in_days": 30,
"csrf_token": "your_csrf_token"
}
Result
{
"data": {
"id": 18,
"name": "Analytics export",
"api_key": "tmk_a1b2c3d4...",
"api_token": "plain_token_value_once",
"token_hint": "Store this token now; it is not returned again.",
"rate_limit_per_minute": 90,
"expires_at": "2026-03-30 10:00:00"
}
}
POST /api/auth/keys/{id}/revoke
Revoke your own key.
Result
{
"data": {
"id": 18,
"revoked": true
}
}
Rate Limits and Errors
- Default limit: 60 requests/minute per key
- Per-key override can be set by admins
- Max list page size: 200
- Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
401 example
{
"error": "Missing API credentials. Provide X-API-Key and X-API-Token (or Authorization: Bearer <token>)."
}
404 example
{
"error": "Submission not found"
}
429 example
{
"error": "Rate limit exceeded"
}