Skip to content
LooScout Sign in

LooScout API

Every loo, one request away.

57,892 public toilets across 26 countries, with opening hours, prices and accessibility, as plain JSON. Build a travel app, a council dashboard, or a bot that tells your group chat where the nearest loo is.

Try it live

No key needed for this one

Pick a place and we’ll call GET /api/nearby, the same endpoint the map uses.

    
          

    Three steps to your first loo

    1. 1

      Make a key

      Settings → API keys. You get a key and a token; the token is shown once, so copy it somewhere safe.

    2. 2

      Send both headers

      X-API-Key and X-API-Token, or the token as Authorization: Bearer ….

    3. 3

      Ask for loos

      Up to 60 requests a minute and 200 results a page. Plenty for most apps.

    curl "https://looscout.com/api/toilets?lat=51.5145&lng=-0.13&radius_km=1&open=1" \
      -H "X-API-Key: tmk_…" -H "X-API-Token: …"

    Endpoints

    Base URL https://looscout.com/api

    GET/toilets

    List loos. Filter by area, distance, features or what’s changed since your last sync.

    bbox
    west,south,east,north
    lat, lng, radius_km
    Nearest first, adds distance_m
    open, free, wheelchair, baby, neutral
    Set to 1 to filter
    updated_since
    ISO date, for incremental sync
    source
    osm, api or community
    limit, offset
    Paging; meta.total has the full count
    Example response
    {
        "data": [
            {
                "id": "83ab427ba3",
                "name": "Public toilets, Soho Square",
                "address": "Soho Square, Soho, City of Westminster, W1D 3QN",
                "lat": 51.515633,
                "lng": -0.132367,
                "country_code": "GB",
                "url": "https://looscout.com/toilet/83ab427ba3",
                "open_now": true,
                "open_status": "Open 24 hours",
                "features": {
                    "wheelchair": false,
                    "baby_changing": false,
                    "gender_neutral": false,
                    "toilet_paper": false,
                    "hand_soap": false
                },
                "access_type": null,
                "is_paid": false,
                "price": null,
                "rating": {
                    "average": 4,
                    "count": 1
                },
                "verified": false,
                "source": "osm",
                "updated_at": "2026-10-23 19:19:42",
                "distance_m": 180
            }
        ],
        "meta": {
            "total": 42,
            "limit": 50,
            "offset": 0,
            "count": 1
        }
    }
    GET/toilets/{id}

    One loo by its id (the short code in its LooScout URL). open_now is null when we don’t know the hours. We never guess.

    Example response
    {
        "data": {
            "id": "83ab427ba3",
            "name": "Public toilets, Soho Square",
            "address": "Soho Square, Soho, City of Westminster, W1D 3QN",
            "lat": 51.515633,
            "lng": -0.132367,
            "country_code": "GB",
            "url": "https://looscout.com/toilet/83ab427ba3",
            "open_now": true,
            "open_status": "Open 24 hours",
            "features": {
                "wheelchair": false,
                "baby_changing": false,
                "gender_neutral": false,
                "toilet_paper": false,
                "hand_soap": false
            },
            "access_type": null,
            "is_paid": false,
            "price": null,
            "rating": {
                "average": 4,
                "count": 1
            },
            "verified": false,
            "source": "osm",
            "updated_at": "2026-10-23 19:19:42"
        }
    }
    GET/statistics·GET/locations

    Totals, top contributors and per-area counts: handy for dashboards. Add include_locations=1 to statistics to get both at once.

    GET/nearby·GET/mapNo key

    What the LooScout map runs on. Compact and fast, but the shape may change without notice, so use /toilets for anything you ship.

    When things go wrong

    Errors come back as {"error": "…"} with a status that tells you what to do next.

    StatusMeans
    401Missing or wrong key/token. Check both headers.
    403Your key can’t do that (e.g. writing with a non-staff key).
    404No such loo, or it isn’t public.
    413Batch too big: 500 loos per request at most.
    422Something in the request didn’t validate; the message says what.
    429Slow down. You’ve hit 60 requests a minute; the X-RateLimit-* headers say when you can go again.

    One small ask

    Most of this data comes from OpenStreetMap, under the Open Database Licence. If you show it, credit “© OpenStreetMap contributors” and LooScout, and link back if you can. See Contributors, and our changelog for what’s new.