Search
The core search endpoint: parameters, response shape, and examples.
Search documents
POST /api/v1/search/query
Search documents in a collection and return ranked results. The retrieval mode (dense, sparse, or hybrid: dense + sparse vectors) is determined by the collection's configuration and cannot be overridden by the caller.
A question about the catalogue itself, such as which data sources, publishers or journals your key can reach, sent without filters, is answered from the catalogue instead of searched: results is empty, the answer is in discovery, and nothing is charged. See Catalogue questions.
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
collection | string | One of collection/collections | Collection name to search. List valid names via Collections |
collections | string[] | One of collection/collections | Collections to search together (max 5), merged into one ranked list |
query | string | Yes | Search query text (max 1000 characters) |
limit | integer | No | Max results to return (default 10, max 30) |
filters | object | null | No | Metadata filters. A filter that cannot be applied is rejected with 422 INVALID_FILTER. See Filtering |
include_metadata | boolean | No | Include metadata in results (default true) |
include_figures | boolean | No | Fetch and include figure images as base64 in metadata.figures[].image_data (default false, adds latency) |
image_max_width | integer | No | Maximum image width in pixels (default 800, 100-1920) |
image_max_height | integer | No | Maximum image height in pixels (default 600, 100-1080) |
image_quality | integer | No | JPEG quality for fetched images (default 75, 1-100) |
Searching multiple collections
Pass collections instead of collection to search several collections in one request.
Results are merged, not grouped
You get back one relevance-ranked list spanning every collection, not one list per collection. Each result's collection field reports which one it came from, so sort or split client-side if you need them apart.
curl -X POST "https://api.redpine.ai/api/v1/search/query" \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"collections": ["my-collection", "another-collection"], "query": "your search query", "limit": 10}'Response fields
| Field | Type | Description |
|---|---|---|
results | array | Array of search results with id, text, metadata, and collection |
queryId | string | Unique query identifier. Use to re-fetch results for free within 7 days via GET /api/v1/search/results/{queryId} |
latencyMs | integer | Search latency in milliseconds |
filterWarnings | array | null | Advisory warnings for filter fields with no payload index; omitted when there are none |
journalMetricExpansions | array | null | How each journal-metric filter condition resolved to ISSNs; omitted when no metric filter was used |
filtersApplied | object | null | The filters you sent, after validation; omitted when no filters were sent |
discovery | object | null | A catalogue answer, set only when the query asked about the catalogue rather than for literature. See Catalogue questions |
Result object
| Field | Type | Description |
|---|---|---|
id | string | Chunk/point ID |
text | string | Chunk text content |
metadata | object | null | Chunk metadata (if include_metadata=true), including chunk_index, the chunk's 0-based position in its document, for ordering or stitching neighbouring passages |
collection | string | null | Origin collection of this result, as requested. Always populated |
relevance | number | null | How well this passage answers the query, 0 to 1, rounded to three decimals. null when the result has no score, including rows cached before this field existed |
Example request
curl -X POST "https://api.redpine.ai/api/v1/search/query" \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"collection": "my-collection",
"query": "What are the symptoms of diabetes?",
"limit": 10,
"include_metadata": true,
"include_figures": true,
"filters": {
"and": [
{"field": "publication_date", "gte": "2020-01-01"},
{"field": "publisher", "eq": "Example Publishing"}
]
}
}'The SDKs accept a raw filter object too, in either format from Filtering, if you already have one built.
Example response
{
"results": [
{
"id": "abc123",
"text": "Type 2 diabetes symptoms include increased thirst, frequent urination...",
"metadata": {
"title": "Diabetes Overview",
"chunk_index": 3,
"figures": [
{
"id": "fig1",
"label": "Figure 1",
"caption": "Glucose metabolism pathway",
"image_data": "<base64>"
}
]
},
"collection": "my-collection",
"relevance": 0.812
}
],
"queryId": "qry_a1b2c3d4e5f6",
"latencyMs": 42,
"filtersApplied": {
"and": [
{"field": "publication_date", "gte": "2020-01-01"},
{"field": "publisher", "eq": "Example Publishing"}
]
}
}Re-fetch results
Every search response includes a queryId. Use it to retrieve the same results again without being charged, for up to 7 days after the original search.
GET /api/v1/search/results/{queryId}
The request must use the same API key that performed the original search.
Response: Identical to the original search response, with latencyMs: 0. Includes X-Cache: hit and X-Cache-Expires headers.
Errors:
404: Query ID not found or belongs to a different API key410: Cached result has expired (past 7-day window)
Example
curl "https://api.redpine.ai/api/v1/search/results/qry_a1b2c3d4e5f6" \
-H "Authorization: Bearer sk_live_YOUR_API_KEY"The re-fetched rows carry the preview and unlock shape: locked is false on rows you have paid for, and the SDKs type the result accordingly. An unknown id raises NotFound (Go: *NotFoundError); an expired one raises Expired (Go: *ExpiredError). Neither is retried.
Filtering
Use the filters parameter to narrow search results by metadata fields. Indexed on every collection: journal, publisher, keywords, publication_date, doi, issn, article_type, section, isbn, open_access, chapter_number, chapter_title, and chapter_authors. Other result metadata fields have no index: they are matched by scanning where the collection supports it, and rejected with 422 INVALID_FILTER where it does not. A field that is not a result metadata field, doc_id and license are rejected with 422 INVALID_FILTER. journal_metric.* thresholds are resolved to the matching ISSNs; see Filtering.
Full operator list, both request formats, and worked examples: see Filtering.