GeoGryphon API Documentation
Programmatic access to AI visibility audits and content briefs. Available on Professional and Agency plans.
Authentication
GeoGryphon supports two auth methods. Both work on every authenticated endpoint — pick whichever fits your use case.
JWT (recommended for browsers)
Sign in with Google via POST /auth/google to receive a JWT, then include it as a Bearer token. JWTs are short-lived (7 days) and tied to a specific user.
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
API Keys (recommended for servers, Professional and Agency tiers)
Generate a key via POST /auth/api-keys, then include it in the X-API-Key header. API keys don't expire — revoke manually if compromised. Each user may have one active key at a time; generating a new one replaces the previous.
X-API-Key: geogryphon_a1b2c3d4...
All endpoints except GET /health and POST /auth/google require authentication. Requests without a valid JWT or API key will receive a 401 Unauthorized response.
Auth Endpoints
Exchange a Google OAuth ID token for a GeoGryphon JWT session token. Use the Google Sign-In SDK to obtain the credential value.
{
"credential": "eyJhbGciOiJSUzI1NiIs...google_id_token"
}
200 OK{
"token": "eyJhbGciOiJIUzI1NiIs...geogryphon_jwt",
"user": {
"userId": "usr_a1b2c3d4",
"email": "user@example.com",
"name": "Jane Smith",
"tier": "professional"
}
}
Get the current authenticated user's profile, plan tier, and usage counters for the current billing period.
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",
"paymentStatus": "ok",
"teamOwnerId": null,
"hasStripe": true,
"oneTimeCredits": {
"snapshot": 0,
"bundle": 0,
"brief": 0,
"agencyPack": 0
}
}
Permanently delete the authenticated user's account. Cancels any active Stripe subscription, wipes all audits, briefs, monitors, API keys, and team memberships. Agency owners also unlink their team members (who are downgraded to Free tier). GDPR/CCPA right-to-erasure compliant.
This action is irreversible. A typed confirmation is required in the request body to prevent accidental deletions.
{
"confirm": "DELETE"
}
200 OK{
"message": "Account deleted",
"deletedAt": "2026-04-21T15:30:00.000Z"
}
Returns 400 if the confirm field is missing or not exactly "DELETE".
API Key Endpoints
API keys let you authenticate server-to-server without a JWT. Professional, Business, and Agency tiers only. Each user may have one active key at a time — generating a new key revokes the previous one automatically.
Generate a new API key. Must be authenticated with a JWT (not with an existing API key). Returns the key once — save it immediately; the full key is not stored and cannot be retrieved later.
201 Created{
"apiKey": "geogryphon_a1b2c3d4e5f6...40hex",
"prefix": "geogryphon_a1b2c3d4e5f",
"message": "Save this key — it won't be shown again"
}
Returns 403 if the user's tier is below Professional.
Check whether the user has an active API key. Returns the prefix (first 22 chars, safe to display) and creation time, never the full key.
200 OK (has key){
"hasKey": true,
"prefix": "geogryphon_a1b2c3d4e5f",
"createdAt": "2026-04-10T12:00:00.000Z"
}
200 OK (no key){
"hasKey": false
}
Revoke the current API key. All subsequent requests using the revoked key will return 401 Unauthorized.
200 OK{
"message": "API key revoked"
}
Team Endpoints
Invite up to 10 team members who sign in with their own Google accounts and inherit your subscription tier. Agency tier only. Auto-link: if you invite an email that later signs in with Google, they're automatically linked to your team on their first login — no separate invite link required.
Invite a new team member by email. Emails are normalized to lowercase before storage, so case mismatches on future Google sign-in won't break the auto-link.
{
"email": "colleague@acme.com",
"role": "member"
}
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Team member's email (RFC-compliant, max 254 chars) |
role | string | Yes | One of: admin, member, viewer |
201 Created{
"inviteId": "inv_a1b2c3d4e5f6...",
"email": "colleague@acme.com",
"role": "member",
"status": "pending"
}
List all team members (pending invites + active members). Team owners see all entries; team members see the same list read-only.
200 OK{
"members": [
{
"email": "colleague@acme.com",
"role": "member",
"status": "active",
"joinedAt": "2026-04-15T10:30:00.000Z"
},
{
"email": "intern@acme.com",
"role": "viewer",
"status": "pending",
"createdAt": "2026-04-20T14:00:00.000Z"
}
]
}
Remove a team member. If the member had already signed in and was linked to your team, their tier is downgraded to Free on their next API call. URL-encode the email in the path.
| Parameter | Type | Description |
|---|---|---|
email | string | URL-encoded email (e.g. colleague%40acme.com). Case-insensitive. |
200 OK{
"message": "Team member removed"
}
Audit Endpoints
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.
{
"domain": "acme.com",
"keywords": ["project management", "task tracking"],
"competitors": ["notion.so", "asana.com"]
}
| Field | Type | Required | Description |
|---|---|---|---|
domain | string | Yes | The domain to audit (e.g. "acme.com") |
keywords | string[] | Yes | Keywords to check visibility for (max 10) |
competitors | string[] | No | Competitor domains to compare against (limit by tier) |
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 }
]
}
List your audits, ordered by most recent first. Returns up to 50 audits per request.
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 the full details of a specific audit by its ID. Returns the complete audit object including all engine results and competitor comparisons.
| Parameter | Type | Description |
|---|---|---|
id | string | The audit ID (e.g. "aud_x7k9m2n4") |
200 OKReturns the full audit object (same structure as POST /audits response).
Content Brief Endpoints
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.
{
"topic": "Best project management tools",
"keywords": ["project management", "team collaboration"],
"domain": "acme.com",
"targetEngine": "chatgpt"
}
| Field | Type | Required | Description |
|---|---|---|---|
topic | string | Yes | The content topic or title |
keywords | string[] | Yes | Target keywords (max 10) |
domain | string | Yes | Your domain for brand-specific guidance |
targetEngine | string | No | AI engine to optimize for: chatgpt, perplexity, gemini, claude, bing_copilot, google_aio, meta_ai, grok. Defaults to "chatgpt". |
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"
}
}
List your content briefs, ordered by most recent first. Returns up to 50 briefs per request.
200 OK{
"briefs": [
{
"briefId": "brf_p3q8r5s1",
"topic": "Best project management tools",
"targetEngine": "chatgpt",
"createdAt": "2026-04-07T15:00:00.000Z"
}
],
"count": 1
}
Get the full details of a specific content brief by its ID.
| Parameter | Type | Description |
|---|---|---|
id | string | The brief ID (e.g. "brf_p3q8r5s1") |
200 OKReturns the full brief object (same structure as POST /briefs response).
Billing Endpoints
Create a Stripe Checkout session to subscribe to a paid plan. Returns a URL to redirect the user to Stripe's hosted checkout page.
{
"priceId": "price_1TJRSW7lGnd7R4baNEF1VmPV",
"successUrl": "https://geogryphon.com/success.html",
"cancelUrl": "https://geogryphon.com/pricing.html"
}
200 OK{
"url": "https://checkout.stripe.com/c/pay/cs_live_...",
"sessionId": "cs_live_..."
}
Create a Stripe Customer Portal session. The portal lets users manage their subscription, update payment methods, and view invoices.
{
"returnUrl": "https://geogryphon.com/dashboard.html"
}
200 OK{
"url": "https://billing.stripe.com/p/session/..."
}
System Endpoints
Health check endpoint. Use this to verify the API is operational.
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."
}
| Status | Error | Description |
|---|---|---|
| 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. |