Overview
Brainito exposes two interfaces for the same underlying API — choose whichever fits your use case:
REST API v1
https://brainito.com/api/v1Standard HTTP endpoints. Clean JSON responses, proper HTTP status codes. Best for server-side integrations, automation scripts, and backend pipelines.
- → POST /api/v1/scan
- → GET /api/v1/report/:scan_uid
- → GET /api/v1/reports
MCP Server
https://brainito.com/api/mcpJSON-RPC 2.0 over HTTP (Model Context Protocol). Works with Claude Desktop, Cursor, Windsurf, and any MCP-aware AI client out of the box.
- → scan_website tool
- → get_report tool
- → list_reports tool
Both interfaces use the same API key authentication and scopes.
Authentication
Every request must include an Authorization header with a Bearer token. Brainito supports two credential types:
brn_live_XXXXXXXX.SECRETFor server-to-server integrations, scripts, and direct HTTP calls. Create in Settings → API Keys.
brn_sa_XXXXXXXX.SECRETFor AI assistants and long-running bots. Ideal for MCP clients like Claude Desktop. Create in Settings → Service Accounts.
Authorization: Bearer brn_live_XXXXXXXX.YOUR_SECRETQuick Start
The fastest way to get a report is with the REST API — three steps, plain curl.
- 1
Create an API key
Go to Settings → API Keys and click Create key. Select scopes
website.scanandreports.read. Copy the key immediately — it won't be shown again. - 2
Start a scan
bashcurl -X POST https://brainito.com/api/v1/scan \ -H "Authorization: Bearer brn_live_XXXXXXXX.YOUR_SECRET" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}' - 3
Poll for the report
Scans take 60–90 seconds. Call until
status === "completed".bashcurl https://brainito.com/api/v1/report/abc123xyz \ -H "Authorization: Bearer brn_live_XXXXXXXX.YOUR_SECRET"
REST API
Base URL: https://brainito.com/api/v1
All responses are plain JSON with standard HTTP status codes. No JSON-RPC wrapper.
/api/v1/scanRequires: website.scanStart a full marketing audit on a website. Returns immediately with a scan_uid — use it to poll GET /api/v1/report/:scan_uid. Deducts 1 credit per scan.
| Body field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Full URL to audit (e.g. https://example.com) |
curl -X POST https://brainito.com/api/v1/scan \
-H "Authorization: Bearer brn_live_XXXXXXXX.YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'HTTP/1.1 202 Accepted
{
"scan_uid": "abc123xyz",
"domain": "example.com",
"status": "pending",
"message": "Scan started. Poll GET /api/v1/report/{scan_uid} until status is 'completed'."
}| Status | Meaning |
|---|---|
202 Accepted | Scan started — use scan_uid to poll for the report |
400 Bad Request | Missing or invalid url field |
402 Payment Required | Insufficient credits |
403 Forbidden | Missing website.scan scope or not on a paid plan |
409 Conflict | A scan for this domain is already in progress |
/api/v1/report/:scan_uidRequires: reports.readGet the full report for a scan. Poll every 5–10 seconds until status === "completed". Returns all 77 factor analyses, section scores, priority actions, and traffic data.
curl https://brainito.com/api/v1/report/abc123xyz \
-H "Authorization: Bearer brn_live_XXXXXXXX.YOUR_SECRET"While pending:
{
"scan_uid": "abc123xyz",
"domain": "example.com",
"status": "pending",
"message": "Scan is pending. Poll again in a few seconds."
}When completed:
{
"scan_uid": "abc123xyz",
"domain": "example.com",
"status": "completed",
"report_url": "https://brainito.com/dashboard/marketing-audit-report/example.com/abc123xyz",
"scores": {
"overall": 62,
"website_essentials": 58,
"on_page_seo": 55,
"technical_seo": 70,
"marketing_channels": 65
},
"priority_actions": [
"Add pricing information clearly on the website.",
"Implement a cookie consent banner for compliance.",
"..."
],
"factors": {
"website_essentials": [
{
"id": "pricing_page",
"name": "Pricing Page",
"score": 10,
"status": "No",
"reasoning": "No dedicated pricing page found.",
"analysis": "The site lacks a clear pricing page...",
"suggestions": ["Add a /pricing page", "Show plan tiers clearly", "..."]
}
],
"on_page_seo": [ ... ],
"technical_seo": [ ... ],
"marketing_channels": [ ... ]
},
"traffic": {
"monthly_visits": 1200,
"domain_authority": 18,
"organic_traffic": 450,
"keywords_ranking": 34,
"backlinks": 120,
"bounce_rate": 0.62,
"top_countries": [{ "country": "United States", "code": "US", "share": 0.45 }],
"top_keywords": [{ "keyword": "marketing audit tool", "volume": 320, "position": 8 }],
"traffic_sources": { "organic": 0.38, "direct": 0.29, "referral": 0.18 },
"ads_active": false,
"ads_platforms": [],
"social_mentions_count": 12
}
}website_essentials, on_page_seo, technical_seo, marketing_channels. Each factor has id, name, score (0–100), status (Yes / No / Not Applicable), reasoning, analysis, and suggestions. Factors that could not be evaluated show "status": "unavailable"./api/v1/reportsRequires: reports.readList recent audit reports for your account, sorted newest first.
| Query param | Type | Default | Description |
|---|---|---|---|
limit | number | 10 | Number of reports to return (1–20) |
curl "https://brainito.com/api/v1/reports?limit=5" \
-H "Authorization: Bearer brn_live_XXXXXXXX.YOUR_SECRET"MCP Protocol
The MCP server at POST /api/mcp implements the Model Context Protocol (JSON-RPC 2.0 over HTTP). Use this when connecting to AI clients like Claude Desktop, Cursor, or Windsurf — they discover the tools automatically.
Initialize
Optional handshake. Returns server info and supported protocol version.
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"clientInfo": { "name": "my-app", "version": "1.0" },
"capabilities": {}
}
}List Tools
Discover available tools and their input schemas.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}MCP Tools
scan_websiteRequires: website.scanStart a marketing health scan. Returns a scan_uid to pass to get_report.
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Full URL of the website to scan (e.g. https://example.com) |
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "scan_website",
"arguments": { "url": "https://example.com" }
}
}get_reportRequires: reports.readRetrieve the full report for a scan. Call repeatedly until status === "completed". Returns all 77 factor analyses, scores, priority actions, and traffic data.
| Parameter | Type | Required | Description |
|---|---|---|---|
scan_uid | string | Yes | The scan UID returned by scan_website |
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "get_report",
"arguments": { "scan_uid": "abc123xyz" }
}
}list_reportsRequires: reports.readList recent marketing audit reports for your account, ordered by creation date.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Number of reports to return (1–20, default: 5) |
{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "list_reports",
"arguments": { "limit": 5 }
}
}Integrations
Brainito ships an official @brainito/mcp npm package — a stdio MCP server that works with every major AI client out of the box. No HTTP transport issues, no OAuth setup. Requires Node.js 18+.
Claude Desktop
Mac: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
// ~/Library/Application Support/Claude/claude_desktop_config.json
// (Windows: %APPDATA%\Claude\claude_desktop_config.json)
{
"mcpServers": {
"brainito": {
"command": "npx",
"args": ["-y", "@brainito/mcp@latest"],
"env": {
"BRAINITO_API_KEY": "brn_sa_XXXXXXXX.YOUR_SECRET"
}
}
}
}Cursor
Go to Settings → MCP → Add new global MCP server, or add to .cursor/mcp.json in your project root:
// Settings → MCP → Add new global MCP server
// or .cursor/mcp.json in your project root
{
"mcpServers": {
"brainito": {
"command": "npx",
"args": ["-y", "@brainito/mcp@latest"],
"env": {
"BRAINITO_API_KEY": "brn_sa_XXXXXXXX.YOUR_SECRET"
}
}
}
}Windsurf
Edit ~/.codeium/windsurf/mcp_config.json:
// ~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"brainito": {
"command": "npx",
"args": ["-y", "@brainito/mcp@latest"],
"env": {
"BRAINITO_API_KEY": "brn_sa_XXXXXXXX.YOUR_SECRET"
}
}
}
}scan_website, get_report, and list_reports appear automatically. The first run fetches the package via npx — subsequent starts use the cached version.Code Examples
JavaScript / TypeScript — full scan + poll loop
REST API v1
const API_KEY = "brn_live_XXXXXXXX.YOUR_SECRET";
const BASE = "https://brainito.com/api/v1";
async function auditWebsite(url) {
// 1. Start scan
const scanRes = await fetch(`${BASE}/scan`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ url }),
});
const { scan_uid } = await scanRes.json();
// 2. Poll until complete
let report;
while (true) {
await new Promise(r => setTimeout(r, 5000)); // wait 5s between polls
const res = await fetch(`${BASE}/report/${scan_uid}`, {
headers: { "Authorization": `Bearer ${API_KEY}` },
});
report = await res.json();
if (report.status === "completed") break;
console.log(`Still ${report.status}...`);
}
return report;
}
const result = await auditWebsite("https://example.com");
console.log("Overall score:", result.scores.overall);
console.log("Top priority:", result.priority_actions[0]);Python — full scan + poll loop
REST API v1
import requests
import time
API_KEY = "brn_live_XXXXXXXX.YOUR_SECRET"
BASE = "https://brainito.com/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def audit_website(url: str) -> dict:
# 1. Start scan
res = requests.post(f"{BASE}/scan", headers=HEADERS, json={"url": url})
res.raise_for_status()
scan_uid = res.json()["scan_uid"]
# 2. Poll until complete
while True:
time.sleep(5)
res = requests.get(f"{BASE}/report/{scan_uid}", headers=HEADERS)
report = res.json()
if report["status"] == "completed":
return report
print(f"Still {report['status']}...")
report = audit_website("https://example.com")
print("Overall score:", report["scores"]["overall"])
print("Top priority:", report["priority_actions"][0])cURL — MCP protocol
Calling the MCP endpoint directly over HTTP
# Initialize
curl -X POST https://brainito.com/api/mcp \
-H "Authorization: Bearer brn_live_XXXXXXXX.YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}'
# Scan
curl -X POST https://brainito.com/api/mcp \
-H "Authorization: Bearer brn_live_XXXXXXXX.YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"scan_website","arguments":{"url":"https://example.com"}}}'Scopes
Scopes limit what a credential can do. Assign only the scopes your application actually needs.
| Scope | Allows | Used by |
|---|---|---|
website.scan | Start website marketing health scans | POST /api/v1/scan · scan_website |
reports.read | Read completed reports | GET /api/v1/report · GET /api/v1/reports · get_report · list_reports |
reports.write | Write / update report data (reserved) | Future use |
Rate Limits
Rate limits apply per credential using a sliding window and are consistent across both the REST API and MCP endpoints.
| Plan | Requests / minute | Scans / day | Concurrent scans |
|---|---|---|---|
Starter | 60 | 50 | 1 |
Pro | 120 | 200 | 3 |
Agency | 300 | 1,000 | 10 |
When exceeded: REST API returns HTTP 429 with {"error": "Rate limit exceeded"}. MCP endpoint returns JSON-RPC error code: -32029. Use exponential backoff before retrying.
Errors
REST API errors
Plain JSON body with an error string.
HTTP/1.1 402 Payment Required
{ "error": "Insufficient credits. You have 40; a scan costs 100.", "available_credits": 40, "required_credits": 100 }| HTTP Status | Meaning |
|---|---|
400 Bad Request | Missing or invalid request fields |
401 Unauthorized | Missing or invalid Authorization header |
402 Payment Required | Insufficient credits |
403 Forbidden | Wrong scopes or plan level required |
404 Not Found | Report not found or access denied |
409 Conflict | Scan already running for this domain |
429 Too Many Requests | Rate limit exceeded — back off and retry |
500 Internal Server Error | Unexpected server error |
MCP errors
JSON-RPC 2.0 error format inside the response body.
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32001,
"message": "Invalid API key format"
}
}| HTTP | JSON-RPC code | Meaning |
|---|---|---|
401 | -32001 | Missing or invalid Authorization header |
403 | -32002 | Tool call rejected — scope or plan error |
429 | -32029 | Rate limit exceeded |
400 | -32600 | Invalid JSON-RPC request |
404 | -32601 | Method not found |
400 | -32602 | Invalid parameters |
500 | -32603 | Internal server error |