Skip to main content
POST
Search assets

Authorizations

Authorization
string
header
required

Gumnut API key (apikey_...) sent as a Bearer token in the Authorization header. Create and manage keys in the Gumnut app, or with the API key endpoints while signed in to it.

Query Parameters

include
string[] | null

Opt-in expansion fields. Supported values: metadata (camera/EXIF/GPS and location names), faces, people, metrics (ML quality scores), file_data (a group token populating the nested file_data object with the file/provenance scalars device_asset_id, device_id, file_created_at, file_modified_at, checksum, checksum_sha1, file_size_bytes), and variants (every asset_urls rung beyond the lean one. Without it asset_urls carries only its lean rung — thumbnail for an image, or thumbnail_image for a video — so callers that render non-thumbnail variants or download the current rendering must pass it). Accepts multiple include= query params or a single comma-delimited value (e.g. include=faces,people). Unknown values return 422. When omitted, only the lean core is returned (id, mime_type, local_datetime, dimensions, file_size_bytes, description, thumbhash, asset_urls, kind, current_version_id) and each data field above is null/absent until you request it.

Body

multipart/form-data
library_id
string | null

Library to search. Optional if the user has a single live (non-trashed) library; required when they have multiple.

query
string | null

Natural-language search text, matched against image embeddings and authoritative metadata. Album and people names belong in album_id and person_ids, and date ranges in local_datetime_before/local_datetime_after, not here.

Maximum string length: 1000
image
file | null

Image file for an independent dense-image retrieval stage. When text is also provided, the stage ranks are fused rather than blending their embeddings.

person_ids
string[] | null

Filter to assets containing ALL of these person IDs (intersection, not union). Accepts multiple person_ids= form fields or a single comma-delimited value (e.g., person_123,person_abc). Person IDs are carried by the entries of an asset's people field (returned with include=people).

album_id
string | null

Return only assets in this album — the album's album_ ID, not its name.

ratings
integer[] | null

Return assets whose effective rating is one of these exact values. Values must be integers from 0 through 5; 5 is a favorite. 0 matches every unrated form: an explicit zero, a null or legacy out-of-range effective rating, or an asset with no metadata. Accepts repeated ratings= parameters or one comma-delimited value. Omit the parameter for no rating filter.

Required range: 0 <= x <= 5
media_type
enum<string> | null

Filter to one media class (image or video). Omit to include both images and videos.

Available options:
image,
video
local_datetime_after
string<date-time> | null

Only include assets captured strictly after this instant (ISO 8601; exclusive). Convert a relative or natural-language date phrase ('in 2023') into an explicit bound before sending. local_datetime is the photo's wall-clock time in the device's own timezone. Naive values compare directly against local_datetime. Timezone-aware values: assets with a known offset are compared in UTC (local_datetime - offset); assets without an offset fall back to wall-clock comparison against local_datetime.

local_datetime_before
string<date-time> | null

Only include assets captured strictly before this instant (ISO 8601; exclusive). Same conversion requirement and awareness/offset semantics as local_datetime_after.

center
string | null

Center point of a radius location filter: two comma-separated decimal-degree numbers longitude,latitude, e.g. -77.05,38.95. Supply with radius. Mutually exclusive with bbox.

radius
number | null

Radius of the center location filter, in meters (greater than 0, at most 50,000). Supply with center. Mutually exclusive with bbox.

bbox
string | null

Bounding-box (map viewport) location filter: four comma-separated decimal-degree numbers min_longitude,min_latitude,max_longitude,max_latitude (west,south,east,north), e.g. -77.1,38.9,-77.0,39.0. A box whose min_longitude exceeds max_longitude crosses the antimeridian: it selects the band running east from min_longitude over ±180° to max_longitude, so there is no need to split it client-side. Longitude order is therefore significant — transposed corners read as a crossing viewport, not as an error. A viewport 360° or wider must be sent as the full range -180,...,180,..., which the wrapped form cannot express.

page
integer
default:1

1-indexed page number; increment it to fetch subsequent pages. Stop when has_more is false, even if the current page is full. search_assets pages by number rather than by cursor. A search with a content criterion ranks a fixed top-200 candidate population by relevance, so pages beyond that population are empty. A structured-filter-only search (no content criterion) returns the full matching set newest-first, paginated without that cap.

Required range: x >= 1
limit
integer
default:20

Maximum number of results per page (1–200). Defaults to 20.

Required range: 1 <= x <= 200

Response

Successful Response

data
SearchResultItem · object[]
required

Text-query matches use the configured reranker over the first 50 Reciprocal Rank Fusion candidates, with fail-open RRF ordering. Image-only matches use RRF across available stages. Structured-filter-only searches retain newest-first capture-date ordering.

has_more
boolean
required

Whether another page remains in this search's result population. For content searches, this refers to the bounded ranked candidate population, not every potentially matching asset in the library. While true, increment page and repeat the same search criteria, filters, and limit.