Surmado API Reference
25 min read
TL;DR
The Surmado API lets you create Surmado Signal, Surmado Scan, and Surmado Solutions reports programmatically. Authenticate with Bearer tokens, consume credits per report, and receive webhooks when complete. White-label mode included at no extra cost for agencies.
Key Terms in this Guide
- API Key
- Your authentication token (format: sur_live_...). Get it from Settings > API Keys in the dashboard.
- Credits
- 1 credit = $25. Surmado Scan and Surmado Signal use 1 credit for basic or 2 credits for pro. Surmado Solutions uses 2 credits ($50).
- White-Label
- Agency branding that removes Surmado mentions from reports. Included free with all API requests.
Surmado API Reference
Build AI visibility, SEO audits, and strategic insights into your application.
Base URL: https://api.surmado.com
Quick Start
Get your first report in 2 minutes:
1. Get Your API Key
- Log into the Surmado Dashboard
- Navigate to Settings → API Keys
- Click Create New API Key
- Save the key (shown only once!)
2. Create Your First Report
Simple approach - just send brand_name:
curl -X POST https://api.surmado.com/v1/reports/signal \
-H "Authorization: Bearer sur_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"brand_name": "Acme Corp",
"tier": "basic",
"email": "you@acme.com",
"industry": "SaaS",
"business_scale": "startup",
"location": "San Francisco",
"product": "Project management software",
"persona": "CTOs at tech companies",
"pain_points": "Team collaboration challenges",
"brand_details": "Modern PM tool for technical teams",
"direct_competitors": "Asana, Monday"
}'
3. Get Your Report
# Response includes report_id and auto-generated brand_slug
{"id": "rpt_abc123", "status": "queued", "brand_slug": "acme_corp", "brand_created": true}
# Check status (API processing usually takes 2-5 minutes)
curl https://api.surmado.com/v1/reports/rpt_abc123 \
-H "Authorization: Bearer sur_live_YOUR_API_KEY"
# When status is "completed", download_url is ready
{"status": "completed", "download_url": "https://storage.googleapis.com/..."}
That’s it! You now have a PDF report analyzing your AI visibility.
Note: We auto-created
brand_slug: "acme_corp"from yourbrand_name. Save this for future reports! Timing: Most reports finish in about 15 minutes end-to-end. The API processing window shown above is usually a few minutes.
Want to explore the live API schema? Open the interactive API docs →
Table of Contents
- Authentication
- Surmado Signal API - AI visibility reports
- Surmado Scan API - SEO audits
- Surmado Solutions API - Strategic consulting
- Retrieving Reports
- API Key Management
- White-Label Mode
- Error Handling
- Webhooks
- Code Examples
Authentication
All API requests require an API key in the Authorization header:
Authorization: Bearer sur_live_YOUR_API_KEY
Getting Your API Key
- Log into the Surmado Dashboard
- Navigate to Settings → API Keys
- Click Create New API Key
- Save the key securely (shown only once!)
Test Mode
Use test keys for development without consuming credits:
Authorization: Bearer sur_test_fake_key_for_testing
Public API
The Surmado API is publicly accessible (no Cloud Run IAM auth required). Security is handled by FastAPI at the application layer. Invalid credentials are rejected with 401 errors before reaching any business logic.
Signal API
Create Surmado Signal reports analyzing how your brand appears in ChatGPT, Claude, Gemini, and other AI platforms.
Endpoint
POST /v1/reports/signal
Pricing
| Tier | Credits | Description |
|---|---|---|
basic | 1 | Essential visibility analysis |
pro | 2 | competitive analysis with 56 queries |
Required Fields
{
// Brand (REQUIRED - Use ONE of these)
"brand_name": "string", // Simple: We auto-create brand_slug
// OR
"brand_slug": "string", // Advanced: You created brand first
// Configuration (REQUIRED)
"tier": "basic", // "basic" or "pro"
"email": "string (email)", // Contact email
// Brand Details (REQUIRED)
"industry": "string", // Your industry
"business_scale": "string", // startup, local, regional, national, global
"location": "string", // Primary location
"product": "string", // What you offer
"persona": "string", // Target customer persona
"pain_points": "string", // Customer pain points you solve
"brand_details": "string", // Detailed brand description
"direct_competitors": "string", // Comma-separated competitor names
// Optional Fields
"keywords": "string", // Optional: Comma-separated keywords
"competitor_urls": ["string"] // Optional: Array of competitor URLs
}
Example Request
curl -X POST https://api.surmado.com/v1/reports/signal \
-H "Authorization: Bearer sur_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"brand_name": "Surmado",
"tier": "basic",
"email": "hi@surmado.com",
"industry": "Software / SaaS",
"business_scale": "national",
"location": "United States",
"product": "Digital visibility software",
"persona": "Agencies and SMBs seeking AI intelligence",
"pain_points": "Invisible to AI discovery, losing to competitors in ChatGPT/Claude",
"brand_details": "Surmado provides AI visibility intelligence for agencies and SMBs",
"direct_competitors": "Profound, Gumshoe",
"keywords": "AI visibility, competitive intelligence, SEO",
"competitor_urls": ["https://tryprofound.ai", "https://gumshoe.ai"]
}'
Response
{
"id": "rpt_abc123xyz",
"token": "SIG-2025-11-XXXXX",
"product": "signal",
"status": "queued",
"brand_slug": "surmado",
"brand_name": "Surmado",
"brand_created": true,
"created_at": "2025-11-14T01:00:00Z"
}
Status Values:
queued- Report created, waiting to processprocessing- AI analysis in progress (2-5 minutes)completed- Report ready,download_urlavailablefailed- Error occurred, seeerror_message
Scan API
Create Surmado Scan reports with SEO, performance, accessibility, and technical analysis.
Endpoint
POST /v1/reports/pulse
Note: The endpoint is
/pulsebut responses show"product": "scan".
Pricing
| Tier | Credits | Pages | Features |
|---|---|---|---|
basic | 1 | 30 | Performance, technical SEO, accessibility |
premium | 2 | 100 | Everything + competitor analysis |
Required Fields
{
// Brand (REQUIRED - Use ONE of these)
"brand_name": "string", // Simple: We auto-create brand_slug
// OR
"brand_slug": "string", // Advanced: You created brand first
// Configuration (REQUIRED)
"url": "string (URL)", // Website to audit
"email": "string (email)", // Contact email
"tier": "string", // "basic" or "premium"
// Optional Fields
"report_style": "string", // Optional: "executive", "technical", or "comprehensive"
"competitor_urls": ["string"], // Optional: Competitor URLs (premium only)
"webhook_url": "string (URL)" // Optional: Completion notification
}
Example Request
curl -X POST https://api.surmado.com/v1/reports/pulse \
-H "Authorization: Bearer sur_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"brand_name": "Surmado",
"url": "https://surmado.com",
"email": "hi@surmado.com",
"tier": "premium",
"report_style": "executive",
"competitor_urls": ["https://competitor1.com"],
"webhook_url": "https://your-app.com/webhooks/scan"
}'
Response
{
"id": "rpt_xyz789abc",
"token": "SCAN-2025-11-XXXXX",
"product": "scan",
"status": "queued",
"brand_slug": "surmado",
"brand_name": "Surmado",
"brand_created": false,
"created_at": "2025-11-14T01:00:00Z"
}
Solutions API
Create Surmado Solutions reports with multi-AI strategic recommendations.
Endpoint
POST /v1/reports/solutions
Note: Responses show
"product": "strategy".
Pricing
2 credits (flat rate)
Required Fields
{
// Brand (REQUIRED - Use ONE of these)
"brand_name": "string", // Simple: We auto-create brand_slug
// OR
"brand_slug": "string", // Advanced: You created brand first
// Configuration (REQUIRED)
"email": "string (email)", // Contact email
"name": "string", // Contact name
// Business Context (REQUIRED)
"business_story": "string", // Tell us about your business
"decision": "string", // What decision are you making?
"success": "string", // What does success look like?
"timeline": "string", // When do you need to implement?
"scale_indicator": "string", // Business scale/size
// Optional Fields
"signal_token": "string", // Optional: Signal report token for enhanced analysis
"webhook_url": "string (URL)" // Optional: Completion notification
}
Example Request
curl -X POST https://api.surmado.com/v1/reports/solutions \
-H "Authorization: Bearer sur_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"brand_name": "Surmado",
"email": "hi@surmado.com",
"name": "Marketing Team",
"business_story": "B2B SaaS company looking to improve AI visibility",
"decision": "Should we invest in AI-powered content strategy?",
"success": "Ranking in top 3 AI search results for our category",
"timeline": "Q1 2025",
"scale_indicator": "Series A funded, 50 employees",
"signal_token": "SIG-2025-11-XXXXX"
}'
Response
{
"id": "rpt_def456ghi",
"token": "SOLUTIONS-2025-11-XXXXX",
"product": "strategy",
"status": "queued",
"brand_slug": "surmado",
"brand_name": "Surmado",
"brand_created": false,
"created_at": "2025-11-14T01:00:00Z"
}
Retrieving Reports
Get Single Report
GET /v1/reports/{report_id}
Response:
{
"id": "rpt_abc123",
"token": "SIG-2025-11-XXXXX",
"product": "signal",
"status": "completed",
"created_at": "2025-11-14T01:00:00Z",
"completed_at": "2025-11-14T01:05:23Z",
"result_url": "gs://surmado-reports/signal/...",
"download_url": "https://storage.googleapis.com/surmado-reports/signal/...?X-Goog-Signature=...",
"error_message": null
}
Key Fields:
download_url- Pre-signed URL to download PDF (expires in 15 minutes)result_url- GCS path (internal use only)status-queued,processing,completed, orfailed
💡 Pro Tip: The
download_urlgrants temporary access to the PDF. Download directly without additional authentication. The URL expires after 15 minutes for security.
List Reports
GET /v1/reports?page=1&page_size=50
Query Parameters:
page- Page number (default: 1)page_size- Items per page (default: 50, max: 100)product- Filter by:signal,scan, orstrategystatus- Filter by:queued,processing,completed,failed
Response:
{
"reports": [
{
"id": "rpt_abc123",
"token": "SIG-2025-11-XXXXX",
"product": "signal",
"status": "completed",
"created_at": "2025-11-14T01:00:00Z",
"download_url": "https://storage.googleapis.com/...",
"completed_at": "2025-11-14T01:05:23Z"
}
],
"total": 150,
"page": 1,
"page_size": 50
}
Get Report Data (Advanced)
Extract specific fields from reports without downloading the PDF:
GET /v1/reports/{report_id}/data?fields=company_name,industry
Use Cases:
- Query historical report data
- Extract metrics for analytics
- Build custom dashboards
- Retrieve insights programmatically
Query Parameters:
fields(optional) - Comma-separated list of fields to return- Omit to get all data
- Use dot notation for nested fields:
analysis.competitors
Example: Get Specific Fields
curl "https://api.surmado.com/v1/reports/rpt_abc123/data?fields=company_name,status,industry" \
-H "Authorization: Bearer sur_live_YOUR_KEY"
Response:
{
"company_name": "Acme Corp",
"status": "completed",
"industry": "SaaS"
}
Example: Get Nested Fields
curl "https://api.surmado.com/v1/reports/rpt_abc123/data?fields=analysis.market_size,analysis.competitors" \
-H "Authorization: Bearer sur_live_YOUR_KEY"
Response:
{
"analysis": {
"market_size": "$800 billion",
"competitors": ["Competitor A", "Competitor B"]
}
}
Note: Available fields vary by product type and tier. The data structure matches what’s stored in Firestore.
API Key Management
Manage your API keys programmatically or through the dashboard.
Create API Key
POST /v1/api-keys
Request:
{
"name": "Production Integration"
}
Response:
{
"key": "sur_live_abc123...", // ⚠️ Shown only once!
"key_id": "abc123",
"name": "Production Integration",
"created_at": "2025-11-14T01:00:00Z"
}
List API Keys
GET /v1/api-keys
Response:
{
"keys": [
{
"key_id": "abc123",
"name": "Production Integration",
"key_prefix": "sur_live_abc",
"created_at": "2025-11-14T01:00:00Z",
"last_used_at": "2025-11-14T02:30:00Z",
"is_active": true
}
]
}
Revoke API Key
DELETE /v1/api-keys/{key_id}
Response:
{
"revoked": true,
"key_id": "abc123",
"revoked_at": "2025-11-14T03:00:00Z"
}
Revoke All API Keys
Emergency revocation of all keys:
DELETE /v1/api-keys/all
Request:
{
"confirmation": "REVOKE ALL"
}
Response:
{
"revoked_count": 5,
"revoked_at": "2025-11-14T03:00:00Z"
}
White-Label Mode (For Agencies)
Agencies can deliver reports with their own branding, removing all Surmado mentions.
How It Works
Add these fields to any report request:
{
"is_agency_white_label": true,
"agency_name": "Your Agency Name"
}
What Changes:
- Report cover shows your agency name instead of “SIGNAL”/“SCAN”/“SOLUTIONS”
- All “Surmado” mentions replaced with your agency name
- Cross-product promotion sections removed
- Contact information removed
- Surmado branding removed
Example: White-Label Signal Report
curl -X POST https://api.surmado.com/v1/reports/signal \
-H "Authorization: Bearer sur_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"brand_name": "Client Business Inc",
"tier": "basic",
"email": "agency@yourfirm.com",
"industry": "E-commerce",
"business_scale": "regional",
"location": "California",
"product": "Organic skincare products",
"persona": "Health-conscious millennials",
"pain_points": "Finding trustworthy natural brands",
"brand_details": "Family-owned organic skincare company",
"direct_competitors": "Honest Company, Beautycounter",
"is_agency_white_label": true,
"agency_name": "Digital Agency Co"
}'
Result: Report shows “DIGITAL AGENCY CO” on the cover. All Surmado branding removed.
Supported Products
White-label mode works for all products:
- Signal - Add to
/v1/reports/signal - Scan - Add to
/v1/reports/pulse - Solutions - Add to
/v1/reports/solutions
Error Handling
HTTP Status Codes
| Code | Meaning |
|---|---|
200 | Success |
201 | Created (new resource) |
202 | Accepted (report queued) |
400 | Bad Request (invalid data) |
401 | Unauthorized (invalid/revoked API key) |
402 | Payment Required (insufficient credits) |
404 | Not Found |
422 | Validation Error |
500 | Internal Server Error |
Error Response Format
{
"detail": {
"code": "insufficient_credits",
"message": "Insufficient credits. Required: 2, Available: 0"
}
}
Common Error Codes
| Code | Description | Fix |
|---|---|---|
invalid_api_key | API key not found | Check your key format |
api_key_revoked | Key has been revoked | Create a new API key |
insufficient_credits | Not enough credits | Purchase credits in dashboard |
invalid_tier | Invalid tier specified | Use “basic” or “premium” |
validation_error | Missing/invalid fields | Check required fields |
invalid_confirmation | Wrong confirmation string | Use exact string “REVOKE ALL” |
Webhooks
Get notified when reports complete.
Setup
Include webhook_url in your report request:
{
"url": "https://example.com",
"email": "test@example.com",
"tier": "basic",
"webhook_url": "https://your-app.com/webhooks/scan-complete"
}
Webhook Payload
{
"event": "report.completed",
"report_id": "rpt_abc123",
"token": "SIG-2025-11-XXXXX",
"product": "signal",
"status": "completed",
"result_url": "gs://surmado-reports/...",
"completed_at": "2025-11-14T01:05:23Z"
}
Webhook Events
report.completed- Report successfully generatedreport.failed- Report generation failed
Security
Webhooks are sent via POST with:
Content-Type: application/jsonUser-Agent: Surmado-Webhook/1.0
Rate Limits
| Limit | Value |
|---|---|
| Requests per minute | 60 |
| Requests per hour | 1000 |
| Concurrent reports | 10 |
Rate limit headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1699564800
Code Examples
Python
import requests
API_KEY = "sur_live_YOUR_API_KEY"
API_URL = "https://api.surmado.com"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Create Signal report (simple approach with brand_name)
response = requests.post(
f"{API_URL}/v1/reports/signal",
headers=headers,
json={
"brand_name": "Acme Corp",
"tier": "basic",
"email": "developer@acme.com",
"industry": "B2B SaaS",
"business_scale": "startup",
"location": "San Francisco",
"product": "Project management software",
"persona": "CTOs at tech companies",
"pain_points": "Team collaboration challenges",
"brand_details": "Modern project management for technical teams",
"direct_competitors": "Asana, Monday"
}
)
report = response.json()
print(f"Report ID: {report['id']}")
print(f"Brand Slug: {report['brand_slug']}")
print(f"Brand Created: {report['brand_created']}")
print(f"Status: {report['status']}")
# Check status
status_response = requests.get(
f"{API_URL}/v1/reports/{report['id']}",
headers=headers
)
result = status_response.json()
if result['status'] == 'completed':
print(f"Download: {result['download_url']}")
Node.js
const axios = require('axios');
const API_KEY = 'sur_live_YOUR_API_KEY';
const API_URL = 'https://api.surmado.com';
const headers = {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
};
// Create Scan report (simple approach with brand_name)
axios.post(`${API_URL}/v1/reports/pulse`, {
brand_name: 'Acme Corp',
url: 'https://acme.com',
email: 'developer@acme.com',
tier: 'premium',
webhook_url: 'https://your-app.com/webhooks/scan'
}, { headers })
.then(response => {
console.log('Report ID:', response.data.id);
console.log('Brand Slug:', response.data.brand_slug);
console.log('Brand Created:', response.data.brand_created);
console.log('Token:', response.data.token);
// Poll for completion
const checkStatus = setInterval(async () => {
const status = await axios.get(
`${API_URL}/v1/reports/${response.data.id}`,
{ headers }
);
if (status.data.status === 'completed') {
console.log('Download URL:', status.data.download_url);
clearInterval(checkStatus);
}
}, 30000); // Check every 30 seconds
})
.catch(error => {
console.error('Error:', error.response.data);
});
cURL
# Health check (no auth required)
curl https://api.surmado.com/health
# Create Signal report (simple approach with brand_name)
curl -X POST https://api.surmado.com/v1/reports/signal \
-H "Authorization: Bearer sur_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"brand_name": "Acme Corp",
"tier": "basic",
"email": "developer@acme.com",
"industry": "SaaS",
"business_scale": "startup",
"location": "San Francisco",
"product": "Project management",
"persona": "Tech CTOs",
"pain_points": "Team collaboration",
"brand_details": "Modern PM tool",
"direct_competitors": "Asana"
}'
# Get report status
curl https://api.surmado.com/v1/reports/rpt_abc123 \
-H "Authorization: Bearer sur_live_YOUR_API_KEY"
# Extract specific data fields
curl "https://api.surmado.com/v1/reports/rpt_abc123/data?fields=brand_name,industry" \
-H "Authorization: Bearer sur_live_YOUR_API_KEY"
# List API keys
curl https://api.surmado.com/v1/api-keys \
-H "Authorization: Bearer sur_live_YOUR_API_KEY"
Credit Costs
| Product | Endpoint | Tier | Credits |
|---|---|---|---|
| Surmado Signal | /v1/reports/signal | Basic | 1 ($25) |
| Surmado Signal | /v1/reports/signal | Pro | 2 ($50) |
| Surmado Scan | /v1/reports/pulse | Basic | 1 ($25) |
| Surmado Scan | /v1/reports/pulse | Premium | 2 ($50) |
| Surmado Solutions | /v1/reports/solutions | N/A | 2 ($50) |
Note: 1 credit = $25. You can also buy a $100 bundle that gives you 6 credits for any mix of reports.
Learn more about credits and bundles →
API Key Management: Free (no credits consumed)
Support
Questions? Contact us at hi@surmado.com
Dashboard: app.surmado.com
Interactive API Docs: api.surmado.com/docs
Was this helpful?
Thanks for your feedback!
Have suggestions for improvement?
Tell us moreHelp Us Improve This Article
Know a better way to explain this? Have a real-world example or tip to share?
Contribute and earn credits:
- Submit: Get $25 credit (Signal, Scan, or Solutions)
- If accepted: Get an additional $25 credit ($50 total)
- Plus: Byline credit on this article