Assisted search

Agentic retrieval that plans its own searches and verifies every result.

/search/query runs one hybrid retrieval pass and returns whatever ranks highest. /search/assisted runs a multi-round agent loop: it reads the query for entities, intent, and aspects, plans internal searches to cover them, and keeps searching and replanning until it has gathered enough candidates or hits the iteration cap. Every candidate gathered is then verified against the query before delivery: a full pool of candidates is not the same as a full pool of verified results, which is why a request can still come back as no_relevant_results after several rounds.

Billing differs too: only delivered, verified results are charged. A clarification request or an honest "no relevant results" answer costs nothing: internal search fan-out and LLM tokens spent along the way are absorbed by Redpine, not billed to you. See Rate limits for the shared billing and rate-limit headers.

POST /api/v1/search/assisted

Runs the agentic search loop and returns verified results, a clarifying question, or an explicit no-relevant-results outcome. Accepts the same filters as /search/query, applied to every internal search.

Request body

ParameterTypeRequiredDescription
collectionstringOne of collection/collectionsCollection name to search
collectionsstring[]One of collection/collectionsCollections to search together (max 5)
querystringYesA natural-language question, or a whole document such as a patient case or chart note (max 16,000 characters). See Long queries
limitintegerNoMaximum verified results to return (default 10, max 30)
filtersobject | nullNoSame filter forms as /search/query, applied to every internal search
include_metadatabooleanNoInclude chunk metadata in results (default true)
include_figuresbooleanNoFetch and attach figure images as base64 in metadata.figures[].image_data, for delivered results only (default false, requires include_metadata)

Response fields

FieldTypeDescription
status"results" | "clarification_needed" | "no_relevant_results"Outcome of the assisted search
queryUnderstandingobjectHow the query was read: entities, intent, aspects, and any structured filters named in the query text. For a long query, also caseSummary (the summary results were judged against) and subQuestions (the separate problems it was split into)
resultsarrayVerified results. Empty unless status is results
clarificationobject | nullThe clarifying question and reason. Set only when status is clarification_needed
billingobjectWhat was actually charged: chargedResults and tokensCharged
queryIdstringQuery identifier for audit reference
latencyMsintegerEnd-to-end latency in milliseconds
iterationsRunintegerNumber of search + replan rounds executed
filterWarningsarray | nullAdvisory warnings for filter fields with no payload index; omitted when there are none
discoveryobject | nullA catalogue answer, set only when the query asked about the catalogue rather than for literature; nothing is charged. See Catalogue questions

Result object

FieldTypeDescription
idstringChunk/point ID
textstringChunk text content
metadataobject | nullChunk metadata (if include_metadata=true)
collectionstring | nullOrigin collection of this result. Populated only for requests made with the collections (multi-collection) form
doiUrlstring | nullResolvable DOI link (https://doi.org/{doi})
sectionstring | nullComma-joined source section(s) of the article (abstract, introduction, background, methods, results, discussion, conclusion, case, supplementary, other)
relevanceobjectRelevance verdict: matchedTerms, judgeScore (0..1), and a one-sentence rationale
subQuestionstring | nullThe sub-question of a multi-problem query that this result answers; null when the query was answered as a single question

Example request

curl -X POST "https://api.redpine.ai/api/v1/search/assisted" \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "collection": "my-collection",
    "query": "Does topical retinoid use increase photosensitivity?",
    "limit": 10,
    "include_metadata": true
  }'

Pass allow_clarification=False (allowClarification: false, AllowClarification: &f) to make the endpoint search on its best interpretation instead of asking. A 503 while the assisted service is unavailable raises AssistedUnavailable; the SDKs retry it twice with backoff before surfacing it.

Example response (verified results)

{
  "status": "results",
  "queryUnderstanding": {
    "entities": ["retinoid", "photosensitivity"],
    "intent": "Determine whether an adverse effect is associated with a treatment",
    "aspects": ["mechanism of action", "clinical outcomes"],
    "filters": {}
  },
  "results": [
    {
      "id": "abc123",
      "text": "Topical retinoids increase skin sensitivity to UV light by thinning the stratum corneum...",
      "metadata": {
        "title": "Retinoid Dermatology Review"
      },
      "collection": null,
      "doiUrl": "https://doi.org/10.1234/example",
      "section": "discussion",
      "relevance": {
        "matchedTerms": ["retinoid", "photosensitivity"],
        "judgeScore": 0.91,
        "rationale": "Directly states the photosensitizing mechanism of topical retinoids."
      }
    }
  ],
  "clarification": null,
  "billing": {
    "chargedResults": 1,
    "tokensCharged": 612
  },
  "queryId": "qry_a1b2c3d4e5f6",
  "latencyMs": 3840,
  "iterationsRun": 2
}

Long queries

query takes up to 16,000 characters, so you can send a whole document, such as a patient case or chart note, instead of a question distilled from it. Other search endpoints still take 1,000.

A long query is read as a document. queryUnderstanding.caseSummary holds the summary results were judged against, and when the document raises several separate problems, queryUnderstanding.subQuestions lists them, up to four. Each sub-question is searched and verified on its own and gets its own result slots; each result's subQuestion says which one it answers. Assisted search returns at most one result per article.

A long query takes longer than a short one. The Python and Go SDKs wait up to 120 seconds for assisted search by default; if you set your own timeout, allow for it. See SDKs.

Clarification flow

When the query genuinely cannot be searched as written, the endpoint returns status: "clarification_needed" with a question instead of running the full search. Re-issue the request with the query augmented by the user's answer. Clarification requests are never billed.

{
  "status": "clarification_needed",
  "queryUnderstanding": {
    "entities": ["treatment"],
    "intent": "Unclear -- no specific condition or drug named",
    "aspects": [],
    "filters": {}
  },
  "results": [],
  "clarification": {
    "question": "Which treatment and condition are you asking about?",
    "reason": "The query is too underspecified to search usefully."
  },
  "billing": {
    "chargedResults": 0,
    "tokensCharged": 0
  },
  "queryId": "qry_f6e5d4c3b2a1",
  "latencyMs": 1120,
  "iterationsRun": 0
}

Filtering

The filters parameter accepts the same simple and structured-DSL forms as /search/query, and is applied to every internal search the agent runs. See Filtering for operators, indexed fields, and the filters that are rejected.

Was this page helpful?

On this page