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

# Ads Research Agents

> Competitive advertising intelligence and landing page analysis

<Note type="enterprise">
  **Shannon Cloud Only**: These agents require a Shannon Cloud subscription and use paid external APIs:

  * **SerpAPI** (Google Search ads)
  * **SearchAPI.io** (Meta Ad Library)
  * **Playwright service** (browser automation)
  * **Vision LLM** (landing page analysis)
</Note>

## Overview

Shannon provides **10 specialized agents** for competitive advertising research, from ad discovery to creative analysis.

**Use cases:**

* Monitor competitor advertising strategies
* Discover winning ad creative patterns
* Analyze landing page messaging and design
* Track multi-platform ad campaigns (Google, Yahoo JP, Meta)

***

## Available Agents

### serp-ads

Extract paid ads from Google Search results for given keywords.

**Agent ID:** `serp-ads`

**Input Schema:**

| Field           | Type    | Required | Default        | Description                                |
| --------------- | ------- | -------- | -------------- | ------------------------------------------ |
| `keywords`      | string  | Yes      | -              | Search keywords to find ads for            |
| `country`       | string  | No       | `"us"`         | Country code (us, jp, uk, etc.)            |
| `location`      | string  | No       | -              | Specific location for geo-targeted ads     |
| `language`      | string  | No       | `"en"`         | Language code (en, ja, zh, etc.)           |
| `device`        | string  | No       | `"desktop"`    | Device type: `desktop`, `mobile`, `tablet` |
| `google_domain` | string  | No       | `"google.com"` | Google domain to query                     |
| `max_results`   | integer | No       | `10`           | Maximum number of ads to return            |

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:8080/api/v1/agents/serp-ads \
  -H "X-API-Key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "keywords": "best credit cards",
      "country": "us",
      "device": "mobile",
      "max_results": 5
    }
  }'
```

**Output Structure:**

```json theme={null}
{
  "keywords": "best credit cards",
  "location": "us",
  "total_ads": 5,
  "ads": [
    {
      "position": 1,
      "title": "Best Credit Cards 2026",
      "description": "Compare top credit cards and find the best rewards...",
      "link": "https://example.com/cards",
      "domain": "example.com"
    }
  ],
  "cost_usd": 0.015,
  "timestamp": "2026-02-15T10:30:00Z"
}
```

***

### yahoo-jp-ads

Extract sponsored ads from Yahoo Japan search results.

**Agent ID:** `yahoo-jp-ads`

<Note>
  **No API key required** - Uses web scraping. Free, but Cloud-only due to IP rotation requirements.
</Note>

**Input Schema:**

| Field      | Type   | Required | Description                          |
| ---------- | ------ | -------- | ------------------------------------ |
| `keywords` | string | Yes      | Search keywords (Japanese preferred) |

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:8080/api/v1/agents/yahoo-jp-ads \
  -H "X-API-Key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "keywords": "クレジットカード おすすめ"
    }
  }'
```

**Output Structure:**

```json theme={null}
{
  "keywords": "クレジットカード おすすめ",
  "total_ads": 3,
  "ads": [
    {
      "position": 1,
      "title": "セブンカード・プラス 公式サイト",
      "description": "年会費無料でnanaco搭載...",
      "link": "https://www.7card.co.jp/...",
      "domain": "7card.co.jp",
      "source": "yahoo_jp"
    }
  ],
  "cost_usd": 0,
  "timestamp": "2026-02-15T10:30:00Z"
}
```

***

### meta-ad-library

Search Meta Ad Library for Facebook and Instagram ads.

**Agent ID:** `meta-ad-library`

**Input Schema:**

| Field      | Type   | Required | Default | Description                                      |
| ---------- | ------ | -------- | ------- | ------------------------------------------------ |
| `query`    | string | Yes      | -       | Search query (brand name, keywords)              |
| `country`  | string | No       | `"US"`  | Country code (US, JP, UK, etc.)                  |
| `platform` | string | No       | All     | Filter: `facebook`, `instagram`, or omit for all |

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:8080/api/v1/agents/meta-ad-library \
  -H "X-API-Key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "query": "nike running shoes",
      "country": "US",
      "platform": "instagram"
    }
  }'
```

**Output Structure:**

```json theme={null}
{
  "search_params": {
    "query": "nike running shoes",
    "country": "US",
    "source": "meta_ad_library"
  },
  "summary": {
    "total_ads_found": 245,
    "active_ads": 18,
    "platforms": ["FACEBOOK", "INSTAGRAM"],
    "unique_advertisers": 5
  },
  "competitors": [
    {
      "name": "Nike Official",
      "domain": "nike.com",
      "page_id": "123456789",
      "ad_count": 18,
      "platforms": ["INSTAGRAM"],
      "sample_ads": [
        {
          "title": "Run Further. Run Faster.",
          "description": "Discover the new Nike Air Zoom...",
          "link": "https://www.nike.com/running",
          "cta": "Shop Now",
          "platforms": ["INSTAGRAM"],
          "images": ["https://..."],
          "display_format": "image"
        }
      ],
      "source": "meta_ad_library"
    }
  ],
  "cost_usd": 0.004,
  "timestamp": "2026-02-15T10:30:00Z"
}
```

***

### competitor-discover

Discover competitor advertisers for given keywords across devices and locations.

**Agent ID:** `competitor-discover`

**Input Schema:**

| Field                  | Type             | Required | Default                 | Description                                      |
| ---------------------- | ---------------- | -------- | ----------------------- | ------------------------------------------------ |
| `keywords`             | array of strings | Yes      | -                       | Search keywords to find competitors              |
| `country`              | string           | No       | `"us"`                  | Country code                                     |
| `language`             | string           | No       | `"en"`                  | Language code                                    |
| `location`             | string           | No       | -                       | Specific location (e.g., "Tokyo, Japan")         |
| `devices`              | array of strings | No       | `["desktop", "mobile"]` | Devices to search                                |
| `transparency_top_n`   | integer          | No       | `5`                     | Top N competitors to fetch transparency data for |
| `max_competitors`      | integer          | No       | `20`                    | Maximum competitors to return                    |
| `include_transparency` | boolean          | No       | `false`                 | Fetch Google Ads Transparency data               |
| `organic_fallback`     | boolean          | No       | `true`                  | Use organic results when no paid ads             |

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:8080/api/v1/agents/competitor-discover \
  -H "X-API-Key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "keywords": ["running shoes", "athletic footwear"],
      "country": "us",
      "devices": ["desktop", "mobile"],
      "include_transparency": true,
      "transparency_top_n": 3
    }
  }'
```

**Output Structure:**

```json theme={null}
{
  "competitors": [
    {
      "domain": "nike.com",
      "ad_count": 15,
      "devices_found": ["desktop", "mobile"],
      "sample_ads": [
        {
          "title": "Nike Running Shoes",
          "description": "Find your perfect running shoe...",
          "link": "https://nike.com/running",
          "device": "desktop"
        }
      ],
      "transparency_data": {
        "advertiser_id": "AR12345678",
        "total_ads": 523,
        "platforms": ["SEARCH", "YOUTUBE"]
      }
    }
  ],
  "total_ads_found": 45,
  "api_cost_usd": 0.03
}
```

***

### ads-transparency

Multi-platform ad transparency: Google Transparency Center, Yahoo JP ads, Meta Ad Library.

**Agent ID:** `ads-transparency`

**Input Schema:**

| Field             | Type   | Required | Description                                                        |
| ----------------- | ------ | -------- | ------------------------------------------------------------------ |
| `advertiser_id`   | string | No       | Google Ads advertiser ID (preferred for Google)                    |
| `domain`          | string | No       | Domain name (Google fallback, Yahoo keyword, Meta query)           |
| `country`         | string | No       | Country code (e.g., 'jp', 'us') - controls auto-platform selection |
| `platforms`       | array  | No       | Override auto-selection: `['google', 'yahoo', 'meta']`             |
| `platform`        | string | No       | Google platform filter: `SEARCH`, `YOUTUBE`, `SHOPPING`, etc.      |
| `meta_platform`   | string | No       | Meta platform filter: `facebook`, `instagram`                      |
| `creative_format` | string | No       | Google ad format: `TEXT`, `IMAGE`, `VIDEO`                         |
| `start_date`      | string | No       | Start date (YYYY-MM-DD)                                            |
| `end_date`        | string | No       | End date (YYYY-MM-DD)                                              |

**Example Request (Japan market, all platforms):**

```bash theme={null}
curl -X POST http://localhost:8080/api/v1/agents/ads-transparency \
  -H "X-API-Key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "domain": "7card.co.jp",
      "country": "jp"
    }
  }'
```

**Output Structure:**

```json theme={null}
{
  "google": {
    "advertiser_id": "AR12345678",
    "total_ads": 523,
    "platforms": ["SEARCH", "YOUTUBE"],
    "sample_ads": [...]
  },
  "yahoo_jp": {
    "total_ads": 3,
    "ads": [...]
  },
  "meta": {
    "total_ads": 18,
    "platforms": ["FACEBOOK", "INSTAGRAM"],
    "advertisers": [...]
  },
  "platforms_queried": ["google", "yahoo_jp", "meta"],
  "country": "jp",
  "errors": {}
}
```

***

### lp-visual-analyze

Screenshot and analyze a landing page using Playwright + Vision LLM.

**Agent ID:** `lp-visual-analyze`

**Input Schema:**

| Field              | Type    | Required | Default       | Description                                    |
| ------------------ | ------- | -------- | ------------- | ---------------------------------------------- |
| `url`              | string  | Yes      | -             | Landing page URL to analyze                    |
| `language`         | string  | No       | `"en"`        | Language for OCR (ja, zh, ko enable OCR)       |
| `full_page`        | boolean | No       | `true`        | Capture full scrolled page                     |
| `analysis_prompt`  | string  | No       | -             | Custom analysis prompt                         |
| `include_markdown` | boolean | No       | `true`        | Include extracted text content                 |
| `enable_ocr`       | boolean | No       | Auto          | Force enable/disable OCR                       |
| `capture_mode`     | string  | No       | `"full_page"` | `full_page` or `sections`                      |
| `device`           | string  | No       | `"desktop"`   | Device viewport: `desktop`, `mobile`, `tablet` |
| `max_sections`     | integer | No       | `8`           | Max sections in sections mode                  |

**Example Request (Full page analysis):**

```bash theme={null}
curl -X POST http://localhost:8080/api/v1/agents/lp-visual-analyze \
  -H "X-API-Key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "url": "https://www.7card.co.jp/lp/plus/",
      "language": "ja",
      "full_page": true,
      "include_markdown": true
    }
  }'
```

**Output Structure (full\_page mode):**

```json theme={null}
{
  "url": "https://www.7card.co.jp/lp/plus/",
  "screenshot_url": "https://storage.firecrawl.dev/...",
  "vision_analysis": {
    "success": true,
    "structured": {
      "above_the_fold": {
        "main_headline": "セブンカード・プラス",
        "primary_cta": {"text": "今すぐ申し込む", "color": "orange"}
      },
      "page_sections": [
        {"name": "Hero", "position": 1, "key_content": "Main headline and CTA"}
      ],
      "pricing": {"visible": true, "currency": "JPY"},
      "trust_elements": {"testimonials": {"count": 3}},
      "visual_design": {"primary_colors": ["orange", "white"], "style": "modern"}
    },
    "cost_usd": {
      "vision": 0.0016,
      "scrape": 0.0053,
      "ocr": 0.0015,
      "total": 0.0084
    }
  }
}
```

<Warning>
  **Large Binary Data**: Screenshots >500KB are stored in Redis and replaced with blob references. Use `/api/v1/blob/{key}` to retrieve the actual image data. See [Blob Storage API](/en/api/rest/agents#blob-storage) for details.
</Warning>

***

### lp-batch-analyze

Analyze multiple landing pages in parallel.

**Agent ID:** `lp-batch-analyze`

**Input Schema:**

| Field              | Type             | Required | Default     | Description                        |
| ------------------ | ---------------- | -------- | ----------- | ---------------------------------- |
| `urls`             | array of strings | Yes      | -           | List of landing page URLs (max 10) |
| `language`         | string           | No       | `"en"`      | Language code                      |
| `full_page`        | boolean          | No       | `false`     | Capture full page                  |
| `device`           | string           | No       | `"desktop"` | Device viewport                    |
| `analysis_prompt`  | string           | No       | -           | Custom analysis prompt             |
| `include_markdown` | boolean          | No       | `false`     | Include extracted text             |

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:8080/api/v1/agents/lp-batch-analyze \
  -H "X-API-Key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "urls": [
        "https://competitor1.com/landing",
        "https://competitor2.com/offer",
        "https://competitor3.com/product"
      ],
      "device": "mobile",
      "language": "en"
    }
  }'
```

**Output Structure:**

```json theme={null}
{
  "batch_id": "batch-abc123",
  "total_urls": 3,
  "successful": 3,
  "failed": 0,
  "results": [
    {
      "url": "https://competitor1.com/landing",
      "success": true,
      "vision_analysis": {
        "structured": {"above_the_fold": {"main_headline": "..."}},
        "cost_usd": {"total": 0.008}
      }
    }
  ],
  "cost_usd": {
    "firecrawl": 0.0159,
    "vision": 0.0045,
    "total": 0.0204
  }
}
```

***

### ad-creative-analyze

Analyze ad copy patterns, persuasion techniques, and messaging gaps.

**Agent ID:** `ad-creative-analyze`

**Input Schema:**

| Field         | Type             | Required | Default     | Description                                                    |
| ------------- | ---------------- | -------- | ----------- | -------------------------------------------------------------- |
| `ads`         | array of objects | Yes      | -           | Ad objects to analyze                                          |
| `competitors` | array of objects | No       | -           | Optional competitor objects                                    |
| `industry`    | string           | No       | `"general"` | Industry preset: `ecommerce`, `shoes`, `finance`, `saas`, etc. |
| `language`    | string           | No       | `"en"`      | Language of ad copy                                            |

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:8080/api/v1/agents/ad-creative-analyze \
  -H "X-API-Key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "ads": [
        {
          "title": "Best Running Shoes 2026",
          "description": "Ultra-lightweight design with maximum cushioning...",
          "domain": "nike.com"
        },
        {
          "title": "Run Like a Pro",
          "description": "Professional-grade performance for everyday runners...",
          "domain": "adidas.com"
        }
      ],
      "industry": "shoes",
      "language": "en"
    }
  }'
```

**Output Structure:**

```json theme={null}
{
  "headline_patterns": [
    "Year-based urgency (2026)",
    "Superlative positioning (Best, Ultra)"
  ],
  "persuasion_techniques": [
    "Social proof (Pro endorsement)",
    "Performance benefits (lightweight, cushioning)"
  ],
  "cta_patterns": [
    "Direct action (Shop Now)",
    "Information seeking (Learn More)"
  ],
  "emotional_triggers": [
    "Aspiration (Run Like a Pro)",
    "Safety (maximum cushioning)"
  ],
  "competitive_gaps": [
    "No price messaging in competitor ads",
    "Limited warranty/guarantee mentions"
  ],
  "recommendations": [
    "Test price-focused headlines",
    "Add money-back guarantee in copy"
  ],
  "api_cost_usd": 0.02
}
```

***

### keyword-extract

Extract search keywords from a natural language query.

**Agent ID:** `keyword-extract`

<Note type="success">
  **Open Source Compatible**: Works in Shannon OSS with your LLM provider API key.
</Note>

**Input Schema:**

| Field          | Type    | Required | Default       | Description                                   |
| -------------- | ------- | -------- | ------------- | --------------------------------------------- |
| `query`        | string  | Yes      | -             | Natural language query or product description |
| `country`      | string  | No       | `"us"`        | Target country for keyword localization       |
| `language`     | string  | No       | Auto-detected | Preferred language for keywords               |
| `max_keywords` | integer | No       | `5`           | Maximum keywords to extract                   |

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:8080/api/v1/agents/keyword-extract \
  -H "X-API-Key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "query": "I need shoes for marathon training in winter conditions",
      "country": "us",
      "max_keywords": 3
    }
  }'
```

**Output Structure:**

```json theme={null}
{
  "keywords": [
    "marathon training shoes",
    "winter running shoes",
    "cold weather athletic footwear"
  ],
  "detected_language": "en",
  "detected_country": "us",
  "api_cost_usd": 0.001
}
```

***

### browser-screenshot

Navigate to a URL and capture a screenshot using Playwright.

**Agent ID:** `browser-screenshot`

**Input Schema:**

| Field        | Type    | Required | Default              | Description                                                        |
| ------------ | ------- | -------- | -------------------- | ------------------------------------------------------------------ |
| `url`        | string  | Yes      | -                    | URL to capture                                                     |
| `full_page`  | boolean | No       | `false`              | Capture full scrolled page                                         |
| `wait_until` | string  | No       | `"domcontentloaded"` | When navigation is done: `load`, `domcontentloaded`, `networkidle` |
| `timeout_ms` | integer | No       | `30000`              | Navigation timeout (milliseconds)                                  |

**Example Request:**

```bash theme={null}
curl -X POST http://localhost:8080/api/v1/agents/browser-screenshot \
  -H "X-API-Key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "url": "https://www.nike.com",
      "full_page": true
    }
  }'
```

**Output Structure:**

```json theme={null}
{
  "screenshot": "iVBORw0KGgoAAAANSUhEUgA...",  // Base64 PNG
  "url": "https://www.nike.com",
  "title": "Nike. Just Do It."
}
```

<Note>
  **Base64 encoding**: Screenshot is returned as base64-encoded PNG. For large images (>500KB), a blob reference is returned instead. See [Blob Storage API](#blob-storage).
</Note>

***

## Blob Storage API

For responses containing large base64 data (screenshots >500KB), the data is stored in Redis and replaced with a reference object.

**Response Format with Blob Reference:**

```json theme={null}
{
  "screenshot_b64": null,
  "screenshot_b64_ref": {
    "redis_key": "shannon:blob:task-abc123:screenshot_b64",
    "size": 1500000,
    "ttl_days": 7
  }
}
```

**Retrieving Blob Data:**

```bash theme={null}
curl -H "X-API-Key: sk_your_api_key" \
  "http://localhost:8080/api/v1/blob/shannon:blob:task-abc123:screenshot_b64"
```

**Returns:** Raw base64 string (Content-Type: text/plain)

**Blob Properties:**

* TTL: 7 days (refreshed on each access)
* Cache-Control: 7-day client caching
* Affected fields: `screenshot_b64`, `popup_screenshot_b64`, `data_base64`, `image_base64`, `screenshot`

***

## Common Workflows

### Workflow 1: Competitor Ad Discovery

```python theme={null}
import httpx

client = httpx.Client(
    base_url="http://localhost:8080",
    headers={"X-API-Key": "sk_your_api_key"}
)

# Step 1: Discover competitors
competitors = client.post("/api/v1/agents/competitor-discover", json={
    "input": {
        "keywords": ["running shoes", "athletic footwear"],
        "include_transparency": True
    }
}).json()

# Step 2: Analyze their ads
for competitor in competitors["competitors"][:3]:
    ads_analysis = client.post("/api/v1/agents/ad-creative-analyze", json={
        "input": {
            "ads": competitor["sample_ads"],
            "industry": "shoes"
        }
    }).json()

    print(f"{competitor['domain']}: {ads_analysis['recommendations']}")
```

### Workflow 2: Landing Page Competitive Analysis

```python theme={null}
# Step 1: Get competitor domains
competitors = client.post("/api/v1/agents/serp-ads", json={
    "input": {"keywords": "credit cards", "max_results": 5}
}).json()

# Step 2: Batch analyze their landing pages
lp_urls = [ad["link"] for ad in competitors["ads"]]

lp_analysis = client.post("/api/v1/agents/lp-batch-analyze", json={
    "input": {
        "urls": lp_urls,
        "device": "mobile",
        "language": "en"
    }
}).json()

# Step 3: Compare results
for result in lp_analysis["results"]:
    print(f"{result['url']}: {result['vision_analysis']['structured']['above_the_fold']}")
```

### Workflow 3: Multi-Platform Ad Tracking

```python theme={null}
# Track a single brand across Google, Yahoo JP, Meta
transparency = client.post("/api/v1/agents/ads-transparency", json={
    "input": {
        "domain": "7card.co.jp",
        "country": "jp"
    }
}).json()

print("Platforms found:")
for platform in transparency["platforms_queried"]:
    data = transparency[platform]
    print(f"  {platform}: {data.get('total_ads', 0)} ads")
```

***

## Related

<CardGroup cols={2}>
  <Card title="Agents API Reference" icon="code" href="/en/api/rest/agents">
    Complete API endpoint documentation
  </Card>

  <Card title="Financial Agents" icon="chart-line" href="/en/api/agents/financial">
    Stock news and sentiment analysis agents
  </Card>

  <Card title="Get Task Status" icon="circle-info" href="/en/api/rest/get-status">
    Retrieve agent execution results
  </Card>

  <Card title="Agents Overview" icon="list" href="/en/api/agents/overview">
    Full agent catalog and availability matrix
  </Card>
</CardGroup>
