Search

Search your assets and generations

Full-text + detection-aware search. The query (q) matches against image names, prompts, AI-generated narratives, and every detected item — clothing, poses, colors, textures, actions. Returns image-level matches scored by relevance. Set include_regions=true to get the matching bounding boxes overlaid by your client; coords are normalized 0..1 so they scale to any render size. Stale-while-revalidate caching: rapid repeat queries are instant. Read scope.

Four modes, one response shape: mode=text (default) is the full-text engine above. mode=color ranks your whole library by perceptual (OKLab) proximity to a hex color — add q to color-reorder a text search instead. mode=similar ranks by likeness to one anchor image (similar_to + similar_type), with similar_mode picking the flavor: all (blended, default), items (same detected stuff), scene (same lighting/mood/setting vocabulary), story (same narrative). mode=browse asks nothing and returns the catalogue newest-first. Color, similar, and browse results carry score: 0 (they are ranked browses, not text relevance).

Text mode also reaches INSIDE indexed videos: an instant of footage that matches the words arrives as an ordinary item flagged is_video, whose video_moment names the exact time_ms — one clip is one card (its best-matching moment), ranked in by relevance alongside the photos. Filter to clips alone with gen_type=video.

The one endpoint publishable keys (pk_sf_live_) can call — embeddable in public pages and callable cross-origin from browsers. Every response (errors included) echoes the request's Origin back in Access-Control-Allow-Origin (* when absent) and sends Vary: Origin; preflights are answered by the OPTIONS operation below. A key's search_scope narrows results silently — see the notes on type, project_id, image_size, and include_regions. A key with an origins allowlist answers 403 forbidden to browser requests from any other origin.

get/v1/search

Request

  • Base URL: https://nanostudiopro.com/api
  • URL: https://nanostudiopro.com/api/v1/search
  • Auth: HTTP bearer

Query parameters

mode'text' | 'color' | 'similar' | 'browse'

Search flavor. text (default) requires q. color requires color (q optional — with it, the text results are re-ranked by color proximity). similar requires similar_to + similar_type and ignores q. browse needs nothing and returns the catalogue newest-first — what an embedded widget shows before a visitor has typed.

qstring

Search query — required for mode=text (the default), optional for mode=color, ignored for mode=similar. Multi-word queries are AND'd; the last word gets prefix-matching while you're still typing (e.g. red dr matches red dress). Trailing whitespace anchors the last word as exact.

colorstring

Target color for mode=color, as a 6-digit hex (# optional). Converted server-side to OKLab — the same perceptual space the in-app picker uses — so #7a1f1f returns your wine-red photos, ranked by how much of each image IS that color.

similar_tostring

Anchor image ID for mode=similar (an asset or generation you own).

similar_type'asset' | 'generation'

What similar_to refers to. Required with mode=similar.

similar_mode'all' | 'items' | 'scene' | 'story'

Similarity flavor for mode=similar. all blends the three signals; items = same detected items; scene = same lighting/mood/setting; story = same narrative situation.

limitinteger

Page size, 1–100.

offsetinteger

Pagination offset. Use next_offset from the previous response.

type'asset' | 'generation'

Restrict to one source. Default returns both. Publishable keys: narrowed by the key's search_scope.types — a type outside the scope returns an empty 200 page (next_offset: null), never an error.

project_idstring

Comma-separated project IDs to filter by. Publishable keys: intersected with the key's search_scope.projects — requesting only out-of-scope projects returns an empty 200 page (next_offset: null), never an error.

gen_type'image' | 'video' | 'cutout' | 'collage' | 'uploaded'

Narrow to one kind of generation — video returns only clips, cutout only transparent subjects, and so on. Honored by text and browse (and color with q); a 400 with similar or a pure color browse, which cannot filter by kind.

style'photograph' | '3d-render' | 'illustration'

Filter by detected image style.

has_poseboolean

Only return images with detected skeletal pose data.

has_colorsboolean

Only return images with extracted color swatches.

colorsstring

Filter by detected color. Comma-separated list, OR'd together. Accepts hex (#7a1f1f) or color names (red,navy). Hex values are resolved to the closest named color in our palette before matching, so colors=#aa0000 and colors=red typically return the same set.

scanned_afterstring date-time

Only return results scanned at or after this ISO 8601 timestamp.

scanned_beforestring date-time

Only return results scanned at or before this ISO 8601 timestamp.

sort'relevance' | 'date_desc' | 'date_asc'

Sort order. relevance (default) ranks by how well each result matches q. date_desc and date_asc order chronologically by scan time — useful for time-based browsing.

aspectstring
Example:16:9,3:2

Filter by frame shape. Accepts a comma-separated list, OR'd together. Coarse words: portrait (< 0.95), landscape (> 1.05), square (0.95–1.05). Exact ratios: 1:1, 3:2, 2:3, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9 — each matches photos whose measured ratio is NEAREST that bucket, so every photo belongs to exactly one. Useful for picking source images that fit a target slot (social post, product card). Applies to text and color modes; ignored by similar.

include_regionsboolean

When true, every result includes a regions array with the detected bounding boxes (label, category, texture, colors, normalized bbox). Heavier payload — leave off for typeahead/grid use cases. color and similar mode results don't carry detection payloads, so their items omit regions regardless. Publishable keys only get regions when the key's search_scope.include_regions is true — the flag is silently ignored otherwise.

image_size'xs' | 'thumb' | 'preview' | 'large' | 'original'

xs=100px · thumb=200px · preview=600px · large=1200px · original=raw upload (full-res)

Resolution for image_url. Variants are pre-rendered at upload time, generated on-demand for legacy images on first request. Default preview is appropriate for most grid/card layouts. Use original only when you need the raw source (zoom, full-screen, download). Publishable keys with a search_scope.max_image_size cap are silently served the capped variant whenever the request — the preview default included — exceeds it: still a 200, just smaller images. Unknown values are a 400 either way.

embed_keystring

Ask for embed_url on every image result: a link to place on a page, served from the edge under a publishable key's domain rules (its allowed sites, and whether a link opened directly works). A search made WITH a publishable key gets them automatically. A server searching with its secret token names one of its own publishable keys here; any other key is ignored. The link uses the image_size asked for (xs is served as thumb).

Response

Paginated search results.

totalinteger

Total matches across all pages.

next_offsetinteger nullable

Pass to the next request as offset. null when there are no further pages.

did_you_meanstring[]

Up to 3 closest names (trigram similarity). Present whenever suggestions exist.

videos_totalinteger

Present when the video branch matched: how many video moments matched across the library.

videos_showninteger

Present when the video branch matched: how many clip cards joined this page (max 4, first page only). next_offset counts photo rows alone.

Example response

{
  "items": [
    {
      "aspect_ratio": "2:3",
      "video_moment": {
        "shot_size": "medium",
        "camera_motion": "pan-left"
      },
      "regions": [
        {
          "label": "dress",
          "category": "clothing",
          "texture": "silk",
          "colors": [
            "#7a1f1f"
          ]
        }
      ]
    }
  ]
}

Changes

No recorded changes to this operation across all 2 revisions of this API.