Official Python client for Surmado's AI visibility testing and SEO reports.
One-time reports. No subscriptions. API-first.
pip install surmadofromsurmadoimportSurmadoclient=Surmado() # uses SURMADO_API_KEY env var# Run an AI Visibility Testreport=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/ for runnable scripts.
/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/ | Python package source (surmado/), unit tests |
| examples/ | Quick start script, ready to run with your API key |
| integrations/ | Step-by-step guides for Zapier, Make, n8n, and webhook setup |
| 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 |
result=client.signal(
url="https://acme.com",
brand_name="Acme Corp", # max 100 charsemail="you@acme.com",
industry="B2B SaaS", # max 200 charslocation="United States", # max 200 charspersona="CTOs at mid-market companies", # max 800 charspain_points="Integration challenges, lack of visibility", # max 1000 charsbrand_details="Modern, dev-focused tooling", # max 1200 charsdirect_competitors="Asana, Monday.com", # max 500 chars
)result=client.scan(
url="https://acme.com",
brand_name="Acme Corp",
email="you@acme.com",
competitor_urls=["https://competitor1.com", "https://competitor2.com"]
)Mode 1: With Signal Token (recommended)
signal_result=client.signal(...)
solutions_result=client.solutions(
email="you@acme.com",
signal_token=signal_result["token"]
)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"
)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"
)result=client.bundle(
brand_slug="acme_corp",
email="you@acme.com"
)
# Creates Scan + Signal + Solutions in one call (3 credits)Once you've set up a brand with personas in the Surmado dashboard, run reports with minimal code:
# Signal: 3 fields instead of 10+result=client.signal_rerun(
brand_slug="acme_corp",
persona_slug="cto-enterprise",
email="you@acme.com"
)
# Scan: 2 fieldsresult=client.scan_rerun(
brand_slug="acme_corp",
email="you@acme.com"
)Perfect for Zapier/Make/n8n workflows, scheduled monitoring, and dashboard integrations. See integrations/ for setup guides.
# List all brandsbrands=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",
website="https://acme.com"
)All reports process asynchronously (~15 minutes). Two ways to get results:
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"])report=client.signal(
...,
webhook_url="https://your-server.com/webhook"
)
# Your webhook receives POST with full report data when completeSee integrations/webhooks.md for payload format and handler examples.
Access raw report data (metrics, analysis) as JSON:
# Full datadata=client.get_report_data("rpt_abc123")
# Specific fields onlydata=client.get_report_data("rpt_abc123", fields=["status", "insights"])fromsurmadoimport (
Surmado,
AuthenticationError,
InsufficientCreditsError,
NotFoundError,
ValidationError,
RateLimitError,
SurmadoError
)
client=Surmado()
try:
result=client.signal(...)
exceptAuthenticationError:
print("Invalid or missing API key")
exceptInsufficientCreditsErrorase:
print(f"Not enough credits: {e.response}")
exceptRateLimitError:
print("Too many requests - back off and retry")
exceptNotFoundError:
print("Brand or report not found")
exceptValidationErrorase:
print(f"Invalid request params: {e}")
exceptSurmadoErrorase:
print(f"API error: {e.status_code} - {e}")| 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.
result=client.test_auth()
print(f"Authenticated as: {result.get('org_id')}")Default request timeout is 30 seconds. Configure per-client:
client=Surmado(timeout=60)For wait_for_report, the polling timeout is separate:
completed=client.wait_for_report(report_id, timeout_minutes=30)Report creation returns HTTP 202 Accepted:
{
"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):
{
"status": "completed",
"download_url": "https://storage.googleapis.com/...", # PDF"pptx_download_url": "https://storage.googleapis.com/...", # PPTX
}See integrations/webhooks.md for the full webhook payload reference, including field tables for Signal and Scan summary data.
| 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 |
All reports are $50 each. No subscriptions.
| Product | Price | Credits |
|---|---|---|
| Signal | $50 | 1 |
| Scan | $50 | 1 |
| Solutions | $50 | 1 |
This package follows SemVer. To check your installed version:
importsurmadoprint(surmado.__version__)- Docs:help.surmado.com/docs/api-reference
- API Key:surmado.com/login
- Client Source:client/
- Examples:examples/
- Integrations:integrations/
- Issues:github.com/surmado/surmado-python/issues
MIT