Metadata-Version: 2.4
Name: surmado
Version: 0.3.1
Summary: Official Python client for Surmado's AI visibility testing and SEO reports
Project-URL: Homepage, https://surmado.com
Project-URL: Documentation, https://help.surmado.com/docs/api-reference/
Project-URL: Repository, https://github.com/surmado/surmado-python
Project-URL: Issues, https://github.com/surmado/surmado-python/issues
Project-URL: Changelog, https://github.com/surmado/surmado-python/blob/main/CHANGELOG.md
Author-email: Surmado Engineering <engineering@surmado.com>
License-Expression: MIT
License-File: LICENSE
Keywords: ai,analytics,chatgpt,geo,llm,marketing,perplexity,seo,surmado,visibility
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Requires-Dist: requests>=2.25.0
Description-Content-Type: text/markdown

# Surmado Python SDK

[![PyPI version](https://img.shields.io/pypi/v/surmado.svg)](https://pypi.org/project/surmado/)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)

Official Python client for Surmado's AI visibility testing and SEO reports.

One-time reports. No subscriptions. API-first.

## Installation

```bash
pip install surmado
```

## Quick Start

```python
from surmado import Surmado

client = Surmado()  # uses SURMADO_API_KEY env var

# Run an AI Visibility Test
report = client.signal(
    url="https://example.com",
    brand_name="Example Brand",
    email="you@example.com",
    industry="E-commerce",
    location="United States",
    persona="Small business owners looking for affordable solutions",
    pain_points="Finding reliable vendors, managing costs",
    brand_details="Affordable solutions for growing businesses",
    direct_competitors="Competitor A, Competitor B"
)

print(f"Report queued: {report['report_id']}")

# Wait for completion (or use webhooks)
completed = client.wait_for_report(report["report_id"])
print(f"PDF ready: {completed['download_url']}")
print("(Save for Surmado Solutions) Report Token: ", completed['token'])
```

See [examples/](examples/) for runnable scripts.

## Repository Structure

```text
/client          ← SDK client code (surmado package)
/examples        ← Runnable usage examples
/integrations    ← Integration guides (Zapier, Make, n8n, Webhooks)
README.md        ← You are here
```

| Directory                      | Contents                                                     |
| ------------------------------ | ------------------------------------------------------------ |
| [client/](client/)             | Python package source (`surmado/`), unit tests               |
| [examples/](examples/)         | Quick start script, ready to run with your API key           |
| [integrations/](integrations/) | Step-by-step guides for Zapier, Make, n8n, and webhook setup |

## API Surface

### Products

| Method                   | Description                                                      | Credits |
| ------------------------ | ---------------------------------------------------------------- | ------- |
| `client.signal(...)`     | AI Visibility report — tests your brand across 7 AI platforms    | 1       |
| `client.scan(...)`       | Site Audit — comprehensive SEO analysis                          | 1       |
| `client.solutions(...)`  | Strategy — multi-AI strategic recommendations from 6 agents      | 1       |
| `client.bundle(...)`     | Full Analysis — all 3 reports in one call                        | 3       |

### Signal — AI Visibility Testing

```python
result = client.signal(
    website="https://acme.com",
    brand_name="Acme Corp",                              # max 100 chars
    email="you@acme.com",
    industry="B2B SaaS",                                 # max 200 chars
    location="United States",                            # max 200 chars
    persona="CTOs at mid-market companies",              # max 800 chars
    pain_points="Integration challenges, lack of visibility",  # max 1000 chars
    brand_details="Modern, dev-focused tooling",         # max 1200 chars
    direct_competitors="Asana, Monday.com",              # max 500 chars
)
```

### Scan — SEO Auditing

```python
result = client.scan(
    website="https://acme.com",
    brand_name="Acme Corp",
    email="you@acme.com",
    competitor_urls=["https://competitor1.com", "https://competitor2.com"]
)
```

### Solutions — Strategic Advisory

**Mode 1: With Signal Token** (recommended)

```python
signal_result = client.signal(...)
solutions_result = client.solutions(
    email="you@acme.com",
    signal_token=signal_result["token"]
)
```

#### Mode 2: Standalone

```python
result = client.solutions(
    email="you@acme.com",
    brand_name="Acme Corp",
    business_story="We're a B2B SaaS company in project management...",
    decision="Should we expand to enterprise market?",
    success="$10M ARR in 18 months",
    timeline="Q2 2025",
    scale_indicator="$2M ARR, 20 employees"
)
```

#### Mode 3: With Financial Analysis

```python
result = client.solutions(
    email="you@acme.com",
    signal_token=signal_result["token"],
    include_financial=True,
    financial_context="Growing but need to optimize costs",
    monthly_revenue="$50K",
    monthly_costs="$40K",
    cash_available="$200K"
)
```

### Bundle — Full Analysis

```python
result = client.bundle(
    brand_slug="acme_corp",
    email="you@acme.com"
)
# Creates Scan + Signal + Solutions in one call (3 credits)
```

## Rerun Methods

Once you've set up a brand with personas in the Surmado dashboard, run reports with minimal code:

```python
# Signal: 3 fields instead of 10+
result = client.signal_rerun(
    brand_slug="acme_corp",
    persona_slug="cto-enterprise",
    email="you@acme.com"
)

# Scan: 2 fields
result = client.scan_rerun(
    brand_slug="acme_corp",
    email="you@acme.com"
)
```

Perfect for Zapier/Make/n8n workflows, scheduled monitoring, and dashboard integrations. See [integrations/](integrations/) for setup guides.

## Brand Management

```python
# List all brands
brands = client.list_brands()

# Create a brand (fails if already exists)
brand = client.create_brand(
    brand_name="Acme Corp",
    website="https://acme.com",
    industry="B2B SaaS"
)

# Create or get existing brand (never fails with conflict)
brand = client.ensure_brand(
    brand_name="Acme Corp",
    url="https://acme.com"
)
```

## Async Reports & Polling

All reports process asynchronously (~15 minutes). Two ways to get results:

### Polling

```python
report = client.signal(...)

# Block until complete (default 20 min timeout)
completed = client.wait_for_report(report["report_id"], timeout_minutes=20)
print(completed["download_url"])
```

### Webhooks

```python
report = client.signal(
    ...,
    webhook_url="https://your-server.com/webhook"
)
# Your webhook receives POST with full report data when complete
```

See [integrations/webhooks.md](integrations/webhooks.md) for payload format and handler examples.

## Report Data

Access raw report data (metrics, analysis) as JSON:

```python
# Full data
data = client.get_report_data("rpt_abc123")

# Specific fields only
data = client.get_report_data("rpt_abc123", fields=["status", "insights"])
```

## Handling Errors

```python
from surmado import (
    Surmado,
    AuthenticationError,
    InsufficientCreditsError,
    NotFoundError,
    ValidationError,
    RateLimitError,
    SurmadoError
)

client = Surmado()

try:
    result = client.signal(...)
except AuthenticationError:
    print("Invalid or missing API key")
except InsufficientCreditsError as e:
    print(f"Not enough credits: {e.response}")
except RateLimitError:
    print("Too many requests - back off and retry")
except NotFoundError:
    print("Brand or report not found")
except ValidationError as e:
    print(f"Invalid request params: {e}")
except SurmadoError as e:
    print(f"API error: {e.status_code} - {e}")
```

### Error Status Mapping

| Status Code | Exception                  |
| ----------- | -------------------------- |
| 400         | `ValidationError`          |
| 401         | `AuthenticationError`      |
| 402         | `InsufficientCreditsError` |
| 404         | `NotFoundError`            |
| 422         | `ValidationError`          |
| 429         | `RateLimitError`           |
| >=500       | `SurmadoError`             |

All exceptions inherit from `SurmadoError` and include `status_code` and `response` attributes.

## Test Your Key

```python
result = client.test_auth()
print(f"Authenticated as: {result.get('org_id')}")
```

## Timeouts

Default request timeout is 30 seconds. Configure per-client:

```python
client = Surmado(timeout=60)
```

For `wait_for_report`, the polling timeout is separate:

```python
completed = client.wait_for_report(report_id, timeout_minutes=30)
```

## Response Format

Report creation returns HTTP 202 Accepted:

```python
{
    "report_id": "rpt_abc123def456",
    "token": "tok_xyz789abc123",  # Save for Solutions Mode 1
    "org_id": "org_xyz789",
    "product": "signal",
    "status": "queued",
    "brand_slug": "example_brand",
    "brand_name": "Example Brand",
    "credits_used": 1,
    "created_at": "2025-01-15T10:30:00Z"
}
```

Completed reports include download URLs (expire in 15 minutes):

```python
{
    "status": "completed",
    "download_url": "https://storage.googleapis.com/...",      # PDF
    "pptx_download_url": "https://storage.googleapis.com/...", # PPTX
}
```

## Webhook Payload

See [integrations/webhooks.md](integrations/webhooks.md) for the full webhook payload reference, including field tables for Signal and Scan summary data.

## Field Length Limits

| Field                | Max Length |
| -------------------- | ---------- |
| brand_name           | 100 chars  |
| industry             | 200 chars  |
| location             | 200 chars  |
| persona              | 800 chars  |
| pain_points          | 1000 chars |
| brand_details        | 1200 chars |
| direct_competitors   | 500 chars  |
| indirect_competitors | 500 chars  |
| keywords             | 500 chars  |
| product              | 1000 chars |
| business_story       | 2000 chars |
| decision             | 1500 chars |
| success              | 1000 chars |
| timeline             | 200 chars  |
| scale_indicator      | 100 chars  |

## Pricing

All reports are $50 each. No subscriptions.

| Product   | Price | Credits |
| --------- | ----- | ------- |
| Signal    | $50   | 1       |
| Scan      | $50   | 1       |
| Solutions | $50   | 1       |

## Versioning

This package follows [SemVer](https://semver.org/). To check your installed version:

```python
import surmado
print(surmado.__version__)
```

## Links

- **Docs:** [help.surmado.com/docs/api-reference](https://help.surmado.com/docs/api-reference/)
- **API Key:** [surmado.com/login](https://surmado.com/login)
- **Client Source:** [client/](client/)
- **Examples:** [examples/](examples/)
- **Integrations:** [integrations/](integrations/)
- **Issues:** [github.com/surmado/surmado-python/issues](https://github.com/surmado/surmado-python/issues)

## License

MIT
