Ship email security
without building
a scanner.
100+ threat detectors, attack chain correlation, and AI-powered analysis, accessible through a REST API with native MCP protocol support. Per-scan metered billing. No infrastructure to maintain.
Try it now
Paste email headers below and hit Analyze. No API key required for anonymous requests (10/min rate limit).
Hit Analyze to see the response here.
100+
Threat Detectors
10
Attack Categories
<30s
Avg Scan Time
MCP
Protocol Native
REST
API Standard
Per-scan
Metered Billing
Up and running in minutes
Four steps to integrate email security into your application.
Get your API key
Create a key in Settings with a scope (read, scan, or all) and a daily rate limit. Keys are SHA-256 hashed at rest.
Authorization: Bearer iw_live_a3f8k2m9...
Install the SDK
Use any HTTP client in your preferred language. No proprietary SDK required. Standard REST calls with JSON responses.
pip install requests # Python npm install node-fetch # Node.js # Or use any HTTP library
Run your first scan
One POST request runs 100+ detectors against a connected Gmail or Microsoft 365 account. Results include findings, attack chains, and a security score.
curl -X POST https://inboxwatch.ai/api/scan \ -H "Authorization: Bearer iw_live_a3f8k2m9..."
Parse the results
Pull categorized findings with severity levels, remediation guides, and AI-powered analysis. Integrate into your product or pipeline.
{
"score": 42, "grade": "D",
"findingsCount": 7, "criticalCount": 2,
"attackChains": [{ "type": "account_takeover" }]
}Your language. Your workflow.
No SDK to install. The InboxWatch API is a standard REST API that works with any HTTP client in any language.
import requests API_KEY = "iw_live_abc123..." BASE_URL = "https://inboxwatch.ai/api/v1" # Trigger a scan response = requests.post( f"{BASE_URL}/scans", headers={"Authorization": f"Bearer {API_KEY}"}, json={"accountId": "acc_xyz"} ) scan = response.json() print(f"Scan started: {scan['data']['scanId']}")
const response = await fetch('https://inboxwatch.ai/api/v1/scans', { method: 'POST', headers: { 'Authorization': 'Bearer iw_live_abc123...', 'Content-Type': 'application/json', }, body: JSON.stringify({ accountId: 'acc_xyz' }), }); const { data } = await response.json(); console.log(`Scan started: ${data.scanId}`);
curl -X POST https://inboxwatch.ai/api/v1/scans \ -H "Authorization: Bearer iw_live_abc123..." \ -H "Content-Type: application/json" \ -d '{"accountId": "acc_xyz"}'
Works with any language that supports HTTP requests: Go, Ruby, Java, PHP, Rust, C#, Swift, and more. Use the standard library HTTP client or your preferred framework.
What you can build
Full programmatic access to InboxWatch's security engine. Here's what teams are shipping with it.
Security Copilot
Build an AI agent that reviews email security posture and surfaces threats before users engage with suspicious messages.
Compliance Automation
Auto-generate email security audit reports for SOC 2, HIPAA, and ISO 27001 with timestamped scan evidence.
SOC Pipeline
Feed enriched threat findings (severity, attack chains, remediation steps) directly into Splunk, Sentinel, or your SIEM.
Managed Security (MSP)
Monitor all client mailboxes from a single API integration. Per-key rate limits and scoped access for multi-tenant setups.
Breach Response
Detect compromised credentials and map email exposure across the dark web. Trigger automated remediation workflows.
Phishing Simulation
Test employee susceptibility with realistic campaigns. Measure click rates, reporting rates, and time-to-report.
Under the hood
Three pillars of the InboxWatch API: scan, detect, and protect.
Scan Engine
100+ detectors across 10 attack categories
- Forwarding rules, OAuth apps, sign-in anomalies
- Attack chain correlation across findings
- AI-powered severity tuning (auto-dismiss false positives)
- Security score + letter grade per scan
- Fix guides with step-by-step remediation
MCP Protocol
Native AI agent integration
- Model Context Protocol tool discovery at /api/mcp
- Header analysis without API key (/api/mcp/analyze)
- AI agents discover and call tools automatically
- Structured JSON responses for LLM consumption
- Compatible with Claude, GPT, and any MCP client
Domain Intelligence
Lookalike detection + exposure mapping
- Lookalike domain detection (homographs, typosquats)
- Email exposure map across sender baselines
- SPF/DKIM/DMARC authentication grading (A to F)
- Dark web credential breach monitoring
- Brand protection with reputation scoring
One API call. 100+ security checks.
Trigger a full account scan: forwarding rules, OAuth app audit, sign-in anomalies, attack chain correlation, and AI-powered severity analysis.
curl -X POST https://inboxwatch.ai/api/scan \ -H "Authorization: Bearer iw_live_a3f8k2m9..." \ -H "Content-Type: application/json"
{
"score": 42,
"grade": "D",
"findingsCount": 7,
"criticalCount": 2,
"attackChains": [
{
"type": "account_takeover_in_progress",
"confidence": 0.89,
"findings": ["forwarding_external", "oauth_mail_send"]
}
],
"topFindings": [
{
"severity": "critical",
"key": "gmail_forward_external",
"title": "Emails forwarding to external address",
"fixAvailable": true
},
{
"severity": "high",
"key": "oauth_app_mail_send",
"title": "OAuth app with mail.send scope"
}
]
}100+
Detectors
Auto
Attack Chains
AI
Severity Tuning
Built-in
Fix Guides
Want to test first? /api/mcp/analyze is free, no key needed.
Authentication, endpoints, webhooks, error handling, and versioning details for integrating the InboxWatch API.
Authentication
Authenticate with a Bearer token in the Authorization header. Keys use the iw_live_ prefix and are SHA-256 hashed at rest. Generate keys in Settings → API Keys.
Authorization: Bearer iw_live_a3f8k2m...
Rate Limiting
Each API key has a configurable daily scan limit. Read endpoints allow 60 requests/minute. Public endpoints are rate-limited per IP. All limits return 429 with a Retry-After header.
Scopes
Each API key has a scope that controls access. Higher scopes include all lower permissions.
allFull access: read + scan + managescanTrigger scans + read resultsreadRead-only access to scan resultsMetered Billing
Billed per scan, not per request. Read endpoints and MCP tool discovery are free. Usage is tracked per API key and reported to Stripe monthly.
Endpoints
Click any endpoint to expand full documentation including parameters, response schemas, and example requests.
Trigger a full email security scan against the authenticated user's connected Gmail or Microsoft 365 account. Runs 100+ threat detectors, attack chain correlation, and returns a security score.
Headers
| Authorization | Bearer iw_live_... | Required |
| Content-Type | application/json | Required |
Response Fields
| Field | Type | Description |
|---|---|---|
scanId | string | Unique scan identifier |
status | string | "completed" | "in_progress" | "failed" |
score | number | Security score from 0 (worst) to 100 (best) |
grade | string | Letter grade: A+ through F |
findingsCount | number | Total findings detected |
criticalCount | number | Critical-severity findings |
highCount | number | High-severity findings |
attackChains | AttackChain[] | Correlated multi-finding attack patterns |
duration_ms | number | Scan duration in milliseconds |
Example Request
curl -X POST https://inboxwatch.ai/api/scan \ -H "Authorization: Bearer iw_live_a3f8k2m9..." \ -H "Content-Type: application/json"
Example Response
{ "scanId": "scan_abc123", "status": "completed", "score": 42, "grade": "D", "findingsCount": 7, "criticalCount": 2, "highCount": 3, "attackChains": [ { "type": "account_takeover_in_progress", "confidence": 0.89, "findings": ["forwarding_external", "oauth_mail_send"] } ], "duration_ms": 4200 }
Retrieve all findings from the latest completed scan. Each finding includes severity, category, remediation steps, and AI-powered analysis when available.
Headers
| Authorization | Bearer iw_live_... | Required |
| Content-Type | application/json | Optional |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
severity | string | Filter by severity: critical, high, medium, low, info |
category | string | Filter by category: rules, access, spoofing, settings, security, inbound |
limit | number | Max findings to return (default: 100, max: 500) |
offset | number | Pagination offset (default: 0) |
Response Fields
| Field | Type | Description |
|---|---|---|
findings | Finding[] | Array of finding objects |
findings[].id | string | Finding identifier |
findings[].key | string | Machine-readable finding key (e.g. gmail_forward_external) |
findings[].severity | string | critical | high | medium | low | info |
findings[].title | string | Human-readable finding title |
findings[].category | string | Detection category |
findings[].fixAvailable | boolean | Whether auto-fix is available |
total | number | Total findings count (before limit/offset) |
Example Request
curl https://inboxwatch.ai/api/findings?severity=critical \ -H "Authorization: Bearer iw_live_a3f8k2m9..."
Example Response
{ "findings": [ { "id": "fnd_def456", "key": "gmail_forward_external", "severity": "critical", "title": "Emails forwarding to external address", "category": "rules", "fixAvailable": true, "metadata": { "forwardTo": "attacker@evil.com", "ruleCreated": "2026-03-10T14:22:00Z" } } ], "total": 7 }
List scan history with scores, grades, and finding summaries. Ordered by most recent scan first.
Headers
| Authorization | Bearer iw_live_... | Required |
| Content-Type | application/json | Optional |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
limit | number | Max scans to return (default: 20, max: 100) |
offset | number | Pagination offset (default: 0) |
Response Fields
| Field | Type | Description |
|---|---|---|
scans | Scan[] | Array of scan summary objects |
scans[].id | string | Scan identifier |
scans[].score | number | Security score 0-100 |
scans[].grade | string | Letter grade A+ through F |
scans[].findingsCount | number | Total findings in this scan |
scans[].createdAt | string | ISO 8601 timestamp |
scans[].provider | string | "google" | "microsoft" |
total | number | Total scans count |
Example Request
curl https://inboxwatch.ai/api/scans?limit=5 \ -H "Authorization: Bearer iw_live_a3f8k2m9..."
Example Response
{ "scans": [ { "id": "scan_abc123", "score": 87, "grade": "B+", "findingsCount": 3, "criticalCount": 0, "provider": "google", "createdAt": "2026-03-12T08:30:00Z" }, { "id": "scan_xyz789", "score": 42, "grade": "D", "findingsCount": 7, "criticalCount": 2, "provider": "google", "createdAt": "2026-03-11T14:15:00Z" } ], "total": 24 }
Check if the authenticated user's email credentials have been exposed in known dark web breach databases.
Headers
| Authorization | Bearer iw_live_... | Required |
| Content-Type | application/json | Optional |
Response Fields
| Field | Type | Description |
|---|---|---|
email | string | Email address checked |
breached | boolean | Whether any breaches were found |
breachCount | number | Total breach records found |
breaches | Breach[] | Array of breach details |
breaches[].source | string | Breach source name |
breaches[].date | string | Date of breach (ISO 8601) |
breaches[].dataTypes | string[] | Types of data exposed |
lastChecked | string | When this check was last run |
Example Request
curl https://inboxwatch.ai/api/breach-check \ -H "Authorization: Bearer iw_live_a3f8k2m9..."
Example Response
{ "email": "user@example.com", "breached": true, "breachCount": 2, "breaches": [ { "source": "ExampleCorp 2025", "date": "2025-11-15", "dataTypes": ["email", "password_hash", "name"] } ], "lastChecked": "2026-03-12T08:30:00Z" }
Retrieve domain monitoring results including lookalike domains, email exposure map, and SPF/DKIM/DMARC authentication grades.
Headers
| Authorization | Bearer iw_live_... | Required |
| Content-Type | application/json | Optional |
Response Fields
| Field | Type | Description |
|---|---|---|
domain | string | Monitored domain |
lookalikeCount | number | Detected lookalike domains |
lookalikes | Lookalike[] | Lookalike domain details |
authGrade | string | Overall authentication grade A-F |
spfStatus | string | SPF record status |
dkimStatus | string | DKIM signing status |
dmarcStatus | string | DMARC policy status |
Example Request
curl https://inboxwatch.ai/api/domain-shield \ -H "Authorization: Bearer iw_live_a3f8k2m9..."
Example Response
{ "domain": "example.com", "lookalikeCount": 3, "lookalikes": [ { "domain": "examp1e.com", "type": "homograph", "registeredAt": "2026-03-01", "riskLevel": "high" } ], "authGrade": "B", "spfStatus": "pass", "dkimStatus": "pass", "dmarcStatus": "quarantine" }
Trigger a fresh domain reputation and lookalike scan. Checks for newly registered lookalike domains and updates authentication grades.
Headers
| Authorization | Bearer iw_live_... | Required |
| Content-Type | application/json | Required |
Response Fields
| Field | Type | Description |
|---|---|---|
scanId | string | Domain scan identifier |
status | string | "completed" | "in_progress" |
newLookalikes | number | Newly detected lookalike domains |
domain | string | Domain that was scanned |
Example Request
curl -X POST https://inboxwatch.ai/api/domain-shield \ -H "Authorization: Bearer iw_live_a3f8k2m9..." \ -H "Content-Type: application/json"
Example Response
{ "scanId": "dscan_mno345", "status": "completed", "newLookalikes": 1, "domain": "example.com" }
Analyze raw email headers for authentication failures, spoofing indicators, and threat signals. No API key required -- rate limited per IP.
Headers
| Content-Type | application/json | Required |
Request Body
| Field | Type | Description |
|---|---|---|
headers | string | Raw email headers to analyze |
Response Fields
| Field | Type | Description |
|---|---|---|
analysis | object | Structured header analysis |
analysis.spf | string | SPF result: pass | fail | softfail | none |
analysis.dkim | string | DKIM result: pass | fail | none |
analysis.dmarc | string | DMARC result: pass | fail | none |
analysis.threats | Threat[] | Detected threat indicators |
analysis.riskScore | number | Risk score 0-100 |
Example Request
curl -X POST https://inboxwatch.ai/api/mcp/analyze \
-H "Content-Type: application/json" \
-d '{"headers": "Received: from mail.example.com..."}'Example Response
{ "analysis": { "spf": "fail", "dkim": "pass", "dmarc": "fail", "threats": [ { "type": "spf_failure", "severity": "high", "detail": "Sender IP not in SPF record" } ], "riskScore": 72 } }
MCP (Model Context Protocol) tool discovery endpoint. Returns the manifest of available tools for AI agents. Used by Claude Desktop, GPT, and other MCP-compatible clients.
Headers
| Content-Type | application/json | Optional |
Response Fields
| Field | Type | Description |
|---|---|---|
tools | Tool[] | Available MCP tools |
tools[].name | string | Tool identifier |
tools[].description | string | What the tool does |
tools[].inputSchema | object | JSON Schema for tool input |
version | string | MCP protocol version |
Example Request
curl https://inboxwatch.ai/api/mcp
Example Response
{ "tools": [ { "name": "analyze_email_headers", "description": "Analyze email headers for spoofing and authentication issues", "inputSchema": { "type": "object", "properties": { "headers": { "type": "string" } }, "required": ["headers"] } } ], "version": "2024-11-05" }
API key lifecycle
Keys follow a generate-use-rotate-revoke lifecycle. Every key is hashed at rest, rate-limited independently, and scoped to a specific permission level.
Key Format
iw_live_<40 chars base64url>Generate
Create a key in Settings > API Keys. The raw key is shown once and must be copied immediately. It is never stored in plaintext -- only its SHA-256 hash is persisted.
Assign scope
Choose a scope: read, scan, all. Higher scopes inherit lower permissions (all > scan > read). You can have up to 10 active keys.
Set expiry
Optionally set an expiration between 1-365 days. Keys without an expiry remain active until manually revoked.
Authenticate
Pass the key as a Bearer token in the Authorization header. The server hashes it, looks up the record, and validates status, expiry, subscription, and rate limits.
Rotate
Generate a new key, update your integration, then revoke the old key. Revocation is immediate and irreversible. Plan rotation before expiry dates.
Revoke
Revoked keys return 401 on all subsequent requests. If a key is compromised, revoke it immediately from Settings. Revocation cannot be undone.
Scope permissions
read- ✓GET /api/findings
- ✓GET /api/scans
- ✓GET /api/breach-check
- ✓GET /api/domain-shield
scan- ✓Everything in read
- ✓POST /api/scan
- ✓POST /api/domain-shield
all- ✓Everything in scan
- ✓API key management
- ✓Webhook configuration
- ✓Account settings
Rotation best practices
- Use the minimum scope needed for each integration. Avoid
allunless the client manages API keys or webhooks. - Set expiration dates and rotate keys before they expire. Overlap old and new keys during the transition window.
- Revoke leaked keys immediately. Generate a replacement key before revoking to avoid downtime.
- Monitor usage via the Settings dashboard. Unexpected spikes may indicate a compromised key.
Real-time event notifications
Register a webhook URL in Settings to receive structured JSON payloads when scans complete, new findings appear, or attack chains are detected.
Available events
| Event | Description | Payload Type |
|---|---|---|
scan.completed | A full email security scan finished successfully | ScanResult |
scan.failed | A scan encountered an error and could not complete | ScanError |
finding.new | A new finding was detected that did not exist in the previous scan | Finding |
finding.resolved | A previously detected finding is no longer present | Finding |
alert.critical | An attack chain or critical-severity finding was detected | Alert |
breach.detected | New credential exposure found in a dark web breach database | BreachRecord |
domain.lookalike | A new lookalike domain was registered targeting your domain | DomainAlert |
webhook.disabled | Webhook endpoint was auto-disabled after 3 consecutive failures | WebhookStatus |
scan.completedScanResultA full email security scan finished successfully
scan.failedScanErrorA scan encountered an error and could not complete
finding.newFindingA new finding was detected that did not exist in the previous scan
finding.resolvedFindingA previously detected finding is no longer present
alert.criticalAlertAn attack chain or critical-severity finding was detected
breach.detectedBreachRecordNew credential exposure found in a dark web breach database
domain.lookalikeDomainAlertA new lookalike domain was registered targeting your domain
webhook.disabledWebhookStatusWebhook endpoint was auto-disabled after 3 consecutive failures
Verification: Every webhook request includes an X-InboxWatch-Signature header containing an HMAC-SHA256 signature. Verify this against your webhook secret before processing the payload.
Payload examples
scan.completedJSONFired when a scan finishes successfully. Includes the security score, grade, and finding summary.
{ "event": "scan.completed", "timestamp": "2026-03-12T08:30:00Z", "data": { "scanId": "scan_abc123", "userId": "usr_xyz", "provider": "google", "score": 87, "grade": "B+", "findingsCount": 3, "criticalCount": 0, "highCount": 1, "duration_ms": 4200 } }
finding.newJSONFired for each new finding that was not present in the previous scan. Use this to trigger alerts or ticket creation.
{ "event": "finding.new", "timestamp": "2026-03-12T08:30:01Z", "data": { "findingId": "fnd_def456", "scanId": "scan_abc123", "key": "gmail_forward_external", "severity": "high", "title": "External forwarding rule detected", "category": "forwarding" } }
alert.criticalHIGH PRIORITYJSONFired when the correlator detects a multi-finding attack chain. Requires immediate attention.
{ "event": "alert.critical", "timestamp": "2026-03-12T08:30:02Z", "data": { "type": "attack_chain", "chainId": "chain_789", "findings": ["fnd_def456", "fnd_ghi789"], "severity": "critical", "description": "Forwarding rule + OAuth app compromise pattern" } }
Retry policy
Webhooks that receive a non-2xx response are retried up to 3 times with exponential backoff (30s, 5m, 30m). After 3 consecutive failures, the webhook is automatically disabled and you receive an email notification. Re-enable in Settings.
Webhook payload schemas
Every webhook delivery includes a consistent envelope with event, timestamp, and data fields. Expand each event below to see the full payload structure.
Fired when a scan finishes successfully. Includes the security score, grade, and finding summary.
{ "event": "scan.completed", "timestamp": "2026-03-12T08:30:00Z", "data": { "scanId": "scan_abc123", "userId": "usr_xyz", "provider": "google", "score": 87, "grade": "B+", "findingsCount": 3, "criticalCount": 0, "highCount": 1, "duration_ms": 4200 } }
Fired when a scan encounters an unrecoverable error. Includes the error code and a message for debugging.
{ "event": "scan.failed", "timestamp": "2026-03-12T09:15:00Z", "data": { "scanId": "scan_def456", "userId": "usr_xyz", "provider": "microsoft", "error": { "code": "PROVIDER_ERROR", "message": "Microsoft Graph API returned 503" } } }
Fired for each new finding not present in the previous scan. Use this to trigger alerts or ticket creation.
{ "event": "finding.new", "timestamp": "2026-03-12T08:30:01Z", "data": { "findingId": "fnd_def456", "scanId": "scan_abc123", "key": "gmail_forward_external", "severity": "high", "title": "External forwarding rule detected", "category": "rules", "metadata": { "forwardTo": "attacker@evil.com", "ruleCreated": "2026-03-10T14:22:00Z" } } }
Fired when a previously detected finding is no longer present. Indicates the user or automation has remediated the issue.
{ "event": "finding.resolved", "timestamp": "2026-03-12T10:00:00Z", "data": { "findingId": "fnd_def456", "scanId": "scan_ghi789", "key": "gmail_forward_external", "severity": "high", "title": "External forwarding rule detected", "resolvedAfter_ms": 5400000 } }
Fired when the correlator detects a multi-finding attack chain. Requires immediate attention.
{ "event": "alert.critical", "timestamp": "2026-03-12T08:30:02Z", "data": { "type": "attack_chain", "chainId": "chain_789", "findings": ["fnd_def456", "fnd_ghi789"], "severity": "critical", "confidence": 0.89, "description": "Forwarding rule + OAuth app compromise pattern" } }
Fired when new credential exposure is found in a dark web breach database.
{ "event": "breach.detected", "timestamp": "2026-03-12T12:00:00Z", "data": { "email": "user@example.com", "source": "ExampleCorp 2025", "breachDate": "2025-11-15", "dataTypes": ["email", "password_hash", "name"], "severity": "high" } }
Fired when a new lookalike domain targeting your domain is detected.
{ "event": "domain.lookalike", "timestamp": "2026-03-12T06:00:00Z", "data": { "targetDomain": "example.com", "lookalikeDomain": "examp1e.com", "type": "homograph", "registeredAt": "2026-03-11", "riskLevel": "high" } }
Sent as a final notification when a webhook is auto-disabled after 3 consecutive delivery failures.
{ "event": "webhook.disabled", "timestamp": "2026-03-12T14:00:00Z", "data": { "webhookId": "wh_abc123", "url": "https://your-app.com/webhook", "reason": "3 consecutive delivery failures", "lastError": "Connection timeout after 30s", "disabledAt": "2026-03-12T14:00:00Z" } }
Common envelope
All payloads share this top-level structure. Parse the event field to route to the correct handler, and use timestamp for ordering and deduplication.
{ "event": "scan.completed", "timestamp": "2026-03-12T08:30:00Z", "data": { } }
Structured error responses
All errors follow a consistent JSON format with machine-readable codes, human-readable messages, and actionable hints. Check the error.code field to handle each case programmatically.
| Code | Status | Description | Action |
|---|---|---|---|
UNAUTHORIZED | 401 | Invalid or expired API key | Check key, regenerate if needed |
FORBIDDEN | 403 | Insufficient permissions for this endpoint | Upgrade plan or check key scopes |
RATE_LIMITED | 429 | Too many requests in the current window | Back off, respect Retry-After header |
SCAN_IN_PROGRESS | 409 | A scan is already running for this account | Wait for the current scan to complete |
QUOTA_EXCEEDED | 402 | Monthly scan quota has been exhausted | Upgrade plan or wait for reset |
PROVIDER_ERROR | 502 | Upstream provider (Google/Microsoft) error | Retry with exponential backoff |
INTERNAL_ERROR | 500 | Unexpected server error | Contact support with the request ID |
UNAUTHORIZED401Invalid or expired API key
Check key, regenerate if needed
FORBIDDEN403Insufficient permissions for this endpoint
Upgrade plan or check key scopes
RATE_LIMITED429Too many requests in the current window
Back off, respect Retry-After header
SCAN_IN_PROGRESS409A scan is already running for this account
Wait for the current scan to complete
QUOTA_EXCEEDED402Monthly scan quota has been exhausted
Upgrade plan or wait for reset
PROVIDER_ERROR502Upstream provider (Google/Microsoft) error
Retry with exponential backoff
INTERNAL_ERROR500Unexpected server error
Contact support with the request ID
{ "error": { "code": "RATE_LIMITED", "message": "Too many requests. Retry after 60 seconds.", "retryAfter": 60 } }
Best practice
Always check the HTTP status code first, then parse error.code for programmatic handling. Include the X-Request-Id header value when contacting support.
Stable by default
The InboxWatch API is versioned to ensure your integration stays stable. We follow semantic versioning principles for all breaking changes.
Current API version
Base URL: https://inboxwatch.ai/api/v1/
URL path versioning
All endpoints are prefixed with the API version. Current: /api/v1/. New major versions get a new path prefix.
90-day deprecation notice
Breaking changes are announced 90 days before the old version is retired. You will receive email and dashboard notifications.
Non-breaking changes (no notice needed):
- +Adding new optional fields to response objects
- +Adding new endpoints or webhook event types
- +Adding new optional query parameters
- +Increasing rate limits
Predictable throttling
Rate limits protect the API and ensure fair usage. All limits return 429 with a Retry-After header.
| Endpoint | Limit | Scope |
|---|---|---|
POST /scans | 10/min | Per API key |
GET /scans/:id | 60/min | Per API key |
GET /findings | 60/min | Per API key |
GET /breach-check | 60/min | Per API key |
GET /domain-shield | 60/min | Per API key |
POST /mcp/analyze | 10/min | Per IP |
Webhooks (outbound) | Unlimited | -- |
Response headers
X-RateLimit-LimitMax requests per windowX-RateLimit-RemainingRequests remainingRetry-AfterSeconds until limit resets (on 429)Your AI agent is one API call
away from email security.
Generate an API key, trigger your first scan, and integrate100+ threat detectors into your product. In minutes, not months.
Free to try. /api/mcp/analyze requires no API key.
Metered billing starts only when you trigger paid scans.