Search endpoints
REST endpoints for CLIP text search, SVM relevance feedback, and faceted filtering.
All search endpoints are mounted under /exq/search/ and accept POST requests with a JSON body. Every request requires a session_info object that identifies the session, collection, and active model.
SessionInfo
All three endpoints share this object:
{
"session": "string",
"collection": "string",
"modelId": "string"
}
| Field | Type | Description |
|---|---|---|
session |
string |
Unique session identifier |
collection |
string |
Collection name as defined in config.ini |
modelId |
string |
Identifier for the model being used (logged for audit) |
POST /exq/search/clip
Performs a text-to-image search using CLIP embeddings. The query text is tokenised and encoded by the server-side CLIP model, then used to retrieve the most similar items from the vector index.
See CLIP search strategy for a detailed explanation of how the search works.
Request body
{
"text": "a dog running on a beach",
"n": 20,
"seen": [101, 205, 340],
"filters": null,
"excluded": [],
"session_info": {
"session": "abc123",
"collection": "my_collection",
"modelId": "model_1"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
text |
string |
Yes | Natural language query |
n |
integer |
Yes | Number of results to return |
seen |
list[int] |
Yes | Media IDs already shown to the user — excluded from results |
filters |
ActiveFilters | null |
No | Filter tree to constrain results. See Filters |
excluded |
list[int] |
No | Additional media IDs to blacklist |
session_info |
SessionInfo |
Yes | Session context |
Response
{
"suggestions": [42, 17, 830, 12],
"request_timestamp": 1718000000000,
"completion_time": 1718000000082,
"strategy": "clip"
}
| Field | Type | Description |
|---|---|---|
suggestions |
list[int] |
Ordered list of media IDs (most relevant first) |
request_timestamp |
integer |
Unix ms timestamp when request was received |
completion_time |
integer |
Unix ms timestamp when results were ready |
strategy |
string |
Always "clip" |
POST /exq/search/rf
Performs relevance feedback search using a linear SVM trained on user-selected positive and negative examples. Optionally, a text query can seed pseudo-positives via CLIP.
See Relevance feedback strategy for a detailed explanation.
Request body
{
"pos": [42, 17],
"neg": [830],
"n": 20,
"seen": [101, 205],
"query": "sunny outdoor scenes",
"filters": null,
"excluded": [],
"session_info": {
"session": "abc123",
"collection": "my_collection",
"modelId": "model_1"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
pos |
list[int] |
Yes | Positive example media IDs |
neg |
list[int] |
Yes | Negative example media IDs |
n |
integer |
Yes | Number of results to return |
seen |
list[int] |
Yes | Media IDs already shown — excluded from results |
query |
string | null |
No | Optional text query; top-10 CLIP results become pseudo-positives if pos is empty |
filters |
ActiveFilters | null |
No | Filter tree. See Filters |
excluded |
list[int] |
No | Additional IDs to blacklist |
session_info |
SessionInfo |
Yes | Session context |
Response
Same shape as CLIP search, with "strategy": "rf".
POST /exq/search/faceted
Returns items matching a filter tree without performing any vector search. Useful for browsing by metadata alone.
See Faceted search strategy for details.
Request body
{
"n": 50,
"filters": {
"root": {
"kind": "group",
"operator": "AND",
"children": [
{
"kind": "leaf",
"filter": {
"id": 3,
"tagtype_id": 1,
"constraint": {
"value_ids": [10, 11],
"operator": "OR"
}
}
}
]
}
},
"session_info": {
"session": "abc123",
"collection": "my_collection",
"modelId": "model_1"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
n |
integer |
Yes | Number of results to return |
filters |
ActiveFilters |
Yes | Filter tree (required for this strategy) |
session_info |
SessionInfo |
Yes | Session context |
Response
Same shape as CLIP search, with "strategy": "faceted".