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

# API Reference

> Complete API documentation for the Claro Python SDK

# API Reference

Complete reference documentation for all classes, methods, and exceptions in the Claro Python SDK.

## BaytClient

The main client class for interacting with the Claro API.

### Constructor

```python theme={null}
BaytClient(
    api_key: Optional[str] = None,
    base_url: str = "https://api.baytos.ai",
    max_retries: int = 3
)
```

**Parameters:**

| Name          | Type          | Default                   | Description                                                              |
| ------------- | ------------- | ------------------------- | ------------------------------------------------------------------------ |
| `api_key`     | `str \| None` | `None`                    | API key. If not provided, reads from `BAYT_API_KEY` environment variable |
| `base_url`    | `str`         | `"https://api.baytos.ai"` | Base URL for the API                                                     |
| `max_retries` | `int`         | `3`                       | Maximum number of retry attempts for rate-limited requests               |

**Raises:**

* `ValueError` - If no API key is provided and `BAYT_API_KEY` is not set
* `ValueError` - If API key format is invalid (must start with `sk_`)

**Example:**

```python theme={null}
from baytos.claro import BaytClient

# Using environment variable
client = BaytClient()

# With explicit API key
client = BaytClient(api_key="your_api_key")

# Custom configuration
client = BaytClient(
    api_key="your_api_key",
    base_url="https://staging-api.baytos.ai",
    max_retries=5
)
```

***

### get\_prompt()

Fetch a prompt by its package name.

```python theme={null}
get_prompt(package_name: str) -> Prompt
```

**Parameters:**

| Name           | Type  | Description                                            |
| -------------- | ----- | ------------------------------------------------------ |
| `package_name` | `str` | Package identifier (e.g., `"@workspace/my-prompt:v1"`) |

**Returns:**

* `Prompt` - Prompt object with content and metadata

**Raises:**

* `BaytValidationError` - If package name format is invalid
* `BaytAuthError` - If authentication fails (401, 403)
* `BaytNotFoundError` - If prompt is not found (404)
* `BaytRateLimitError` - If rate limit is exceeded after retries (429)
* `BaytAPIError` - For other API errors

**Example:**

```python theme={null}
prompt = client.get_prompt("@workspace/support:v1")
print(prompt.title)
print(prompt.generator)
```

***

### list\_prompts()

List prompts accessible to the authenticated user.

```python theme={null}
list_prompts(
    limit: int = 20,
    cursor: Optional[str] = None
) -> Dict[str, Any]
```

**Parameters:**

| Name     | Type          | Default | Description                                 |
| -------- | ------------- | ------- | ------------------------------------------- |
| `limit`  | `int`         | `20`    | Maximum number of prompts to return (1-100) |
| `cursor` | `str \| None` | `None`  | Pagination cursor from previous response    |

**Returns:**

Dictionary with the following keys:

* `prompts` (`List[Prompt]`) - List of Prompt objects
* `cursor` (`str`) - Cursor for next page
* `hasMore` (`bool`) - True if more pages available

**Raises:**

* `BaytValidationError` - If limit is not between 1 and 100
* `BaytAuthError` - If authentication fails
* `BaytRateLimitError` - If rate limit is exceeded
* `BaytAPIError` - For other API errors

**Example:**

```python theme={null}
# First page
result = client.list_prompts(limit=20)

for prompt in result['prompts']:
    print(prompt.title)

# Next page
if result['hasMore']:
    next_page = client.list_prompts(limit=20, cursor=result['cursor'])
```

***

### download\_context\_file()

Download a context file and return its content as bytes.

```python theme={null}
download_context_file(context_id: str) -> bytes
```

**Parameters:**

| Name         | Type  | Description                           |
| ------------ | ----- | ------------------------------------- |
| `context_id` | `str` | Context item ID from `prompt.context` |

**Returns:**

* `bytes` - File content

**Raises:**

* `BaytAuthError` - If authentication fails
* `BaytNotFoundError` - If context item is not found
* `BaytValidationError` - If context item is not a file type
* `BaytAPIError` - For other API errors

**Example:**

```python theme={null}
prompt = client.get_prompt("@workspace/research:v1")
files = prompt.get_file_contexts()

if files:
    content = client.download_context_file(files[0].id)
    with open(files[0].file_name, 'wb') as f:
        f.write(content)
```

***

### get\_context\_download\_url()

Get a signed download URL for a context file.

```python theme={null}
get_context_download_url(context_id: str) -> Dict[str, Any]
```

**Parameters:**

| Name         | Type  | Description                           |
| ------------ | ----- | ------------------------------------- |
| `context_id` | `str` | Context item ID from `prompt.context` |

**Returns:**

Dictionary with the following keys:

* `url` (`str`) - Signed download URL
* `expiresIn` (`int`) - Seconds until URL expires

**Raises:**

* `BaytAuthError` - If authentication fails
* `BaytNotFoundError` - If context item is not found
* `BaytValidationError` - If context item is not a file type
* `BaytAPIError` - For other API errors

**Example:**

```python theme={null}
files = prompt.get_file_contexts()

if files:
    url_info = client.get_context_download_url(files[0].id)
    print(f"Download URL: {url_info['url']}")
    print(f"Expires in: {url_info['expiresIn']} seconds")
```

***

## Prompt

Represents a Claro prompt with all its content and metadata.

### Properties

| Property       | Type                | Description                    |
| -------------- | ------------------- | ------------------------------ |
| `id`           | `str`               | Unique prompt identifier       |
| `title`        | `str`               | Human-readable title           |
| `description`  | `str \| None`       | Optional description           |
| `generator`    | `str`               | Main prompt content            |
| `content`      | `str`               | Alias for `generator`          |
| `system`       | `str`               | System prompt (may be empty)   |
| `critique`     | `str`               | Critique prompt (may be empty) |
| `namespace`    | `str`               | Workspace slug                 |
| `slug`         | `str`               | Prompt slug                    |
| `version`      | `str`               | Version string (e.g., "v1")    |
| `package_name` | `str`               | Full package name              |
| `is_draft`     | `bool`              | True if version is v0          |
| `category`     | `str`               | Prompt category                |
| `context`      | `List[ContextItem]` | Attached context items         |

### Methods

#### has\_context()

Check if the prompt has any context items.

```python theme={null}
has_context() -> bool
```

**Returns:**

* `bool` - True if prompt has context items

**Example:**

```python theme={null}
if prompt.has_context():
    print("Prompt has attachments")
```

***

#### has\_system\_prompt()

Check if the prompt has a system prompt.

```python theme={null}
has_system_prompt() -> bool
```

**Returns:**

* `bool` - True if prompt has a system prompt

***

#### has\_critique\_prompt()

Check if the prompt has a critique prompt.

```python theme={null}
has_critique_prompt() -> bool
```

**Returns:**

* `bool` - True if prompt has a critique prompt

***

#### get\_file\_contexts()

Get only file-type context items.

```python theme={null}
get_file_contexts() -> List[ContextItem]
```

**Returns:**

* `List[ContextItem]` - List of file context items

**Example:**

```python theme={null}
files = prompt.get_file_contexts()
for file in files:
    print(f"{file.file_name} ({file.file_size} bytes)")
```

***

#### get\_url\_contexts()

Get only URL-type context items.

```python theme={null}
get_url_contexts() -> List[ContextItem]
```

**Returns:**

* `List[ContextItem]` - List of URL context items

**Example:**

```python theme={null}
urls = prompt.get_url_contexts()
for url in urls:
    print(url.url)
```

***

#### extract\_variables()

Extract variables from prompt content with optional type hints.

```python theme={null}
extract_variables() -> List[Dict[str, str]]
```

**Returns:**

List of dictionaries with the following keys:

* `name` (`str`) - Variable name
* `type` (`str`, optional) - Variable type
* `description` (`str`, optional) - Variable description

**Example:**

```python theme={null}
variables = prompt.extract_variables()

for var in variables:
    print(f"Name: {var['name']}")
    if 'type' in var:
        print(f"Type: {var['type']}")
```

***

#### validate\_variables()

Validate provided variables against expected variables.

```python theme={null}
validate_variables(provided_variables: Dict[str, Any]) -> Dict[str, str]
```

**Parameters:**

| Name                 | Type             | Description               |
| -------------------- | ---------------- | ------------------------- |
| `provided_variables` | `Dict[str, Any]` | Variable names and values |

**Returns:**

* `Dict[str, str]` - Validation errors (empty if all valid)

**Example:**

```python theme={null}
values = {
    'user_name': 'Alice',
    'count': 42
}

errors = prompt.validate_variables(values)

if errors:
    for field, message in errors.items():
        print(f"{field}: {message}")
```

***

#### to\_dict()

Get the full dictionary representation of the prompt.

```python theme={null}
to_dict() -> Dict[str, Any]
```

**Returns:**

* `Dict[str, Any]` - Dictionary representation

***

### Dictionary-Style Access

Prompts support dictionary-style access:

```python theme={null}
# Get field
title = prompt['title']

# Get with default
desc = prompt.get('description', 'No description')

# Check if field exists
if 'system' in prompt:
    print(prompt['system'])

# Get all keys
keys = prompt.keys()

# Get all values
values = prompt.values()

# Get all items
items = prompt.items()
```

***

## ContextItem

Represents a context item (file or URL) attached to a prompt.

### Properties

| Property         | Type              | Description                                     |
| ---------------- | ----------------- | ----------------------------------------------- |
| `id`             | `str`             | Unique context item identifier                  |
| `type`           | `"file" \| "url"` | Context item type                               |
| `label`          | `str \| None`     | Optional label                                  |
| `created_at`     | `int \| None`     | Unix timestamp when created                     |
| `file_name`      | `str \| None`     | File name (files only)                          |
| `file_size`      | `int \| None`     | File size in bytes (files only)                 |
| `mime_type`      | `str \| None`     | MIME type (files only)                          |
| `url`            | `str \| None`     | URL (URLs only)                                 |
| `url_fetched_at` | `int \| None`     | Unix timestamp when URL was fetched (URLs only) |

### Methods

#### is\_file()

Check if this context item is a file.

```python theme={null}
is_file() -> bool
```

**Returns:**

* `bool` - True if type is "file"

***

#### is\_url()

Check if this context item is a URL.

```python theme={null}
is_url() -> bool
```

**Returns:**

* `bool` - True if type is "url"

***

#### to\_dict()

Get the full dictionary representation of the context item.

```python theme={null}
to_dict() -> Dict[str, Any]
```

**Returns:**

* `Dict[str, Any]` - Dictionary representation

**Example:**

```python theme={null}
for item in prompt.context:
    if item.is_file():
        print(f"File: {item.file_name} ({item.file_size} bytes)")
    elif item.is_url():
        print(f"URL: {item.url}")
```

***

## Exceptions

All exceptions inherit from `BaytAPIError`.

### BaytAPIError

Base exception for all SDK errors.

```python theme={null}
class BaytAPIError(Exception)
```

**Usage:**

```python theme={null}
from baytos.claro import BaytAPIError

try:
    prompt = client.get_prompt("@workspace/test:v1")
except BaytAPIError as e:
    print(f"SDK error: {e}")
```

***

### BaytAuthError

Authentication or authorization error (HTTP 401, 403).

```python theme={null}
class BaytAuthError(BaytAPIError)
```

**Common causes:**

* Invalid API key
* Expired API key
* Insufficient permissions
* Workspace access denied

**Usage:**

```python theme={null}
from baytos.claro import BaytAuthError

try:
    prompt = client.get_prompt("@workspace/test:v1")
except BaytAuthError:
    print("Authentication failed - check your API key")
```

***

### BaytNotFoundError

Resource not found error (HTTP 404).

```python theme={null}
class BaytNotFoundError(BaytAPIError)
```

**Common causes:**

* Incorrect package name
* Wrong version number
* Prompt deleted
* No access to workspace

**Usage:**

```python theme={null}
from baytos.claro import BaytNotFoundError

try:
    prompt = client.get_prompt("@workspace/test:v1")
except BaytNotFoundError:
    print("Prompt not found")
```

***

### BaytRateLimitError

Rate limit exceeded error (HTTP 429).

```python theme={null}
class BaytRateLimitError(BaytAPIError)
```

Raised only after all automatic retries are exhausted.

**Usage:**

```python theme={null}
from baytos.claro import BaytRateLimitError
import time

try:
    prompt = client.get_prompt("@workspace/test:v1")
except BaytRateLimitError:
    print("Rate limited - waiting before retry")
    time.sleep(60)
```

***

### BaytValidationError

Invalid request parameters (HTTP 400).

```python theme={null}
class BaytValidationError(BaytAPIError)
```

**Common causes:**

* Invalid package name format
* Out of range parameters
* Missing required fields

**Usage:**

```python theme={null}
from baytos.claro import BaytValidationError

try:
    result = client.list_prompts(limit=200)  # Invalid
except BaytValidationError as e:
    print(f"Validation error: {e}")
```

***

## Type Hints

The SDK is fully typed. Import types for type checking:

```python theme={null}
from typing import Dict, List, Any, Optional
from baytos.claro import BaytClient, Prompt, ContextItem

def process_prompt(client: BaytClient, package_name: str) -> Prompt:
    """Fetch and process a prompt"""
    prompt: Prompt = client.get_prompt(package_name)

    files: List[ContextItem] = prompt.get_file_contexts()

    for file in files:
        content: bytes = client.download_context_file(file.id)
        # Process file...

    return prompt
```

## Complete Example

```python theme={null}
#!/usr/bin/env python3
"""
Complete API reference example showing all main features
"""

import os
from baytos.claro import (
    BaytClient,
    BaytAuthError,
    BaytNotFoundError,
    BaytAPIError
)

def main():
    # Initialize client
    client = BaytClient(
        api_key=os.getenv("BAYT_API_KEY"),
        max_retries=3
    )

    try:
        # Get a prompt
        prompt = client.get_prompt("@workspace/support:v1")

        # Access properties
        print(f"Title: {prompt.title}")
        print(f"Version: {prompt.version}")
        print(f"Package: {prompt.package_name}")

        # Content
        print(f"\nGenerator:\n{prompt.generator[:200]}...")

        if prompt.has_system_prompt():
            print(f"\nSystem:\n{prompt.system[:200]}...")

        # Variables
        variables = prompt.extract_variables()
        if variables:
            print(f"\nVariables: {len(variables)}")
            for var in variables:
                print(f"  - {var['name']}")

        # Context
        if prompt.has_context():
            files = prompt.get_file_contexts()
            urls = prompt.get_url_contexts()

            print(f"\nContext: {len(files)} files, {len(urls)} URLs")

            # Download first file
            if files:
                file = files[0]
                content = client.download_context_file(file.id)
                print(f"Downloaded: {file.file_name} ({len(content)} bytes)")

        # List prompts
        result = client.list_prompts(limit=10)
        print(f"\nTotal prompts: {len(result['prompts'])}")

    except BaytAuthError:
        print("Authentication failed")
    except BaytNotFoundError:
        print("Prompt not found")
    except BaytAPIError as e:
        print(f"API error: {e}")

if __name__ == "__main__":
    main()
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="play" href="/sdk/python/quickstart">
    Get started with the SDK
  </Card>

  <Card title="Working with Prompts" icon="sparkles" href="/sdk/python/prompts">
    Learn about prompts in detail
  </Card>

  <Card title="Error Handling" icon="shield" href="/sdk/python/error-handling">
    Handle errors gracefully
  </Card>

  <Card title="Advanced Features" icon="rocket" href="/sdk/python/advanced">
    Optimize performance
  </Card>
</CardGroup>
