Analyze and optimize your web pages for AI visibility using our template-based scoring system. Generate LLMS.txt files with AI-powered content analysis.
The Geoleaper API uses Laravel Sanctum for token-based authentication. All API endpoints (except token creation) require a valid Bearer token.
Generate a new API token by providing your account credentials:
curl -X POST https://app.geoleaper.com/api/auth/token \
-H "Content-Type: application/json" \
-d '{
"email": "your@email.com",
"password": "your_password",
"token_name": "my-app-token"
}'
{
"token": "1|abc123...",
"token_name": "my-app-token",
"login_url": "https://geoleaper.com/login-as/...",
"tenant": {
"id": 1,
"name": "My Company"
},
"user": {
"id": 1,
"name": "John Doe",
"email": "your@email.com"
}
}
Include your API token in the Authorization header with the Bearer prefix:
curl https://app.geoleaper.com/api/analyses \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
GET /auth/tokens
DELETE /auth/tokens/current
DELETE /auth/tokens/all
curl -X POST https://app.geoleaper.com/api/auth/token \
-H "Content-Type: application/json" \
-d '{
"email": "your@email.com",
"password": "your_password"
}'
curl -X POST https://app.geoleaper.com/api/analyses \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/product"}'
curl https://app.geoleaper.com/api/analyses/{id} \
-H "Authorization: Bearer YOUR_API_TOKEN"
|
Package
|
Max Unique URLs
|
Max Domains
|
Bulk Limit
|
|---|---|---|---|
| 10 | 1 | 10 URLs | |
| 200 | 1 | 200 URLs | |
| 1,500 | 5 | 1,500 URLs |
/analyses
Retrieve paginated list of analyses with optional URL filtering.
|
Parameter
|
Type
|
Required
|
Description
|
|---|---|---|---|
url
|
string | No | Filter by URL (partial match) |
per_page
|
integer | No | Results per page (default: 20, max: 100) |
curl "https://app.geoleaper.com/api/analyses?url=example.com&per_page=10"
{
"data": [
{
"id": 7,
"url": "https://example.com/product",
"score": 90,
"status": "completed",
"created_at": "2025-11-02T09:16:28+00:00"
}
],
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 10,
"total": 45
}
}
/analyses
Create a new analysis job. Returns immediately with analysis ID. The analysis runs asynchronously in the background queue.
{
"url": "https://example.com/product"
}
{
"id": 7,
"url": "https://example.com/product",
"status": "pending",
"check_url": "https://app.geoleaper.com/api/analyses/7",
"created_at": "2025-11-02T09:16:28+00:00"
}
/analyses/bulk
Create multiple analyses from a sitemap.xml file. Supports sitemap index files and nested sitemaps.
{
"sitemap_url": "https://example.com/sitemap.xml",
"limit": 50
}
|
Parameter
|
Type
|
Required
|
Description
|
|---|---|---|---|
sitemap_url
|
string | Yes | URL to sitemap.xml file |
limit
|
integer | No | Max URLs to analyze (default: 100, max: 1000) |
{
"message": "Bulk analysis started",
"total": 50,
"analyses": [
{
"id": 10,
"url": "https://example.com/page1",
"status": "pending",
"check_url": "https://app.geoleaper.com/api/analyses/10"
}
]
}
/analyses/{id}
Get analysis status and results. Poll this endpoint to check if analysis is complete.
The LLMS.txt Generation feature uses AI to automatically create optimized llms.txt files for your website. The AI analyzes your website content, discovers important pages, and generates a comprehensive llms.txt file that helps AI systems better understand your business.
Generation limit for all plans
Average generation time
Content sources analyzed
The AI fetches your homepage and identifies important pages (about, pricing, features, documentation, etc.)
Scrapes and analyzes content from your homepage and up to 4 additional important pages
Uses GPT-4o to analyze the content and generate a comprehensive, structured llms.txt file in English
The generated file is optimized for AI understanding with clear structure, concrete information, and scannable formatting
/llms-txt
Retrieve paginated list of llms.txt generations for your tenant.
|
Parameter
|
Type
|
Required
|
Description
|
|---|---|---|---|
per_page
|
integer | No | Results per page (default: 20, max: 100) |
{
"data": [
{
"id": 1,
"url": "https://example.com",
"status": "completed",
"created_at": "2025-11-20T10:00:00+00:00",
"generated_at": "2025-11-20T10:02:15+00:00"
}
],
"meta": {
"current_page": 1,
"last_page": 1,
"per_page": 20,
"total": 1
}
}
/llms-txt
Create a new llms.txt generation job. The AI will browse your website and create a comprehensive llms.txt file. This process runs asynchronously and typically takes 2-5 minutes.
{
"url": "https://example.com"
}
{
"id": 1,
"url": "https://example.com",
"status": "pending",
"message": "LLMS.txt generation started. Check status using the provided check_url.",
"check_url": "https://app.geoleaper.com/api/llms-txt/1",
"created_at": "2025-11-20T10:00:00+00:00"
}
Feature not available (Free plan):
{
"message": "LLMS.txt generation is only available for Pro and Max plans.",
"error": "upgrade_required"
}
Rate limit exceeded:
{
"message": "Monthly generation limit reached. You can generate up to 3 llms.txt files per month.",
"error": "rate_limit_exceeded",
"usage": {
"generations_used": 3,
"generations_limit": 3,
"generations_remaining": 0,
"can_generate": false
}
}
/llms-txt/{id}
Check the status of an llms.txt generation and retrieve the content when completed.
/llms-txt/{id}/download
Download the generated llms.txt content as a plain text file.
Returns plain text file with Content-Disposition: attachment; filename="llms.txt"
Generation not completed yet
Generation not found
curl https://app.geoleaper.com/api/llms-txt/1/download \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-o llms.txt
/llms-txt/usage
Get current month's usage statistics for llms.txt generation.
{
"has_access": true,
"usage": {
"generations_used": 2,
"generations_limit": 3,
"generations_remaining": 1,
"can_generate": true
},
"resets_at": "2025-12-01T00:00:00+00:00"
}
{
"message": "LLMS.txt generation is only available for Pro and Max plans.",
"has_access": false
}
curl https://app.geoleaper.com/api/llms-txt/usage \
-H "Authorization: Bearer YOUR_API_TOKEN"
curl -X POST https://app.geoleaper.com/api/llms-txt \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
# Response:
{
"id": 1,
"check_url": "https://app.geoleaper.com/api/llms-txt/1"
}
Poll every 30 seconds until status is completed:
curl https://app.geoleaper.com/api/llms-txt/1 \
-H "Authorization: Bearer YOUR_API_TOKEN"
Option A: Download as file
curl https://app.geoleaper.com/api/llms-txt/1/download \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-o llms.txt
Option B: Get content in JSON
curl https://app.geoleaper.com/api/llms-txt/1 \
-H "Authorization: Bearer YOUR_API_TOKEN"
# Use the "content" field from the response
/tenant
Get current tenant information including package, features, limits, and usage.
{
"id": 1,
"name": "My Company",
"package": "pro",
"package_description": "Analyze with AI up to 200 different URLs on 1 domain",
"features": {
"perfect_json_ld": true,
"llms_txt_generation": true,
"ollama_detection": true,
"custom_prompts": true
},
"limits": {
"max_urls": 200,
"max_domains": 1,
"analyses_per_month": 200,
"bulk_limit": 200,
"llms_txt_per_month": 3
},
"usage": {
"analyses_this_month": 45,
"unique_urls_analyzed": 87,
"unique_domains_analyzed": 1,
"urls_remaining": 113,
"domains_remaining": 0,
"llms_txt_generated_this_month": 2,
"llms_txt_remaining": 1
},
"created_at": "2025-01-01T00:00:00+00:00"
}
/tenant
Update tenant settings.
{
"name": "Updated Company Name"
}
{
"message": "Tenant updated successfully",
"tenant": {
"id": 1,
"name": "Updated Company Name",
"package": "pro"
}
}
/tenant/usage
Get tenant's current usage and quota information including package details, URLs analyzed, and remaining limits.
{
"package": "pro",
"urls_analyzed": 5,
"urls_remaining": 995,
"urls_limit": 1000,
"domains_analyzed": 2,
"domains_remaining": 3,
"domains_limit": 5,
"llms_txt_generated": 2,
"llms_txt_remaining": 1,
"llms_txt_limit": 3
}
|
Field
|
Type
|
Description
|
|---|---|---|
package
|
string | Current package: "free", "pro", or "max" |
urls_analyzed
|
integer | Total unique URLs analyzed this month |
urls_remaining
|
integer | Remaining URL quota for this month |
urls_limit
|
integer | Total URL limit per month |
domains_analyzed
|
integer | Total unique domains analyzed |
domains_remaining
|
integer | Remaining domain quota |
domains_limit
|
integer | Total domain limit |
llms_txt_generated
|
integer | LLMS.txt files generated this month |
llms_txt_remaining
|
integer | Remaining LLMS.txt generations this month |
llms_txt_limit
|
integer | Total LLMS.txt generation limit per month (3 for Pro/Max) |
/tenant/stats
Get detailed statistics for the tenant including analysis counts, average scores, and top performers.
{
"total_analyses": 150,
"completed_analyses": 145,
"failed_analyses": 3,
"pending_analyses": 2,
"average_score": 82.5,
"this_month": {
"total": 45,
"completed": 43,
"average_score": 85.2
},
"top_scores": [
{
"id": 10,
"url": "https://example.com/best-page",
"total_score": 98,
"created_at": "2025-11-01T10:00:00+00:00"
}
]
}
/tenant/dashboard
Get dashboard statistics with optional filters for domain and date range. Returns stats cards, recent analyses, and available domains.
|
Parameter
|
Type
|
Required
|
Description
|
|---|---|---|---|
domain
|
string | No | Filter by specific domain |
from_date
|
date | No | Start date (YYYY-MM-DD) |
to_date
|
date | No | End date (YYYY-MM-DD) |
curl "https://app.geoleaper.com/api/tenant/dashboard?domain=example.com&from_date=2025-11-01&to_date=2025-11-30" \
-H "Authorization: Bearer YOUR_API_TOKEN"
{
"stats": {
"total_analyses": 13,
"average_score": 63,
"analyses_this_week": 13,
"critical_issues": 0
},
"recent_analyses": [
{
"id": 13,
"url": "https://example.com",
"total_score": 63,
"grade": "D",
"status": "completed",
"created_at": "2025-11-20T11:43:02+00:00"
},
{
"id": 12,
"url": "https://example.com/page",
"total_score": 85,
"grade": "B",
"status": "completed",
"created_at": "2025-11-20T11:42:39+00:00"
}
],
"available_domains": [
"example.com",
"another-site.com"
]
}
/tenant/score-distribution
Get score distribution by grade (A-F) with optional filters for domain and date range. All grades are always included in the response with a count of 0 if no analyses match that grade.
|
Parameter
|
Type
|
Required
|
Description
|
|---|---|---|---|
domain
|
string | No | Filter by specific domain |
from_date
|
date | No | Start date (YYYY-MM-DD) |
to_date
|
date | No | End date (YYYY-MM-DD) |
curl "https://app.geoleaper.com/api/tenant/score-distribution?domain=example.com" \
-H "Authorization: Bearer YOUR_API_TOKEN"
{
"distribution": {
"A": 5,
"B": 12,
"C": 8,
"D": 3,
"F": 2
},
"total": 30
}
|
Grade
|
Score Range
|
Description
|
|---|---|---|
| 90-100 | Excellent AI visibility | |
| 80-89 | Good AI visibility | |
| 70-79 | Fair AI visibility | |
| 60-69 | Poor AI visibility | |
| 0-59 | Very poor AI visibility |
/user
Get current user information.
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"tenant_id": 1,
"created_at": "2025-01-01T00:00:00+00:00"
}
/user
Update user profile.
{
"name": "Jane Doe",
"email": "jane@example.com"
}
/user/stats
Get detailed user statistics.
{
"total_analyses": 75,
"completed_analyses": 72,
"failed_analyses": 2,
"pending_analyses": 1,
"average_score": 84.3,
"best_score": 98,
"worst_score": 45,
"this_week": {
"total": 15,
"completed": 14
},
"this_month": {
"total": 45,
"completed": 43
},
"recent_analyses": [
{
"id": 123,
"url": "https://example.com/page",
"status": "completed",
"total_score": 92,
"created_at": "2025-11-20T10:00:00+00:00"
}
]
}
|
Code
|
Description
|
When
|
|---|---|---|
| Success | Request succeeded | |
| Accepted | Processing in background | |
| Unauthorized | Missing or invalid authentication | |
| Not Found | Resource doesn't exist | |
| Validation Error | Invalid request data | |
| Server Error | Analysis failed or server error |
|
Status
|
Description
|
Next Action
|
|---|---|---|
pending
|
Queued, not started yet | Wait and poll |
analyzing
|
Fetching HTML and analyzing | Wait and poll |
generating
|
Generating perfect JSON-LD (Pro/Max) | Wait and poll |
completed
|
Analysis complete | Read results |
failed
|
Analysis failed | Check error field |
Total score: 0-100 points (4 categories × 25 points each)
per month
Analyze basic without AI up to 10 different URLs on 1 domain
per month
Analyze with AI up to 200 different URLs on 1 domain
per month
Analyze with AI up to 1500 different URLs on 5 domains