BETA
Skip to content

Stats and Realtime ​

Query aggregated analytics data, real-time visitor counts, and custom event statistics.

Base URL: https://app.krafter.dev/api/v1/analytics


Get Stats ​

Retrieve aggregated statistics for a site over a given period, with optional breakdowns by dimension.

GET /analytics/sites/:key/stats

Required scope: analytics:read

Query Parameters ​

ParameterTypeDefaultDescription
periodstring7dTime period. One of: today, 7d, 30d, 12mo, custom. Each named period is inclusive of today and spans exactly the days it names, so 7d is today and the six days before it. An unrecognised value falls back to 7d.
fromstring--Start date (ISO 8601, e.g., 2025-01-01). Required when period=custom.
tostring--End date (ISO 8601, e.g., 2025-01-31). Required when period=custom.
dimensionsstring--Comma-separated list of dimensions to break down by.

Dimensions ​

DimensionDescription
pathPage URL path
referrerTraffic source / referring URL
countryVisitor country (ISO 3166-1 alpha-2)
deviceDevice type (Desktop, Mobile, Tablet)
browserBrowser name (Chrome, Firefox, Safari, etc.)
osOperating system (Windows, macOS, Linux, iOS, Android)
utm_sourceUTM source parameter
utm_mediumUTM medium parameter
utm_campaignUTM campaign parameter

Example Request ​

bash
curl "https://app.krafter.dev/api/v1/analytics/sites/sk_abc123def456/stats?period=7d&dimensions=path,country" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Example Response ​

json
{
  "data": {
    "period": {
      "from": "2025-02-11",
      "to": "2025-02-18"
    },
    "totals": {
      "pageviews": 1000,
      "visitors": 500,
      "visits": 600
    },
    "timeseries": [
      {
        "date": "2025-02-11",
        "pageviews": 100,
        "visitors": 50,
        "visits": 60
      },
      {
        "date": "2025-02-12",
        "pageviews": 120,
        "visitors": 65,
        "visits": 72
      },
      {
        "date": "2025-02-13",
        "pageviews": 95,
        "visitors": 48,
        "visits": 55
      },
      {
        "date": "2025-02-14",
        "pageviews": 180,
        "visitors": 90,
        "visits": 105
      },
      {
        "date": "2025-02-15",
        "pageviews": 150,
        "visitors": 75,
        "visits": 88
      },
      {
        "date": "2025-02-16",
        "pageviews": 140,
        "visitors": 72,
        "visits": 85
      },
      {
        "date": "2025-02-17",
        "pageviews": 110,
        "visitors": 55,
        "visits": 68
      },
      {
        "date": "2025-02-18",
        "pageviews": 105,
        "visitors": 45,
        "visits": 67
      }
    ],
    "breakdown": {
      "path": [
        { "value": "/", "count": 500, "visitors": 410, "percent": 50.0 },
        { "value": "/pricing", "count": 200, "visitors": 180, "percent": 20.0 },
        { "value": "/blog", "count": 150, "visitors": 130, "percent": 15.0 },
        { "value": "/docs", "count": 100, "visitors": 85, "percent": 10.0 },
        { "value": "/about", "count": 50, "visitors": 48, "percent": 5.0 }
      ],
      "country": [
        { "value": "US", "count": 300, "visitors": 240, "percent": 30.0 },
        { "value": "DE", "count": 150, "visitors": 120, "percent": 15.0 },
        { "value": "GB", "count": 120, "visitors": 95, "percent": 12.0 },
        { "value": "FR", "count": 80, "visitors": 70, "percent": 8.0 },
        { "value": "RS", "count": 50, "visitors": 44, "percent": 5.0 }
      ]
    }
  }
}

Custom Date Range ​

Use period=custom with from and to parameters:

bash
curl "https://app.krafter.dev/api/v1/analytics/sites/sk_abc123def456/stats?period=custom&from=2025-01-01&to=2025-01-31&dimensions=referrer" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Response Fields ​

FieldDescription
period.fromStart date of the queried period.
period.toEnd date of the queried period.
totals.pageviewsTotal page views in the period.
totals.visitorsTotal unique visitors in the period.
totals.visitsTotal sessions/visits in the period.
timeseriesArray of daily data points with date, pageviews, visitors, and visits.
breakdownObject with keys for each requested dimension. Each contains an array of {value, count, visitors, percent}, ordered by count descending and cut at 20 rows. count is page views, visitors unique visitors.
breakdown.*.percentThe row's count as a share of totals.pageviews, with one decimal. It is null when the period total is unknown.

TIP

If you do not pass any dimensions, the response will include totals and timeseries but no breakdown object.

INFO

percent is a share of the whole period, not of the rows returned. The rows of a dimension therefore add up to at most 100 and usually less: the list is cut at 20, and the utm_* dimensions leave out page views that carried no UTM parameter at all. The same share is what the dashboard and the MCP tools analytics_get_stats, analytics_top_pages and analytics_top_referrers report.


Get Realtime ​

Get the number of visitors currently on your site.

GET /analytics/sites/:key/realtime

Required scope: analytics:read

Example Request ​

bash
curl https://app.krafter.dev/api/v1/analytics/sites/sk_abc123def456/realtime \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Example Response ​

json
{
  "data": {
    "current_visitors": 5
  }
}

INFO

The realtime endpoint returns visitors active in the last 5 minutes. This is updated continuously and reflects live traffic to your site.


List Custom Events ​

Retrieve a list of custom events tracked for a site, with total and unique counts.

GET /analytics/sites/:key/events

Required scope: analytics:read

Query Parameters ​

ParameterTypeDefaultDescription
periodstring7dTime period. One of: today, 7d, 30d, 12mo, custom. Each named period is inclusive of today and spans exactly the days it names, so 7d is today and the six days before it. An unrecognised value falls back to 7d.
fromstring--Start date. Required when period=custom.
tostring--End date. Required when period=custom.

Example Request ​

bash
curl "https://app.krafter.dev/api/v1/analytics/sites/sk_abc123def456/events?period=30d" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Example Response ​

json
{
  "data": [
    {
      "event_name": "signup",
      "total": 245,
      "unique_count": 230,
      "revenue": null
    },
    {
      "event_name": "purchase",
      "total": 89,
      "unique_count": 82,
      "revenue": 4355.00
    },
    {
      "event_name": "download",
      "total": 156,
      "unique_count": 140,
      "revenue": null
    }
  ]
}
FieldDescription
event_nameName of the custom event.
totalTotal number of times the event was triggered.
unique_countNumber of unique visitors who triggered the event.
revenueTotal revenue associated with the event, or null if no revenue tracked.

When the store cannot answer ​

Every endpoint on this page reads from ClickHouse. A query that did not run is reported, never smoothed into zeros: a site with traffic must not be described as a site without any.

StatusBodyMeaning
200{"data": {...}} with zeros and empty listsThe query ran and the period genuinely has nothing in it.
503{"error": "Analytics storage temporarily unavailable"}ClickHouse did not answer. Safe to retry after a brief backoff. Nothing partial is returned — if one requested dimensions breakdown fails, the whole response is a 503 rather than an empty list beside the ones that did read.

Scopes ​

ScopeEndpoints
analytics:readAll endpoints on this page

Built by Krafter Studio