Analytics API
REST API endpoints for retrieving documentation analytics including page views, search queries, and reader engagement.
Overview
The Analytics API provides read-only access to your documentation's performance data. Track page views, search behavior, AI assistant usage, and reader feedback programmatically. Use this data to build custom dashboards, pipe metrics into your data warehouse, or trigger alerts when content underperforms.
Base path: https://api.holydocs.com/api/v1/analytics
All analytics endpoints require authentication with the analytics:read scope.
Analytics data is aggregated in 1-hour buckets. Real-time data may have up to a 5-minute delay before appearing in API responses.
Overview Endpoint
Retrieve high-level metrics for a project over a given time period.
bashGET /api/v1/analytics/overview?projectId=PROJECT_ID&period=30d
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
projectId | string | Yes | Project ID to query analytics for |
period | 7d | 30d | 90d | No | Time period (default: 30d) |
Response
json{ "data": { "period": "30d", "startDate": "2026-03-12T00:00:00Z", "endDate": "2026-04-11T00:00:00Z", "totalViews": 48230, "uniqueVisitors": 12847, "avgTimeOnPage": 142, "bounceRate": 0.34, "topPages": [ { "path": "/quickstart", "title": "Quickstart Guide", "views": 8420, "uniqueVisitors": 3210, "avgTimeOnPage": 185 }, { "path": "/api/authentication", "title": "API Authentication", "views": 5130, "uniqueVisitors": 2890, "avgTimeOnPage": 210 }, { "path": "/components", "title": "Components", "views": 4015, "uniqueVisitors": 1980, "avgTimeOnPage": 165 } ], "viewsByDay": [ { "date": "2026-04-10", "views": 1620, "uniqueVisitors": 430 }, { "date": "2026-04-11", "views": 1580, "uniqueVisitors": 415 } ] }}
Response Fields
bashcurl "https://api.holydocs.com/api/v1/analytics/overview?projectId=$PROJECT_ID&period=30d" \ -H "Authorization: Bearer $HOLYDOCS_API_KEY"
bashholydocs api get "/analytics/overview?projectId=$PROJECT_ID&period=30d"
tsimport { HolyDocs } from '@holydocs/sdk';const client = new HolyDocs({ apiKey: process.env.HOLYDOCS_API_KEY });const { data } = await client.analytics.overview(projectId, { period: '30d' });console.log(`${data.totalViews} views from ${data.uniqueVisitors} visitors`);
Page Analytics
Retrieve per-page analytics with granular engagement data.
bashGET /api/v1/analytics/pages?projectId=PROJECT_ID
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
projectId | string | Yes | Project ID |
period | 7d | 30d | 90d | No | Time period (default: 30d) |
page | number | No | Page number (default: 1) |
perPage | number | No | Results per page (default: 50, max: 200) |
sortBy | views | timeOnPage | feedback | No | Sort field (default: views) |
order | asc | desc | No | Sort order (default: desc) |
Response
json{ "data": [ { "path": "/quickstart", "title": "Quickstart Guide", "views": 8420, "uniqueVisitors": 3210, "avgTimeOnPage": 185, "scrollDepth": 0.72, "feedbackScore": 4.6, "feedbackCount": 34, "entrances": 2100, "exits": 1850 }, { "path": "/api/authentication", "title": "API Authentication", "views": 5130, "uniqueVisitors": 2890, "avgTimeOnPage": 210, "scrollDepth": 0.85, "feedbackScore": 4.8, "feedbackCount": 22, "entrances": 980, "exits": 1200 } ], "meta": { "total": 42, "page": 1, "perPage": 50, "totalPages": 1 }}
Use the entrances and exits fields to identify pages where readers drop off. A high exit-to-entrance ratio on a non-terminal page may indicate content gaps.
Search Analytics
Understand what your readers are searching for and whether they find what they need.
bashGET /api/v1/analytics/search?projectId=PROJECT_ID
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
projectId | string | Yes | Project ID |
period | 7d | 30d | 90d | No | Time period (default: 30d) |
page | number | No | Page number (default: 1) |
perPage | number | No | Results per page (default: 50, max: 200) |
filter | all | zero_results | No | Filter by result type (default: all) |
Response
json{ "data": { "totalSearches": 3420, "uniqueQueries": 1280, "avgClickThrough": 0.68, "zeroResultRate": 0.09, "queries": [ { "query": "authentication", "count": 185, "clickThrough": 0.82, "topResult": "/api/authentication", "avgPosition": 1.2 }, { "query": "rate limiting", "count": 142, "clickThrough": 0.75, "topResult": "/api/authentication", "avgPosition": 1.5 }, { "query": "deploy github actions", "count": 98, "clickThrough": 0.45, "topResult": "/deployments", "avgPosition": 2.8 }, { "query": "graphql support", "count": 67, "clickThrough": 0.0, "topResult": null, "avgPosition": null } ] }, "meta": { "total": 1280, "page": 1, "perPage": 50, "totalPages": 26 }}
Zero-result queries are content opportunities. Use the filter=zero_results parameter to find terms your readers search for that your docs don't cover, then prioritize creating that content.
AI Assistant Analytics
Track AI assistant usage, popular questions, and tool utilization.
bashGET /api/v1/analytics/ai?projectId=PROJECT_ID
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
projectId | string | Yes | Project ID |
period | 7d | 30d | 90d | No | Time period (default: 30d) |
Response
json{ "data": { "totalConversations": 1240, "totalMessages": 5680, "avgMessagesPerConversation": 4.6, "avgResponseTime": 2.3, "satisfactionRate": 0.87, "toolUsage": { "search_docs": 4200, "get_page": 2850, "list_pages": 920 }, "topQuestions": [ { "question": "How do I set up custom domains?", "count": 89, "avgSatisfaction": 0.92 }, { "question": "What authentication methods are supported?", "count": 76, "avgSatisfaction": 0.88 }, { "question": "How do I deploy from GitHub Actions?", "count": 62, "avgSatisfaction": 0.85 }, { "question": "Can I use MDX components in my docs?", "count": 54, "avgSatisfaction": 0.91 } ], "unansweredTopics": [ "GraphQL schema integration", "Monorepo multi-project setup", "Custom theme CSS variables" ] }}
The unansweredTopics array surfaces documentation gaps that are only visible through AI interactions. Use it alongside zero-result search queries to prioritize new content.
Feedback Analytics
Retrieve reader feedback entries with page context, ratings, and comments.
bashGET /api/v1/analytics/feedback?projectId=PROJECT_ID
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
projectId | string | Yes | Project ID |
period | 7d | 30d | 90d | No | Time period (default: 30d) |
page | number | No | Page number (default: 1) |
perPage | number | No | Results per page (default: 50, max: 200) |
rating | 1 | 2 | 3 | 4 | 5 | No | Filter by rating |
hasComment | boolean | No | Filter to entries with comments only |
Response
json{ "data": { "summary": { "totalEntries": 156, "avgRating": 4.3, "distribution": { "1": 4, "2": 8, "3": 18, "4": 52, "5": 74 } }, "entries": [ { "id": "fb_abc123", "pagePath": "/quickstart", "pageTitle": "Quickstart Guide", "rating": 5, "comment": "Clear and easy to follow. Had my docs deployed in under 5 minutes.", "visitorId": "v_anon_xyz", "createdAt": "2026-04-10T14:23:00Z" }, { "id": "fb_def456", "pagePath": "/api/authentication", "pageTitle": "API Authentication", "rating": 3, "comment": "Missing examples for Python. Only shows cURL.", "visitorId": "v_anon_abc", "createdAt": "2026-04-09T09:15:00Z" }, { "id": "fb_ghi789", "pagePath": "/openapi", "pageTitle": "OpenAPI Integration", "rating": 2, "comment": null, "visitorId": "v_anon_def", "createdAt": "2026-04-08T18:42:00Z" } ] }, "meta": { "total": 156, "page": 1, "perPage": 50, "totalPages": 4 }}
Common Patterns
Building a Content Quality Dashboard
Combine multiple analytics endpoints to identify underperforming pages:
Identify low-engagement pages
Query /analytics/pages sorted by timeOnPage ascending to find pages where readers leave quickly.
Cross-reference with feedback
Query /analytics/feedback filtered by rating=1 or rating=2 to find pages with poor reader satisfaction.
Check search gaps
Query /analytics/search?filter=zero_results to find topics readers want but cannot find.
Review AI gaps
Query /analytics/ai and inspect unansweredTopics for content the assistant cannot answer about.
Exporting Analytics to a Data Warehouse
javascript// Nightly export of page analytics to your data warehouseasync function exportAnalytics(projectId, apiKey) { let page = 1; let hasMore = true; while (hasMore) { const response = await fetch( `https://api.holydocs.com/api/v1/analytics/pages?projectId=${projectId}&period=7d&page=${page}&perPage=200`, { headers: { Authorization: `Bearer ${apiKey}` } } ); const { data, meta } = await response.json(); await insertIntoWarehouse('holydocs_page_analytics', data); hasMore = page < meta.totalPages; page++; }}
Rate Limits
Analytics endpoints share the standard rate limits for your plan:
| Plan | Requests per Minute |
|---|---|
| Free | 60 |
| Starter | 120 |
| Pro | 600 |
| Business | 3,000 |
| Enterprise | 6,000 |
Analytics queries over large time periods (90d) are computationally expensive. If you need frequent access to historical data, cache responses on your side or use shorter periods with pagination.
Error Codes
| Code | Status | Description |
|---|---|---|
NOT_FOUND | 404 | Project not found |
VALIDATION_ERROR | 400 | Invalid query parameters (bad period, invalid projectId) |
AUTH_ERROR | 401 | Missing or invalid authentication |
FORBIDDEN | 403 | API key lacks analytics:read scope |
LIMIT_EXCEEDED | 429 | Rate limit exceeded |