Pagination
List endpoints support cursor-based pagination usinglimit and starting_after_id:
has_more field indicating whether additional results exist:
id of the last item as starting_after_id.
If you’re using one of our SDKs, pagination is handled automatically with built-in iterators.
Filtering
Use query parameters to filter results:Filtering by capture time
local_datetime_after and local_datetime_before filter on the asset’s capture time:
- Send offsetless values such as
2024-01-01T00:00:00when you want wall-clock filtering. - Send offset-aware values such as
2024-01-01T00:00:00-05:00when you want an absolute time window. - Keep both bounds consistent. Mixing an offsetless value with an offset-aware value in the same request is rejected.
- Assets with a known capture offset are compared using that offset. Assets without one fall back to wall-clock comparison, so offsetless captures still participate in aware range filters.
Filtering semantic search
UseGET /api/search when you want natural-language or metadata search. The endpoint accepts the same canonical date and album filters as asset lists:
album_id. You can also pass person_ids for one or more people. Include at least one search criterion such as query, album_id, person_ids, or a date bound; a location filter only narrows those results. The same filters are available on POST /api/search when you submit a multipart request for image-aware search.
Use the canonical parameter names shown above. The legacy search spellings captured_after, captured_before, and album_ids are no longer supported; replace them with local_datetime_after, local_datetime_before, and album_id.
Filtering by location
GET /api/assets supports two location filter shapes:
center+radiusfor a circular search area in metersbboxfor a rectangular viewport inmin_longitude,min_latitude,max_longitude,max_latitudeorder
center and radius together. Don’t combine them with bbox.
A viewport that crosses the antimeridian is a single box whose west longitude is greater than its east longitude. It selects the band running east from min_longitude over ±180° to max_longitude, so you don’t split it into two requests.
Because longitude order carries that meaning, it’s significant: a box with west and east transposed reads as a crossing viewport rather than an error. A viewport 360° or wider must be sent as the full range -180,...,180,..., which the wrapped form can’t express.
For semantic search, GET /api/search supports both center + radius and bbox as mutually exclusive location filters. A location filter only narrows a search; include at least one search criterion such as query, album_id, person_ids, or a date bound.
See Requests & Responses for how local_datetime is serialized, and see the API Reference tab for the full list of available filter parameters for each endpoint.
Map views with geo clusters
When you need a map-friendly summary of geotagged assets inside a viewport, useGET /api/assets/geo-clusters instead of paging through GET /api/assets and grouping results client-side.
The endpoint takes a bbox string in min_longitude,min_latitude,max_longitude,max_latitude order plus a cell_size in decimal degrees.
library_id, album_id, person_ids, local_datetime_after, local_datetime_before, and state.
Each item in data represents one non-empty grid cell and includes a centroid (latitude, longitude), the number of matching assets (count), and a representative_asset_id you can use as a cover image or lookup key.
GET /api/assets/geo-clusters is not paginated. The response is capped at 1000 non-empty cells, so a dense viewport returns 422 instead of partial results. If that happens, increase cell_size or zoom in and retry. A viewport crossing the antimeridian is clustered as one wrap-around band — send it as a single box whose west longitude is greater than its east longitude. Note that the 1000-cell cap then applies to that one response, so a viewport both very wide and very dense across ±180° may need a coarser cell_size than each half would have.