1. Authentication (API Key)
Sign in to the dashboard, then open /dashboard/keys to create a key, formatted as nangua_<24 hex>. Use it on every authenticated endpoint:
bashcurl -H "Authorization: Bearer nangua_xxx" https://maxfound.ai/api/me
2. Rate limits
| Endpoint | Anonymous | Signed-in | Bearer (API key) |
|---|---|---|---|
| /api/check/run | 5/IP/day | tier quota | tier quota |
| /api/query | 5/IP/day | 3–20/day (tier) | 30 req/min |
| /api/aeo/rewrite | sign-in required | 5–100/day | 30 req/min |
| /api/dashboard/* | sign-in required | unlimited | 120 req/min |
| /api/health · /status | none | none | none |
Over the limit returns 429 · the Retry-After header gives the retry delay in seconds.
/api/healthAuth: NoneService health check
For external uptime monitoring · cached for 30s.
bashcurl https://maxfound.ai/api/health
Example response (HTTP 200):
json{ "status": "ok", "service": "maxfound-ai", "version": "d7c90ca", "env": "production", "region": "iad1", "timestamp": "2026-05-14T17:30:00.000Z", "checks": { "db": { "ok": true, "latency_ms": 25 } }, "took_ms": 25 }
/api/statusAuth: NoneLive AI engine + DB status
Detailed status · concurrently pings the AI engine APIs and DB · cached for 60s.
bashcurl https://maxfound.ai/api/status
Response (excerpt):
json{ "status": "operational", "db": { "ok": true, "latency_ms": 25 }, "llms": { "up": 4, "total": 4, "up_rate": 1.0, "platforms": [ { "platform": "chatgpt", "name": "ChatGPT", "ok": true, "latency_ms": 4123 }, { "platform": "gemini", "name": "Gemini", "ok": true, "latency_ms": 5234 }, ... ] } }
/api/check/runAuth: None (IP rate-limited)Free 30-second scan
Live scan across 3 AI engines (ChatGPT / Gemini / Claude) · see how visible your brand is in AI answers.
bashcurl -X POST https://maxfound.ai/api/check/run \ -H "Content-Type: application/json" \ -d '{ "brand_name": "Acme Coffee Roasters", "industry": "Food & Beverage - Coffee", "competitors": ["Blue Harbor Coffee", "Northside Roastery"] }'
Response (excerpt):
json{ "runId": "839d8479-427c-459e-a670-569cc5875074", "platforms": ["chatgpt", "gemini", "claude"], "summary": [ { "platform": "chatgpt", "total": 2, "mentions": 2, "positive": 1 }, { "platform": "gemini", "total": 2, "mentions": 1, "positive": 1 }, { "platform": "claude", "total": 2, "mentions": 2, "positive": 2 } ], "rateLimitRemaining": 4 }
/api/queryAuth: Cookie or BearerFull multi-engine query
For signed-in users or API keys · scans all engines (ChatGPT / Gemini / Claude / Perplexity) · metered · persisted to your DB.
bash# With an API key curl -X POST https://maxfound.ai/api/query?mode=all \ -H "Authorization: Bearer nangua_xxx" \ -H "Content-Type: application/json" \ -d '{ "brand": "Acme Coffee Roasters", "category": "Food & Beverage - Coffee", "platforms": ["chatgpt", "gemini", "claude", "perplexity"] }'
Node.js SDK example:
javascriptasync function queryAi(brand, category) { const r = await fetch('https://maxfound.ai/api/query?mode=all', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.NANGUA_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ brand, category }), }); return r.json(); } const result = await queryAi('Acme Coffee Roasters', 'Food & Beverage - Coffee'); console.log(result.runs[0].results[0].text); // the engine's answer console.log(result.runs[0].results[0].analysis.mentioned); // true / false console.log(result.runs[0].results[0].analysis.position); // char position
/api/aeo/rewriteAuth: Cookie or BearerAEO inverted-pyramid rewrite
Rewrites your source copy into an inverted-pyramid structure plus JSON-LD to meaningfully improve how often AI engines cite it.
bashcurl -X POST https://maxfound.ai/api/aeo/rewrite \ -H "Authorization: Bearer nangua_xxx" \ -H "Content-Type: application/json" \ -d '{ "text": "Acme Coffee Roasters is a specialty coffee chain focused on the in-store experience...", "brand": "Acme Coffee Roasters", "audience": "Families dining out in New York" }'
Response:
json{ "headline": "Acme Coffee Roasters · Specialty Coffee Chain", "section_1_answer": "Acme Coffee Roasters is a specialty coffee chain with 300+ locations nationwide...", "section_2_evidence": ["300+ company-owned locations", "Present in 40+ cities", ...], "section_3_context": "In the specialty coffee market, Acme Coffee Roasters compares with similarly priced chains...", "section_4_faq": [ { "q": "How much does Acme Coffee Roasters cost per person?", "a": "Roughly $8-15 per person..." }, ... ], "score_aviv": 78, "source": "chatgpt", "latency_ms": 8234, "cost_usd": 0.00091, "jsonld": "{...}" }
8. /api/dashboard/* dashboard data API
Every dashboard view has a matching JSON API · pull it into BI, exports, and automation.
| Endpoint | Returns |
|---|---|
| GET /api/dashboard/visibility/timeseries?brand_id=X&days=30 | 30-day daily visibility trend |
| GET /api/dashboard/competitors/breakdown?brand_id=X&days=30 | Per-engine breakdown |
| GET /api/dashboard/prompts/breakdown?brand_id=X&days=30 | Prompt monitoring hit rate |
| GET /api/dashboard/prompts/aida?brand_id=X&days=30 | AIDA funnel stages |
| GET /api/brands/compare?days=30 | Multi-brand comparison |
| GET /api/sentiment/overview?brand_id=X&days=30 | Sentiment alerts |
| GET /api/crisis/incidents?brand_id=X | Crisis incidents |
9. Webhooks
Open /dashboard/webhooks to set a URL, choose the events to subscribe to, and we POST them to your server.
5 event types
wiki.page.created· Wiki page createdwiki.page.updated· Wiki page updatedlint.issue.detected· Lint issue detectedaeo.batch.completed· AEO batch rewrite completedcitation.gap.alert· Citation gap alert
Payload format
json{ "event": "aeo.batch.completed", "brandId": "42cdf804-045f-4b4e-bc99-aa288765aaa0", "timestamp": "2026-05-14T17:30:00.000Z", "data": { "batchId": "xxx", "successCount": 10, "failureCount": 0 } }
Signature verification
Each request carries X-Nangua-Signature: t=<ts>,v1=<hmac> · verify it with an HMAC-SHA256 of your secret:
javascriptimport crypto from 'node:crypto'; function verifyWebhook(rawBody, signatureHeader, secret) { const parts = Object.fromEntries( signatureHeader.split(',').map(p => p.split('=')) ); const expected = crypto .createHmac('sha256', secret) .update(`${parts.t}.${rawBody}`) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(parts.v1) ); }
10. Error codes
| HTTP | Meaning | How to handle |
|---|---|---|
| 400 | Bad parameter | Check error.message and fix the request |
| 401 | Unauthenticated | Check the API key, or whether the cookie has expired |
| 403 | Forbidden | Upgrade your tier or check your team role |
| 404 | Not found | Check the brandId / runId |
| 429 | Rate limited | The Retry-After header gives the retry delay |
| 500 | Server error | Retry; if it persists, email hi@maxfound.ai |
| 502 | AI engine upstream unavailable | Retry with exponential backoff, or switch to another engine |
| 503 | Service degraded | Check /api/status and wait for recovery |