| Title: | Client for the 'Close' API |
| Version: | 1.5.0 |
| Description: | Access travel times from every US census block to nearby points of interest, by walking, biking, and public transit, over the 'Close' API. Wraps the metered, read-only public endpoints with keyset pagination, ETag/304 conditional requests, token accounting, typed RFC 9457 error handling, and tabular output by default ('sf' where geometry applies, a data frame otherwise). |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| URL: | https://henryspatialanalysis.github.io/closecity-r/, https://github.com/henryspatialanalysis/closecity-r |
| BugReports: | https://github.com/henryspatialanalysis/closecity-r/issues |
| Depends: | R (≥ 4.1) |
| Imports: | httr2 (≥ 1.0.0), jsonlite, R6, rlang, sf |
| Suggests: | testthat (≥ 3.0.0), withr, tigris, plotly, geojsonsf, knitr, rmarkdown |
| Config/testthat/edition: | 3 |
| Config/Needs/website: | pkgdown |
| RoxygenNote: | 8.0.0 |
| VignetteBuilder: | knitr |
| NeedsCompilation: | no |
| Packaged: | 2026-07-23 09:57:55 UTC; nathenry |
| Author: | Nathaniel Henry [aut, cre], Henry Spatial Analysis [aut, cph, fnd] |
| Maintainer: | Nathaniel Henry <nat@henryspatialanalysis.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-08-02 16:30:07 UTC |
Close API client
Description
An R6 object that holds your connection settings and gives you one method per
public route. Create it with close_client() rather than calling $new().
Results come back per the output field: an sf object where geometry
applies, a data frame otherwise, or a close_reply when output is 'raw'.
Public fields
output(
character(1))
How results come back:'spatial','tabular', or'raw'. Change it any time, or override it per call with the method'soutputargument.
Methods
Public methods
CloseClient$new()
Create a client. Prefer close_client().
Usage
CloseClient$new( api_key = NULL, base_url = DEFAULT_BASE_URL, timeout = 30, output = "spatial" )
Arguments
api_keyYour API key, or NULL for the free routes. When NULL, the
CLOSECITY_KEYenvironment variable is used if set.base_urlAPI base URL.
timeoutRequest timeout, in seconds.
outputOne of
'spatial','tabular', or'raw'.
CloseClient$health()
Liveness check (free). Always a raw close_reply.
Usage
CloseClient$health()
Returns
A close_reply.
CloseClient$last_updated()
Publication time of the newest data (free). Always a raw reply.
Usage
CloseClient$last_updated()
Returns
A close_reply.
CloseClient$modes()
Travel modes and their numeric ids (free).
Usage
CloseClient$modes(output = NULL)
Arguments
outputOverride the client's output mode for this call.
Returns
A data frame, or a close_reply when output is 'raw'.
CloseClient$destination_types()
Destination-type taxonomy (free). Use it to look up the numeric
type ids the data routes filter on; a parent type expands to its
leaf_ids.
Usage
CloseClient$destination_types(output = NULL)
Arguments
outputOverride the client's output mode for this call.
Returns
A data frame, or a close_reply when output is 'raw'.
CloseClient$vintage()
Active version of each dataset component (free).
Usage
CloseClient$vintage(output = NULL)
Arguments
outputOverride the client's output mode for this call.
Returns
A data frame, or a close_reply when output is 'raw'.
CloseClient$places()
Look up a city or town by name (free). Each match carries its census place GEOID and centre point.
Usage
CloseClient$places(q, limit = NULL, output = NULL)
Arguments
qName to search for, such as "Providence".
limitMost matches to return (1 to 20).
outputOverride the client's output mode for this call.
Returns
An sf of points (a data frame in tabular mode, a
close_reply when output is 'raw').
CloseClient$block_summary()
Fastest travel time from a census block to each destination category, by mode. Pass a vector of GEOIDs to query many blocks in one call (one request, one rate-limit tick).
Usage
CloseClient$block_summary( geoid, mode = NULL, type = NULL, if_none_match = NULL, output = NULL )
Arguments
geoidA 15-digit census block GEOID, or a vector of them for a single multi-origin call. Every result row carries its origin
geoid; per-originerrors/truncated/truncated_reasonride on the frame's attributes.modeTravel mode(s) to keep: "walk", "bike", "transit".
typeDestination type id(s) to keep.
if_none_matchAn ETag from an earlier reply, to revalidate for free (single-block form only).
outputOverride the client's output mode for this call.
Returns
A data frame with a broadcast geoid column, or a close_reply
when output is 'raw'.
CloseClient$block_pois()
Nearby points of interest and their travel time from a block, one row per (POI, mode). Reads every page by default. Pass a vector of GEOIDs to query many blocks in one call (one request, one rate-limit tick; the multi-origin form is not paginated).
Usage
CloseClient$block_pois( geoid, mode = NULL, type = NULL, dest_id = NULL, max_minutes = NULL, limit = NULL, cursor = NULL, paginate = TRUE, output = NULL )
Arguments
geoidA 15-digit census block GEOID, or a vector of them for a single multi-origin call. Every row carries its origin
geoid; per-originerrors/truncatedride on the frame's attributes.modeTravel mode(s) to keep.
typeDestination type id(s) to keep.
dest_idSpecific destination id(s) to keep.
max_minutesUpper bound on travel time (up to 30).
limitRows per page (up to 1000; single-block form only).
cursorPage cursor from a previous reply's
next_cursor; supplying one fetches only that page.paginateFollow
next_cursorand return every page (the default); setFALSEfor the first page only.outputOverride the client's output mode for this call.
Returns
An sf of points (a data frame in tabular mode, a
close_reply when output is 'raw').
CloseClient$point_summary()
Like $block_summary(), but from the block containing a
lat/lon point. The resolved block is echoed as resolved_block and
broadcast to a geoid column. Pass equal-length lat / lon vectors to
query many points in one call (one request, one rate-limit tick).
Usage
CloseClient$point_summary( lat, lon, mode = NULL, type = NULL, if_none_match = NULL, output = NULL )
Arguments
latLatitude, or a vector of latitudes for a multi-origin call.
lonLongitude, or a matching vector of longitudes. In the multi-origin form each row carries its
origin_lat/origin_lon, and resolved blocks /errors/truncatedride on the frame's attributes.modeTravel mode(s) to keep.
typeDestination type id(s) to keep.
if_none_matchAn ETag to revalidate for free (single-point form only).
outputOverride the client's output mode for this call.
Returns
A data frame, or a close_reply when output is 'raw'.
CloseClient$point_pois()
Like $block_pois(), but from the block containing a lat/lon
point. Reads every page by default. Pass equal-length lat / lon
vectors to query many points in one call (one request, one rate-limit
tick; the multi-origin form is not paginated).
Usage
CloseClient$point_pois( lat, lon, mode = NULL, type = NULL, dest_id = NULL, max_minutes = NULL, limit = NULL, cursor = NULL, paginate = TRUE, output = NULL )
Arguments
latLatitude, or a vector of latitudes for a multi-origin call.
lonLongitude, or a matching vector of longitudes. In the multi-origin form each row carries its
origin_lat/origin_lon.modeTravel mode(s) to keep.
typeDestination type id(s) to keep.
dest_idSpecific destination id(s) to keep.
max_minutesUpper bound on travel time (up to 30).
limitRows per page (up to 1000; single-point form only).
cursorPage cursor; supplying one fetches only that page.
paginateFollow
next_cursorand return every page (the default); setFALSEfor the first page only.outputOverride the client's output mode for this call.
Returns
An sf of points (a data frame in tabular mode, a
close_reply when output is 'raw').
CloseClient$pois_search()
Search points of interest by bounding box, or by a circle
(lat + lon + radius_m). Reads every page by default.
Usage
CloseClient$pois_search( lat = NULL, lon = NULL, radius_m = NULL, bbox = NULL, type = NULL, q = NULL, limit = NULL, cursor = NULL, paginate = TRUE, output = NULL )
Arguments
lat, lonCircle centre.
radius_mCircle radius, in metres (up to 50000).
bboxBounding box, "min_lon,min_lat,max_lon,max_lat".
typeDestination type id(s) to keep.
qName text to match.
limitRows per page (up to 1000).
cursorPage cursor; supplying one fetches only that page.
paginateFollow
next_cursorand return every page (the default); setFALSEfor the first page only.outputOverride the client's output mode for this call.
Returns
An sf of points (a data frame in tabular mode, a
close_reply when output is 'raw').
CloseClient$poi()
Details for one point of interest.
Usage
CloseClient$poi(dest_id, if_none_match = NULL, output = NULL)
Arguments
dest_idDestination id.
if_none_matchAn ETag to revalidate for free.
outputOverride the client's output mode for this call.
Returns
An sf of one point (a data frame in tabular mode, a
close_reply when output is 'raw').
CloseClient$poi_catchment()
Every census block that can reach a point of interest, one row per (block, mode). Reads every page by default. Pass a vector of dest_ids to query many POIs in one call (one request, one rate-limit tick; the multi-origin form is not paginated).
Usage
CloseClient$poi_catchment( dest_id, mode = NULL, block = NULL, max_minutes = NULL, limit = NULL, cursor = NULL, paginate = TRUE, output = NULL )
Arguments
dest_idA destination id, or a vector of them for a single multi-origin call. Every row carries its origin
dest_id; per-POIerrors/truncatedride on the frame's attributes.modeTravel mode(s) to keep.
blockSpecific block id(s) to keep.
max_minutesUpper bound on travel time (up to 30).
limitRows per page (up to 1000; single-POI form only).
cursorPage cursor; supplying one fetches only that page.
paginateFollow
next_cursorand return every page (the default); setFALSEfor the first page only.outputOverride the client's output mode for this call.
Returns
An sf of block polygons (a data frame in tabular mode, a
close_reply when output is 'raw').
CloseClient$blocks_query()
Blocks inside a GeoJSON polygon, or a circle (center +
radius_m), one row per (block, category, mode). Rows carry the numeric
mode_id (join $modes() to label it). Reads every page by default.
Usage
CloseClient$blocks_query( polygon = NULL, center = NULL, radius_m = NULL, type = NULL, mode = NULL, include_population = NULL, limit = NULL, cursor = NULL, paginate = TRUE, output = NULL )
Arguments
polygonA GeoJSON polygon or multipolygon (a list).
centerA circle centre,
list(lon =, lat =).radius_mCircle radius, in metres (up to 28000).
typeDestination type id(s) to keep.
modeTravel mode(s) to keep.
include_populationAdd each block's population to its rows.
limitRows per page (up to 1000).
cursorPage cursor; supplying one fetches only that page.
paginateFollow
next_cursorand return every page (the default); setFALSEfor the first page only.outputOverride the client's output mode for this call.
Returns
An sf of block polygons (a data frame in tabular mode, a
close_reply when output is 'raw').
CloseClient$place_blocks()
Per-block travel times for every block in a place (a city or
town), by place GEOID. Rows carry the numeric mode_id (join $modes()
to label it). Reads every page by default.
Usage
CloseClient$place_blocks( geoid, mode = NULL, type = NULL, include_population = NULL, limit = NULL, cursor = NULL, paginate = TRUE, output = NULL )
Arguments
geoidCensus place GEOID.
modeTravel mode(s) to keep.
typeDestination type id(s) to keep.
include_populationAdd each block's population to its rows.
limitRows per page (up to 1000).
cursorPage cursor; supplying one fetches only that page.
paginateFollow
next_cursorand return every page (the default); setFALSEfor the first page only.outputOverride the client's output mode for this call.
Returns
An sf of block polygons (a data frame in tabular mode, a
close_reply when output is 'raw').
CloseClient$place_pois()
Every point of interest within a census place (a city or
town), by place GEOID. The place analog of $pois_search(); pass
type to get, e.g., all supermarkets in a city. Spatial only, no
travel times. Reads every page by default.
Usage
CloseClient$place_pois( geoid, type = NULL, q = NULL, limit = NULL, cursor = NULL, paginate = TRUE, output = NULL )
Arguments
geoidCensus place GEOID.
typeDestination type id(s) to keep.
qName substring to match.
limitRows per page (up to 1000).
cursorPage cursor; supplying one fetches only that page.
paginateFollow
next_cursorand return every page (the default); setFALSEfor the first page only.outputOverride the client's output mode for this call.
Returns
An sf of points (a data frame in tabular mode, a
close_reply when output is 'raw').
CloseClient$place_boundary()
The boundary polygon of a census place, as a one-row
sf, handy as a boundary layer for close_map() when mapping
a city's blocks or POIs. Free (no API key).
Usage
CloseClient$place_boundary(geoid, output = NULL)
Arguments
geoidCensus place GEOID.
outputOverride the client's output mode for this call.
Returns
A one-row sf polygon (a close_reply when output is
'raw').
CloseClient$isochrone()
Travel-time contours from a block or a lat/lon point. Give
minutes for one threshold, or contours for up to four.
Usage
CloseClient$isochrone( block = NULL, lon = NULL, lat = NULL, mode = NULL, direction = NULL, minutes = NULL, contours = NULL, format = NULL, v = NULL, if_none_match = NULL, output = NULL )
Arguments
blockOrigin block GEOID (or give
lon+lat).lon, latOrigin point, instead of
block.mode"walk", "bike", or "transit".
direction"to" (blocks that can reach the origin) or "from".
minutesA single threshold (1 to 60).
contoursUp to four ascending levels, instead of
minutes.format"geojson" (polygons) or "blocks" (a block list).
vOptional cache-buster, echoed back.
if_none_matchAn ETag to revalidate for free.
outputOverride the client's output mode for this call.
Returns
An sf (contour polygons for geojson, block polygons for
blocks), a data frame in tabular mode, or a close_reply when output
is 'raw'.
CloseClient$isochrone_meta()
Isochrone version, directions, modes, and assumptions (free). Always a raw close_reply.
Usage
CloseClient$isochrone_meta(if_none_match = NULL)
Arguments
if_none_matchAn ETag to revalidate for free.
Returns
A close_reply.
CloseClient$records()
Read every record from a paginated method, following the cursor to the last page. The paginated methods now read every page by default, so this is rarely needed; it remains for explicit control and back-compat.
Usage
CloseClient$records(endpoint, ..., output = NULL)
Arguments
endpointName of a paginated method, such as "pois_search".
...Arguments passed on to that method.
outputOverride the client's output mode for this call.
Returns
A data frame (an sf in spatial mode), or a list of records
when output is 'raw'.
Examples
close$records("pois_search", lat = 41.82, lon = -71.41, radius_m = 1500)
CloseClient$clone()
The objects of this class are cloneable with this method.
Usage
CloseClient$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
## ------------------------------------------------
## Method `CloseClient$records()`
## ------------------------------------------------
## Not run:
close$records("pois_search", lat = 41.82, lon = -71.41, radius_m = 1500)
## End(Not run)
Convert a Close reply to a data.frame
Description
Turns a close_reply into a plain data.frame, one row per record. This is
what the client returns in the "tabular" output mode; close_as_sf() adds
geometry on top of the same rows. Metering and envelope metadata (token counts,
block_geoid, assumptions, ...) are attached as attributes.
Usage
close_as_df(x, key = NULL)
Arguments
x |
( |
key |
( |
Value
A data.frame. Summary replies gain a broadcast geoid column.
Examples
## Not run:
close <- close_client(output = 'raw')
close_as_df(close$modes())
## End(Not run)
Convert a Close reply to an sf object
Description
Detects the geometry from the payload. POI replies (from $pois_search(),
$block_pois(), $point_pois(), $poi(), $places()) become points from
their lat/lon. An isochrone reply with format = "geojson" becomes
polygons. Block replies ($blocks_query(), $place_blocks(),
$poi_catchment(), isochrone format = "blocks") carry only GEOIDs, so the
block boundaries are joined from block_geometry, or downloaded with tigris
when fetch = TRUE.
Usage
close_as_sf(
x,
block_geometry = NULL,
geoid_col = "GEOID20",
crs = 4326,
fetch = FALSE
)
Arguments
x |
( |
block_geometry |
( |
geoid_col |
( |
crs |
(default |
fetch |
( |
Value
An sf data frame. Metering and envelope metadata are attached as attributes.
Examples
## Not run:
close <- close_client(output = 'raw')
close_as_sf(close$pois_search(lat = 41.82, lon = -71.41, radius_m = 1500))
## End(Not run)
Create a Close API client
Description
Builds a CloseClient. The catalog and health routes are free, so a key is
optional. Every data route needs one (a ck_live_ key), created at
https://account.close.city (5,000 free tokens on signup, no card).
Usage
close_client(
api_key = NULL,
base_url = DEFAULT_BASE_URL,
timeout = 30,
output = "spatial"
)
Arguments
api_key |
( |
base_url |
( |
timeout |
( |
output |
( |
Value
A CloseClient. Make calls through its methods.
Examples
## Not run:
close <- close_client('ck_live_your_key') # use your own key here
close$block_summary('440070008001068', mode = 'walk')
## End(Not run)
Interactive map of Close spatial results
Description
Draw the sf object a client method returns as an interactive map on a CARTO Positron basemap. Points (POIs, places) render as bright hoverable markers; polygons (census blocks) are filled, optionally greying the features that do not meet a criterion so the ones that matter stand out. The view auto-zooms to fit every layer with a margin, and hover shows all attributes.
Usage
close_map(
x,
color = "#e8590c",
highlight = NULL,
fill = NULL,
palette = "YlGnBu",
reverse = FALSE,
label = NULL,
size = 15,
opacity = 0.65,
boundary = NULL,
background = NULL,
background_color = "#3b6fb0",
background_opacity = 0.3,
background_fill = TRUE,
points = NULL,
points_color = "#e8590c",
mark = NULL,
buffer = 0.15,
zoom = NULL
)
Arguments
x |
An sf from a client method: points or polygons. |
color |
Marker/fill colour for flat features (or for highlighted ones). |
highlight |
Optional. A logical vector (length |
fill |
Optional. The name of a numeric column to shade features by, on a
continuous ColorBrewer scale with a legend (e.g. travel time, or an access
score). Use this OR |
palette |
A plotly ColorBrewer colorscale name for |
reverse |
Which end of the |
label |
Optional. A column shown first (bold) in the hover; the rest of the attributes follow. |
size |
Marker size, for point maps. |
opacity |
Fill opacity, for polygon maps. |
boundary |
Optional. A polygon sf drawn as a grey outline
underneath the data, e.g. a city boundary from |
background |
Optional. A polygon sf, or a list of them, drawn as semi-transparent fills underneath the data, e.g. commute isochrones, or a walkshed under its POIs. |
background_color |
Fill colour(s) for |
background_opacity |
Fill opacity for |
background_fill |
Fill the |
points |
Optional. A point sf drawn as markers on top of the main layer, e.g. POI locations over a block map. |
points_color |
Marker colour for |
mark |
Optional. A point to mark on top with an X, either a
|
buffer |
Fraction of the data extent to pad the view by (default 0.15). |
zoom |
Deprecated/ignored; the view auto-zooms to the data. |
Value
A plotly map object.
Examples
## Not run:
close <- close_client()
close_map(close$place_pois(geoid = "4459000", type = 30), color = "#e8590c")
## End(Not run)
The reply object
Description
When output is 'raw', every method returns a close_reply: a list with the
parsed body plus the metering and caching information as named fields.
Fields
dataThe parsed body (a list), or
NULLfor a 304.resultsThe
resultsarray for list routes (else an empty list).next_cursorThe cursor for the next page, or
NULL.tokens_charged,tokens_remainingToken counts;
NULLon free routes.etagThe response ETag, to pass back as
if_none_match.statusHTTP status code.
not_modifiedTRUEfor a 304 (dataisNULL).request_idServer request id, handy for support.
See Also
close_as_df() and close_as_sf() to convert a reply by hand.
Print a close_reply
Description
Print a close_reply
Usage
## S3 method for class 'close_reply'
print(x, ...)
Arguments
x |
A close_reply. |
... |
Ignored. |
Value
x, invisibly.