> ## Documentation Index
> Fetch the complete documentation index at: https://cortex-ad5578da.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# SDKs - Node and Python

> Official TypeScript/Node.js and Python SDKs so that you can integrate Cortex AI into your application with ease.

Get started with our fully-typed SDKs that provide a seamless developer experience for integrating Cortex AI into your applications.

## Installation

<Tabs>
  <Tab title="TypeScript / Node.js">
    ```bash theme={null}
    npm i @usecortex_ai/node
    ```
  </Tab>

  <Tab title="Python">
    ```bash theme={null}
    pip install usecortex-ai
    ```
  </Tab>
</Tabs>

## Client Setup

<Tabs>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { CortexAIClient } from "@usecortex_ai/node";

    const client = new CortexAIClient({
      token: process.env.CORTEX_API_KEY,
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import os
    from usecortex_ai import CortexAI, AsyncCortexAI

    api_key = os.environ["CORTEX_API_KEY"]

    # Sync client
    client = CortexAI(token=api_key)

    # Async client (for async/await usage)
    async_client = AsyncCortexAI(token=api_key)
    ```
  </Tab>
</Tabs>

<Warning>
  Always use environment variables for API keys. Never hardcode credentials in your source code.
</Warning>

<Info>
  **Python developers**: We provide both synchronous and asynchronous clients. Use `AsyncCortexAI` for async/await patterns and `CortexAI` for traditional synchronous operations.
</Info>

## SDK Method Structure & Type Safety

Our SDKs follow a predictable pattern that mirrors the API structure while providing full type safety:

<Note>
  **Method Mapping**: `client.<group>.<function_name>` mirrors `api.usecortex.ai/<group>/<function_name>`

  For example: `client.upload.uploadText()` corresponds to `POST /upload/upload_text`
</Note>

### Input and Output Type Matching

The SDKs provide exact type parity with the API specification:

* **Request Parameters**: Every field documented in the API reference (required, optional, types, validation rules) is reflected in the SDK method signatures
* **Response Objects**: Return types match the exact JSON schema documented for each endpoint
* **Error Types**: Exception structures mirror the error response formats from the API
* **Nested Objects**: Complex nested parameters and responses maintain their full structure and typing

**Language Conventions**:

* **TypeScript**: camelCase method names (`uploadText`, `getAll`) with full TypeScript interfaces
* **Python**: snake\_case method names (`upload_text`, `get_all`) with type hints and dataclasses

<Info>
  This means you can rely on your IDE's autocomplete and type checking. If a parameter is optional in the API docs, it's optional in the SDK. If a response contains a specific field, your IDE will know about it.
</Info>

## Getting Started: Complete Workflow

Let's walk through a complete example from creating a tenant to searching your data.

### Step 1: Create a Tenant

<Tabs>
  <Tab title="TypeScript">
    ```ts theme={null}
    async function createTenant() {
      const tenantCreationResponse = await client.user.createTenant({
        tenant_id: "my-company"
      });
      return tenantCreationResponse;
    }
    ```
  </Tab>

  <Tab title="Python (Sync)">
    ```python theme={null}
    def create_tenant():
        return client.user.create_tenant(tenant_id="my-company")
    ```
  </Tab>

  <Tab title="Python (Async)">
    ```python theme={null}
    async def create_tenant():
        return await async_client.user.create_tenant(tenant_id="my-company")
    ```
  </Tab>
</Tabs>

<Info>
  **For a more detailed explanation** of tenant creation, including metadata schemas, sub-tenant management, and advanced configuration options, refer to the [Create Tenant endpoint documentation](https://docs.usecortex.ai/api-reference/endpoint/create-tenant).
</Info>

### Step 2: Index Your Data

Now let's upload some content to make it searchable:

<Tabs>
  <Tab title="TypeScript">
    ```ts theme={null}
    // Upload text content
    async function uploadText() {
      const res = await client.upload.uploadText({
        tenant_id: "my-company",
        sub_tenant_id: "engineering",
        body: {
          content: "Our API rate limits are 1000 requests per minute for premium accounts.",
          file_id: "api-docs-rate-limits",
          tenant_metadata: { sub_tenant_id: "engineering" }
        }
      });
      return res;
    }

    // Upload a document file
    async function uploadFile() {
      const uploadResult = await client.upload.uploadDocument({
        file: fs.readFileSync("company-handbook.pdf"),
        tenant_id: "my-company",
        sub_tenant_id: "hr",
        file_id: "doc_q1_summary"
      });
      return uploadResult;
    }
    ```
  </Tab>

  <Tab title="Python (Sync)">
    ```python theme={null}
    # Upload text content
    def upload_text():
        return client.upload.upload_text(
            tenant_id="my-company-py-sync",
            sub_tenant_id="engineering",
            content="Our API rate limits are 1000 requests per minute for premium accounts.",
            file_id="api-docs-rate-limits",
            tenant_metadata={"sub_tenant_id": "engineering"}
        )

    # Upload document file
    def upload_file():
        with open("company-handbook.pdf", 'rb') as file_obj:
            file_data = ("company-handbook.pdf", file_obj)
            return client.upload.upload_document(
                tenant_id="my-company",
                file=file_data,
                file_id="company-handbook.pdf"
            )
    ```
  </Tab>

  <Tab title="Python (Async)">
    ```python theme={null}
    # Upload text content
    async def upload_text():
        return await async_client.upload.upload_text(
            tenant_id="my-company",
            sub_tenant_id="engineering",
            content="Our API rate limits are 1000 requests per minute for premium accounts.",
            file_id="api-docs-rate-limits",
            tenant_metadata={"sub_tenant_id": "engineering"}
        )

    # Upload document file
    async def upload_file():
        with open("company-handbook.pdf", 'rb') as file_obj:
            file_data = ("company-handbook.pdf", file_obj)
            return await async_client.upload.upload_document(
                tenant_id="my-company",
                file=file_data,
                file_id="company-handbook.pdf"
            )
    ```
  </Tab>
</Tabs>

<Info>
  **For a more detailed explanation** of document upload, including supported file formats, processing pipeline, metadata handling, and advanced configuration options, refer to the [Upload Document endpoint documentation](https://docs.usecortex.ai/api-reference/endpoint/upload-document).
</Info>

### Step 3: Search and Retrieve

<Tabs>
  <Tab title="TypeScript">
    ```ts theme={null}
    // Semantic search with retrieval
    const results = await client.search.retrieve({
      query: "What are the API rate limits?",
      tenant_id: "my-company",
      sub_tenant_id: "engineering",
      max_chunks: 10
    });

    // List all sources
    const allSources = await client.sources.getAll({
        tenant_id: "my-company",
        sub_tenant_id: "engineering"
    });

    // Get specific sources by ID
    const specificSources = await client.sources.getByIds({
      tenant_id: "my-company",
      sub_tenant_id: "engineering",
      source_ids: ["api-docs-rate-limits", "company-handbook"]
    });
    ```
  </Tab>

  <Tab title="Python (Sync)">
    ```python theme={null}
    # Semantic search with retrieval
    results = client.search.retrieve(
        query="What are the API rate limits?",
        tenant_id="my-company",
        sub_tenant_id="engineering",
        max_chunks=10
    )

    # List all sources
    all_sources = client.sources.get_all(
        tenant_id="my-company",
        sub_tenant_id="engineering",
    )

    # Get specific sources by ID
    specific_sources = client.sources.get_by_ids(
        tenant_id="my-company",
        sub_tenant_id="engineering",
        source_ids=["api-docs-rate-limits", "company-handbook"]
    )
    ```
  </Tab>

  <Tab title="Python (Async)">
    ```python theme={null}
    # Semantic search with retrieval
    results = await async_client.search.retrieve(
        query="What are the API rate limits?",
        tenant_id="my-company",
        sub_tenant_id="engineering",
        max_chunks=10
    )

    # List all sources
    all_sources = await async_client.sources.get_all(
        tenant_id="my-company",
        sub_tenant_id="engineering",
    )

    # Get specific sources by ID
    specific_sources = await async_client.sources.get_by_ids(
        tenant_id="my-company",
        sub_tenant_id="engineering",
        source_ids=["api-docs-rate-limits", "company-handbook"]
    )
    ```
  </Tab>
</Tabs>

<Info>
  **For a more detailed explanation** of search and retrieval, including query parameters, scoring mechanisms, result structure, and advanced search features, refer to the [Search endpoint documentation](https://docs.usecortex.ai/api-reference/endpoint/search).
</Info>

## Special Endpoints

### List Sources

<Info>
  The `/list` endpoints use special naming in the SDKs for better developer experience:

  * `/list/sources` → `sources.getAll()` / `sources.get_all()`
  * `/list/sources_by_id` → `sources.getByIds()` / `sources.get_by_ids()`
</Info>

This avoids conflicts with language keywords while providing intuitive method names.

## Type Safety

<Check>
  All SDKs are fully typed with TypeScript definitions and Python type hints. Your IDE will provide:

  * **Autocomplete** for all method names and parameters
  * **Type checking** for request and response objects
  * **Inline documentation** for each parameter
  * **Error prevention** through compile-time validation
</Check>

## Error Handling

Both SDKs throw exceptions for API errors. The error objects contain the same structure as documented in our [Error Responses](/api-reference/error-responses) section.

## The Complete Guide: Your IDE Knows Everything

<Check>
  **Everything you need is at your fingertips**: The examples and patterns shown above are sufficient for understanding our SDK. Your IDE's autocomplete is your most powerful tool.
</Check>

### The Universal CMD+Space Approach

Whether you're using **TypeScript**, **Python**, **VS Code**, **PyCharm**, or **any modern IDE**, the approach is identical:

1. **Type the method name** → See all available methods
2. **Open the parentheses** → See all required and optional parameters
3. **Press Cmd+Space (Mac) or Ctrl+Space (Windows/Linux)** → Get instant documentation

This works universally because our SDKs are fully typed with comprehensive documentation.

<Tabs>
  <Tab title="TypeScript">
    ```ts theme={null}
    // Start typing and your IDE will guide you through everything:
    client.search.  // - Shows: retrieve, fullTextSearch, qna

    client.search.retrieve({
      // - Cmd+Space here shows all parameters with documentation
      query: "your search query",
      tenant_id: "required-tenant-id",
      // Your IDE knows these are optional:
      max_chunks: 10,
      alpha: 0.7,
      personalise_search: true
    })
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # Identical experience - your IDE shows everything:
    client.search.  # - Shows: retrieve, full_text_search, qna

    client.search.retrieve(
        # - Ctrl+Space here shows all parameters with type hints
        query="your search query", 
        tenant_id="required-tenant-id",
        # Python IDE knows these are optional too:
        max_chunks=10,
        alpha=0.7,
        personalise_search=True
    )
    ```
  </Tab>
</Tabs>

### Why This Approach is Complete

Our SDKs are auto-generated from the same API specification that powers this documentation, ensuring:

* **100% Parameter Coverage**: Every field in the API docs appears in your IDE
* **Accurate Type Information**: Required vs optional, data types, validation rules
* **Inline Documentation**: Parameter descriptions appear as you type
* **Live Examples**: The @example annotations in our type definitions show real usage

<Info>
  **The examples you've seen above demonstrate every pattern you'll encounter.** Once you understand the tenant/sub-tenant concept and the resource organization (`client.upload.uploadText`, `client.search.retrieve`, etc.), your IDE will handle the rest.
</Info>

### Resource Organization

Our SDK follows a predictable structure that mirrors the API endpoints.

<Warning>
  **Don't overthink it**: The patterns shown in our complete workflow example cover 90% of use cases. For anything else, trust your IDE's autocomplete - it knows the exact structure and will guide you perfectly.
</Warning>

<Tip>
  **For in-depth explanations of each function**: While your IDE's autocomplete will guide you through the basic usage, refer to the next sections of this documentation for detailed explanations of every API endpoint, parameter options, and advanced use cases.
</Tip>
