API Reference · v1

Imgen Cache API

A semantic image search and retrieval API. Describe what you are looking for in natural language and receive images ranked by relevance. Queries are matched against machine-generated visual descriptions of every image, the images themselves, and the generation prompts — then fused, reranked and diversified.

Semantic and lexical, fused

Dense vector retrieval, BM25 full-text and tag overlap are combined with reciprocal rank fusion, then reranked. Prose queries and raw generation tag soup both work.

Taxonomy filters

Narrow by character, model or style in any combination. Filters are applied inside the vector index, so recall does not degrade when you filter.

Stable URLs

Every result carries a direct full-resolution URL and a thumbnail URL. Both are stable and safe to embed or re-host.

Curated results only

The public API returns only human-reviewed images. Rejected and duplicate images are excluded, and near-identical batch siblings are capped so results stay varied.

Quick start

Every request carries your API key in an Authorization header. A minimal search:

curl
curl -X POST https://example.com/api/search \
  -H "Authorization: Bearer $IMGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"sunset over mountains","limit":5}'
  1. Obtain an API key from your account owner.
  2. POST to /api/search with a natural-language query.
  3. Render thumbnail in grids and url on detail views.
  4. Populate filter controls from the taxonomy endpoints and cache them locally.
  5. Verify your integration interactively in the Playground.

Authentication

All endpoints authenticate with a bearer token:

Header
Authorization: Bearer YOUR_API_KEY

Keys are stored server-side only as SHA-256 digests and are compared in constant time. A revoked key begins returning 401 immediately and cannot be reactivated.

Never ship a key to a browser or mobile binary. Proxy requests through your own backend. If a key is exposed, revoke it and issue a replacement.

Base URL

All paths in this reference are relative to a single origin:

Base URL
https://example.com/api

Rate limits & caching

EndpointLimitWindowScope
/api/search240 requests60 sAPI key + client IP
/api/generate120 requests60 sAPI key + client IP
taxonomy endpointsNot limited. Cached for 5 minutes at the edge.

Exceeding a limit returns 429 with a Retry-After header. Identical search requests are served from an edge cache; a served response carries X-Cache: HIT. Treat cache headers as advisory.

Generate

Return the single best match for a prompt. Use this when you want “something that looks like this” rather than a list of candidates.

POST/api/generate Authentication required

Request body

FieldTypeRequiredDescription
promptstringrequired Natural-language description. Maximum 500 characters.
characterstringoptional Restrict to one character.
modelstringoptional Restrict to one model.
stylestringoptional Restrict to one style.
search_instringoptional both, caption or prompt. Default both.

Example response

200 OK
{
  "image": {
    "id": "a1b2c3d4",
    "url": "https://cdn.example.com/08-26/2450c4bc/5c5be245.jpg",
    "thumbnail": "https://cdn.example.com/08-26/2450c4bc/5c5be245_t.jpg",
    "width": 832,
    "height": 1216,
    "character": "",
    "model": "sdxl",
    "style": "photoreal",
    "prompt": "misty lake, golden dawn light, reflections on still water",
    "caption": "A misty lake at dawn with pale golden light and still, reflective water."
  }
}
No match? When nothing suitable exists, the endpoint returns 404 with {"error":"No match found"}. This is not a server error — the filter combination was too narrow, or the library has no close match. Do not retry.

List characters

Character identifiers currently available as filter values.

GET/api/characters Public
200 OK
{ "characters": ["aya", "mira", "noa"] }

List models

GET/api/models Public
200 OK
{ "models": ["sdxl", "flux"] }

List styles

GET/api/styles Public
200 OK
{ "styles": ["photoreal", "illustration", "cinematic"] }

The image object

Every image returned by the API shares this shape. Individual endpoints omit fields that are not relevant to their response.

FieldTypeDescription
idstringStable opaque identifier. Safe to store and reference.
gen_idstringUpstream generation identifier.
urlstringAbsolute URL to the full-resolution asset.
thumbnailstringAbsolute URL to the preview derivative. Preferred for grids.
widthintegerFull-resolution pixel width.
heightintegerFull-resolution pixel height.
characterstringCharacter identifier, or empty string.
modelstringModel identifier, or empty string.
stylestringStyle identifier, or empty string.
promptstringThe prompt the image was generated from.
edited_promptstringCurator override. Present only when set.
captionstringVisual description. Suitable for alt text and display.
edited_captionstringCurator override. Present only when set. Prefer this over caption.
scorenumberRelative relevance. Present on search responses only.
topbooleanFlagged best-in-class by a reviewer. Search responses only.
Responses may contain additional fields beyond those documented here. Ignore unknown fields to stay forward-compatible.

Errors

Every error response is JSON and shares one shape:

Error envelope
{ "error": "human-readable description of what went wrong" }

Branch on the HTTP status code. The error string is for logs and developer display, and its wording may change without notice.

Status codes

200Success. A result body is returned.
400Malformed body, or a required field was missing or invalid.
401The Authorization header was missing, or the key is invalid or revoked.
404Nothing matched. For generate, no image satisfied the prompt plus filters.
429Rate limit exceeded. Honour Retry-After.
502A transient upstream dependency failed. Safe to retry with backoff.
500Unexpected server error. Contact support if it persists.
Retries. Retry 429 and 502 with exponential backoff (500 ms, 1.5 s, 4 s). Never retry 4xx other than 429 — the request will not succeed without a change.

Code examples

Node.js

javascript
const BASE = 'https://example.com';
const KEY = process.env.IMGEN_API_KEY;

async function search(query, opts = {}) {
  const res = await fetch(BASE + '/api/search', {
    method: 'POST',
    headers: {
      Authorization: 'Bearer ' + KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query,
      character: opts.character,
      model: opts.model,
      style: opts.style,
      search_in: opts.searchIn || 'both',
      limit: opts.limit || 10,
    }),
    signal: AbortSignal.timeout(15000),
  });

  if (res.status === 429) {
    throw new Error('rate limited; retry after ' + res.headers.get('Retry-After') + 's');
  }
  if (!res.ok) {
    const err = await res.json().catch(() => ({ error: res.statusText }));
    throw new Error('search failed (' + res.status + '): ' + err.error);
  }

  const { results } = await res.json();
  return results;
}

for (const img of await search('sunset over mountains', { limit: 5 })) {
  console.log(img.id, img.score.toFixed(3), img.thumbnail);
}

Python

python
import os
import requests

BASE = "https://example.com"
KEY = os.environ["IMGEN_API_KEY"]

session = requests.Session()
session.headers.update({
    "Authorization": f"Bearer {KEY}",
    "Content-Type": "application/json",
})

def search(query, **opts):
    r = session.post(
        f"{BASE}/api/search",
        json={
            "query": query,
            "character": opts.get("character"),
            "model": opts.get("model"),
            "style": opts.get("style"),
            "search_in": opts.get("search_in", "both"),
            "limit": opts.get("limit", 10),
        },
        timeout=15,
    )
    r.raise_for_status()
    return r.json()["results"]

for img in search("sunset over mountains", limit=5):
    print(img["id"], round(img["score"], 3), img["thumbnail"])

Integration guidance

  • Cache the taxonomy endpoints locally. They change infrequently.
  • Keep limit as low as your interface actually renders. Smaller responses are faster.
  • Use thumbnail in grids; load url only on detail or zoom.
  • Store id when you need a stable reference across sessions.
  • Prefer edited_caption over caption when both are present.
  • Always set a client-side timeout. 15 seconds is a sensible default.
  • If you are probing this API as a generation cache, send the raw generation prompt verbatim: exact prompt matches are detected and short-circuited without any model inference.
Imgen Cache API · v1 Open the Playground