Efficient token use¶
The API is metered in tokens: one per returned row, minimum one per request, and 10 per isochrone contour. Tokens are rows, so spending well is mostly about not asking for rows you will throw away.
Free things¶
The whole catalog is free and keyless: modes(), destination_types(),
vintage(), places(), isochrone_meta(), last_updated(), and health(). Do
your lookups before you spend a token.
Revalidation is free too. Keep a reply’s etag and pass it back as
if_none_match; an unchanged response returns a free 304. Read output="raw"
when you want the etag:
close.output = "raw"
first = close.block_summary("440070008001068", mode = "walk")
again = close.block_summary("440070008001068", mode = "walk",
if_none_match = first.etag)
again.not_modified # True, and nothing was charged
The big levers¶
The rows a query returns multiply out as modes times types times blocks:
Pass
mode. Omitting it returns all three modes, so three times the rows.Request leaf types, not parents. A parent type expands to its leaves, so
type = grocery(one leaf) is a quarter of the rows of theparksparent.Shrink the area. Cost grows with the square of
radius_m, so halving the radius is roughly a quarter of the tokens.Use
max_minutes. It drops rows you would filter out anyway.
Isochrones are the cheap reach primitive¶
An isochrone is 10 tokens per contour regardless of area, and format="blocks"
returns every reachable block with its minutes. A whole walkshed for 10 tokens,
where a catchment or block query charges per block:
shed = close.isochrone(block = "440070008001068", minutes = 30, mode = "walk",
format = "blocks")
Watch what you spend¶
Every metered reply carries the token counts. In the frame output modes they ride
on df.attrs; in output="raw" they are on the reply.
groceries = close.pois_search(lat = 41.823, lon = -71.412, radius_m = 1200)
groceries.attrs["tokens_charged"], groceries.attrs["tokens_remaining"]
(323, 999867549)
When you only want the numbers, output="tabular" skips the block-boundary
download entirely. The block boundaries the spatial mode joins are cached locally,
so re-running a script costs time, not tokens; pass a block_geometry frame you
already have to skip even that.