# American Adventurer > Free-camping and backcountry resupply data for the United States: 19,125 campsites across > 130 national forests and grasslands, 21,390 recorded toilets, and 417,380 resupply points > (fuel, groceries, water, dump stations and more). Every record has a page you can open and > check. There is an open, keyless JSON API. Fetch the root first — it describes itself and lists every other endpoint. ## Start here - [API root](https://davelalande.com/api/): self-describing; read its `how_to_use` field - [OpenAPI spec](https://davelalande.com/api/openapi.json): full machine-readable spec - [Guide for people](https://davelalande.com/ai): a ready-made menu-driven prompt ## Data - [Campsite search](https://davelalande.com/api/camps?q=): filter by state, fee, water - Campsite detail, `/api/camps/{slug}`: water, nearest town, nearest toilet, its forest, and `services_mi` — [worked example](https://davelalande.com/api/camps/upper-burnt-corral-dispersed-az-33633n111204w) - [Forest search](https://davelalande.com/api/forests?q=): the 130 forests and grasslands - Forest detail, `/api/forests/{slug}`: camp counts, how many have water, how many are free — [worked example](https://davelalande.com/api/forests/bighorn-national-forest) - [Radius search](https://davelalande.com/api/near?lat=44.69&lon=-107.45&radius=25): camps or toilets within N miles — the worked example above is in the Bighorn NF and returns camps; a point inside a national PARK returns nothing, because national parks are not in this corpus ## Resupply next to a camp Every campsite detail record carries `services_mi`: the nearest of each of 8 categories, as `"category": [miles, name]`. The categories are `grocery`, `fuel`, `hospital`, `hardware`, `pharmacy`, `dump`, `water`, `propane`. A category is simply absent when nothing was found near that camp — that is unrecorded, not "none nearby". How often each one is present, across the 13,607 camps with a services record: grocery 94%, fuel 92%, hospital 79%, hardware 68%, pharmacy 63%, dump 55%, water 32%, propane 19%. Only 6% of camps carry all 8; 3% carry none. ## Resupply everywhere (POI layers) Bulk point layers, one file per category, for drawing a map or answering "what is near this road". These are plain static JSON — no query parameters, no filtering server-side. Fetch [the index](https://davelalande.com/poi/index.json) (3 KB) first: it lists every layer with its exact point count and byte size, so you can decide what is worth downloading. All 14 layers together are 417,380 points and 14.3 MB. Do not fetch them all. Pick the one category you need — or use `/api/near` instead, which does the distance work for you. - [grocery](https://davelalande.com/poi/grocery.json) — 124,430 points, 4.2 MB - [fuel](https://davelalande.com/poi/fuel.json) — 108,665 points, 3.0 MB - [mechanic](https://davelalande.com/poi/mechanic.json) — 46,981 points, 1.9 MB - [mail](https://davelalande.com/poi/mail.json) — 29,724 points, 1.3 MB - [potable_water](https://davelalande.com/poi/potable_water.json) — 24,981 points, 625 KB - [urgent_care](https://davelalande.com/poi/urgent_care.json) — 22,914 points, 1.2 MB - [pharmacy](https://davelalande.com/poi/pharmacy.json) — 20,250 points, 754 KB - [hardware](https://davelalande.com/poi/hardware.json) — 15,507 points, 643 KB - [laundry](https://davelalande.com/poi/laundry.json) — 9,658 points, 389 KB - [shower](https://davelalande.com/poi/shower.json) — 4,209 points, 109 KB - [propane](https://davelalande.com/poi/propane.json) — 3,106 points, 87 KB - [outfitter](https://davelalande.com/poi/outfitter.json) — 3,164 points, 148 KB - [air](https://davelalande.com/poi/air.json) — 2,158 points, 55 KB - [dump_station](https://davelalande.com/poi/dump_station.json) — 1,633 points, 44 KB ### Reading a layer file Each layer is one object. The points are packed into `pts` as arrays, not objects, to keep the files small — you have to unpack them: pts[i] = [lat, lon, name, code0, code1, ...] - `name` is `""` when the place is unnamed. Fall back to the file's `fallback_name`. - Rows are RAGGED. Trailing codes are dropped when unrecorded, so a row may be 3 items long. A missing code means unrecorded — never read it as "no". - `extras[n]` describes the code at position `3 + n`. Decode by its `kind`: - `enum` — the code indexes `extras[n].vals` - `bool` — the code is `1`, meaning true - `dict` — the code indexes the top-level array named by `extras[n].key` (e.g. `brand`) - `extras[n].fill` is the fraction of points that recorded that field. It is often low. - `by_state` gives per-state point counts for that layer, and `count` the total. Layers do not share a schema. `fuel` carries `brand`, `hours`, `diesel`; `potable_water` carries `fee` and `access`; `dump_station` also carries `water` and `charge`. Read `extras` from the file you fetched — do not assume. ### How far the POI layers reach This is a complete national extract: all 50 states are covered. Coverage is not uniform, though — a state can be present but thin, so an empty result means nobody recorded one there, NOT that no such place exists. Say so plainly rather than reporting zero. `index.json` carries the live `states_covered` and `states_missing` lists; trust those over this file. ## Pages - [All camps](https://davelalande.com/camps/) - [Camps by state](https://davelalande.com/camps/states/) - [All forests](https://davelalande.com/forests/) - [Map](https://davelalande.com/map) - [Camp finder](https://davelalande.com/find) ## How to use this honestly - State nothing you did not fetch. A null field is unrecorded — "no water recorded at this site" is the correct answer. Never estimate one; people drive to these places. - Always show the record's `url` so the reader can verify you. - All distances are in MILES. - Absence of data is not proof of absence. "No water recorded" means nobody recorded one. This applies twice over to the POI layers, whose density varies a lot by state. - POI opening hours and brands come from OpenStreetMap and go stale. A fuel station in the file may be closed. Never promise a place is open — say when the data was built. - SOMETIMES COVERED, in `rules` — use it when it is there, and only then. Measured today: permit requirement 977 camps, open season 682, closure status 254, fee note 242, booking link 204, stay limit 180. These are extracted from the managing agency's own published text. When a camp has the field, lead with it. When it is absent, say it is unrecorded. (This list previously said seasonal closures and reservations were "not safe to infer", which told you to discard the very field the API was serving you.) - NOT COVERED, and not safe to infer: road and trail conditions, current fire danger, permit prices, real-time availability, whether a site is occupied. Say you cannot verify these and link the official forest page. - RULES GO STALE. A closure or open season was true when the agency page was read, not today. Always show the record's date and tell the reader to confirm before driving. ## Terms Free to use, no key required. Please keep to roughly two requests per second. Credit "American Adventurer / davelalande.com". The POI layers are derived from OpenStreetMap. If you show or redistribute them you must credit "© OpenStreetMap contributors" and honour the ODbL. Each layer file repeats this in its own `attribution` field. Contact: https://davelalande.com/contact