> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.alfa.boosted.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.alfa.boosted.ai/_mcp/server.

# Custom documents

> Learn how to upload, manage, and use custom documents with Alfa agents

Custom documents allow you to analyze your own data using Alfa agents. This guide explains how to upload documents, list them, and reference them in your agent prompts.

## Uploading custom documents

You can upload your own documents (PDFs, Word files, Excel spreadsheets, etc.) to be processed and made available to your agents.

```python
import requests

BASE_URL = "https://alfa.boosted.ai/client"
API_KEY = "YOUR_API_KEY_HERE"

headers = {"x-api-key": API_KEY}  # No Content-Type for multipart uploads

def upload_custom_documents(file_paths, base_path=""):
    """
    Upload one or more custom documents for use with agents.
    
    Args:
        file_paths (list): List of paths to files you want to upload
        base_path (str, optional): Folder path where files should be stored
        
    Returns:
        dict: Response with uploaded document details
    """
    url = f"{BASE_URL}/custom-documents/add-documents"
    
    # Add optional base_path parameter if provided
    if base_path:
        url += f"?base_path={base_path}"
    
    # Prepare files for multipart upload
    files = []
    for path in file_paths:
        file_name = path.split("/")[-1]
        files.append(("files", (file_name, open(path, "rb"))))
    
    # Make the request without Content-Type header (it's set automatically)
    response = requests.post(
        url,
        headers={"x-api-key": API_KEY},
        files=files
    )
    
    # Close all file handles
    for _, (_, file_obj) in files:
        file_obj.close()
    
    if response.status_code == 202:
        return response.json()
    else:
        print(f"Error uploading documents: {response.status_code}, {response.text}")
        return None

# Example usage
file_paths = [
    "/path/to/quarterly_report.pdf",
    "/path/to/market_analysis.docx"
]

upload_result = upload_custom_documents(file_paths, "financial_reports")

if upload_result and upload_result.get("success"):
    print(f"Successfully uploaded {len(upload_result.get('added_listings', []))} documents")
    for doc in upload_result.get("added_listings", []):
        print(f"Document ID: {doc['file_id']}")
        print(f"Name: {doc['name']}")
        print(f"Path: {doc['full_path']}")
        print(f"Size: {doc['size']} bytes")
        print("---")
```

### Example: Uploading quarterly reports

#### Prepare your documents

Gather the documents you want to analyze (PDFs, Excel files, Word documents, etc.)

#### Upload the documents

```python
# Upload Q1 and Q2 reports to a designated folder
quarterly_reports = [
    "Q1_2023_Financials.pdf",
    "Q2_2023_Financials.pdf"
]

result = upload_custom_documents(quarterly_reports, "quarterly_reports/2023")

# Store document IDs for later use
document_ids = {}
if result and result.get("success"):
    for doc in result.get("added_listings", []):
        document_ids[doc["name"]] = doc["file_id"]
        print(f"Uploaded: {doc['name']} (ID: {doc['file_id']})")
```

> **Tip**
>
> For large documents, the upload process may take some time as the system processes and indexes the content for searching.

## Listing custom documents

To view all custom documents that you've uploaded:

```python
def list_custom_documents():
    """
    List all custom documents in your workspace.
    
    Returns:
        list: List of document objects with their details
    """
    url = f"{BASE_URL}/custom-documents"
    
    response = requests.get(url, headers=headers)
    
    if response.status_code == 200:
        data = response.json()
        return data.get("documents", [])
    else:
        print(f"Error listing documents: {response.status_code}, {response.text}")
        return []

# Get and display all custom documents
documents = list_custom_documents()

print(f"Found {len(documents)} custom documents:")
for doc in documents:
    print(f"ID: {doc['file_id']}")
    print(f"Name: {doc['name']}")
    print(f"Path: {doc['full_path']}")
    print(f"Type: {doc['type']}")
    print(f"Upload time: {doc['upload_time']}")
    print("---")
```

## Creating agents with custom documents

You can reference custom documents in your agent prompts using a special syntax. The agent will then be able to read and analyze these documents.

```python
def create_agent_with_document(prompt, document_id):
    """
    Create an agent that references a custom document.
    
    Args:
        prompt (str): The prompt with {doc} placeholder
        document_id (str): The ID of the custom document to reference
        
    Returns:
        str: The agent ID if successful, empty string otherwise
    """
    url = f"{BASE_URL}/agent/create-agent"
    
    # Create the request payload with the document reference
    payload = {
        "prompt": prompt,
        "args": {
            "doc": {
                "id": document_id,
                "type": "custom_document"
            }
        }
    }
    
    response = requests.post(url, headers=headers, json=payload)
    
    if response.status_code == 201:
        data = response.json()
        agent_id = data.get("agent_id")
        print(f"Agent created with ID: {agent_id}")
        return agent_id
    else:
        print(f"Error creating agent: {response.status_code}, {response.text}")
        return ""

# Example: Create an agent to analyze a quarterly report
document_id = "6fcc0ae7-809b-498c-b35b-4ced1114438b"  # ID from a previous upload
prompt = "Read the custom document {doc} and summarize its key points. Format the summary to be easy to read."

agent_id = create_agent_with_document(prompt, document_id)
```

> **Note**
>
> The `{doc}` placeholder in your prompt will be replaced with the actual document content when the agent processes it.

### Understanding the document reference format

The payload for creating an agent with a document reference follows this structure:

```json
{
  "prompt": "Read the custom document {doc} and summarize its key points. Format the summary to be easy to read.",
  "args": {
    "doc": {
      "id": "6fcc0ae7-809b-498c-b35b-4ced1114438b",
      "type": "custom_document"
    }
  }
}
```

* **prompt**: Your instruction with the `{doc}` placeholder
* **args**: A dictionary mapping placeholders to their values
* **doc**: The placeholder name that matches what you used in the prompt
* **id**: The unique ID of the document (obtained when uploading or listing documents)
* **type**: Must be "custom\_document" to indicate you're referencing a document