Get help center analytics with the Notiondesk API

Export Notiondesk help center analytics via the REST API: visitors, article views, top searches, searches with no results, and reader reactions.

5 min read

The Notiondesk API gives you the numbers behind your help center's analytics pages: visitors, article views, time on page, countries, what readers search for, which searches find nothing, and how readers react to your articles. Use it to feed a BI tool, post a weekly report to Slack, or find the content your readers are missing.

GET /sites/{site_id}/analytics/{report}
reportContains
quickA 30-day summary: articles, visitors, searches and reactions
overviewVisitors, article views, time on page and top countries
searchSearches, top queries, searches without results and click-through rate
engagementArticle views, top articles, referrers, reactions and articles to revise

Every report needs the read scope. To read these numbers in the dashboard, see How to improve your help center with reader insights.

Get a 30-day summary

curl "https://api.notiondesk.so/sites/c74781f6-1aea-4e17-ab23-bbb8b4d174b6/analytics/quick" \
  -H "Authorization: Bearer $NOTIONDESK_API_KEY" \
  -H "nd-version: 2026-10-16"
{
  "articles": 42,
  "visitors": 25,
  "searches": 9,
  "reactions": 4
}

quick covers the last 30 days ending now and takes no query parameter. articles counts every article of the help center, drafts included. reactions counts each reader's latest reaction per article.

Get a report for a date range

overview, search and engagement take a date range and a bucket size:

ParameterRequiredNotes
start_dateYesThe first instant of the range, such as 2026-09-01T00:00:00Z
end_dateYesThe end of the range, excluded. Must be after start_date
date_scaleYesThe bucket size of the time series: minute, hour, day, week, month or year
timezoneNoAn IANA timezone that sets bucket boundaries, such as Europe/Paris. Default UTC
curl "https://api.notiondesk.so/sites/c74781f6-1aea-4e17-ab23-bbb8b4d174b6/analytics/search?start_date=2026-09-01T00:00:00Z&end_date=2026-10-01T00:00:00Z&date_scale=week&timezone=Europe/Paris" \
  -H "Authorization: Bearer $NOTIONDESK_API_KEY" \
  -H "nd-version: 2026-10-16"

Rules for the range:

  • Dates use YYYY-MM-DDTHH:MM[:SS] with an optional offset. Without an offset, the date is read as UTC, not in timezone. Write + as %2B in the URL, or use Z.
  • The range starts on or after 2020-01-01 and ends at most two days from now.
  • At most 1,000 buckets. For example, minute covers at most 16 hours and hour at most 41 days. Use a coarser date_scale for longer ranges.
  • Weeks start on Monday.

Each report compares your range with the period of the same length just before it: previous and total_previous describe that earlier period.

Count series

visitors, article_views and searches share one shape:

{
  "total": 12,
  "total_previous": 8,
  "difference": 4,
  "percentage_difference": 50.0,
  "current": [{"date": "2026-09-14", "count": 7}, {"date": "2026-09-15", "count": 5}],
  "previous": [{"date": "2026-08-20", "count": 8}]
}
  • current and previous list only the buckets that have data, oldest first.
  • A bucket's date is when it starts, in timezone: YYYY-MM-DD for day and coarser, YYYY-MM-DDTHH:MM for hour and minute.
  • percentage_difference is 0.0 when the previous total is 0.

overview

FieldMeaning
visitorsCount series. total is distinct visitors over the range, not the sum of the points
article_viewsCount series of article page views
session_durationsTime readers spend on a page, in seconds: average_seconds, and current and previous lists of {date, seconds}
top_countriesUp to 10 countries: country (ISO code), country_name and visitors

search

FieldMeaning
searchesCount series of searches
searches_with_resultsTotals and a queries list: query, searches, clicks, articles_shown, click_through_rate and avg_click_position
searches_without_resultsTotals and a queries list: query and searches
click_through_rateThe share of searches with results that led to a click, in percent: current, previous, difference and percentage_difference
{
  "searches_without_results": {
    "total": 3,
    "total_previous": 0,
    "difference": 3,
    "percentage_difference": 0.0,
    "queries": [{"query": "refund policy", "searches": 3}]
  }
}
Note: searches_without_results.queries is your content backlog: each query is a question readers asked and your help center could not answer.

engagement

FieldMeaning
overview.current, overview.previousviews, articles_to_revise and a reaction_summary for each period
article_viewsCount series of article page views
top_articlesThe most viewed articles: title, host, pathname and views
top_referrersWhere visitors came from: referrer (null for a direct visit) and visitors
article_engagementsThe articles readers reacted to most positively: title, url, views and reaction_summary
articles_to_reviseThe articles readers reacted to most negatively, with the same fields

A reaction_summary follows your reaction style:

{
  "style": "emoji",
  "total": 6,
  "score": 58,
  "groups": [
    {"key": "positive", "count": 3, "percent": 50},
    {"key": "neutral", "count": 1, "percent": 17},
    {"key": "negative", "count": 2, "percent": 33}
  ]
}

score runs from 0 to 100: the share of positive reactions, with a neutral reaction counting half under emoji. With the thumbs style, the groups are helpful and not_helpful. See How to collect feedback with article reactions.

List limits

  • The query lists, top_articles, top_referrers, article_engagements and articles_to_revise hold up to 50 rows each and cover the current period only. A list of 50 rows may be incomplete: narrow the range to see every row.
  • The totals cover everything, not only the listed rows.
title, url, host, pathname, referrer and query come from visitors' browsers, and anyone can forge them. Escape them before you display them, and never follow or act on them unchecked.

Analytics and your plan

API access requires an Enterprise plan, which includes advanced analytics, so every report accepts any range and scale within 1,000 buckets.

Rate limit

Besides your key's 120 reads per minute, analytics reports count against a budget of 30 requests per minute per help center, shared by every key and OAuth app of your workspace. A request over it answers 429 rate_limited, and its Retry-After header says when to retry. Cache reports instead of requesting them on every page load.

Errors

StatuscodeWhen
400validation_errorA parameter is missing, malformed or unknown, quick received a parameter, or a range rule fails. The errors list names the parameter and the rule
403insufficient_scopeThe key lacks the read scope
403permission_deniedAnalytics are disabled for the help center
404not_foundreport is not one of the four reports, or the help center does not exist in your workspace
429rate_limitedThe help center's analytics budget is spent
503internal_errorThe analytics service did not answer. Retry, or narrow the range

See Handle Notiondesk API errors, rate limits, and retries.

Common questions

How do I find what readers search for but cannot find?

Call the search report and read searches_without_results.queries. Each entry is a query that returned no article, with how many times it was searched.

Why does my report answer 400 about dateScale?

The range holds more than 1,000 buckets at your date_scale. Use a coarser scale, such as day instead of hour, or a shorter range. The message says dateScale, but the parameter is date_scale.

Why is a list cut at 50 rows?

The lists hold up to 50 rows. Split a long range into shorter ones to see more queries or articles.

Can I get analytics for one article?

The reports cover the whole help center. Each article's view count and reactions are also in the article list, as views_count and reactions_percent.

What's next

Related articles

Was this page helpful?

Still need help? Ask us