A REST API to measure, fix and prove GEO — pull AI-visibility data into Looker, GA4, HubSpot or your own app, and trigger scans, audits and generation. Pay-as-you-go, no subscription needed: read endpoints are free; metered calls cost credits.
Create a key under Developer & API and send it as a bearer token. Keys have a scope (read / write) and a mode (live / test). geo_test_ keys run in sandbox mode and never charge credits — perfect for CI.
curl https://geopta.com/v1/clients/Acme/scorecard \ -H "Authorization: Bearer geo_live_…"
Reads are free. Each scan / ask / generate / sandbox / agent-ready costs 1 credit. Variable endpoints (locale-scan, conversation) cost credits proportional to the work (~1 per 3 locales). Buy credits at /billing — they never expire and need no subscription. Check your balance at GET /v1/usage.
120 requests/minute per key. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 includes Retry-After.
Send Idempotency-Key: <uuid> on POST /v1/scans — a retry returns the original response instead of charging another credit.
Non-2xx responses use a consistent envelope:
{
"error": {
"code": "insufficient_credits",
"message": "This run needs 2 credits but you have 1. Top up at /billing.",
"docs": "https://geopta.com/docs/api"
}
}List endpoints accept ?limit (max 100) & ?cursor, and return nextCursor (null at the end) plus total.
Subscribe a URL to scan, alert and remediation events. Non-Slack deliveries are signed with X-GEOpta-Signature: sha256=… — an HMAC of the raw body using your webhook secret (rotate it in Developer & API). Verify like so:
const sig = req.headers["x-geopta-signature"]; // "sha256=…"
const mac = "sha256=" + crypto.createHmac("sha256", SECRET)
.update(rawBody).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(mac))) reject();
{
"source": "geopta",
"event": "scan",
"at": "2026-06-21T09:12:00Z",
"brand": "Acme",
"score": 64,
"delta": 2,
"mentionRate": "5/6"
}
Let Claude, Cursor or any MCP client query your GEO data as a tool. Point it at the GEOpta MCP server with one of your keys:
GEOPTA_API_KEY=geo_live_… node src/mcp.js # tools: list_clients · get_visibility · check_visibility # audit_product · get_roi · run_scan · get_surfaces
/clientsList your tracked brands with their latest visibility score. Paginated via ?limit & ?cursor.
curl https://geopta.com/v1/clients?limit=2 \ -H "Authorization: Bearer geo_live_…"
{
"clients": [
{
"brand": "Acme",
"niche": "CRM software",
"website": "acme.com",
"visibilityScore": 62,
"lastScan": "2026-06-21T09:12:00Z"
}
],
"nextCursor": null,
"total": 1
}/clientsCreate a brand to track. Write key required.
curl -X POST https://geopta.com/v1/clients \
-H "Authorization: Bearer geo_live_…" \
-d '{"brand":"Acme","website":"acme.com",
"prompts":["best CRM for startups"],
"competitors":["Salesforce"]}'{
"brand": "Acme",
"type": "app",
"website": "acme.com",
"prompts": [
"best CRM for startups"
],
"competitors": [
"Salesforce"
]
}/clients/{brand}/scorecardThe latest full scorecard — score, mention/citation rate, top competitors and cited sources.
curl https://geopta.com/v1/clients/Acme/scorecard \ -H "Authorization: Bearer geo_live_…"
{
"scannedAt": "2026-06-21T09:12:00Z",
"visibilityScore": 62,
"mentionRate": "4/6",
"citationRate": "1/6",
"topCompetitors": [
{
"name": "Salesforce",
"count": 5
}
],
"topCitedSources": [
{
"name": "g2.com",
"count": 3
}
]
}/clients/{brand}/roiFull-funnel ROI: AI referral → signup → revenue → LTV, per engine.
curl https://geopta.com/v1/clients/Acme/roi \ -H "Authorization: Bearer geo_live_…"
{
"totals": {
"visits": 1240,
"conversions": 38,
"revenue30": 182000,
"ltv": 2184000,
"roi": 4.2
},
"headline": "ChatGPT drove ₹1,82,000 this month from 22 signups — 60% of your AI revenue."
}/scansStart a scan job (1 credit). Pass an Idempotency-Key so a retry never double-charges.
curl -X POST https://geopta.com/v1/scans \
-H "Authorization: Bearer geo_live_…" \
-H "Idempotency-Key: 9f8b2c…" \
-d '{"brand":"Acme"}'{
"jobId": "job_3a9f…",
"status": "queued",
"poll": "https://geopta.com/v1/scans/job_3a9f…",
"mode": "live"
}/scans/{jobId}Poll a job until status is done (or error).
curl https://geopta.com/v1/scans/job_3a9f… \ -H "Authorization: Bearer geo_live_…"
{
"id": "job_3a9f…",
"brand": "Acme",
"status": "done",
"result": {
"brand": "Acme",
"visibilityScore": 64,
"mentionRate": "5/6",
"prev": 62
}
}/scans/bulkKick off scans for many brands at once (one job each).
curl -X POST https://geopta.com/v1/scans/bulk \
-H "Authorization: Bearer geo_live_…" \
-d '{"brands":["Acme","Beta","Gamma"]}'{
"jobs": [
{
"brand": "Acme",
"jobId": "job_a1…"
},
{
"brand": "Beta",
"jobId": "job_b2…"
}
]
}/askRun any prompt across the engines without saving a client (1 credit).
curl -X POST https://geopta.com/v1/ask \
-H "Authorization: Bearer geo_live_…" \
-d '{"brand":"Acme","prompt":"best CRM for startups",
"competitors":["Salesforce"]}'{
"brand": "Acme",
"prompt": "best CRM for startups",
"engines": [
{
"engine": "gemini",
"mentioned": true,
"cited": false,
"position": 18
},
{
"engine": "claude",
"mentioned": false
}
],
"mentionRate": "1/2",
"mentioned": true
}/agent-readyAudit a product URL for AI-shopping-agent readiness (1 credit).
curl -X POST https://geopta.com/v1/agent-ready \
-H "Authorization: Bearer geo_live_…" \
-d '{"url":"https://acme.com/p/pro","brand":"Acme"}'{
"url": "https://acme.com/p/pro",
"score": 78,
"verdict": "ready",
"product": {
"price": "49.00",
"currency": "USD",
"availability": "InStock"
},
"access": {
"accessScore": 88
}
}/sandboxPredict a draft page's citation-likelihood lift before you publish (1 credit).
curl -X POST https://geopta.com/v1/sandbox \
-H "Authorization: Bearer geo_live_…" \
-d '{"brand":"Acme","content":"# Best CRM for startups\nAcme is…"}'{
"geoScore": 71,
"grade": "Moderate",
"predicted": {
"currentScore": 62,
"projectedScore": 71,
"liftPoints": 9
}
}/generatePaste-ready on-site assets: JSON-LD schema, llms.txt and FAQ (1 credit).
curl -X POST https://geopta.com/v1/generate \
-H "Authorization: Bearer geo_live_…" \
-d '{"brand":"Acme"}'{
"aiUsed": true,
"schemaJsonLd": "{ \"@context\": \"https://schema.org\", … }",
"llmsTxt": "# Acme\\n…",
"faqs": [
{
"q": "What is Acme?",
"a": "Acme is a CRM…"
}
]
}/locale-scanAsync multi-language visibility scan. Credits scale with locales (~1 per 3).
curl -X POST https://geopta.com/v1/locale-scan \
-H "Authorization: Bearer geo_live_…" \
-d '{"brand":"Acme","locales":["en-US","hi-IN","ta-IN"]}'{
"jobId": "job_lc…",
"status": "queued",
"creditsCharged": 1,
"poll": "https://geopta.com/v1/scans/job_lc…"
}/webhooksList your webhook subscriptions.
curl https://geopta.com/v1/webhooks \ -H "Authorization: Bearer geo_live_…"
{
"webhooks": [
{
"id": "wh_1",
"url": "https://api.acme.com/geopta",
"events": [
"scan",
"alert"
],
"format": "json"
}
]
}/webhooksSubscribe a URL to scan / alert / remediation events.
curl -X POST https://geopta.com/v1/webhooks \
-H "Authorization: Bearer geo_live_…" \
-d '{"url":"https://api.acme.com/geopta",
"events":["scan","alert"]}'{
"webhooks": [
{
"id": "wh_2",
"url": "https://api.acme.com/geopta",
"events": [
"scan",
"alert"
],
"format": "json"
}
]
}/usageYour plan, credit balance and remaining scans.
curl https://geopta.com/v1/usage \ -H "Authorization: Bearer geo_live_…"
{
"plan": "free",
"mode": "live",
"scope": "write",
"monthlyScans": 0,
"credits": 23,
"remaining": 23,
"resetsAt": "2026-06-30T18:30:00Z"
}/surfacesThe map of AI surfaces GEOpta measures.
curl https://geopta.com/v1/surfaces \ -H "Authorization: Bearer geo_live_…"
{
"counts": {
"live": 4,
"proxy": 2,
"roadmap": 7
},
"regions": [
"Global",
"India"
]
}/exportDelta export of snapshots for a warehouse sync (?since=ISO8601).
curl "https://geopta.com/v1/export?since=2026-06-01" \ -H "Authorization: Bearer geo_live_…"
{
"since": "2026-06-01",
"count": 128,
"snapshots": [
{
"brand": "Acme",
"scannedAt": "2026-06-21T09:12:00Z",
"visibilityScore": 62
}
]
}