REST API reference

Analytics

Export
Download Markdown Use with AI

Pull your help center's numbers into your own reports, dashboards and scripts. Three read-only reports give you a traffic summary, the performance of each article, and what readers searched for and didn't find. They read the same data as the statistics in your dashboard (see Read your help center statistics).

The reports are available on every plan. Any API key can read them, Read only included; OAuth apps need the analytics.read scope. An API key reports on the help center it was created in, and an OAuth app names the help center with the X-HCio-Site header (see Choose which help center a request acts on).

Endpoints

Method and path

What it returns

GET /v1/analytics/summary

Article views, visitors and searches for a period, each with the change against the period before, plus ratings and your team's authoring activity.

GET /v1/analytics/content

Views and ratings for each article read in the period.

GET /v1/analytics/searches

The searches that failed, the most frequent searches and the most common search words.

All three allow 6 requests a minute per API key or OAuth app, shared between them (see Limits below).

Choose a period

All three endpoints take the same optional parameters:

Parameter

Type

Description

from

date

The first day of the period, for example 2026-09-01. A time of day is ignored. Default: 6 days before to.

to

date

The last day of the period, included. Default: today.

lang

string

Only figures for this language. It must be a language of your help center. Default: all languages.

Without from and to, you get the last 7 days, today included. Days are counted in UTC. A period can be up to 92 days long: a longer one is refused with 422 Unprocessable Entity rather than cut short, so ask for several periods in turn. Every response says which period it measured in range, for example {"from": "2026-09-24", "to": "2026-09-30", "days": 7}.

Get a summary

GET/v1/analytics/summary

Traffic, ratings and authoring activity for a period. Traffic comes with the change against the period before.

Field

Description

traffic.article_views

Article views in the period.

traffic.visitors

Visitors in the period.

traffic.searches

Searches in the period. This is the total the search report does not give.

traffic.article_views_per_visitor

Article views divided by visitors, rounded up.

ratings.total

Ratings readers gave your articles in the period.

activity

Your team's work in the period: articles_created, articles_updated, articles_published (drafts that were published), articles_unpublished (published articles turned back into drafts) and active_team_members (people who edited articles). lang doesn't filter these.

totals.published_articles

Articles published now, whatever the period. With lang set to another language than your default, the published articles translated into it.

Each traffic figure has a count and a change_pct: the change in percent against the preceding period of the same length, rounded to one decimal. For the last 7 days, that is the 7 days before them. change_pct is 0 when the preceding period had nothing to compare with. Numbers with nothing after the decimal point come without one (0, not 0.0), so read them as numbers, not as a fixed format.

Get article performance

GET/v1/analytics/content

Views and ratings for each article read in the period. Sort by rating to find the articles readers like least.

Parameter

Type

Description

sort

string

views_desc (default) for the most read first, views_asc for the least read first, or rating_asc for the largest share of thumbs down first, with ties broken toward the most read article.

category_id

integer

Only articles filed directly in this category, not in its subcategories. It must be a category of your help center. A category with no articles gives an empty list, and so do 0 and -1: they don't select uncategorized articles.

page, per_page

integer

The page, from 1, and articles per page, 1 to 100. Default per_page: 25.

  • Only articles read in the period are listed, as excludes_never_viewed reminds you. To find the articles nobody opened, list your articles with the Articles endpoints and compare. Drafts and articles in the Trash never appear.

  • views_in_range counts views in the period. total_views is an all-time counter that no longer counts new views, so it can be lower than views_in_range. Use views_in_range for current traffic.

  • Ratings are percentages of all the ratings the article ever received, not only those in the period, and not counts. Each is rounded up, so they can add up to more than 100 (67 and 34 in the example). One thumbs down reads as 100%, so weigh ratings against views. With lang, only ratings in that language count.

  • title and slug are always the English ones: an article without an English title comes back with both empty. Match rows to your articles with article_id; _links.view is the article's address on your help center in any case.

  • updated_at is when the article was last changed.

Get search demand and content gaps

GET/v1/analytics/searches

What readers searched for: the searches that failed, the most frequent searches and the most common words.

Use limit to set how many rows each list returns: 1 to 50, 20 by default. There is no paging: each list holds the top rows only, as meta.lists_are_top_n says.

  • content_gaps lists the searches that failed most, frequent_queries the most frequent searches (with the same fields), and common_terms the single words most used in searches.

  • Rows are counted per day, not over the period. Each row holds one query on one day, and a query searched in several languages, or both on your help center and in the widget, gets a row for each. The same query can therefore appear in several rows of one list, like "cancel annual plan refund" in the example: add the rows up for a period total.

  • A search fails when it returns no results or nobody opens a result: failed_searches is zero_result_searches plus no_click_searches, and failure_rate is failed_searches divided by searches, rounded to two decimals.

  • reason tells you what to fix. 0 results: nothing matched, so write the article. no click: results came back but nobody opened one, so the article probably exists and its title doesn't match what readers type. mixed: both happened. It is null in frequent_queries.

  • top_hit is the first result readers got for the query, and article_clicked the article a reader opened from the results, each taken from the latest search that had one. Each is null or {article_id, title, status}, where status can also be trashed, or deleted with no title.

  • last_searched_at is when the query was last searched that day, in UTC. query is the text as readers typed it.

  • For the total number of searches, use traffic.searches from the summary.

How fresh the numbers are

Views, visitors, searches and the search lists are computed once a day. Today's figures are incomplete until the next day, and the most recent days can still change as the daily run processes them again. Ratings, authoring activity and published totals are counted when you ask.

So fetch a report once and keep it. Asking for the same period again during the day returns the same traffic figures and spends your limit.

Limits

  • The analytics endpoints allow 6 requests a minute per API key or OAuth app, shared between the three, on top of the general limit of 300 a minute (see Rate limits). Requests refused with 422 count too.

  • Over the limit, the API answers 429 Too Many Requests with the code analytics_rate_limited, and Retry-After gives the seconds to wait. Wait instead of retrying in a loop.

  • When the reports can't be computed, the API answers 503 Service Unavailable with the code analytics_unavailable and Retry-After: 300. It isn't a problem with your request: try again after five minutes.

What the reports include

Only totals, counts and rates: no visitor IP addresses, no visitor identifiers, no individual searches and no reader journeys. Search query text is returned as readers typed it, so treat it like any text readers send you.

Private articles, and articles in private categories, appear with their titles like every other article: a key or token sees all of its help center's articles, as it does through the Articles endpoints.

Errors

Status

When

401 Unauthorized

The key or token is missing or not valid: {"status": "unauthorized"}.

403 Forbidden

insufficient_scope: the OAuth token doesn't have analytics.read.

422 Unprocessable Entity

A parameter is not valid: a period over 92 days, to before from, a date the API can't read, a language that isn't enabled, a category of another help center, or sort, per_page or limit out of range. errors names the parameter.

429 Too Many Requests

analytics_rate_limited: more than 6 analytics requests in a minute.

503 Service Unavailable

analytics_unavailable: try again after the seconds in Retry-After.

Was this article helpful?