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.

bash
GET /api/v1/analytics/overview?projectId=PROJECT_ID&period=30d

Query Parameters

ParameterTypeRequiredDescription
projectIdstringYesProject ID to query analytics for
period7d | 30d | 90dNoTime 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

bash
curl "https://api.holydocs.com/api/v1/analytics/overview?projectId=$PROJECT_ID&period=30d" \ -H "Authorization: Bearer $HOLYDOCS_API_KEY"

Page Analytics

Retrieve per-page analytics with granular engagement data.

bash
GET /api/v1/analytics/pages?projectId=PROJECT_ID

Query Parameters

ParameterTypeRequiredDescription
projectIdstringYesProject ID
period7d | 30d | 90dNoTime period (default: 30d)
pagenumberNoPage number (default: 1)
perPagenumberNoResults per page (default: 50, max: 200)
sortByviews | timeOnPage | feedbackNoSort field (default: views)
orderasc | descNoSort 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.

bash
GET /api/v1/analytics/search?projectId=PROJECT_ID

Query Parameters

ParameterTypeRequiredDescription
projectIdstringYesProject ID
period7d | 30d | 90dNoTime period (default: 30d)
pagenumberNoPage number (default: 1)
perPagenumberNoResults per page (default: 50, max: 200)
filterall | zero_resultsNoFilter 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.

bash
GET /api/v1/analytics/ai?projectId=PROJECT_ID

Query Parameters

ParameterTypeRequiredDescription
projectIdstringYesProject ID
period7d | 30d | 90dNoTime 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.

bash
GET /api/v1/analytics/feedback?projectId=PROJECT_ID

Query Parameters

ParameterTypeRequiredDescription
projectIdstringYesProject ID
period7d | 30d | 90dNoTime period (default: 30d)
pagenumberNoPage number (default: 1)
perPagenumberNoResults per page (default: 50, max: 200)
rating1 | 2 | 3 | 4 | 5NoFilter by rating
hasCommentbooleanNoFilter 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:

1

Identify low-engagement pages

Query /analytics/pages sorted by timeOnPage ascending to find pages where readers leave quickly.

2

Cross-reference with feedback

Query /analytics/feedback filtered by rating=1 or rating=2 to find pages with poor reader satisfaction.

3

Check search gaps

Query /analytics/search?filter=zero_results to find topics readers want but cannot find.

4

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:

PlanRequests per Minute
Free60
Starter120
Pro600
Business3,000
Enterprise6,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

CodeStatusDescription
NOT_FOUND404Project not found
VALIDATION_ERROR400Invalid query parameters (bad period, invalid projectId)
AUTH_ERROR401Missing or invalid authentication
FORBIDDEN403API key lacks analytics:read scope
LIMIT_EXCEEDED429Rate limit exceeded
Ask a question... ⌘I