Imgen Cache API
A semantic image search and retrieval API. Describe what you are looking for in natural language and get back images that match, ranked by relevance.
Find images by meaning, not just keywords. Queries are matched against each image's visual description.
Narrow results by character, model, or style — any combination, all optional.
Every result includes a direct image URL and a thumbnail URL suitable for embedding.
All requests and responses use JSON. All errors follow a single predictable shape.
Quick start #
Every authenticated request includes your API key in an Authorization header. A minimal search looks like this:
curl -X POST https://imgen-cache.demo.efficientstack.com//api/search \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"sunset over mountains","limit":5}'
- Obtain an API key from your account owner.
- Issue a
POSTto/api/searchwith your natural-languagequery. - Render the returned
url(full-size) orthumbnailfields in your UI. - Use the taxonomy endpoints (characters, models, styles) to populate filter dropdowns.
Authentication #
Protected endpoints authenticate via a Bearer token. Pass your key in the Authorization header on every request:
Authorization: Bearer YOUR_API_KEY
Each endpoint's reference indicates whether authentication is required via an Auth or Public tag. Requests missing or presenting an invalid key receive an HTTP 401 response.
Base URL #
All endpoints are served from a single origin. Paths in this reference are relative to:
https://imgen-cache.demo.efficientstack.com/api
Search #
Search the image library with a natural-language query. Returns a ranked list of matches, most relevant first.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| query | string | Required | Natural-language description of the image you want. Free-form; 1–500 characters works best. |
| character | string | optional | Restrict results to a specific character. Use GET /api/characters to list available values. |
| model | string | optional | Restrict results to a specific model identifier. |
| style | string | optional | Restrict results to a specific style identifier. |
| search_in | string | optional | Which text source the query is compared against. One of both, caption, or prompt. default: both |
| limit | integer | optional | Maximum number of results to return. Range 1–50. default: 10 |
Example request
{
"query": "cinematic portrait at golden hour",
"character": "aya",
"search_in": "both",
"limit": 5
}
Example response
{
"results": [
{
"id": "a1b2c3d4",
"url": "https://cdn.example.com/images/a1b2c3d4.png",
"thumbnail": "https://cdn.example.com/thumbs/a1b2c3d4.jpg",
"width": 1024,
"height": 1536,
"character": "aya",
"model": "sdxl",
"style": "photoreal",
"prompt": "portrait, shallow depth of field, warm sunset light",
"caption": "A close-up portrait in warm golden-hour light with a soft blurred background.",
"score": 0.842
}
],
"count": 1
}
score is a relative relevance value (higher is more relevant). It is not calibrated across queries — use it to rank within a single response, not to set absolute thresholds.
Generate #
Return a single image best matching a prompt. Useful when you want "something that looks like this" rather than a list of candidates.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| prompt | string | Required | Natural-language description. Max 500 characters. |
| character | string | optional | Restrict to a specific character. |
| model | string | optional | Restrict to a specific model. |
| style | string | optional | Restrict to a specific style. |
| search_in | string | optional | One of both, caption, or prompt. default: both |
Example request
{
"prompt": "a quiet lakeside at dawn, soft mist",
"style": "photoreal"
}
Example response
{
"image": {
"id": "a1b2c3d4",
"url": "https://cdn.example.com/images/a1b2c3d4.png",
"thumbnail": "https://cdn.example.com/thumbs/a1b2c3d4.jpg",
"width": 1024,
"height": 1536,
"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."
}
}
404 with {"error":"No match found"}. This is not a server error — it means your filter combination was too narrow or the library currently has no close match.
List characters #
Returns the full list of character identifiers currently available as filter values.
Example response
{
"characters": ["aya", "mira", "noa"]
}
List models #
Returns the full list of model identifiers currently available as filter values.
Example response
{
"models": ["sdxl", "flux"]
}
List styles #
Returns the full list of style identifiers currently available as filter values.
Example response
{
"styles": ["photoreal", "illustration", "cinematic"]
}
The image object #
Every image returned by the API shares the following shape. Individual endpoints may omit fields that are not relevant to their response.
| Field | Type | Description |
|---|---|---|
| id | string | Stable, opaque identifier for the image. Safe to store and reference. |
| url | string | Absolute URL to the full-resolution image. Suitable for <img src>. |
| thumbnail | string | Absolute URL to a smaller preview variant. Preferred for list / grid layouts. |
| width | integer | Full-resolution pixel width. |
| height | integer | Full-resolution pixel height. |
| character | string | Character identifier, or empty string if none. |
| model | string | Model identifier, or empty string if none. |
| style | string | Style identifier, or empty string if none. |
| prompt | string | The text prompt the image was generated from. |
| caption | string | Short description of what the image depicts. Suitable for alt-text and display. |
| score | number | Relative relevance score. Present on search responses only. |
Errors #
Every error response is JSON and shares a single shape:
{
"error": "human-readable description of what went wrong"
}
Always inspect the HTTP status code first; the error string is intended for logging and developer display, not for programmatic branching.
Status codes #
| 200 | The request succeeded. A result body is returned. |
| 400 | The request body was malformed or a required field was missing / invalid. |
| 401 | The Authorization header was missing or the API key is invalid / revoked. |
| 404 | No resource matched the request. For generate, this means no image satisfied the prompt plus filters. |
| 502 | A transient upstream dependency failed. Safe to retry with backoff. |
| 500 | An unexpected server error occurred. If it persists, contact support. |
502 responses with exponential backoff (e.g. 500 ms, 1.5 s, 4 s). Do not retry 4xx responses — they indicate a client-side issue that will not resolve without a change to the request.
Code examples #
curl
curl -X POST https://imgen-cache.demo.efficientstack.com/api/search \
-H "Authorization: Bearer $IMGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "soft pastel illustration of a garden",
"style": "illustration",
"limit": 8
}'
Node.js (fetch)
const BASE = 'https://imgen-cache.demo.efficientstack.com';
const KEY = process.env.IMGEN_API_KEY;
async function search(query, opts) {
opts = opts || {};
const res = await fetch(BASE + '/api/search', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: query,
character: opts.character,
model: opts.model,
style: opts.style,
search_in: opts.search_in || 'both',
limit: opts.limit || 10,
}),
});
if (!res.ok) {
const err = await res.json().catch(function () { return { error: res.statusText }; });
throw new Error('Search failed (' + res.status + '): ' + err.error);
}
const data = await res.json();
return data.results;
}
// Usage
const results = await search('sunset over mountains', { limit: 5 });
for (const img of results) {
console.log(img.id, img.score.toFixed(3), img.url);
}
Python (requests)
import os
import requests
BASE = "https://imgen-cache.demo.efficientstack.com"
KEY = os.environ["IMGEN_API_KEY"]
def search(query, **opts):
r = requests.post(
f"{BASE}/api/search",
headers={
"Authorization": f"Bearer {KEY}",
"Content-Type": "application/json",
},
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"]
# Usage
for img in search("sunset over mountains", limit=5):
print(img["id"], round(img["score"], 3), img["url"])
Best practices
- Cache the taxonomy endpoints (
/api/characters,/api/models,/api/styles) on your side. They change infrequently. - Keep
limitas low as your UI actually needs. Smaller responses mean lower latency and less bandwidth. - Prefer
thumbnailfor grids and list views; load the fullurlonly on detail / zoom. - Store the image
idif you need a stable reference across sessions. - Always set a reasonable client-side timeout on your HTTP call (10–15 seconds is a sensible default).