> ## Documentation Index
> Fetch the complete documentation index at: https://docs.soarlabs.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Perform a Retrieval

> Fetch ranked context passages without generating an LLM answer.

## Overview

Retrieval-only requests return ranked context passages without LLM generation. Use this endpoint when you want to:

* Build your own prompting layer
* Inspect retrieval quality before LLM generation
* Implement custom response logic
* Reduce costs (no LLM API calls)

<Info>
  **Performance Benefit**: Retrieval-only requests are typically 5-10x faster than full query requests since they skip LLM generation.
</Info>

<Note>
  Events are recorded with `is_query=false` in the history, distinguishing them from full query executions.
</Note>

## Authentication

Requires valid JWT token or session authentication. You must own the target corpus.

## Request Body

<ParamField body="corpora" type="UUID" required>
  ID of the corpus to search. Must be fully indexed (`indexing_status: "IND"`).
</ParamField>

<ParamField body="user_query" type="string" required>
  Natural-language query used to fetch relevant context passages.

  **How retrieval works:**

  1. Query is analyzed for intent and complexity
  2. Multiple retrieval strategies run in parallel (semantic, keyword, hybrid)
  3. Results are reranked using ensemble methods
  4. Top-ranked chunks are returned with metadata

  **Query tips:**

  * Be specific for better precision
  * Use natural language (not keyword stuffing)
  * Phrase as questions for best results
  * Context is king - include relevant details
</ParamField>

## Example request

```bash theme={null}
curl -X POST https://{your-host}/api/retrieve/ \
  -H "Authorization: Bearer $SOAR_LABS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "corpora": "8d0f0a5d-4b5e-4c09-9db6-0e9d2aa8a9fd",
    "user_query": "Summarize onboarding prerequisites"
  }'
```

## Response

<ResponseField name="id" type="UUID">
  Unique identifier for this retrieval execution.
</ResponseField>

<ResponseField name="created_at" type="timestamp">
  ISO 8601 timestamp when retrieval was executed.
</ResponseField>

<ResponseField name="updated_at" type="timestamp">
  Last update timestamp (usually same as `created_at`).
</ResponseField>

<ResponseField name="corpora" type="UUID">
  ID of the corpus that was searched.
</ResponseField>

<ResponseField name="user_query" type="string">
  The query used for retrieval.
</ResponseField>

<ResponseField name="retrieval_time" type="float">
  Total execution time in milliseconds (includes search, ranking, and reranking).
</ResponseField>

<ResponseField name="retrieve_data" type="object">
  Structured retrieval results with ranked context passages.

  <Expandable title="result" defaultOpen>
    <ResponseField name="result" type="array">
      Array of retrieved chunks, ranked by relevance.

      <Expandable title="chunk properties">
        <ResponseField name="text" type="string">
          The actual content of the retrieved chunk.
        </ResponseField>

        <ResponseField name="metadata" type="object">
          Context metadata about the source.

          <Expandable title="metadata fields">
            <ResponseField name="document_title" type="string">
              Title of the source document.
            </ResponseField>

            <ResponseField name="section_summary" type="string">
              AI-generated summary of the containing section.
            </ResponseField>

            <ResponseField name="corpora" type="string">
              Corpus name (normalized format).
            </ResponseField>

            Additional metadata may include:

            * `excerpt_keywords` - Extracted keywords
            * `questions` - Sample questions the chunk can answer
            * `file_name` - Original filename (if from file)
            * `url` - Source URL (if from web)
          </Expandable>
        </ResponseField>

        <ResponseField name="score" type="float">
          Relevance score (0-1) after ensemble reranking. Higher is more relevant.
        </ResponseField>

        <ResponseField name="rank" type="integer">
          Zero-indexed position in ranked results (0 = most relevant).
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## Example Response

```json theme={null}
{
  "id": "11c7d0d5-f3bd-4dfb-9157-bf51c38e62fd",
  "created_at": "2024-09-01T13:29:06.102Z",
  "updated_at": "2024-09-01T13:29:06.102Z",
  "corpora": "8d0f0a5d-4b5e-4c09-9db6-0e9d2aa8a9fd",
  "user_query": "Summarize onboarding prerequisites",
  "retrieval_time": 311.8,
  "retrieve_data": {
    "result": [
      {
        "text": "Before onboarding, ensure SSO is configured...",
        "metadata": {
          "document_title": "Onboarding checklist",
          "section_summary": "Environment prerequisites",
          "corpora": "support_playbooks"
        },
        "score": 0.77,
        "rank": 0
      }
    ]
  }
}
```

## Client examples

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import os
    import requests

    BASE_URL = "https://your-soar-instance.com"
    TOKEN = os.environ["SOAR_LABS_TOKEN"]
    CORPUS_ID = "8d0f0a5d-4b5e-4c09-9db6-0e9d2aa8a9fd"

    payload = {
        "corpora": CORPUS_ID,
        "user_query": "Summarize onboarding prerequisites",
    }

    response = requests.post(
        f"{BASE_URL}/api/retrieve/",
        headers={
            "Authorization": f"Bearer {TOKEN}",
            "Content-Type": "application/json",
        },
        json=payload,
        timeout=60,
    )
    response.raise_for_status()
    retrieval = response.json()
    ```
  </Tab>

  <Tab title="TypeScript / JavaScript">
    ```ts theme={null}
    const BASE_URL = "https://your-soar-instance.com";
    const token = process.env.SOAR_LABS_TOKEN!;

    async function retrieveContext(corpusId: string, userQuery: string) {
      const response = await fetch(`${BASE_URL}/api/retrieve/`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({ corpora: corpusId, user_query: userQuery }),
      });

      if (!response.ok) {
        throw new Error(`Retrieve failed: ${response.status}`);
      }

      return response.json();
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    import java.net.URI;
    import java.net.http.HttpClient;
    import java.net.http.HttpRequest;
    import java.net.http.HttpResponse;

    var BASE_URL = "https://your-soar-instance.com";
    var token = System.getenv("SOAR_LABS_TOKEN");
    var corpusId = "8d0f0a5d-4b5e-4c09-9db6-0e9d2aa8a9fd";

    var json = "{" +
        "\"corpora\":\"" + corpusId + "\"," +
        "\"user_query\":\"Summarize onboarding prerequisites\"" +
    "}";

    var request = HttpRequest.newBuilder(URI.create(BASE_URL + "/api/retrieve/"))
        .header("Authorization", "Bearer " + token)
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(json))
        .build();

    var response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());

    if (response.statusCode() >= 400) {
        throw new RuntimeException("Retrieve failed: " + response.statusCode());
    }

    var body = response.body();
    ```
  </Tab>
</Tabs>

## Use Cases

<AccordionGroup>
  <Accordion title="Custom LLM Integration" icon="microchip">
    Retrieve context and use your own LLM:

    ```python theme={null}
    # Get relevant chunks
    retrieval = client.post("/api/retrieve/", json={
        "corpora": corpus_id,
        "user_query": "How do I configure SSL?"
    })

    # Extract context
    context = "\n\n".join([
        chunk["text"]
        for chunk in retrieval["retrieve_data"]["result"]
    ])

    # Use your own LLM
    response = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[
            {"role": "system", "content": "Answer using this context: " + context},
            {"role": "user", "content": retrieval["user_query"]}
        ]
    )
    ```
  </Accordion>

  <Accordion title="Quality Assessment" icon="magnifying-glass-chart">
    Test retrieval quality before full deployment:

    1. Submit test queries
    2. Inspect returned chunks and scores
    3. Verify relevance of top results
    4. Adjust corpus content if needed
    5. Run A/B tests with different configurations
  </Accordion>

  <Accordion title="Citation-Only Responses" icon="quote-left">
    Return citations without LLM generation:

    ```json theme={null}
    {
      "answer": "See relevant documentation:",
      "sources": [
        {
          "title": "Onboarding checklist",
          "excerpt": "Before onboarding, ensure SSO is configured...",
          "url": "/docs/onboarding"
        }
      ]
    }
    ```
  </Accordion>

  <Accordion title="Cost Optimization" icon="dollar-sign">
    Reduce API costs by:

    * Caching retrieval results
    * Generating answers client-side
    * Using cheaper LLMs with retrieved context
    * Implementing custom prompt logic

    **Savings**: \~80-90% reduction in LLM API costs for high-volume use cases.
  </Accordion>
</AccordionGroup>

## Retrieval History

<AccordionGroup>
  <Accordion title="List Retrieval Events" icon="clock-rotate-left">
    View past retrievals for a corpus:

    ```bash theme={null}
    curl -X GET "https://{your-host}/api/retrieve/?corpora_id={corpus-uuid}" \
      -H "Authorization: Bearer $SOAR_LABS_TOKEN"
    ```

    **Query parameters:**

    * `order_by` - Sort by `created_at` or `-created_at` (newest first, default)
    * `start_date` - Filter after this date (UTC, `YYYY-MM-DD` format)
    * `end_date` - Filter before this date (UTC, `YYYY-MM-DD` format)
    * `page` - Page number (default: 1)
    * `page_size` - Results per page (default: 20)
  </Accordion>

  <Accordion title="Delete Retrieval Records" icon="trash">
    Remove individual retrievals from history:

    ```bash theme={null}
    curl -X DELETE "https://{your-host}/api/retrieve/{retrieval-id}/" \
      -H "Authorization: Bearer $SOAR_LABS_TOKEN"
    ```
  </Accordion>
</AccordionGroup>

<Note>
  Retrieval entries are immutable snapshots. `PUT` and `PATCH` operations return `403 Forbidden`.
</Note>

## Error Handling

<AccordionGroup>
  <Accordion title="400 Bad Request" icon="circle-exclamation">
    **Causes:**

    * Missing `corpora` or `user_query` fields
    * Corpus is not indexed (`indexing_status` != `IND`)
    * Invalid UUID format

    **Resolution:**

    * Verify all required fields are present
    * Check corpus indexing status: `GET /api/corpora/{id}/`
    * Ensure corpus has indexed resources
  </Accordion>

  <Accordion title="404 Not Found" icon="question-circle">
    **Causes:**

    * Corpus doesn't exist
    * You don't own the corpus

    **Resolution:**

    * Verify corpus ID is correct
    * List your corpora: `GET /api/corpora/`
    * Check authentication credentials
  </Accordion>

  <Accordion title="500 Internal Server Error" icon="server">
    **Causes:**

    * Vector database connectivity issues
    * Retrieval pipeline errors
    * Reranker service failures

    **Resolution:**

    * Retry with exponential backoff
    * Check system health: `GET /sys-health`
    * Contact support if errors persist
  </Accordion>
</AccordionGroup>

## Performance Tips

<Tip>
  **Typical Response Times:**

  * Small corpora (\< 1000 chunks): 100-300ms
  * Medium corpora (1000-10000 chunks): 300-800ms
  * Large corpora (10000+ chunks): 800-2000ms
</Tip>

<AccordionGroup>
  <Accordion title="Optimize Retrieval Speed" icon="gauge-high">
    Improve performance with these strategies:

    1. **Corpus size** - Smaller, focused corpora retrieve faster
    2. **Query specificity** - Precise queries require less computation
    3. **Result limits** - Request fewer chunks if you don't need many
    4. **Caching** - Cache frequent queries on your end
    5. **Parallel requests** - Run multiple retrievals concurrently
  </Accordion>

  <Accordion title="Understanding Scores" icon="ranking-star">
    Relevance scores explained:

    * **0.9-1.0**: Highly relevant, exact match or very close
    * **0.7-0.9**: Relevant, good semantic match
    * **0.5-0.7**: Moderately relevant, partial match
    * **\< 0.5**: Low relevance, consider filtering out

    **Tip**: Set a minimum score threshold (e.g., 0.6) to filter low-quality results.
  </Accordion>
</AccordionGroup>


## OpenAPI

````yaml POST /api/retrieve/
openapi: 3.0.3
info:
  title: Soar Labs API - Insider Dev preview
  version: 0.1.0
  description: <b>Soar Labs Advanced RAG platform</b>
servers: []
security: []
paths:
  /api/retrieve/:
    post:
      tags:
        - Query History
      description: >-
        An API set that provides `retrieve` ONLY functionality.

        Query parameters:

        - corpora_id: The corpora_id to filter by

        - order_by: The order_by field to sort by (default: -created_at),
        accepted values: [created_at, -created_at]

        - start_date: The start date to filter by

        - end_date: The end date to filter by


        Allowed actions: [GET, DELETE, POST, OPTIONS]

        Disallowed actions: [PUT, PATCH]
      operationId: api_retrieve_create
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Retrieve'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/Retrieve'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Retrieve'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Retrieve'
          description: ''
      security:
        - jwtHeaderAuth: []
        - jwtCookieAuth: []
        - cookieAuth: []
        - basicAuth: []
components:
  schemas:
    Retrieve:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: The date and time the organization was created
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Last updated time
        user_query:
          type: string
          description: The query that was executed to get the results
        retrieval_time:
          type: number
          format: double
          readOnly: true
          nullable: true
          description: Time taken to process and retrieve data (in milliseconds)
        retrieve_data:
          readOnly: true
          nullable: true
          description: Metadata retrieved from the query
        corpora:
          type: string
          format: uuid
          nullable: true
          description: The corpora to which the query belongs
      required:
        - corpora
        - created_at
        - id
        - retrieval_time
        - retrieve_data
        - updated_at
        - user_query
  securitySchemes:
    jwtHeaderAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    jwtCookieAuth:
      type: apiKey
      in: cookie
      name: soar-app-auth
    cookieAuth:
      type: apiKey
      in: cookie
      name: sessionid
    basicAuth:
      type: http
      scheme: basic

````