We can't find the internet

Attempting to reconnect

Something went wrong!

Hang in there while we get back on track

[B\\
BotSee API](/content/docs/index.html)

# Quick Start (Claude Code Plugin)

Install the BotSee plugin for the fastest setup. Choose the method that matches your platform.

## Method 1: Claude Code Plugin (recommended)

```
/install-plugin https://github.com/RivalSee/botsee
```

Auto-updates to latest version. All `/botsee` commands are available immediately.

## Method 2: Direct Python CLI (Codex, Cursor, any platform)

```
git clone https://github.com/RivalSee/botsee-skill.git
python3 /path/to/botsee-skill/skills/botsee/botsee.py [command] [args]
```

Works on any platform with Python 3. No dependencies beyond stdlib. Update manually with `git pull`.

## Method 3: Codex / OpenAI agents

Add the script path to your agent's tool configuration. The CLI accepts all commands as positional args:

```
python3 /path/to/botsee-skill/skills/botsee/botsee.py signup --api-key YOUR_KEY
python3 /path/to/botsee-skill/skills/botsee/botsee.py create-site https://example.com
python3 /path/to/botsee-skill/skills/botsee/botsee.py analyze
```

All output is stdout (human-readable for workflow commands, JSON for CRUD commands). Exit code 1 on errors with messages to stderr.

## Commands

- `/botsee` \- Status and help
- `/botsee signup [--email EMAIL] [--name NAME] [--company COMPANY]` \- Start signup flow (all params optional)
- `/botsee create-site <domain> [--types N] [--personas P] [--questions Q]` \- Create site and generate structure
- `/botsee analyze` \- Run competitive analysis (~660 credits)
- `/botsee content` \- Generate blog post from analysis (15 credits)
- `/botsee config-show` \- Display current workspace configuration
- `/botsee status` \- Show balance and active site

## Example Workflow

Here are 6 sequential prompts for the workflow:

**Prompt 1: Install & Signup**

```
Install the BotSee Plugin: /install-plugin https://github.com/RivalSee/botsee. Then sign me up for BotSee using my email user@example.com so I can analyze how AI search engines see my product.
```

**Prompt 2: Create Site with Structure**

```
Create a BotSee site for https://myproduct.com with 1 customer type, 2 personas, and 5 questions per persona. Set it up so I can run a competitive analysis.
```

**Prompt 3: Analyze & Show Competitors**

```
Run a competitive analysis and show me the full list of competitors mentioned by AI search engines, including their mention percentages and what contexts they appear in.
```

**Prompt 4: Show Keywords**

```
Show me all the keywords that AI search engines associate with my product category, sorted by frequency.
```

**Prompt 5: Generate Blog Titles**

```
Based on those keywords and competitor insights, give me 5 compelling blog post titles that would help us compete better in AI search results.
```

**Prompt 6: Write Blog Post**

```
Write a full blog post for the first title, including our competitive position, opportunities, threats, and recommended actions based on the analysis data.
```

The plugin handles authentication, API calls, and result formatting automatically.

# All Plugin Commands

Complete reference for all BotSee plugin commands. Shown as \`/botsee <command>\` (Claude Code plugin). Direct CLI equivalent: \`python3 path/to/botsee.py <command>\`.

## Account & Status

```
/botsee status              # Show balance, active site, key suffix
/botsee account             # Show email, company, site count
/botsee signup [--email] [--name] [--company] [--api-key KEY]
/botsee update              # Update skill to latest version
```

## Workflow Commands

```
/botsee create-site <domain> [--types T --personas P --questions Q]
/botsee config-show         # Display workspace configuration
/botsee analyze [site_uuid] # Run competitive analysis
/botsee content             # Generate blog post from latest analysis
/ai-visibility-audit <url>  # Full audit: setup → analyze → gap table → copy changes
```

## Sites Management

```
/botsee list-sites
/botsee get-site [uuid]
/botsee archive-site <uuid>
/botsee use-site <uuid>     # Switch active site
```

## Customer Types Management

```
/botsee list-types [--site-uuid UUID]
/botsee get-type <uuid>
/botsee create-type <site_uuid> --name "..." [--description "..."]
/botsee generate-types [--site-uuid UUID --count N]
/botsee update-type <uuid> [--name "..." --description "..."]
/botsee archive-type <uuid>
```

## Personas Management

```
/botsee list-personas [type_uuid]
/botsee get-persona <uuid>
/botsee create-persona <type_uuid> --name "..." [--icp-persona "..."]
/botsee generate-personas <type_uuid> [--count N]
/botsee update-persona <uuid> [--name "..." --icp-persona "..."]
/botsee archive-persona <uuid>
```

## Questions Management

```
/botsee list-questions [persona_uuid]
/botsee get-question <uuid>
/botsee create-question <persona_uuid> --text "..."
/botsee generate-questions <persona_uuid> [--count N]
/botsee update-question <uuid> --text "..."
/botsee delete-question <uuid>
```

## Results Viewing

```
/botsee results-competitors <analysis_uuid>
/botsee results-keywords <analysis_uuid>
/botsee results-sources <analysis_uuid>
/botsee results-responses <analysis_uuid>
```

# AI Visibility Audit

A complete workflow that audits how AI search engines see a site, identifies terminology gaps, and produces surgical landing page copy changes. Available as a skill (/ai-visibility-audit) or as manual steps.

## Quick Start

```
/ai-visibility-audit https://example.com
```

The skill creates a BotSee site, generates customer types/personas/questions, runs analysis across ChatGPT, Claude, Perplexity, and Gemini, then:

1\. Pulls keyword and source opportunities
2\. Fetches your live homepage and compares terminology
3\. Produces a gap table of missing terms with evidence
4\. Proposes surgical copy changes (text only, no layout changes)
5\. Compiles, commits, and pushes when approved

## Overview

The AI Visibility Audit combines BotSee analysis with homepage comparison to find and close terminology gaps — terms AI engines use that your site doesn't.

**Cost:** ~735 credits (~$7.35) \| **Time:** ~25 minutes

## Workflow

### Step 1: Create site and generate structure

```
/botsee create-site https://example.com
```

Creates a site with 2 customer types, 4 personas, and 20 auto-generated questions (~75 credits).

### Step 2: Review and replace questions

Auto-generated questions are often too generic. Replace them with questions matching how real customers ask AI engines.

```
/botsee list-questions <persona_uuid>
/botsee delete-question <question_uuid>
/botsee create-question <persona_uuid> "What tools help with AI search optimization?"
```

### Step 3: Run analysis

```
/botsee analyze
```

Queries ChatGPT, Claude, Perplexity, and Gemini in parallel (~660 credits). Capture the analysis UUID from output.

### Step 4: Pull opportunities

```
/botsee results-keyword-opportunities <analysis_uuid>
/botsee results-source-opportunities <analysis_uuid>
```

- **Keyword opportunities** — queries where your brand is missing or ranks poorly
- **Source opportunities** — sites AI cites when it doesn't mention you (link-building targets)

### Step 5: Compare against live homepage

Fetch the live homepage and compare its language against what AI engines searched for. Look for:

- Terms AI uses that the page doesn't (industry acronyms, category names)
- Phrases competitors rank for that the site doesn't use
- Audience segments not addressed
- Missing integration or feature keywords

Produces a gap table:

| Missing Term | Evidence |
| --- | --- |
| "share of voice" | 8 search queries mentioning it |
| "REST API" | Competitor X ranks for this |

### Step 6: Make surgical copy changes

Edit only text strings — no layout changes. Target: page title, meta description, hero headline, feature descriptions, section headers, and integration lists.

### Step 7: Verify and ship

Compile to check for syntax errors, then commit and push.

## Skill Shortcut

Install the BotSee plugin, then run `/ai-visibility-audit` to execute this entire workflow automatically. See \[Recipes\](/recipes#ai-visibility-audit) for a visual walkthrough.

# REST API

BotSee monitors how AI search engines see your products. Query multiple AI models with target questions and analyze which competitors, sources, and keywords appear.

# Authentication

All authenticated endpoints require a Bearer token in the Authorization header.

## Authorization Header

Use this header on all authenticated API endpoints:

```
Authorization: Bearer bts_live_your_api_key
```

## Example

```
curl -X POST https://botsee.io/api/v1/auth/validate \
  -H "Authorization: Bearer $BOTSEE_API_KEY"
```

## Notes

- Do not send `Authorization` for public signup endpoints.
- USDC `payment` headers are documented in `Signup` and `USDC Top-Ups`.

### Validate API key

POST
`/api/v1/auth/validate`
Auth

Validates the API key and returns organization info and credit balance.

#### Response

Copy

```
{
  "valid": true,
  "api_key": {
    "id": 1,
    "name": "My Key",
    "status": "active",
    "key_prefix": "bts_live_abc1",
    "last_used_at": "2026-02-05T10:00:00Z"
  },
  "organization": {
    "id": 1,
    "name": "Acme Corp",
    "slug": "acme-corp"
  },
  "credits": {
    "balance": 500
  }
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/auth/validate -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get account information

GET
`/api/v1/account`
Auth

Returns account details including company name, site count, and owner information.

#### Response

Copy

```
{
  "company_name": "Acme Corp",
  "owner_email": "jane@acme.com",
  "owner_name": "Jane Smith",
  "site_count": 5
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/account -H "Authorization: Bearer $BOTSEE_API_KEY"
```

# API Keys

Manage API keys for the organization. Newly created keys are returned only once — store the raw key client-side immediately.

### List API keys

GET
`/api/v1/api-keys`
Auth

Lists all API keys for the organization (raw key never returned).

#### Response

Copy

```
{
  "api_keys": [\
    {\
      "id": "ak_1",\
      "name": "Production Key",\
      "status": "active",\
      "key_prefix": "bts_live_a1b2",\
      "last_used_at": "2026-04-29T09:00:00Z",\
      "created_at": "2026-01-01T00:00:00Z"\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/api-keys -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Create API key

POST
`/api/v1/api-keys`
Auth

Creates a new API key. The raw key is returned only once in the response body — store it immediately.

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  name<br>` | string | optional (API Key) | Human-readable name for the key. |

#### Response

Copy

```
{
  "api_key": {
    "id": "ak_2",
    "name": "Production Key",
    "status": "active",
    "key": "bts_live_abc123...",
    "key_prefix": "bts_live_abc1",
    "created_at": "2026-04-29T10:00:00Z"
  }
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/api-keys -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"name":"Production Key"}'
```

### Revoke API key

DELETE
`/api/v1/api-keys/:id`
Auth

Revokes an API key. You cannot revoke the key being used to make this request — use rotate or another key.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  id<br>` | path | string | required | API key id |

#### Example

Copy

```
curl -X DELETE https://botsee.io/api/v1/api-keys/AK_ID -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Rotate API key

POST
`/api/v1/api-keys/:id/rotate`
Auth

Atomically creates a new API key with the same name and revokes the old one. Returns the new raw key once.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  id<br>` | path | string | required | API key id to rotate |

#### Response

Copy

```
{
  "api_key": {
    "id": "ak_3",
    "name": "Production Key",
    "status": "active",
    "key": "bts_live_def456...",
    "key_prefix": "bts_live_def4",
    "created_at": "2026-04-29T11:00:00Z"
  }
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/api-keys/AK_ID/rotate -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Reset API key with one-time token

POST
`/api/v1/api-keys/reset`

Exchanges a one-time reset token (from email) for a fresh API key. Public endpoint — no Bearer auth required, the token authenticates the request.

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  token<br>` | string | required | Single-use reset token from the reset email. |

#### Response

Copy

```
{
  "api_key": {
    "id": "ak_4",
    "name": "API Key",
    "status": "active",
    "key": "bts_live_ghi789...",
    "key_prefix": "bts_live_ghi7",
    "created_at": "2026-04-29T12:00:00Z"
  }
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/api-keys/reset -H "Content-Type: application/json" -d '{"token":"RESET_TOKEN"}'
```

# Signup

Agent-initiated signup flows: credit card, USDC, and x402 challenge.

### Signup Credit Card

POST
`/api/v1/signup`

Creates a credit-card signup token. USDC signups must use \`/api/v1/signup/usdc\`.

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  company_name<br>` | string | optional | Company name (optional) |
| `<br>                  contact_name<br>` | string | optional | Contact person name (optional) |
| `<br>                  contact_email<br>` | string | optional | Contact email (optional) |
| `<br>                  payment_method<br>` | string | optional (credit\_card) | Defaults to 'credit\_card'. Use \`/api/v1/signup/usdc\` for USDC. |

#### Response

Copy

```
{
  "expires_at": "2026-02-06T10:00:00Z",
  "payment_method": "credit_card",
  "setup_token": "abc123...",
  "setup_url": "https://botsee.io/setup/abc123...",
  "status_url": "/api/v1/signup/abc123.../status"
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/signup -H "Content-Type: application/json" -d '{"company_name":"Acme Corp","contact_name":"Jane","contact_email":"jane@acme.com","payment_method":"credit_card"}'
```

### Agent Wallet Options for x402

- [Pinch](https://pinch.sh/) (hosted agent wallet + payment flow)
- [Coinbase Developer Platform Agentic Wallet](https://docs.cdp.coinbase.com/agentic-wallet/welcome)

Use your chosen wallet provider to satisfy the 402 challenge and retry with a `payment` header.

### Create USDC signup token

POST
`/api/v1/signup/usdc`

Creates a USDC signup token. Use \`no\_email: true\` for autonomous agent flows (no setup\_url returned).

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  company_name<br>` | string | optional | Company name (optional) |
| `<br>                  contact_name<br>` | string | optional | Contact name (optional) |
| `<br>                  contact_email<br>` | string | optional | Contact email (optional for USDC) |
| `<br>                  no_email<br>` | boolean | optional (false) | Set to true for autonomous agents that skip email verification |

#### Response

Copy

```
{
  "expires_at": "2026-02-06T10:00:00Z",
  "payment_method": "usdc",
  "setup_token": "abc123...",
  "setup_url": "https://botsee.io/setup/abc123...",
  "status_url": "/api/v1/signup/abc123.../status",
  "pay_usdc_url": "/api/v1/signup/abc123.../pay-usdc",
  "poll_url": "/api/v1/signup/abc123.../status"
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/signup/usdc -H "Content-Type: application/json" -d '{"company_name":"Acme Corp","contact_name":"Jane","contact_email":"jane@acme.com"}'
```

### Sign up via x402 challenge

POST
`/api/v1/signup/:token/pay-usdc`

Call without \`payment\` header to get a 402 challenge and \`payment-required\` details. Use Pinch or Coinbase CDP Agentic Wallet to generate the payment header and retry.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  token<br>` | path | string | required | Signup token |
| `<br>                  payment<br>` | header | string | optional | Omit this header to receive 402 payment-required challenge |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  amount_cents<br>` | integer | required | Amount in USD cents (250-100000, i.e., $2.50-$1000) |

#### Response

Copy

```
{
  "error": {
    "code": "payment_required",
    "message": "USDC payment required"
  },
  "accepts": [\
    {\
      "amount": "2500000",\
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",\
      "extra": {\
        "name": "USD Coin",\
        "version": "2"\
      },\
      "maxTimeoutSeconds": 300,\
      "network": "eip155:8453",\
      "payTo": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",\
      "scheme": "exact"\
    }\
  ],
  "amount_cents": 250,
  "payment_requirements": [\
    {\
      "amount": "2500000",\
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",\
      "extra": {\
        "name": "USD Coin",\
        "version": "2"\
      },\
      "maxTimeoutSeconds": 300,\
      "network": "eip155:8453",\
      "payTo": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",\
      "scheme": "exact"\
    }\
  ],
  "x402Version": 2
}
```

#### Example

Copy

```
curl -i -X POST https://botsee.io/api/v1/signup/TOKEN/pay-usdc -H "Content-Type: application/json" -d '{"amount_cents":250}'
```

### Check signup status

GET
`/api/v1/signup/:token/status`

Polls the status of a signup token. Returns 'pending', 'completed', or 'expired'.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  token<br>` | path | string | required | Signup token |

#### Response

Copy

```
{
  "status": "completed",
  "api_key": "bts_live_abc1",
  "payment_method": "usdc",
  "company_name": "Acme Corp",
  "contact_email": "jane@acme.com",
  "docs_url": "https://botsee.io/docs"
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/signup/TOKEN/status
```

# Pricing

Public endpoint exposing per-operation credit pricing. Useful for agents to estimate costs before signup or before committing to an analysis.

### Get pricing

GET
`/api/v1/pricing`

Returns the credit cost for each chargeable operation. Analysis costs are estimates; the actual debit is computed after completion from actual LLM usage and platform pricing.

#### Response

Copy

```
{
  "pricing": {
    "note": "Analysis costs shown are estimates. Final charges are calculated after completion from actual LLM usage and platform pricing.",
    "analysis_estimated_per_query": {
      "default": 6,
      "claude": 6,
      "gemini": 2,
      "grok": 6,
      "openai": 8,
      "perplexity": 4
    },
    "analysis_reservation_buffer": 1.25,
    "customer_type_generation_per_type": 5,
    "persona_generation_per_persona": 5,
    "question_generation": 10,
    "site_creation_auto_generate": 5
  }
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/pricing
```

# USDC Top-Ups

Add credits with BASE USDC using x402 challenge flow.

### Agent Wallet Options for x402

For top-ups, request the challenge first, then retry the same endpoint with your payment payload.

```
# 1) Discovery (no auth required, returns 402 + payment-required)
curl -i -X POST https://botsee.io/api/v1/billing/topups/usdc \
  -H "Content-Type: application/json" \
  -d '{"amount_cents":250}'

# 2) Final paid retry (auth + payment header required)
curl -i -X POST "https://botsee.io/api/v1/billing/topups/usdc?api_key=$BOTSEE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "payment-signature: $BASE64_PAYMENT_PAYLOAD" \
  -d '{"amount_cents":250}'
```

### Top up via x402 challenge

POST
`/api/v1/billing/topups/usdc`

Discovery call without payment headers returns 402 and does not require auth. Final paid retry requires API key (Authorization, x-api-key, or api\_key query param) and supports both \`payment\` and \`payment-signature\` headers. Method-compatible with POST, PUT, PATCH, and DELETE.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  authorization<br>` | header | string | optional | Required on final paid retry when using Bearer auth. Format: Bearer bts\_live\_... |
| `<br>                  x-api-key<br>` | header | string | optional | Alternative to Authorization on final paid retry |
| `<br>                  api_key<br>` | query | string | optional | Alternative auth for facilitator-driven final paid retry |
| `<br>                  payment<br>` | header | string | optional | Base64-encoded payment payload. Omit for discovery challenge; include on final paid retry. |
| `<br>                  payment-signature<br>` | header | string | optional | Alias for \`payment\` header |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  amount_cents<br>` | integer | optional | Amount in USD cents (250-100000, i.e., $2.50-$1000). Optional for discovery-only 402 challenge (defaults to configured discovery amount). |

#### Response

Copy

#### Example

Copy

```
curl -i -X POST https://botsee.io/api/v1/billing/topups/usdc -H "Content-Type: application/json" -d '{"amount_cents":250}'
```

# Billing Settings

Read and update billing preferences (monthly spend limit, current-month spend, low-balance threshold). For credit balance and transaction history use /api/v1/usage.

### Get billing settings

GET
`/api/v1/billing/settings`
Auth

Returns the organization's billing settings and current credit balance.

#### Response

Copy

```
{
  "balance": 4250,
  "monthly_spend_limit_cents": 10000,
  "low_balance_threshold": 100,
  "current_month_spend_cents": 1500,
  "max_monthly_spend_cents": 50000
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/billing/settings -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Update billing settings

PATCH
`/api/v1/billing/settings`
Auth

Updates the organization's monthly spend limit. Other settings are read-only via this endpoint.

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  monthly_spend_limit_cents<br>` | integer | optional | Maximum spend per calendar month in cents. Cannot exceed max\_monthly\_spend\_cents. |

#### Response

Copy

```
{
  "balance": 4250,
  "monthly_spend_limit_cents": 20000,
  "low_balance_threshold": 100,
  "current_month_spend_cents": 1500,
  "max_monthly_spend_cents": 50000
}
```

#### Example

Copy

```
curl -X PATCH https://botsee.io/api/v1/billing/settings -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"monthly_spend_limit_cents":20000}'
```

# Sites

Sites represent a domain and product you want to monitor across AI search engines.

### List sites

GET
`/api/v1/sites`
Auth

Returns a paginated list of sites for the organization.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  limit<br>` | query | integer | optional (50) | Max results (1-100) |
| `<br>                  cursor<br>` | query | string | optional | Pagination cursor from previous response |
| `<br>                  include_archived<br>` | query | boolean | optional (false) | Include archived sites |

#### Response

Copy

```
{
  "cursor": null,
  "sites": [\
    {\
      "status": "active",\
      "domain": "example.com",\
      "uuid": "abc-123",\
      "product_name": "My Product",\
      "created_at": "2026-02-05T10:00:00Z"\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/sites -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get site

GET
`/api/v1/sites/:uuid`
Auth

Returns a site with its customer types and persona counts.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Site UUID |

#### Response

Copy

```
{
  "site": {
    "status": "active",
    "domain": "example.com",
    "uuid": "abc-123",
    "product_name": "My Product",
    "value_proposition": "We help teams...",
    "created_at": "2026-02-05T10:00:00Z",
    "customer_types": [\
      {\
        "name": "Enterprise",\
        "uuid": "ct-1",\
        "persona_count": 3\
      }\
    ],
    "customer_type_count": 2
  }
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/sites/SITE_UUID -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Create site

POST
`/api/v1/sites`
5 (if auto-generating)

Auth

Creates a new site. Auto-generates product\_name and value\_proposition from URL if not provided (5 credits).

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  url<br>` | string | required | Full URL to analyze (e.g. 'https://example.com/products/foo') |
| `<br>                  domain<br>` | string | optional | Domain override (extracted from URL if not provided) |
| `<br>                  product_name<br>` | string | optional | Product name (auto-generated from URL if not provided, costs 5 credits) |
| `<br>                  value_proposition<br>` | string | optional | Value proposition (auto-generated from URL if not provided, costs 5 credits) |

#### Response

Copy

```
{
  "meta": {
    "credits_used": 5,
    "auto_generated": true
  },
  "site": {
    "status": "active",
    "domain": "example.com",
    "uuid": "abc-123",
    "product_name": "My Product",
    "value_proposition": "We help teams...",
    "created_at": "2026-02-05T10:00:00Z",
    "customer_types": [],
    "customer_type_count": 0
  }
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/sites -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"url":"https://example.com"}'
```

### Archive site

DELETE
`/api/v1/sites/:uuid`
Auth

Archives a site. Returns 204 No Content on success.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Site UUID |

#### Example

Copy

```
curl -X DELETE https://botsee.io/api/v1/sites/SITE_UUID -H "Authorization: Bearer $BOTSEE_API_KEY"
```

# Customer Types

Customer types represent market segments for a site. Each customer type can have multiple personas.

### List customer types

GET
`/api/v1/sites/:site_uuid/customer-types`
Auth

Lists all customer types for a site.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  site_uuid<br>` | path | string | required | Site UUID |

#### Response

Copy

```
{
  "customer_types": [\
    {\
      "name": "Enterprise IT",\
      "description": "Large company IT departments",\
      "uuid": "ct-1",\
      "created_at": "2026-02-05T10:00:00Z",\
      "persona_count": 2\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/sites/SITE_UUID/customer-types -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get customer type

GET
`/api/v1/customer-types/:uuid`
Auth

Returns a customer type with its personas.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Customer type UUID |

#### Response

Copy

```
{
  "customer_type": {
    "name": "Enterprise IT",
    "description": "Large company IT departments",
    "uuid": "ct-1",
    "personas": [\
      {\
        "name": "CTO",\
        "uuid": "p-1",\
        "question_count": 5\
      }\
    ],
    "created_at": "2026-02-05T10:00:00Z",
    "persona_count": 2
  }
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/customer-types/CT_UUID -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Create customer type

POST
`/api/v1/sites/:site_uuid/customer-types`
5 credits

Auth

Creates a customer type manually. Costs 5 credits.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  site_uuid<br>` | path | string | required | Site UUID |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  name<br>` | string | required | Customer type name |
| `<br>                  description<br>` | string | optional | Description of this market segment |

#### Response

Copy

```
{
  "customer_type": {
    "name": "Enterprise IT",
    "description": "Large company IT departments",
    "uuid": "ct-1",
    "created_at": "2026-02-05T10:00:00Z",
    "persona_count": 0
  }
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/sites/SITE_UUID/customer-types -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"name":"Enterprise IT","description":"Large company IT departments"}'
```

### Generate customer types via LLM

POST
`/api/v1/sites/:site_uuid/customer-types/generate`
5 per type

Auth

Uses AI to generate customer types based on the site's product and value proposition. Costs 5 credits per generated type.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  site_uuid<br>` | path | string | required | Site UUID |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  count<br>` | integer | optional (3) | Number of customer types to generate |

#### Response

Copy

```
{
  "credits_used": 15,
  "customer_types": [\
    {\
      "name": "Enterprise IT Directors",\
      "description": "IT leaders at large companies",\
      "uuid": "ct-1",\
      "created_at": "2026-02-05T10:00:00Z",\
      "persona_count": 0\
    }\
  ]
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/sites/SITE_UUID/customer-types/generate -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"count":3}'
```

### Update customer type

PUT
`/api/v1/customer-types/:uuid`
Auth

Updates a customer type. Only include fields you want to change.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Customer type UUID |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  name<br>` | string | optional | Updated customer type name |
| `<br>                  description<br>` | string | optional | Updated description |

#### Response

Copy

```
{
  "customer_type": {
    "name": "Updated Name",
    "description": "Updated description",
    "uuid": "ct-1",
    "created_at": "2026-02-05T10:00:00Z",
    "persona_count": 2
  }
}
```

#### Example

Copy

```
curl -X PUT https://botsee.io/api/v1/customer-types/CT_UUID -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"name":"New Name","description":"New description"}'
```

### Archive customer type

DELETE
`/api/v1/customer-types/:uuid`
Auth

Archives a customer type. Returns 204 No Content on success.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Customer type UUID |

#### Example

Copy

```
curl -X DELETE https://botsee.io/api/v1/customer-types/CT_UUID -H "Authorization: Bearer $BOTSEE_API_KEY"
```

# Personas

Personas represent specific buyer profiles within a customer type. Each persona has questions that get asked to AI models during analysis.

### List personas

GET
`/api/v1/customer-types/:customer_type_uuid/personas`
Auth

Lists all personas for a customer type.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  customer_type_uuid<br>` | path | string | required | Customer type UUID |

#### Response

Copy

```
{
  "personas": [\
    {\
      "name": "CTO",\
      "description": "Technical leader managing...",\
      "uuid": "p-1",\
      "question_count": 5,\
      "created_at": "2026-02-05T10:00:00Z"\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/customer-types/CT_UUID/personas -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get persona

GET
`/api/v1/personas/:uuid`
Auth

Returns a persona with its questions.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Persona UUID |

#### Response

Copy

```
{
  "persona": {
    "name": "CTO",
    "description": "Technical leader managing...",
    "uuid": "p-1",
    "question_count": 5,
    "created_at": "2026-02-05T10:00:00Z",
    "questions": [\
      {\
        "priority": "high",\
        "category": "problem_solving",\
        "question": "What tools help with code review?",\
        "uuid": "q-1",\
        "is_active": true\
      }\
    ]
  }
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/personas/PERSONA_UUID -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Create persona

POST
`/api/v1/customer-types/:customer_type_uuid/personas`
5 credits

Auth

Creates a persona manually. Costs 5 credits.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  customer_type_uuid<br>` | path | string | required | Customer type UUID |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  name<br>` | string | required | Persona name (e.g. 'CTO') |
| `<br>                  description<br>` | string | required | Detailed persona description |

#### Response

Copy

```
{
  "persona": {
    "name": "CTO",
    "description": "Technical leader managing...",
    "uuid": "p-1",
    "question_count": 0,
    "created_at": "2026-02-05T10:00:00Z"
  }
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/customer-types/CT_UUID/personas -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"name":"CTO","description":"Technical leader managing 50+ engineers"}'
```

### Generate personas via LLM

POST
`/api/v1/customer-types/:customer_type_uuid/personas/generate`
5 per persona

Auth

Uses AI to generate personas based on the customer type. Costs 5 credits per persona. Optionally pass \`prompt\` to steer the LLM toward a specific persona within the customer segment (requires \`count: 1\`).

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  customer_type_uuid<br>` | path | string | required | Customer type UUID |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  count<br>` | integer | optional (3) | Number of personas to generate |
| `<br>                  prompt<br>` | string | optional | Free-text hint (max 2000 chars) that steers generation toward a specific persona. Only supported with count: 1. When omitted, the generator produces diverse personas across the customer segment. |

#### Response

Copy

```
{
  "personas": [\
    {\
      "name": "CTO",\
      "description": "Technical leader managing...",\
      "uuid": "p-1",\
      "question_count": 0,\
      "created_at": "2026-02-05T10:00:00Z"\
    }\
  ],
  "credits_used": 15
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/customer-types/CT_UUID/personas/generate -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"count":1,"prompt":"VP of Engineering at a Series B fintech managing a 40-person platform team"}'
```

### Update persona

PUT
`/api/v1/personas/:uuid`
Auth

Updates a persona. Only include fields you want to change.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Persona UUID |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  name<br>` | string | optional | Updated persona name |
| `<br>                  description<br>` | string | optional | Updated persona description |

#### Response

Copy

```
{
  "persona": {
    "name": "Updated Name",
    "description": "Updated persona description",
    "uuid": "p-1",
    "question_count": 5,
    "created_at": "2026-02-05T10:00:00Z"
  }
}
```

#### Example

Copy

```
curl -X PUT https://botsee.io/api/v1/personas/PERSONA_UUID -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"name":"New Name","description":"New description"}'
```

### Archive persona

DELETE
`/api/v1/personas/:uuid`
Auth

Archives a persona. Returns 204 No Content on success.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Persona UUID |

#### Example

Copy

```
curl -X DELETE https://botsee.io/api/v1/personas/PERSONA_UUID -H "Authorization: Bearer $BOTSEE_API_KEY"
```

# Questions

Questions are what get asked to AI search engines during analysis. Each question belongs to a persona and can be manually created or AI-generated.

### List questions

GET
`/api/v1/personas/:persona_uuid/questions`
Auth

Lists all questions for a persona.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  persona_uuid<br>` | path | string | required | Persona UUID |

#### Response

Copy

```
{
  "questions": [\
    {\
      "priority": "high",\
      "category": "problem_solving",\
      "question": "What tools help with code review?",\
      "uuid": "q-1",\
      "is_active": true,\
      "created_at": "2026-02-05T10:00:00Z"\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/personas/PERSONA_UUID/questions -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Create question

POST
`/api/v1/personas/:persona_uuid/questions`
Auth

Creates a question manually. Free operation.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  persona_uuid<br>` | path | string | required | Persona UUID |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  question<br>` | string | required | The question text to ask AI models |
| `<br>                  category<br>` | string | optional (problem\_solving) | Question category |
| `<br>                  priority<br>` | string | optional (medium) | Priority: low, medium, high |

#### Response

Copy

```
{
  "question": {
    "priority": "medium",
    "category": "problem_solving",
    "question": "What tools help with code review?",
    "uuid": "q-1",
    "is_active": true,
    "created_at": "2026-02-05T10:00:00Z"
  }
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/personas/PERSONA_UUID/questions -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"question":"What tools help with code review?"}'
```

### Generate questions via LLM

POST
`/api/v1/personas/:persona_uuid/questions/generate`
10 credits

Auth

Uses AI to generate questions based on the persona and site context. Costs 10 credits flat.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  persona_uuid<br>` | path | string | required | Persona UUID |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  count<br>` | integer | optional (5) | Number of questions to generate |

#### Response

Copy

```
{
  "credits_used": 10,
  "questions": [\
    {\
      "priority": "medium",\
      "category": "problem_solving",\
      "question": "What are the best AI-powered code review tools?",\
      "uuid": "q-1",\
      "is_active": true,\
      "created_at": "2026-02-05T10:00:00Z"\
    }\
  ]
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/personas/PERSONA_UUID/questions/generate -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"count":5}'
```

### Update question

PUT
`/api/v1/questions/:uuid`
Auth

Updates a question. Only include fields you want to change.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Question UUID |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  question<br>` | string | optional | Updated question text |
| `<br>                  category<br>` | string | optional | Updated category |
| `<br>                  priority<br>` | string | optional | Updated priority |
| `<br>                  is_active<br>` | boolean | optional | Active/inactive toggle |

#### Response

Copy

```
{
  "question": {
    "priority": "high",
    "category": "problem_solving",
    "question": "Updated question text?",
    "uuid": "q-1",
    "is_active": true,
    "created_at": "2026-02-05T10:00:00Z"
  }
}
```

#### Example

Copy

```
curl -X PUT https://botsee.io/api/v1/questions/Q_UUID -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"priority":"high","question":"Updated question?"}'
```

### Delete question

DELETE
`/api/v1/questions/:uuid`
Auth

Deletes a question. Returns 204 No Content on success.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Question UUID |

#### Example

Copy

```
curl -X DELETE https://botsee.io/api/v1/questions/Q_UUID -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get question results

GET
`/api/v1/questions/:uuid/results`
Auth

Returns analysis results for a specific question. Use the \`fields\` parameter to include additional data (keywords, competitors, sources, responses).

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Question UUID |
| `<br>                  fields<br>` | query | string | optional | Comma-separated fields: keywords, competitors, sources, responses. Default: keywords only. |

#### Response

Copy

```
{
  "question": "What tools help with code review?",
  "keywords_by_model": {
    "claude": [\
      "code review",\
      "static analysis"\
    ],
    "openai": [\
      "code review",\
      "pull request"\
    ]
  }
}
```

#### Example

Copy

```
curl "https://botsee.io/api/v1/questions/Q_UUID/results?fields=keywords,competitors" -H "Authorization: Bearer $BOTSEE_API_KEY"
```

# Analysis

Run analyses that query AI search engines with your questions and collect structured results including competitors, sources, and keywords.

### Run analysis

POST
`/api/v1/analysis`
5 per question per model

Auth

Starts an analysis run. This is asynchronous - poll GET /api/v1/analysis/:uuid for status. Returns 202 Accepted.

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  site_uuid<br>` | string | required | Site UUID to analyze |
| `<br>                  scope<br>` | string | optional (site) | Scope: 'site', 'customer\_type', 'persona', or 'questions' |
| `<br>                  target_uuids<br>` | array | optional | Required for non-site scope. UUIDs of customer types, personas, or questions. |
| `<br>                  models<br>` | array | optional (openaiclaudeperplexity) | AI models: openai, claude, perplexity, gemini, grok |

#### Response

Copy

```
{
  "analysis": {
    "scope": "site",
    "status": "running",
    "started_at": "2026-02-05T10:00:00Z",
    "uuid": "a-1",
    "completed_at": null,
    "response_count": 0,
    "models": [\
      "openai",\
      "claude",\
      "perplexity"\
    ],
    "site_uuid": "s-1",
    "credits_used": 0
  },
  "estimated_credits": 45
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/analysis -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"site_uuid":"SITE_UUID","scope":"site","models":["openai","claude","perplexity"]}'
```

### List analyses

GET
`/api/v1/sites/:site_uuid/analysis`
Auth

Lists analysis runs for a site with optional filters.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  site_uuid<br>` | path | string | required | Site UUID |
| `<br>                  limit<br>` | query | integer | optional (20) | Max results |
| `<br>                  cursor<br>` | query | string | optional | Pagination cursor |
| `<br>                  persona_uuid<br>` | query | string | optional | Filter by persona |
| `<br>                  model<br>` | query | string | optional | Filter by model |
| `<br>                  from<br>` | query | string | optional | Start date (ISO 8601) |
| `<br>                  to<br>` | query | string | optional | End date (ISO 8601) |

#### Response

Copy

```
{
  "cursor": null,
  "analyses": [\
    {\
      "scope": "site",\
      "status": "completed",\
      "started_at": "2026-02-05T10:00:00Z",\
      "uuid": "a-1",\
      "completed_at": "2026-02-05T10:05:00Z",\
      "response_count": 5,\
      "models": [\
        "openai"\
      ],\
      "site_uuid": "s-1",\
      "credits_used": 15\
    }\
  ]
}
```

#### Example

Copy

```
curl "https://botsee.io/api/v1/sites/SITE_UUID/analysis?limit=10" -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get analysis status

GET
`/api/v1/analysis/:uuid`
Auth

Returns analysis details including status. Poll this endpoint until status is 'completed' or 'failed'.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Analysis UUID |

#### Response

Copy

```
{
  "analysis": {
    "scope": "site",
    "status": "completed",
    "started_at": "2026-02-05T10:00:00Z",
    "uuid": "a-1",
    "completed_at": "2026-02-05T10:05:00Z",
    "question_count": 5,
    "response_count": 10,
    "models": [\
      "openai",\
      "claude"\
    ],
    "target_uuids": null,
    "site_uuid": "s-1",
    "credits_used": 30,
    "error_count": 0
  }
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/analysis/ANALYSIS_UUID -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get raw responses

GET
`/api/v1/analysis/:uuid/responses`
Auth

Returns raw AI model responses for the analysis.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Analysis UUID |

#### Response

Copy

```
{
  "responses": [\
    {\
      "question": "What tools help with code review?",\
      "uuid": "r-1",\
      "mentioned": true,\
      "model": "openai",\
      "created_at": "2026-02-05T10:02:00Z",\
      "response_text": "There are several excellent code review tools...",\
      "search_terms": [\
        "code review",\
        "pull request tools"\
      ]\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/analysis/ANALYSIS_UUID/responses -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get cited sources

GET
`/api/v1/analysis/:uuid/sources`
Auth

Returns aggregated sources cited across all responses, with own\_company\_mentioned flag.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Analysis UUID |

#### Response

Copy

```
{
  "sources": [\
    {\
      "title": "Code Review Guide",\
      "url": "https://example.com/review",\
      "mention_count": 3,\
      "own_company_mentioned": true\
    }\
  ],
  "total_unique": 15
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/analysis/ANALYSIS_UUID/sources -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get competitors mentioned

GET
`/api/v1/analysis/:uuid/competitors`
Auth

Returns competitors mentioned in responses, grouped by customer type. Each competitor includes appearance percentage (% of responses mentioning them), mentions count, average ranking, and confidence scores.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Analysis UUID |

#### Response

Copy

```
{
  "by_customer_type": [\
    {\
      "total_responses": 10,\
      "competitors": [\
        {\
          "name": "Competitor A",\
          "url": "https://competitor-a.com",\
          "mentions": 8,\
          "appearance_percentage": 80.0,\
          "avg_rank": 2.5,\
          "unique_responses": 8,\
          "avg_confidence": 0.85,\
          "best_rank": 1\
        }\
      ],\
      "total_unique_competitors": 5,\
      "customer_type_name": "Enterprise IT Directors",\
      "customer_type_uuid": "abc-123-def"\
    }\
  ],
  "overall_summary": {
    "own_company_mentioned": true,
    "total_responses_analyzed": 50,
    "total_unique_competitors": 15
  }
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/analysis/ANALYSIS_UUID/competitors -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get keywords

GET
`/api/v1/analysis/:uuid/keywords`
Auth

Returns aggregated keywords/search terms from all responses.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Analysis UUID |

#### Response

Copy

```
{
  "keywords": [\
    {\
      "count": 8,\
      "term": "code review",\
      "models": [\
        "openai",\
        "claude",\
        "perplexity"\
      ]\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/analysis/ANALYSIS_UUID/keywords -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get keyword opportunities

GET
`/api/v1/analysis/:uuid/keyword_opportunities`
Auth

Returns questions where your brand's mention rate is below a threshold. Use this to discover which queries you should target with content. Results include a per-provider breakdown with the search keywords used and your brand's rank position.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Analysis UUID |
| `<br>                  threshold<br>` | query | number | optional (1.0) | Mention rate threshold (0.0–1.0). Questions where mention\_rate < threshold are returned. Default 1.0 returns any question where brand was missed at least once. |
| `<br>                  rank_threshold<br>` | query | integer | optional | Also flag questions where brand appeared at rank worse than this value, even if mention rate meets the threshold. |

#### Response

Copy

```
{
  "opportunities": [\
    {\
      "question": "What tools help with AI visibility?",\
      "total_responses": 3,\
      "persona": "Marketing Director",\
      "question_uuid": "Q_UUID",\
      "persona_uuid": "P_UUID",\
      "by_model": [\
        {\
          "rank": null,\
          "provider": "openai",\
          "mentioned": false,\
          "search_keywords": [\
            "ai search visibility",\
            "brand monitoring"\
          ]\
        },\
        {\
          "rank": null,\
          "provider": "claude",\
          "mentioned": false,\
          "search_keywords": [\
            "ai seo tools"\
          ]\
        },\
        {\
          "rank": 4,\
          "provider": "perplexity",\
          "mentioned": true,\
          "search_keywords": [\
            "ai visibility tracking"\
          ]\
        }\
      ],\
      "mentioned_count": 0\
    }\
  ]
}
```

#### Example

Copy

```
curl "https://botsee.io/api/v1/analysis/ANALYSIS_UUID/keyword_opportunities?threshold=0.8" -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get source opportunities

GET
`/api/v1/analysis/:uuid/source_opportunities`
Auth

Returns sources that AI cited in responses where your brand was NOT mentioned. These are high-value targets for outreach or content placement — getting coverage on these sources may improve your AI visibility.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Analysis UUID |

#### Response

Copy

```
{
  "sources": [\
    {\
      "title": "Best AI Tools 2025",\
      "url": "https://techcrunch.com/ai-tools",\
      "mentions": 5\
    },\
    {\
      "title": "AI SEO Software",\
      "url": "https://g2.com/categories/ai-seo",\
      "mentions": 3\
    }\
  ],
  "total_unique": 2
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/analysis/ANALYSIS_UUID/source_opportunities -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Generate recommendations

POST
`/api/v1/analysis/:uuid/recommendations`
5 (first call only)

Auth

Generates actionable recommendations from the analysis (cached after first call). Costs 5 credits the first time; subsequent calls return the cached result.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Analysis UUID |

#### Response

Copy

```
{
  "recommendations": {
    "actions": [\
      {\
        "title": "Publish on top-cited sources",\
        "detail": "Target the 3 sources where competitors are cited but you are not."\
      }\
    ],
    "summary": "Improve AI visibility on competitor-heavy queries."
  }
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/analysis/ANALYSIS_UUID/recommendations -H "Authorization: Bearer $BOTSEE_API_KEY"
```

# Content Generation

Generate blog posts from analysis results.

### Generate blog post

POST
`/api/v1/analysis/:analysis_uuid/content`
15 credits

Auth

Generates a blog post from analysis results for a specific question. Costs 15 credits.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  analysis_uuid<br>` | path | string | required | Analysis UUID |

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  question_uuid<br>` | string | required | Question UUID to base the post on |
| `<br>                  provider<br>` | string | optional (gemini) | LLM provider: 'gemini' or 'claude' |
| `<br>                  keywords<br>` | array | optional | Custom keywords to incorporate |

#### Response

Copy

```
{
  "tokens": {
    "input": 2500,
    "output": 1800,
    "total": 4300
  },
  "content": "# Best Code Review Tools for 2026\n\nIn the fast-evolving world of software development...",
  "provider": "gemini",
  "credits_used": 15,
  "model": "gemini-2.0-flash"
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/analysis/ANALYSIS_UUID/content -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"question_uuid":"Q_UUID","provider":"gemini"}'
```

# Usage & Credits

Monitor credit balance, transaction history, and usage breakdown by API key.

### Get usage summary

GET
`/api/v1/usage`
Auth

Returns credit balance, auto-charge settings, and paginated transaction history.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  limit<br>` | query | integer | optional (50) | Max transactions to return |
| `<br>                  cursor<br>` | query | string | optional | Pagination cursor |
| `<br>                  from<br>` | query | string | optional | Start date (ISO 8601) |
| `<br>                  to<br>` | query | string | optional | End date (ISO 8601) |

#### Response

Copy

```
{
  "balance": 450,
  "cursor": null,
  "transactions": [\
    {\
      "id": 1,\
      "type": "deduction",\
      "description": "Analysis run",\
      "amount": -15,\
      "resource_id": "a-1",\
      "resource_type": "analysis",\
      "balance_after": 450,\
      "api_key_id": 1,\
      "created_at": "2026-02-05T10:05:00Z"\
    }\
  ],
  "monthly_spend_limit_cents": 10000,
  "low_balance_threshold": 500,
  "current_month_spend_cents": 5000,
  "max_monthly_spend_cents": 10000
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/usage -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get usage by API key

GET
`/api/v1/usage/by-key`
Auth

Returns credit usage breakdown per API key.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  from<br>` | query | string | optional | Start date (ISO 8601) |
| `<br>                  to<br>` | query | string | optional | End date (ISO 8601) |

#### Response

Copy

```
{
  "usage_by_key": [\
    {\
      "api_key_id": 1,\
      "api_key_name": "Production Key",\
      "api_key_prefix": "bts_live_abc1",\
      "total_credits_used": 250,\
      "analysis_count": 5,\
      "generation_count": 12\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/usage/by-key -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get usage by site

GET
`/api/v1/usage/by-site`
Auth

Returns credit usage grouped by site: per-site totals plus a per-category breakdown.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  from<br>` | query | string | optional | Start date (ISO 8601) |
| `<br>                  to<br>` | query | string | optional | End date (ISO 8601) |
| `<br>                  site_uuid<br>` | query | string | optional | Limit to a single site (404 if it does not belong to the org) |

#### Response

Copy

```
{
  "from": "2026-02-01",
  "to": "2026-02-28",
  "sites": [\
    {\
      "name": "Example",\
      "domain": "example.com",\
      "site_uuid": "550e8400-e29b-41d4-a716-446655440000",\
      "total_credits": 159,\
      "breakdown": [\
        {\
          "category": "analysis",\
          "credits": 153\
        },\
        {\
          "category": "content_generation",\
          "credits": 6\
        }\
      ]\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/usage/by-site -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Get usage line items

GET
`/api/v1/usage/line-items`
Auth

Lists individual paid operations (line items), newest first. One row per site, category, operation, and resource.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  from<br>` | query | string | optional | Start date (ISO 8601) |
| `<br>                  to<br>` | query | string | optional | End date (ISO 8601) |
| `<br>                  site_uuid<br>` | query | string | optional | Limit to a single site (404 if it does not belong to the org) |
| `<br>                  category<br>` | query | string | optional | Limit to one operation category (e.g. analysis, setup, content\_generation) |
| `<br>                  limit<br>` | query | integer | optional (200) | Max line items to return |

#### Response

Copy

```
{
  "from": "2026-02-01",
  "to": "2026-02-28",
  "line_items": [\
    {\
      "name": "Example",\
      "domain": "example.com",\
      "operation": "seo_question",\
      "category": "analysis",\
      "credits": 153,\
      "site_uuid": "550e8400-e29b-41d4-a716-446655440000",\
      "last_charged_at": "2026-02-24T05:55:00Z"\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/usage/line-items -H "Authorization: Bearer $BOTSEE_API_KEY"
```

# Rate Limits

Every BotSee API request is rate-limited per API key (or per client IP for unauthenticated requests). The current ceiling is 600 requests per minute (10/sec).

## Limit

- **600 requests per minute** per API key (or per client IP for
- unauthenticated requests). The window slides; there is no daily cap
- beyond this rolling per-minute ceiling.

## Response Headers

Every response (success or error) includes:

| Header | Meaning |
| --- | --- |
| `x-ratelimit-limit` | Maximum requests allowed in the window (`600`). |
| `x-ratelimit-remaining` | Requests remaining in the current window. |
| `x-ratelimit-reset` | Unix timestamp (seconds) when the window resets. |
| `retry-after` | Seconds to wait before retrying. **Returned only on 429 responses.** |

## When you hit the limit

The server returns `429 Too Many Requests` with this body:

```
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Limit: 600 per minute."
  }
}
```

## Recommended back-off for agents

1\. Honour `retry-after` when present — wait that many seconds before retrying.
2\. If `retry-after` is absent on a transient error, use exponential back-off
starting at 1s, doubling each retry, capped at 60s.
3\. Watch `x-ratelimit-remaining` on every response. When it drops below
a small floor (e.g. 50), pause non-essential work until the window resets.
4\. For predictable budgets, call `GET /api/v1/rate-limits` to read state
without consuming a slot beyond the call itself.

## Bucket key

Authenticated requests bucket by API key (the SHA-256 prefix of the bearer
token). Unauthenticated requests bucket by client IP. The rate-limit plug
runs **before** authentication so brute-force attempts are throttled
regardless of key validity.

### Get rate-limit budget

GET
`/api/v1/rate-limits`
Auth

Returns the caller's current rate-limit state without consuming additional budget. Useful for agents that want to back off proactively before hitting 429.

#### Response

Copy

```
{
  "count": 1,
  "limit": 600,
  "remaining": 599,
  "reset_at": "2026-04-29T12:01:00Z",
  "window_seconds": 60
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/rate-limits -H "Authorization: Bearer $BOTSEE_API_KEY"
```

# Webhooks

Register webhook URLs to receive notifications when events occur (e.g., analysis completed).

## Delivery Envelope

Every webhook POST carries a JSON body shaped like:

```
{
  "event": "analysis.completed",
  "timestamp": "2026-04-29T12:00:00Z",
  "data": { /* event-specific payload */ }
}
```

And these headers:

| Header | Meaning |
| --- | --- |
| `x-botsee-signature` | `sha256=<hex>` HMAC of `"<x-botsee-timestamp>.<json_body>"` using your webhook secret. |
| `x-botsee-timestamp` | Unix timestamp (seconds) when the server signed the payload. |
| `user-agent` | `BotSee-Webhook/1.0`. |

Always reject deliveries with timestamps older than ~5 minutes to defeat replay.

## Signature Verification

### Node

```
const crypto = require('crypto');

function verify(rawBody, signatureHeader, timestamp, secret) {
  const sig = signatureHeader.replace(/^sha256=/, '');
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(sig, 'hex'),
    Buffer.from(expected, 'hex')
  );
}
```

### Python

```
import hmac, hashlib

def verify(raw_body: bytes, signature_header: str, timestamp: str, secret: str) -> bool:
    sig = signature_header.removeprefix("sha256=")
    expected = hmac.new(
        secret.encode(),
        f"{timestamp}.{raw_body.decode()}".encode(),
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(sig, expected)
```

### Elixir

```
def verify(raw_body, "sha256=" <> sig, timestamp, secret) do
  expected =
    :crypto.mac(:hmac, :sha256, secret, "#{timestamp}.#{raw_body}")
    |> Base.encode16(case: :lower)

Plug.Crypto.secure_compare(sig, expected)
end
```

## Events

The full machine-readable catalog (with JSON Schemas per event) is at
`GET /api/v1/webhooks/events`.

| Event | When it fires |
| --- | --- |
| `analysis.completed` | Analysis run finished successfully. |
| `analysis.failed` | Analysis run failed. |
| `webhook.test` | Test-only event, fired by `POST /api/v1/webhooks/:uuid/test`. Safe to subscribe to without expecting traffic. |

### Sample payload — \`analysis.completed\`

```
{
  "event": "analysis.completed",
  "timestamp": "2026-04-29T12:00:00Z",
  "data": {
    "analysis_uuid": "a-1",
    "site_uuid": "s-1",
    "scope": "site",
    "status": "completed",
    "models": ["openai", "claude"],
    "credits_used": 30,
    "response_count": 10,
    "started_at": "2026-04-29T11:55:00Z",
    "completed_at": "2026-04-29T12:00:00Z"
  }
}
```

### Sample payload — \`analysis.failed\`

```
{
  "event": "analysis.failed",
  "timestamp": "2026-04-29T12:00:00Z",
  "data": {
    "analysis_uuid": "a-1",
    "site_uuid": "s-1",
    "status": "failed",
    "error": "openai rate limit exceeded after 3 retries",
    "started_at": "2026-04-29T11:55:00Z",
    "failed_at": "2026-04-29T12:00:00Z"
  }
}
```

## Retry Policy & Auto-Disable

- **3 delivery attempts** with exponential back-off (~5s, ~30s, ~2min).
- Webhook is auto-disabled after **10 consecutive failures** (`status` flips
- to `disabled`); no further deliveries are attempted.
- Re-enable by deleting and re-creating the webhook.
- Each successful delivery resets `failure_count` to 0 and updates
- `last_triggered_at`.

## Event Filtering

Event filtering is **exact-match**: subscribers only receive the event
types they explicitly registered for. Adding a new event type to the
catalog does not change traffic for existing webhooks.

### List webhook event catalog

GET
`/api/v1/webhooks/events`
Auth

Returns the catalog of event types this API can emit, with JSON Schemas per event. Use this to self-discover available events programmatically without parsing the full OpenAPI doc.

#### Response

Copy

```
{
  "events": [\
    {\
      "description": "Fires when an analysis run finishes successfully.",\
      "event": "analysis.completed",\
      "payload_schema": {\
        "type": "object",\
        "properties": {}\
      }\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/webhooks/events -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### List webhooks

GET
`/api/v1/webhooks`
Auth

Lists all registered webhooks for the organization.

#### Response

Copy

```
{
  "webhooks": [\
    {\
      "status": "active",\
      "events": [\
        "analysis.completed",\
        "analysis.failed"\
      ],\
      "url": "https://example.com/webhook",\
      "uuid": "wh-1",\
      "created_at": "2026-02-05T10:00:00Z",\
      "failure_count": 0,\
      "last_triggered_at": null\
    }\
  ]
}
```

#### Example

Copy

```
curl https://botsee.io/api/v1/webhooks -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Create webhook

POST
`/api/v1/webhooks`
Auth

Registers a webhook URL. Returns the webhook with its signing secret (shown only once).

#### Request Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `<br>                  url<br>` | string | required | HTTPS URL to receive webhook payloads |
| `<br>                  events<br>` | array | optional (analysis.completedanalysis.failed) | Events to subscribe to. Call GET /api/v1/webhooks/events for the canonical catalog of currently-emitted event types and their payload schemas. |

#### Response

Copy

```
{
  "webhook": {
    "status": "active",
    "events": [\
      "analysis.completed"\
    ],
    "secret": "whsec_abc123...",
    "url": "https://example.com/webhook",
    "uuid": "wh-1",
    "created_at": "2026-02-05T10:00:00Z",
    "failure_count": 0,
    "last_triggered_at": null
  }
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/webhooks -H "Authorization: Bearer $BOTSEE_API_KEY" -H "Content-Type: application/json" -d '{"url":"https://example.com/webhook","events":["analysis.completed"]}'
```

### Send synthetic test event

POST
`/api/v1/webhooks/:uuid/test`
Auth

Fires a synthetic webhook.test event to the registered URL via the standard delivery worker. Useful for end-to-end testing of signature verification on the subscriber side. Returns 202 with the enqueued Oban job id.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Webhook UUID |

#### Response

Copy

```
{
  "event": "webhook.test",
  "job_id": 12345
}
```

#### Example

Copy

```
curl -X POST https://botsee.io/api/v1/webhooks/WH_UUID/test -H "Authorization: Bearer $BOTSEE_API_KEY"
```

### Delete webhook

DELETE
`/api/v1/webhooks/:uuid`
Auth

Deletes a webhook. Returns 204 No Content on success.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `<br>                  uuid<br>` | path | string | required | Webhook UUID |

#### Example

Copy

```
curl -X DELETE https://botsee.io/api/v1/webhooks/WH_UUID -H "Authorization: Bearer $BOTSEE_API_KEY"
```

# Error Handling

All errors follow a consistent JSON format.

## Error Response Format

```
{
  "error": {
    "code": "error_code_string",
    "message": "Human-readable description"
  }
}
```

For validation errors, a `details` field contains per-field errors:

```
{
  "error": {
    "code": "validation_error",
    "details": {
      "domain": ["can't be blank"],
      "product_name": ["is too short"]
    }
  }
}
```

## Pagination

List endpoints use cursor-based pagination. Pass the `cursor` from the response to get the next page:

```
# First page
curl "https://botsee.io/api/v1/sites?limit=10" -H "Authorization: Bearer $BOTSEE_API_KEY"

# Next page (use cursor from response)
curl "https://botsee.io/api/v1/sites?limit=10&cursor=CURSOR_VALUE" -H "Authorization: Bearer $BOTSEE_API_KEY"
```

When `cursor` is `null` in the response, there are no more pages.
