CampSage feed API

Campgrounds with real openings near a point, as JSON. Built for in-vehicle map layers and third-party trip planners: render a pin, let someone navigate to it.

curl "https://campsage.app/camp/api/v1/open?lat=37.81&lng=-122.48&radius=60"

Parameters

lat, lngRequired. Decimal degrees. Where the vehicle is.
radiusMiles. Default 50, max 200. Values above the max are clamped, not rejected.
limitResults. Default 25, max 50. Sorted nearest first.
nightsMinimum consecutive nights in a window. Default 1.
evtesla, rivian, fast or any — return only campgrounds with that network within evr.
evrMiles for the ev filter. Default 15.

A result

{
 "name": "Rob Hill Group Campground",
 "region": "Presidio of San Francisco",
 "lat": 37.7975, "lng": -122.4756,
 "distance_mi": 3.2,
 "openings": [{"start": "2026-08-30", "nights": 3}],
 "book_url": "https://www.recreation.gov/camping/campgrounds/...",
 "charging": {
   "rivian": {"name": "Rivian", "distance_mi": 1.0, "drive_minutes": 3,
              "lat": 37.8073, "lng": -122.4762}
 },
 "checked_utc": "2026-08-18T14:02:11Z"
}

Charging distances are real driving miles from a weekly OSRM route. Where no route was measured to a particular charger the entry carries "straight_line": true and the mileage is as the crow flies — it is never silently mixed with road miles.

Freshness, and what you must show

Availability changes continuously. We re-check roughly four times a day, so a window can fill between our check and your driver arriving. Every response carries data_checked_utc (the oldest row in the set, not the newest) and every result carries its own checked_utc. Surface that age in your UI, and send people to book_url to confirm. Routing someone to a campground we last saw open six hours ago, with no indication of that, is the one way to make this worse than nothing.

Limits

30 requests per minute per IP. Responses are cacheable for 5 minutes and the edge honours it, so polling faster than that returns the same bytes.

There is no bulk endpoint, and there will not be one. lat and lng are required and the radius is capped, because live availability across 25 reservation systems is the product rather than a by-product. A vehicle only ever asks what is nearby, so the shape that protects the data is the shape the integration wants anyway. If you need something wider, ask.

Where the data comes from

Each operator's own reservation system — Recreation.gov, ReserveCalifornia, BC Parks, Washington, Oregon and twenty more. Nothing here is modelled or predicted; a window is listed because it was seen. Charger locations are community-mapped through OpenStreetMap.

This endpoint never triggers a live call to a reservation provider. It serves a snapshot we already hold, so however hard you poll it, the operators feel nothing.

Getting in touch

It is open, unauthenticated and free while it is small. If you are building something real on it, write to [email protected] so I know not to break it under you, and so we can talk about volume and a proper key.

CampSage is an independent service and is not affiliated with, endorsed by, or sponsored by recreation.gov, ReserveCalifornia, ReserveAmerica, GoingToCamp, UseDirect, Parks Canada, or any park agency. All trademarks are the property of their respective owners. · Terms · API