GeoGryphon API Documentation

Programmatic access to AI visibility audits and content briefs. Available on Professional and Agency plans.

https://api.geogryphon.com

Authentication

GeoGryphon uses JWT-based authentication. To obtain a token, sign in with your Google account via the POST /auth/google endpoint. Then include the token in all subsequent requests as a Bearer token.

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

All endpoints except GET /health and POST /auth/google require authentication. Requests without a valid token will receive a 401 Unauthorized response.

Coming soon: API key-based authentication for server-to-server integrations. Contact support if you need this today.

Auth Endpoints

POST /auth/google No Auth Required

Exchange a Google OAuth ID token for a GeoGryphon JWT session token. Use the Google Sign-In SDK to obtain the credential value.

Request Body
{
  "credential": "eyJhbGciOiJSUzI1NiIs...google_id_token"
}
Response 200 OK
{
  "token": "eyJhbGciOiJIUzI1NiIs...geogryphon_jwt",
  "user": {
    "userId": "usr_a1b2c3d4",
    "email": "user@example.com",
    "name": "Jane Smith",
    "tier": "professional"
  }
}
GET /auth/me Auth Required

Get the current authenticated user's profile, plan tier, and usage counters for the current billing period.

Response 200 OK
{
  "userId": "usr_a1b2c3d4",
  "email": "user@example.com",
  "name": "Jane Smith",
  "tier": "professional",
  "auditsUsed": 12,
  "briefsUsed": 5,
  "resetsAt": "2026-05-01T00:00:00.000Z"
}

Audit Endpoints

POST /audits Auth Required

Run an AI visibility audit for a domain across multiple AI engines. Checks how each engine references your brand, calculates share of voice, and compares against competitors.

Request Body
{
  "domain": "acme.com",
  "keywords": ["project management", "task tracking"],
  "competitors": ["notion.so", "asana.com"]
}
FieldTypeRequiredDescription
domainstringYesThe domain to audit (e.g. "acme.com")
keywordsstring[]YesKeywords to check visibility for (max 10)
competitorsstring[]NoCompetitor domains to compare against (limit by tier)
Response 200 OK
{
  "auditId": "aud_x7k9m2n4",
  "userId": "usr_a1b2c3d4",
  "domain": "acme.com",
  "keywords": ["project management"],
  "createdAt": "2026-04-07T14:30:00.000Z",
  "engines": {
    "chatgpt": {
      "mentioned": true,
      "position": 2,
      "snippet": "Acme is a leading project management tool...",
      "citationUrl": "https://acme.com/features"
    },
    "perplexity": {
      "mentioned": true,
      "position": 1,
      "snippet": "For project management, Acme offers...",
      "citationUrl": "https://acme.com"
    }
  },
  "shareOfVoice": {
    "score": 0.42,
    "rank": 2,
    "totalCompetitors": 5
  },
  "comparison": [
    { "domain": "notion.so", "score": 0.58, "rank": 1 },
    { "domain": "acme.com", "score": 0.42, "rank": 2 }
  ]
}
GET /audits Auth Required

List your audits, ordered by most recent first. Returns up to 50 audits per request.

Response 200 OK
{
  "audits": [
    {
      "auditId": "aud_x7k9m2n4",
      "domain": "acme.com",
      "keywords": ["project management"],
      "shareOfVoice": { "score": 0.42 },
      "createdAt": "2026-04-07T14:30:00.000Z"
    }
  ],
  "count": 1
}
GET /audits/{id} Auth Required

Get the full details of a specific audit by its ID. Returns the complete audit object including all engine results and competitor comparisons.

Path Parameters
ParameterTypeDescription
idstringThe audit ID (e.g. "aud_x7k9m2n4")
Response 200 OK

Returns the full audit object (same structure as POST /audits response).

Content Brief Endpoints

POST /briefs Auth Required

Generate a citation-optimized content brief. The brief includes recommended sections, entities to mention, JSON-LD structured data, and SEO guidance tailored to a specific AI engine.

Request Body
{
  "topic": "Best project management tools",
  "keywords": ["project management", "team collaboration"],
  "domain": "acme.com",
  "targetEngine": "chatgpt"
}
FieldTypeRequiredDescription
topicstringYesThe content topic or title
keywordsstring[]YesTarget keywords (max 10)
domainstringYesYour domain for brand-specific guidance
targetEnginestringNoAI engine to optimize for: chatgpt, perplexity, gemini, claude, bing_copilot, google_aio, meta_ai, grok. Defaults to "chatgpt".
Response 200 OK
{
  "briefId": "brf_p3q8r5s1",
  "userId": "usr_a1b2c3d4",
  "topic": "Best project management tools",
  "targetEngine": "chatgpt",
  "createdAt": "2026-04-07T15:00:00.000Z",
  "sections": [
    {
      "heading": "Introduction",
      "wordCount": 150,
      "guidance": "Lead with a clear definition. Mention your brand by name in the first paragraph..."
    },
    {
      "heading": "Feature Comparison",
      "wordCount": 400,
      "guidance": "Use a structured comparison table. Include specific metrics..."
    }
  ],
  "entities": [
    { "name": "project management", "type": "concept", "importance": "high" },
    { "name": "Acme", "type": "brand", "importance": "high" }
  ],
  "jsonLd": {
    "@context": "https://schema.org",
    "@type": "Article",
    "headline": "Best project management tools",
    "author": { "@type": "Organization", "name": "Acme" }
  },
  "seoGuidance": {
    "titleTag": "Best Project Management Tools (2026) | Acme",
    "metaDescription": "Compare the best project management tools...",
    "targetWordCount": 2200,
    "readabilityLevel": "grade 8"
  }
}
GET /briefs Auth Required

List your content briefs, ordered by most recent first. Returns up to 50 briefs per request.

Response 200 OK
{
  "briefs": [
    {
      "briefId": "brf_p3q8r5s1",
      "topic": "Best project management tools",
      "targetEngine": "chatgpt",
      "createdAt": "2026-04-07T15:00:00.000Z"
    }
  ],
  "count": 1
}
GET /briefs/{id} Auth Required

Get the full details of a specific content brief by its ID.

Path Parameters
ParameterTypeDescription
idstringThe brief ID (e.g. "brf_p3q8r5s1")
Response 200 OK

Returns the full brief object (same structure as POST /briefs response).

Billing Endpoints

POST /stripe/create-checkout Auth Required

Create a Stripe Checkout session to subscribe to a paid plan. Returns a URL to redirect the user to Stripe's hosted checkout page.

Request Body
{
  "priceId": "price_1TJRSW7lGnd7R4baNEF1VmPV",
  "successUrl": "https://geogryphon.com/success.html",
  "cancelUrl": "https://geogryphon.com/pricing.html"
}
Response 200 OK
{
  "url": "https://checkout.stripe.com/c/pay/cs_live_...",
  "sessionId": "cs_live_..."
}
POST /stripe/portal Auth Required

Create a Stripe Customer Portal session. The portal lets users manage their subscription, update payment methods, and view invoices.

Request Body
{
  "returnUrl": "https://geogryphon.com/dashboard.html"
}
Response 200 OK
{
  "url": "https://billing.stripe.com/p/session/..."
}

System Endpoints

GET /health No Auth Required

Health check endpoint. Use this to verify the API is operational.

Response 200 OK
{
  "status": "ok",
  "timestamp": "2026-04-07T14:30:00.000Z"
}

Rate Limits

API requests are rate-limited per user using a sliding window of 60 seconds. When you exceed the limit, the API returns 429 Too Many Requests. The response includes a Retry-After header indicating how many seconds to wait.

Tier Audits Briefs Auth Monthly Audits Monthly Briefs
Free 5/min 3/min 10/min (IP) 3 1
Starter 15/min 10/min 10/min (IP) 25 10
Professional 30/min 20/min 10/min (IP) Unlimited Unlimited
Agency 60/min 40/min 10/min (IP) Unlimited Unlimited

Monthly usage counters reset automatically on the first day of each billing period. Check your current usage via GET /auth/me.

Code Examples

cURL — Run an AI Visibility Audit

# Run an audit for acme.com
curl -X POST https://api.geogryphon.com/audits \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{
    "domain": "acme.com",
    "keywords": ["project management", "task tracking"],
    "competitors": ["notion.so", "asana.com"]
  }'

JavaScript — Fetch Audit Results

// Run an audit and retrieve results
const response = await fetch('https://api.geogryphon.com/audits', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  },
  body: JSON.stringify({
    domain: 'acme.com',
    keywords: ['project management'],
    competitors: ['notion.so']
  })
});

const audit = await response.json();
console.log(`Share of Voice: ${audit.shareOfVoice.score * 100}%`);
console.log(`Engines checked: ${Object.keys(audit.engines).length}`);

Python — Generate a Content Brief

import requests

API_BASE = "https://api.geogryphon.com"
TOKEN = "YOUR_JWT_TOKEN"

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {TOKEN}"
}

# Generate a content brief optimized for ChatGPT
brief = requests.post(
    f"{API_BASE}/briefs",
    headers=headers,
    json={
        "topic": "Best project management tools",
        "keywords": ["project management"],
        "domain": "acme.com",
        "targetEngine": "chatgpt"
    }
).json()

print(f"Brief ID: {brief['briefId']}")
print(f"Sections: {len(brief['sections'])}")
print(f"Entities: {len(brief['entities'])}")

Error Codes

All error responses follow a consistent format:

{
  "error": "Short error code",
  "message": "Human-readable description of what went wrong."
}
StatusErrorDescription
400 bad_request Missing or invalid request parameters. Check the request body matches the expected schema.
401 unauthorized Missing or invalid JWT token. Re-authenticate via POST /auth/google to obtain a new token.
403 forbidden Your plan does not include access to this feature. Upgrade at pricing.
404 not_found The requested resource (audit, brief, etc.) does not exist or belongs to another user.
429 rate_limited Too many requests. Wait for the duration specified in the Retry-After header before retrying.
500 internal_error An unexpected server error occurred. If this persists, contact support.