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

# External API

> Complete guide to Shieldbase External API for headless AI integration

## Overview

The Shieldbase External API provides a comprehensive set of endpoints for integrating AI capabilities into your applications. This API supports:

* **Models Management** - List available AI models
* **File Upload & Indexing** - Upload documents for semantic search
* **Library Management** - Browse and manage uploaded files
* **Semantic Search** - Hybrid BM25 + vector search across your content
* **Chat Streaming** - Real-time AI conversations via SSE
* **Headless Agents** - Blocking agentic task execution

<Note>
  All endpoints are mounted at `/external-docs` and require API key authentication.
  Interactive documentation is available at `/external-docs/docs` (Scalar UI).
</Note>

***

## Authentication

All API endpoints (except `/external/keys/*`) require three headers:

```bash theme={null}
X-Client-ID: your-client-id
X-API-Key: your-api-key  
X-Secret: your-secret
```

### Getting API Keys

1. Login to your Shieldbase account at [https://app.sbai.cloud/](https://app.sbai.cloud/)
2. Navigate to **Settings → API**
3. Click **"Generate"** to create your API credentials
4. **Save them securely** - the API key is only shown once!

<Warning>
  Keep your API credentials secure. Never commit them to version control or expose them in client-side code.
</Warning>

***

## Base URLs

<CodeGroup>
  ```bash Production theme={null}
  https://api.shieldbase.ai
  ```

  ```bash Development theme={null}
  http://localhost:8000
  ```
</CodeGroup>

***

## Quick Start

### 1. Set Environment Variables

```bash theme={null}
export SBAI_CLIENT_ID="sbai_client_xxx"
export SBAI_API_KEY="sbai_sk_xxx"
export SBAI_SECRET="sbai_secret_xxx"
export SBAI_BASE_URL="https://api.shieldbase.ai"
```

### 2. Test Connection

```bash theme={null}
curl -X GET "${SBAI_BASE_URL}/external/models" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}"
```

***

## Endpoints

### Models

#### List Available Models

**GET /external/models**

Returns all AI models available in the system with real-time availability status.

**Example Request:**

```bash theme={null}
curl -X GET "${SBAI_BASE_URL}/external/models" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}"
```

**Example Response:**

```json theme={null}
{
  "success": true,
  "data": [
    {
      "id": "gpt-5.1",
      "name": "GPT-5.1",
      "image": "openai-logo.png",
      "group_name": "OpenAI",
      "is_available": true
    },
    {
      "id": "gemini-2.5-pro",
      "name": "Gemini 2.5 Pro",
      "image": "google-logo.png",
      "group_name": "Google",
      "is_available": true
    }
  ]
}
```

***

### Upload

#### Upload Files to Library

**POST /external/upload**

Upload files asynchronously. Files are queued for indexing and become searchable once processing completes.

**Supported file types:**\
`pdf`, `doc`, `docx`, `xls`, `xlsx`, `csv`, `json`, `txt`, `html`, `ppt`, `pptx`, `zip`, `md`, `sql`, `yml`, `yaml`, `png`, `jpg`, `jpeg`, `gif`, `webp`

**Max file size:** 1 GB per file

**Example Request:**

```bash theme={null}
curl -X POST "${SBAI_BASE_URL}/external/upload" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -F "files=@report.pdf" \
  -F "files=@data.csv" \
  -F "folder_paths=reports/2024"
```

**Example Response:**

```json theme={null}
{
  "message": "Uploaded content is being processed",
  "data": [
    {
      "id": "abc123",
      "file_name": "report.pdf",
      "state": "loading",
      "provider": "file"
    },
    {
      "id": "def456",
      "file_name": "data.csv",
      "state": "loading",
      "provider": "file"
    }
  ]
}
```

***

### Libraries

#### List Library Files

**GET /external/libraries**

Retrieve paginated list of library files with advanced filtering options.

**Query Parameters:**

| Parameter      | Type   | Default | Description                                       |
| -------------- | ------ | ------- | ------------------------------------------------- |
| `page`         | int    | 1       | Page number (starts at 1)                         |
| `page_size`    | int    | 40      | Items per page (max 100)                          |
| `search`       | string | -       | Search by file name or folder path                |
| `provider`     | string | -       | Filter by provider (e.g. `file`, `google_drive`)  |
| `folder_paths` | string | -       | Filter by folder path                             |
| `file_types`   | string | -       | Comma-separated file extensions (e.g. `pdf,docx`) |
| `sort_by`      | string | -       | Field to sort by (e.g. `created_at`, `file_name`) |
| `sort_order`   | string | desc    | Sort direction: `asc` or `desc`                   |

**Example Request:**

```bash theme={null}
curl -X GET "${SBAI_BASE_URL}/external/libraries?page=1&page_size=40&sort_order=desc" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}"
```

**Example Response:**

```json theme={null}
{
  "total_items": 120,
  "providers": { "file": 80, "google_drive": 40 },
  "page": 1,
  "page_size": 40,
  "total_pages": 3,
  "items": [
    {
      "id": "abc123",
      "file_name": "report.pdf",
      "provider": "file",
      "mime_type": "application/pdf",
      "state": "success",
      "download_link": "https://cdn.shieldbase.ai/...",
      "created_at": "2024-06-22T10:00:00",
      "folder_path": ["reports", "2024"],
      "is_shared": false
    }
  ]
}
```

***

### Search

#### Semantic + Keyword Search

**POST /external/search**

Combine keyword matching (BM25) with semantic similarity (vector search) for best results.

**Payload Fields:**

| Field                | Type      | Default      | Description                                        |
| -------------------- | --------- | ------------ | -------------------------------------------------- |
| `keyword` or `query` | string    | **required** | Search query                                       |
| `limit` or `top_k`   | int       | 20           | Max results (max 100)                              |
| `group_by_file`      | bool      | false        | Merge chunks from same file                        |
| `types`              | string\[] | -            | Filter by type: `file`, `workflow`, `conversation` |
| `use_bm25`           | bool      | true         | Enable BM25 keyword search                         |
| `use_vector`         | bool      | true         | Enable semantic vector search                      |
| `bm25_weight`        | float     | 0.7          | BM25 score weight (0–1)                            |
| `vector_weight`      | float     | 0.3          | Vector score weight (0–1)                          |
| `relative_threshold` | float     | 0.7          | Min score as % of top result                       |

**Example Request:**

```bash theme={null}
curl -X POST "${SBAI_BASE_URL}/external/search" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -H "Content-Type: application/json" \
  -d '{
    "keyword": "quarterly revenue",
    "limit": 40,
    "group_by_file": true
  }'
```

**Advanced Search Example:**

```bash theme={null}
curl -X POST "${SBAI_BASE_URL}/external/search" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "quarterly revenue report",
    "top_k": 20,
    "types": ["file", "workflow"],
    "use_bm25": true,
    "use_vector": true,
    "bm25_weight": 0.7,
    "vector_weight": 0.3,
    "relative_threshold": 0.7,
    "group_by_file": true
  }'
```

**Example Response:**

```json theme={null}
{
  "success": true,
  "results": [
    {
      "id": "local-user##report.pdf",
      "title": "Q1 Revenue Report 2024.pdf",
      "content": "The quarterly revenue increased by...",
      "type": "library",
      "provider": "file",
      "score": 0.95
    }
  ]
}
```

***

### Chat (Streaming)

#### Create New Conversation

**POST /external/conversations**

Create a new conversation and receive real-time AI responses via SSE streaming.

**Payload Fields:**

| Field                 | Type      | Default      | Description                                 |
| --------------------- | --------- | ------------ | ------------------------------------------- |
| `content`             | string    | **required** | The user message                            |
| `model`               | string    | gpt-5.1      | AI model ID (see `/external/models`)        |
| `document_ids`        | string\[] | -            | Library file IDs to include as context      |
| `file_ids`            | string\[] | -            | Uploaded file IDs (from `/external/upload`) |
| `user_timezone`       | string    | UTC          | IANA timezone (e.g. `Asia/Jakarta`)         |
| `quoted_text`         | string    | -            | Text to quote/reply to                      |
| `additional_metadata` | object    | -            | Extended options (see below)                |

**`additional_metadata` Options:**

| Field          | Type      | Default | Description                                  |
| -------------- | --------- | ------- | -------------------------------------------- |
| `web_search`   | bool      | true    | Enable web search                            |
| `think`        | bool      | false   | Extended thinking mode                       |
| `agentic_mode` | bool      | false   | Agentic multi-step mode                      |
| `agent_id`     | string    | -       | Specific agent ID                            |
| `preferences`  | object    | -       | `{language, output_style, tones, character}` |
| `side_by_side` | bool      | false   | Run two models in parallel                   |
| `models`       | string\[] | -       | `[modelA, modelB]` for side-by-side          |

**Example Request:**

```bash theme={null}
curl -N -X POST "${SBAI_BASE_URL}/external/conversations" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "What is machine learning?",
    "model": "gpt-5.1",
    "additional_metadata": {
      "web_search": true
    }
  }'
```

**SSE Event Types:**

| Event                  | Payload                               | Notes                                  |
| ---------------------- | ------------------------------------- | -------------------------------------- |
| `stream_meta`          | `{run_id, conversation_id}`           | First event; persist `conversation_id` |
| `conversation_created` | `{conversation_id}`                   | New-conversation endpoint only         |
| `message_start`        | `{message_id, user_message_id}`       | AI reply started                       |
| `content`              | `{content: "…chunk…"}`                | Stream text chunk                      |
| `thinking`             | `{content: "…"}`                      | Extended-thinking mode only            |
| `done`                 | `{conversation_id, message_id, …}`    | Stream complete                        |
| `error`                | `{content: "stream_error", error_id}` | Fatal error                            |

#### Continue Existing Conversation

**POST /external/conversations/{id}**

Send a follow-up message to an existing conversation and stream the AI reply.

**Example Request:**

```bash theme={null}
curl -N -X POST "${SBAI_BASE_URL}/external/conversations/{conversation_id}" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Can you explain that in more detail?",
    "model": "gpt-5.1"
  }'
```

<Note>
  Use the `conversation_id` from the `conversation_created` event to continue the thread.
</Note>

***

### Agents (Headless Execution)

#### Run Agentic Task

**POST /external/agents/run**

Headless agentic execution - perfect for automation, scripts, and webhooks.

**Payload Fields:**

| Field                 | Type      | Default      | Description                                 |
| --------------------- | --------- | ------------ | ------------------------------------------- |
| `prompt`              | string    | **required** | The task / instruction to execute           |
| `agent_id`            | string    | -            | Specific agent ID to use                    |
| `model`               | string    | -            | AI model override (see `/external/models`)  |
| `document_ids`        | string\[] | -            | Library file IDs to include as context      |
| `file_ids`            | string\[] | -            | Uploaded file IDs (from `/external/upload`) |
| `user_timezone`       | string    | UTC          | IANA timezone                               |
| `timeout_seconds`     | int       | 600          | Max wait time (max 1800)                    |
| `additional_metadata` | object    | -            | Extra options passed through to the model   |

**Example Request:**

```bash theme={null}
curl -X POST "${SBAI_BASE_URL}/external/agents/run" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Analyze the Q1 sales data and generate a summary report with charts",
    "document_ids": ["local-user##q1_sales.xlsx"],
    "timeout_seconds": 300
  }'
```

**Example Response:**

```json theme={null}
{
  "conversation_id": "8e5245f6-...",
  "output": "## Q1 Sales Summary\n\nKey highlights: ...",
  "generated_files": [
    {
      "url": "https://cdn.shieldbase.ai/...",
      "filename": "q1_summary.pdf",
      "size": 204800
    }
  ],
  "success": true,
  "error": null
}
```

**When to use `/external/agents/run` vs `/external/conversations`:**

|                   | `/external/agents/run`                 | `/external/conversations`                   |
| ----------------- | -------------------------------------- | ------------------------------------------- |
| Response          | Blocking JSON                          | SSE stream                                  |
| Best for          | Headless automation, scripts, webhooks | Real-time UI, progress display              |
| `generated_files` | Included directly in response          | Requires fetching conversation after `done` |

<Warning>
  **Timeout:** Default 10 minutes, max 30 minutes. Returns HTTP 408 if exceeded.
</Warning>

***

## Privacy & Data Redaction

### Redacting Sensitive Information

To protect sensitive data in prompts and responses, you can enable automatic redaction of:

* **PII (Personally Identifiable Information):** Names, emails, phone numbers, addresses
* **Financial Data:** Credit card numbers, bank account numbers
* **Credentials:** API keys, passwords, tokens
* **Custom Patterns:** Define your own regex patterns for domain-specific data

**Example configuration (backend):**

```python theme={null}
# backend/sbai/config.py or environment variables
ENABLE_PII_REDACTION = True
REDACTION_PATTERNS = {
    "email": r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b",
    "phone": r"\b\d{3}[-.]?\d{3}[-.]?\d{4}\b",
    "credit_card": r"\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b",
}
```

**Example usage in API request:**

```bash theme={null}
curl -X POST "${SBAI_BASE_URL}/external/conversations" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Process this customer data: John Doe, john@example.com, 555-1234",
    "model": "gpt-5.1",
    "additional_metadata": {
      "redact_pii": true
    }
  }'
```

The system will automatically redact sensitive information:

* Input: `"John Doe, john@example.com, 555-1234"`
* Processed: `"[REDACTED_NAME], [REDACTED_EMAIL], [REDACTED_PHONE]"`

***

## Rate Limits

<Info>
  **100 requests per minute** per API key
</Info>

Rate limit headers are included in responses:

* `X-RateLimit-Limit`: Total requests allowed per minute
* `X-RateLimit-Remaining`: Requests remaining in current window
* `X-RateLimit-Reset`: Unix timestamp when the limit resets

***

## Error Handling

All errors follow this format:

```json theme={null}
{
  "error": "error_code",
  "message": "Human readable error message"
}
```

**Common error codes:**

| Code                  | HTTP Status | Description             |
| --------------------- | ----------- | ----------------------- |
| `invalid_credentials` | 403         | Invalid API credentials |
| `invalid_model`       | 400         | Model not found         |
| `not_found`           | 404         | Resource not found      |
| `rate_limit_exceeded` | 429         | Too many requests       |
| `internal_error`      | 500         | Server error            |

***

## Testing Script

Save this as `test-external-api.sh`:

```bash theme={null}
#!/bin/bash

# Configuration
export SBAI_CLIENT_ID="sbai_client_xxx"
export SBAI_API_KEY="sbai_sk_xxx"
export SBAI_SECRET="sbai_secret_xxx"
export SBAI_BASE_URL="http://localhost:8000"

echo "🧪 Testing Shieldbase External API"
echo "=================================="

# Test 1: List Models
echo -e "\n1️⃣  Testing GET /external/models"
curl -s -X GET "${SBAI_BASE_URL}/external/models" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" | jq '.'

# Test 2: Upload File
echo -e "\n2️⃣  Testing POST /external/upload"
echo "Sample content for testing" > test-file.txt
curl -s -X POST "${SBAI_BASE_URL}/external/upload" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -F "files=@test-file.txt" \
  -F "folder_paths=test" | jq '.'
rm test-file.txt

# Test 3: List Libraries
echo -e "\n3️⃣  Testing GET /external/libraries"
curl -s -X GET "${SBAI_BASE_URL}/external/libraries?page=1&page_size=10" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" | jq '.'

# Test 4: Search
echo -e "\n4️⃣  Testing POST /external/search"
curl -s -X POST "${SBAI_BASE_URL}/external/search" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -H "Content-Type: application/json" \
  -d '{
    "keyword": "test",
    "limit": 10,
    "group_by_file": true
  }' | jq '.'

# Test 5: Chat (New Conversation)
echo -e "\n5️⃣  Testing POST /external/conversations (SSE stream)"
curl -N -X POST "${SBAI_BASE_URL}/external/conversations" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Hello! What is 2+2?",
    "model": "gpt-5.1"
  }' 2>&1 | head -n 20

# Test 6: Agents Run
echo -e "\n6️⃣  Testing POST /external/agents/run"
curl -s -X POST "${SBAI_BASE_URL}/external/agents/run" \
  -H "X-Client-ID: ${SBAI_CLIENT_ID}" \
  -H "X-API-Key: ${SBAI_API_KEY}" \
  -H "X-Secret: ${SBAI_SECRET}" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Calculate 5 + 3 and explain the result",
    "timeout_seconds": 60
  }' | jq '.'

echo -e "\n✅ All tests completed!"
```

Make it executable and run:

```bash theme={null}
chmod +x test-external-api.sh
./test-external-api.sh
```

***

## Additional Resources

* **[Interactive API Docs](/external-docs/docs)** - Explore the API with Scalar UI (dark mode, modern layout)
* **[OpenAPI Spec](/external-docs/openapi.json)** - Download the OpenAPI specification
* **[Support](mailto:support@shieldbase.ai)** - Contact our support team
* **[Status Page](https://status.shieldbase.ai)** - Check API status and uptime

***

## Coming Soon

* Python SDK
* JavaScript/TypeScript SDK
* Go SDK
* Webhook support for async notifications
* GraphQL endpoint
* Batch processing API
