Public API Reference
Access your LogLens analytics data programmatically. Build custom dashboards, integrate with your tools, or automate reporting.
Base URL
https://api.loglens.ai
1 Authentication
All API requests require authentication using an API key. API keys can be created in your Organization Settings.
Pass your API key in the Authorization header:
Authorization: Bearer llapi_your_api_key_here
Note: API keys start with llapi_ to distinguish them from ingest keys.
2 Rate Limits
Rate limits are applied per organization, per hour. The limit depends on your plan:
| Plan | Requests/Hour |
|---|---|
| Free | No API access |
| Starter | 100 |
| Professional | 500 |
| Enterprise | 2,000 |
Rate limit headers are included in every response:
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 499
X-RateLimit-Reset: 2024-01-21T18:00:00Z
3 Error Handling
The API uses standard HTTP status codes and returns JSON error responses:
| Status | Description |
|---|---|
200 |
Success |
401 |
Invalid or missing API key |
403 |
API access not available on your plan |
404 |
Website not found |
429 |
Rate limit exceeded |
500 |
Internal server error |
{
"detail": "Rate limit exceeded",
"limit": 100,
"reset_at": "2024-01-21T18:00:00Z"
}
4 Date Ranges
All analytics endpoints accept a time range. Use hours for a rolling window, or start and end for a specific date range (ISO 8601 format).
GET /websites/{id}/bots?hours=168
GET /websites/{id}/bots?start=2026-03-05&end=2026-03-27
If neither is provided, the default is hours=24. When start/end are present, hours is ignored.
Googlebot Split Variants
The bots endpoint accepts split_variants=true to show Googlebot Desktop and Googlebot Smartphone as separate entries instead of merged:
GET /websites/{id}/bots?hours=168&split_variants=true
Command-Line Interface (CLI) NEW
Access your LogLens analytics from the terminal. Query traffic, bots, SEO data, and more — with table, JSON, and CSV output.
Installation
npm install -g @loglens/cli
Setup
# Save your API key
loglens config set-key YOUR_API_KEY
# Set a default website (optional)
loglens config set-website YOUR_WEBSITE_ID
Examples
# List websites
loglens websites
# Bot breakdown (last 7 days, JSON output)
loglens bots -w <id> -h 168 --json
# SEO crawl budget by directory
loglens seo budget-urls -w <id> --dir /blog/
# Export paths as CSV
loglens paths -w <id> --csv > paths.csv
# Pipe to jq
loglens bots -w <id> --json | jq '.[].name'
# Query a specific date range
loglens bots -w <id> --start 2026-03-05 --end 2026-03-27
# Show Googlebot Desktop and Smartphone separately
loglens bots -w <id> --split-variants
Run loglens --help for the full list of commands. See the help docs for detailed usage.
MCP Server Integration NEW
Connect LogLens to AI assistants like Claude, Cursor, and other tools that support the
Model Context Protocol (MCP).
The MCP server exposes all API endpoints as tools that AI assistants can call automatically. All tools support start, end, and hours date parameters.
MCP Endpoint
https://mcp-loglens.com/mcp?apiKey=YOUR_API_KEY
Setup
Install the mcp-remote bridge (requires Node.js 18+):
npm install -g mcp-remote
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"loglens": {
"command": "npx",
"args": [
"mcp-remote",
"https://mcp-loglens.com/mcp?apiKey=YOUR_API_KEY"
]
}
}
}
If npx isn't found, use the full path to node and mcp-remote. Run which node and which mcp-remote to find them.
Cursor
Go to Settings → MCP Servers and add the endpoint URL:
https://mcp-loglens.com/mcp?apiKey=YOUR_API_KEY
Other MCP Clients
Any MCP-compatible client can connect using the endpoint URL. Clients that don't support remote servers directly can use the mcp-remote bridge as shown above.
Available Tools
23 tools covering all LogLens analytics — traffic, bots, SEO, crawl budget, index coverage, and more. AI assistants will discover these automatically when connected.
| Tool | Description |
|---|---|
list_websites | List all websites in your account |
get_summary | Traffic summary for a website |
get_traffic | Traffic time-series data |
get_bots | Bot and crawler breakdown (supports split_variants for Googlebot Desktop/Smartphone) |
get_seo | SEO crawler analytics |
get_budget_urls | Per-URL crawl budget breakdown |
get_url_patterns | Auto-detected URL patterns |
get_index_coverage | Google index coverage summary |
Plus 15 more tools for paths, geography, status codes, IPs, referrers, devices, robots.txt, sitemap history, and site events.
List Websites
Returns all websites accessible to your API key.
GET /public/v1/websites
Response
{
"websites": [
{
"id": "ws_abc123",
"domain": "example.com",
"name": "Main Website",
"created_at": "2024-01-01T00:00:00Z"
}
],
"count": 1
}
Get Summary
Returns summary statistics for a website.
GET /public/v1/websites/{website_id}/summary
Parameters
| Name | Type | Description |
|---|---|---|
hours |
integer | Time period in hours (default: 24, max: 8760) |
Get Traffic
Returns traffic data with hourly breakdown.
GET /public/v1/websites/{website_id}/traffic?hours=24
Get Bots
Returns bot analytics including identification and verification status.
GET /public/v1/websites/{website_id}/bots?hours=24
Get Paths
Returns path/URL analytics sorted by request count.
GET /public/v1/websites/{website_id}/paths?hours=24&limit=100
Parameters
| Name | Type | Description |
|---|---|---|
hours |
integer | Time period (default: 24) |
limit |
integer | Max results (default: 100, max: 1000) |
Get Geography
Returns geographic distribution of traffic by country and city.
GET /public/v1/websites/{website_id}/geography?hours=24
Get Status Codes
Returns HTTP status code distribution with hourly breakdown.
GET /public/v1/websites/{website_id}/status-codes?hours=24
Get IPs
Returns IP address and IP range analytics.
GET /public/v1/websites/{website_id}/ips?hours=24
Get Referrers
Returns referrer domain analytics - see which sites are sending traffic to you.
GET /public/v1/websites/{website_id}/referrers?hours=24&limit=100
Query Parameters
hours- Time period (1-8760, default: 24)limit- Maximum referrers to return (1-500, default: 100)
Get Devices
Returns device, browser, and operating system analytics.
GET /public/v1/websites/{website_id}/devices?hours=24
Response includes
browsers- Browser breakdown (Chrome, Safari, Firefox, etc.)operating_systems- OS breakdown (Windows, macOS, iOS, Android, etc.)device_types- Device type breakdown (Desktop, Mobile, Tablet)
Get SEO Stats
Returns search engine crawler statistics - Googlebot, Bingbot, etc.
GET /public/v1/websites/{website_id}/seo?hours=24&bot=googlebot
Query Parameters
hours- Time period (1-8760, default: 24)bot- Filter by specific bot (optional, e.g. "googlebot", "bingbot")
Response includes
crawler_requests- Total crawler requestsverified_requests- Verified (legitimate) crawler requestsunverified_suspicious- Potentially spoofed crawler requestsavg_response_time_ms- Average response time to crawlerstop_crawlers- Breakdown by crawler
LLM / AI Crawler Analytics
NEWDedicated analytics for LLM and AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, etc.). Returns per-bot time series, crawler verification status, and the pages those bots are reading.
GET /public/v1/websites/{website_id}/llms?hours=168
Query Parameters
| Name | Type | Description |
|---|---|---|
hours |
integer | Rolling window in hours (default: 24, max: 8760) |
start |
string | ISO 8601 start timestamp (use with end instead of hours) |
end |
string | ISO 8601 end timestamp |
countries |
string | Comma-separated ISO country codes to filter by (e.g. US,GB,DE) |
Response
{
"total_requests": 184201,
"total_ai_requests": 21084,
"ai_percentage": 11.4,
"unique_crawlers": 7,
"unique_pages_crawled": 3419,
"period_hours": 168,
"granularity": "hourly",
"crawlers": [
{
"bot_name": "GPTBot",
"requests": 12847,
"unique_pages": 2105,
"verified_count": 12840,
"unverified_count": 7,
"verification_status": "verified"
}
],
"bot_hourly": [
{ "time_bucket": "2026-05-09-14-00", "GPTBot": 432, "ClaudeBot": 118 }
],
"bot_names": ["GPTBot", "ClaudeBot", "PerplexityBot"],
"pages": [
{
"path": "/blog/launch",
"requests": 412,
"unique_bots": 5,
"status_2xx": 410,
"status_4xx": 2
}
]
}
Available on Starter and above.
Crawl Budget URLs
Per-URL crawl budget breakdown within a directory. Shows which paths search engine crawlers are spending budget on, so you can spot waste.
GET /public/v1/websites/{website_id}/seo/budget-urls?hours=168&directory=/blog/
Query Parameters
| Name | Type | Description |
|---|---|---|
hours | integer | Time window (default: 24, max: 8760) |
directory | string | Directory prefix to drill into (default: /) |
bot | string | Filter to a single crawler (e.g. googlebot) |
page | integer | Page number (default: 1) |
page_size | integer | Results per page (default: 50, max: 500) |
params_filter | string | Filter by URL params (e.g. with_params, no_params) |
file_type | string | Filter by file extension (e.g. html, pdf) |
Response
{
"urls": [
{
"path": "/blog/seo-guide",
"requests": 842,
"percentage": 12.4,
"daily_avg": 120.3
}
],
"total": 317,
"page": 1,
"page_size": 50,
"directory": "/blog/"
}
Available on Starter and above.
URL Patterns
Auto-detected URL pattern templates with crawl frequency. Variable segments (numbers, UUIDs, dates) are replaced with placeholders so you can see how crawlers treat each route family.
GET /public/v1/websites/{website_id}/seo/url-patterns?hours=168&min_urls=3
Query Parameters
| Name | Type | Description |
|---|---|---|
hours | integer | Time window (default: 168, max: 8760) |
bot | string | Filter to a single crawler |
min_urls | integer | Minimum unique URLs per pattern to be returned (default: 3) |
params_filter | string | Filter by URL params |
file_type | string | Filter by file extension |
Response
{
"patterns": [
{
"pattern": "/products/{id}",
"total_requests": 14820,
"unique_urls": 1042,
"daily_avg": 2117.1,
"pct_of_crawl": 22.5,
"status_2xx": 14501,
"status_3xx": 12,
"status_4xx": 301,
"status_5xx": 6,
"pattern_type": "numeric_id",
"flags": ["high_cardinality"],
"example_url": "/products/8421"
}
],
"total_crawl_requests": 65820,
"days_in_period": 7.0,
"min_urls": 3
}
Available on Starter and above.
Path Explorer
Hierarchical view of crawled paths with per-bot and per-status breakdowns. Use to build a directory tree of crawler activity.
GET /public/v1/websites/{website_id}/seo/path-explorer?hours=24
Query Parameters
| Name | Type | Description |
|---|---|---|
hours | integer | Time window (default: 24, max: 8760) |
bot | string | Filter to a single crawler |
params_filter | string | Filter by URL params |
file_type | string | Filter by file extension |
Response
{
"paths": [
{
"path": "/blog/seo-guide",
"requests": 842,
"bots": { "Googlebot": 621, "Bingbot": 221 },
"status_2xx": 840,
"status_3xx": 0,
"status_4xx": 2,
"status_5xx": 0
}
],
"top_bots": ["Googlebot", "Bingbot", "GPTBot"],
"total_paths": 3219
}
Available on Starter and above.
Status Consistency
URLs whose HTTP status changed across crawls — e.g. mostly 200
but occasionally 404 or 5xx.
Useful for surfacing flapping pages and intermittent errors that hit crawlers.
GET /public/v1/websites/{website_id}/seo/status-consistency?hours=168&min_requests=3
Query Parameters
| Name | Type | Description |
|---|---|---|
hours | integer | Time window (default: 24, max: 8760) |
bot | string | Filter to a single crawler |
min_requests | integer | Only include pages with at least this many crawls (default: 3) |
params_filter | string | Filter by URL params |
file_type | string | Filter by file extension |
Response
{
"pages": [
{
"path": "/checkout",
"total_requests": 214,
"status_2xx": 198,
"status_3xx": 0,
"status_4xx": 12,
"status_5xx": 4,
"statuses": { "200": 198, "404": 12, "503": 4 },
"dominant_class": "2xx",
"consistency_pct": 92.5,
"non_2xx_pct": 7.5,
"impact_score": 16,
"last_non_2xx": "2026-05-09T18:42:00Z",
"status_classes": 3
}
],
"summary": {
"total_pages_checked": 2418,
"total_inconsistent": 147,
"critical": 12,
"warning": 38,
"healthy": 97
}
}
Available on Starter and above.
Crawler Request Log
Raw crawler request log with filtering. Each row is one crawler hit — timestamp, path, status, bot identity and verification, and response time.
GET /public/v1/websites/{website_id}/seo/requests?hours=24&filter_type=4xx&page=1
Query Parameters
| Name | Type | Description |
|---|---|---|
hours | integer | Time window (default: 24, max: 8760) |
bot | string | Filter to a single crawler |
filter_type | string | One of: all, verified, unverified, 2xx, 3xx, 4xx, 5xx, slowest |
page | integer | Page number (default: 1) |
page_size | integer | Results per page (default: 50, max: 500) |
params_filter | string | Filter by URL params |
file_type | string | Filter by file extension |
Response
{
"items": [
{
"timestamp": "2026-05-09T18:42:11Z",
"path": "/blog/old-post",
"status": 404,
"method": "GET",
"client_ip": "66.249.66.1",
"user_agent": "Mozilla/5.0 (compatible; Googlebot/2.1; ...)",
"bot_name": "Googlebot",
"bot_verified": true,
"bot_verification_status": "verified",
"time_taken_ms": 182.4
}
],
"total_count": 312,
"page": 1,
"page_size": 50,
"total_pages": 7,
"has_next": true,
"has_prev": false,
"filter": "4xx"
}
Available on Starter and above.
robots.txt Audit
Fetches your live robots.txt, parses the rule groups, and
cross-references them against actual crawler activity to surface violations
(bots hitting paths they were told to skip).
GET /public/v1/websites/{website_id}/seo/robots?hours=168
Query Parameters
| Name | Type | Description |
|---|---|---|
hours | integer | Time window for violation lookup (default: 24, max: 8760) |
bot | string | Limit violation check to a single crawler |
Response
{
"domain": "example.com",
"status": 200,
"fetch_blocked": false,
"using_saved": false,
"raw_content": "User-agent: *\nDisallow: /admin/\n...",
"rule_groups": [
{
"user_agent": "*",
"rules": [
{ "type": "disallow", "path": "/admin/" }
]
}
],
"sitemaps": ["https://example.com/sitemap.xml"],
"violations": [
{
"bot_name": "SemrushBot",
"path": "/admin/login",
"requests": 42,
"rule": "Disallow: /admin/"
}
],
"violations_total": 42,
"violation_summary": {
"SemrushBot": { "total_violations": 1, "total_requests": 42, "unique_paths": 1 }
},
"history": [],
"is_new_version": false,
"current_hash": "a1b2c3..."
}
Available on Starter and above.
Get Sitemap Coverage
Returns sitemap coverage data - tracks which URLs from your sitemap have been crawled by search engines, their crawl frequency, and current status.
GET /public/v1/websites/{website_id}/seo/sitemap?page=1&page_size=50&status=never_crawled
Query Parameters
page- Page number (default: 1)page_size- Results per page (1-500, default: 50)status- Filter: all, never_crawled, recently_crawled, stale, not_in_sitemapsort- Sort by: path, times_crawled, last_crawled, first_seensort_dir- Sort direction: asc, desc
Response fields (per URL)
url- Full URL from sitemapstatus- Crawl status: crawled or not_crawledlast_crawl_date- Timestamp of most recent crawlcrawl_count- Total number of times this URL has been crawledcontent_type- Content type of the URL (e.g. text/html)response_code- HTTP response code from last crawl
URL Crawl History
Per-URL crawl history — every individual crawl event for a single sitemap URL, including which bot, status code, response time, and country.
GET /public/v1/websites/{website_id}/seo/sitemap/url-history?url_path=/blog/post-1&hours=720
Query Parameters
| Name | Type | Description |
|---|---|---|
url_path | string | Required. Path of the URL to look up (e.g. /blog/post-1) |
hours | integer | Time window (default: 168, max: 8760) |
bot | string | Filter to a single crawler |
page | integer | Page number (default: 1) |
page_size | integer | Results per page (default: 50, max: 500) |
Response
{
"url_path": "/blog/post-1",
"total_crawls": 42,
"hours": 720,
"events": [
{
"timestamp": "2026-05-09 14:22:00",
"bot_name": "Googlebot",
"status": 200,
"method": "GET",
"user_agent": "Mozilla/5.0 (compatible; Googlebot/2.1; ...)",
"response_time_ms": 182,
"country": "US"
}
],
"page": 1,
"page_size": 50,
"total_pages": 1,
"bot_summary": {
"Googlebot": { "count": 38, "last_crawled": "2026-05-09 14:22:00" }
}
}
Available on Starter and above.
Index Coverage
Get Google index coverage summary for your website.
GET /public/v1/websites/{website_id}/seo/index-coverage
Response
{
"buckets": {
"crawled_indexed": 1842,
"crawled_not_indexed": 356,
"not_crawled_indexed": 23,
"not_crawled_not_indexed": 491
}
}
Index Coverage URLs
Get paginated list of URLs in an index coverage bucket.
GET /public/v1/websites/{website_id}/seo/index-coverage/urls?bucket=crawled_indexed&page=1&page_size=50
Parameters
| Name | Type | Description |
|---|---|---|
bucket |
string | Required. One of: crawled_indexed, crawled_not_indexed, not_crawled_indexed, not_crawled_not_indexed |
page |
integer | Page number (default: 1) |
page_size |
integer | Results per page (default: 50) |
Response
{
"urls": [
{
"url": "https://example.com/blog/post-1",
"last_crawl_date": "2024-01-28T14:22:00Z",
"last_status_code": 200
}
],
"page": 1,
"page_size": 50,
"total": 1842
}
Site Events
Annotated, site-wide events that overlay onto charts in the dashboard — deploys, algorithm updates, marketing campaigns, anything you want to correlate against traffic shifts.
GET /public/v1/websites/{website_id}/site-events?start_date=2026-04-01&end_date=2026-05-10
Query Parameters
| Name | Type | Description |
|---|---|---|
start_date | string | Optional. Earliest event date (YYYY-MM-DD) |
end_date | string | Optional. Latest event date (YYYY-MM-DD). Use with start_date. |
Response
{
"events": [
{
"website_id": "ws_abc123",
"event_id": "evt_71d2...",
"date": "2026-05-08",
"time": "14:30",
"title": "Deployed v2.4",
"category": "deploy",
"description": "New caching layer rolled out to all regions",
"created_by": "user_abc",
"created_at": "2026-05-08T14:31:09Z",
"updated_at": "2026-05-08T14:31:09Z"
}
]
}
Available on Starter and above.
Operations
Background exports, alert history, and alert configuration for orchestrating LogLens from your own systems.
List Exports
NEWList your background export jobs for a website with status, row count, file size, and a presigned download URL for completed jobs (URL valid for 7 days).
GET /public/v1/websites/{website_id}/exports
Response
{
"exports": [
{
"job_id": "9c1f...e31",
"export_type": "seo-requests",
"status": "completed",
"row_count": 12842,
"file_size_bytes": 4129083,
"created_at": "2026-05-09T10:30:00Z",
"completed_at": "2026-05-09T10:31:48Z",
"error": null,
"filters": "{\"hours\":\"168\",\"filter\":\"4xx\"}",
"description": "4xx filter | last 7d",
"download_url": "https://...s3.amazonaws.com/exports/9c1f...e31.csv?X-Amz-..."
}
]
}
Available on Starter and above. Only your own exports are returned.
Create Export
NEWQueue a new background export job. The export runs asynchronously; poll List Exports for status, or wait for the email notification when it's ready. Files are CSV and links expire after 7 days.
POST /public/v1/websites/{website_id}/exports
Request Body
| Name | Type | Description |
|---|---|---|
export_type |
string | Required. One of: traffic, paths, status-codes, bots, bot-history, referrers, geography, devices, ips, sitemap-coverage, crawl-budget-urls, seo-requests, url-pattern-urls, recommendations-paths-404, recommendations-slow-paths, recommendations-unverified-bots |
hours |
integer | Rolling window in hours. Use this or start/end. |
start / end |
string | ISO 8601 timestamps for an explicit range. |
bot / bot_name |
string | Filter to a single crawler. |
countries |
string | Comma-separated ISO country codes. |
status / status_code / status_category |
string | Filter by HTTP status (e.g. 404) or category (4xx). |
filter |
string | Sub-filter passed through to the underlying endpoint (e.g. verified, slowest for seo-requests). |
directory |
string | Directory prefix (used by crawl-budget-urls). |
pattern |
string | URL pattern template (used by url-pattern-urls). |
params_filter / file_type / path_filter |
string | Optional URL/path filters, mirror the underlying SEO endpoints. |
Response
HTTP/1.1 201 Created
{
"job_id": "9c1f...e31",
"status": "pending",
"message": "Export started. You'll receive an email when it's ready."
}
Available on Starter and above.
Alert History
NEWFired alerts for a website (anomaly detector, error spikes, new-bot detection, etc.). Sorted most-recent first; includes a count of unacknowledged alerts in the last 30 days.
GET /public/v1/websites/{website_id}/alerts?limit=50&type=traffic_spike
Query Parameters
| Name | Type | Description |
|---|---|---|
limit | integer | Max alerts to return (default: 50, max: 500) |
type | string | Filter to a specific alert_type (e.g. traffic_spike, error_rate, new_bot) |
acknowledged | boolean | Filter by acknowledgement state (true/false) |
Response
{
"alerts": [
{
"website_id": "ws_abc123",
"alert_id": "2026-05-09T14:22:00Z#a1b2",
"alert_type": "traffic_spike",
"severity": "warning",
"message": "Traffic 340% above baseline for the last hour",
"details": {
"current_value": 12842,
"baseline_value": 2914,
"deviation_pct": 340.6
},
"acknowledged": false,
"created_at": "2026-05-09T14:22:00Z"
}
],
"count": 1,
"unacknowledged_count": 3
}
Available on Starter and above.
Alert Configuration
NEWReturns the website's current alert configuration — which alert types are enabled, how often each runs, suppression lists, email/webhook settings, and the anomaly-detector baseline status.
GET /public/v1/websites/{website_id}/alerts/config
Response
{
"config": {
"alerts_enabled": true,
"traffic_alerts_enabled": true,
"traffic_frequency_minutes": 60,
"error_alerts_enabled": true,
"error_frequency_minutes": 5,
"bot_alerts_enabled": true,
"bot_frequency_minutes": 1440,
"seo_alerts_enabled": true,
"seo_frequency_minutes": 60,
"suppressed_crawlers": [],
"suppressed_bots": [],
"email_notifications_enabled": true,
"email_disabled_types": [],
"min_email_severity": 5,
"digest_enabled": true,
"min_digest_severity": 3,
"digest_send_hour_utc": 8,
"webhook_notifications_enabled": false,
"webhook_urls": []
},
"baseline_status": {
"status": "ready",
"message": "Baseline established. Anomaly detection is active.",
"data_points": 1248,
"ready": true
}
}
Available on Starter and above.
Search IP Requests
Returns all requests made by a specific IP address. Useful for investigating suspicious activity.
GET /public/v1/websites/{website_id}/ips/{ip_address}/requests?hours=24&page=1
Query Parameters
hours- Time period (1-168, default: 24, max 7 days)page- Page number (default: 1)page_size- Results per page (1-500, default: 50)
Response includes (for each request)
timestamp- Request timestamppath- URL path requestedmethod- HTTP methodstatus- HTTP status codeuser_agent- User agent stringis_bot- Whether request was from a bot
Example Usage
$ cURL
curl -X GET \
"https://api.loglens.ai/public/v1/websites" \
-H "Authorization: Bearer llapi_your_key_here"
JS JavaScript / Node.js
const response = await fetch(
'https://api.loglens.ai/public/v1/websites',
{
headers: {
'Authorization': `Bearer ${apiKey}`
}
}
);
const data = await response.json();
console.log(data.websites);
PY Python
import requests
response = requests.get(
"https://api.loglens.ai/public/v1/websites",
headers={"Authorization": f"Bearer {api_key}"}
)
data = response.json()
print(data["websites"])