Cactal Analytics API

Read first-party traffic analytics for a website and export datasets as CSV.

Operations 3

GET /websites/{websiteId}/analytics/query Query analytics totals and breakdowns #
GET /websites/{websiteId}/analytics/timeseries Get an analytics time series #
GET /websites/{websiteId}/analytics/realtime Get a realtime traffic snapshot #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/cactal-ai:cactal-ai-analytics-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

cactal-ai-analytics-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Cactal Ai Analytics API
  version: 1.0.0
  description: 'Operations tagged Analytics across 2 of this provider''s published API definitions: openapi.json, cactal-ai-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.cactal.ai/v1
security:
- apiKey: []
tags:
- name: Analytics
  description: Read first-party traffic analytics for a website and export datasets as CSV.
paths:
  /websites/{websiteId}/analytics/query:
    get:
      operationId: websiteAnalytics.query.get
      summary: Query analytics totals and breakdowns
      description: 'Returns aggregate engagement totals — page views, distinct visitors, visits, bounces, and total time in seconds — for a date range, optionally broken down by one dimension. Use it to answer "how much traffic did the site get" and "what are the top pages/referrers/countries" style questions; use the timeseries endpoint when you need values over time instead. `startAt` and `endAt` are Unix epoch milliseconds; optional filter parameters (path, referrer, country, event, UTM fields, ...) narrow the data. Without `dimension` the response carries the totals alone. With `dimension` (e.g. `path` for top pages, `referrer` for top referrers, `country` for top countries) the response also carries `rows`: up to `limit` (default 25, max 1000) values of that dimension ranked by page views, each with its own engagement totals. Requires a plan that includes analytics (403 otherwise); all-zero totals until the website is published and has traffic.'
      tags:
      - Analytics
      parameters:
      - name: websiteId
        in: path
        required: true
        schema:
          type: string
          minLength: 1
      - name: startAt
        in: query
        required: true
        schema:
          type: integer
          minimum: 0
          maximum: 9007199254740991
      - name: endAt
        in: query
        required: true
        schema:
          type: integer
          minimum: 0
          maximum: 9007199254740991
      - name: path
        in: query
        required: false
        schema:
          type: string
      - name: referrer
        in: query
        required: false
        schema:
          type: string
      - name: title
        in: query
        required: false
        schema:
          type: string
      - name: query
        in: query
        required: false
        schema:
          type: string
      - name: browser
        in: query
        required: false
        schema:
          type: string
      - name: os
        in: query
        required: false
        schema:
          type: string
      - name: device
        in: query
        required: false
        schema:
          type: string
      - name: country
        in: query
        required: false
        schema:
          type: string
      - name: region
        in: query
        required: false
        schema:
          type: string
      - name: city
        in: query
        required: false
        schema:
          type: string
      - name: language
        in: query
        required: false
        schema:
          type: string
      - name: hostname
        in: query
        required: false
        schema:
          type: string
      - name: tag
        in: query
        required: false
        schema:
          type: string
      - name: event
        in: query
        required: false
        schema:
          type: string
      - name: distinctId
        in: query
        required: false
        schema:
          type: string
      - name: utmSource
        in: query
        required: false
        schema:
          type: string
      - name: utmMedium
        in: query
        required: false
        schema:
          type: string
      - name: utmCampaign
        in: query
        required: false
        schema:
          type: string
      - name: utmContent
        in: query
        required: false
        schema:
          type: string
      - name: utmTerm
        in: query
        required: false
        schema:
          type: string
      - name: segment
        in: query
        required: false
        schema:
          type: string
          format: uuid
          pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
      - name: cohort
        in: query
        required: false
        schema:
          type: string
          format: uuid
          pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
      - name: dimension
        in: query
        required: false
        schema:
          description: Break the range down by this dimension, e.g. `path` for top pages, `referrer` for top referrers, `country` for top countries. Omit for totals only.
          type: string
          enum:
          - path
          - entry
          - exit
          - title
          - query
          - referrer
          - channel
          - domain
          - country
          - region
          - city
          - browser
          - os
          - device
          - language
          - screen
          - event
          - hostname
          - tag
          - distinctId
      - name: limit
        in: query
        required: false
        schema:
          default: 25
          description: Maximum number of dimension rows to return (default 25, max 1000). Only used when `dimension` is set.
          type: integer
          minimum: 1
          maximum: 1000
      responses:
        '200':
          description: Engagement totals for the range, plus ranked `rows` when a `dimension` was requested.
          content:
            application/json:
              schema:
                type: object
                properties:
                  pageviews:
                    type: number
                    description: Total page views.
                  visitors:
                    type: number
                    description: Distinct visitors.
                  visits:
                    type: number
                    description: Visits (sessions).
                  bounces:
                    type: number
                    description: Single-page visits.
                  totaltime:
                    type: number
                    description: Total time spent in seconds, summed across visits.
                  comparison:
                    description: Totals for the comparison period, present when the provider computes one.
                    type: object
                    properties:
                      pageviews:
                        type: number
                        description: Total page views.
                      visitors:
                        type: number
                        description: Distinct visitors.
                      visits:
                        type: number
                        description: Visits (sessions).
                      bounces:
                        type: number
                        description: Single-page visits.
                      totaltime:
                        type: number
                        description: Total time spent in seconds, summed across visits.
                    required:
                    - pageviews
                    - visitors
                    - visits
                    - bounces
                    - totaltime
                    additionalProperties: false
                  rows:
                    description: Values of the requested `dimension` ranked by page views, each with its own engagement totals. Present only when `dimension` is set.
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                          description: Dimension value, e.g. the URL path, referrer domain, or country code.
                        pageviews:
                          type: number
                          description: Total page views.
                        visitors:
                          type: number
                          description: Distinct visitors.
                        visits:
                          type: number
                          description: Visits (sessions).
                        bounces:
                          type: number
                          description: Single-page visits.
                        totaltime:
                          type: number
                          description: Total time spent in seconds, summed across visits.
                      required:
                      - name
                      - pageviews
                      - visitors
                      - visits
                      - bounces
                      - totaltime
                      additionalProperties: false
                required:
                - pageviews
                - visitors
                - visits
                - bounces
                - totaltime
                additionalProperties: false
        '400':
          description: Validation failed. The response `message` names the first invalid field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '401':
          description: Missing, invalid, expired, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '403':
          description: The authenticated principal lacks the required capability.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '404':
          description: The resource does not exist or is outside the principal’s access scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '429':
          description: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
      x-cactal-required-capability: websiteAnalytics.view
      x-cactal-read-only: true
      x-cactal-destructive: false
      x-cactal-idempotent: true
    servers:
    - url: https://api.cactal.ai/v1
  /websites/{websiteId}/analytics/timeseries:
    get:
      operationId: websiteAnalytics.timeseries.get
      summary: Get an analytics time series
      description: 'Returns one traffic time series bucketed by `unit` (`year`, `month`, `day`, `hour`, or `minute`). `series` selects which: `pageviews` returns parallel `pageviews` and `sessions` arrays with one point per time bucket (and accepts `compare` — `prev` or `yoy` — to request comparison data for the previous period or year), while `events` returns tracked custom-event counts as one `events` point per event name per time bucket. Only the requested series'' fields are present in the response. `startAt` and `endAt` are Unix epoch milliseconds; `timezone` is an IANA name (e.g. `America/New_York`) that controls bucket boundaries; optional filter parameters narrow the data. The series is capped to the most recent `maxPoints` time buckets (default 30, max 500); a `truncated` field reports when the cap was applied. Requires a plan that includes analytics (403 otherwise); empty until the website is published and has traffic.'
      tags:
      - Analytics
      parameters:
      - name: websiteId
        in: path
        required: true
        schema:
          type: string
          minLength: 1
      - name: startAt
        in: query
        required: true
        schema:
          type: integer
          minimum: 0
          maximum: 9007199254740991
      - name: endAt
        in: query
        required: true
        schema:
          type: integer
          minimum: 0
          maximum: 9007199254740991
      - name: path
        in: query
        required: false
        schema:
          type: string
      - name: referrer
        in: query
        required: false
        schema:
          type: string
      - name: title
        in: query
        required: false
        schema:
          type: string
      - name: query
        in: query
        required: false
        schema:
          type: string
      - name: browser
        in: query
        required: false
        schema:
          type: string
      - name: os
        in: query
        required: false
        schema:
          type: string
      - name: device
        in: query
        required: false
        schema:
          type: string
      - name: country
        in: query
        required: false
        schema:
          type: string
      - name: region
        in: query
        required: false
        schema:
          type: string
      - name: city
        in: query
        required: false
        schema:
          type: string
      - name: language
        in: query
        required: false
        schema:
          type: string
      - name: hostname
        in: query
        required: false
        schema:
          type: string
      - name: tag
        in: query
        required: false
        schema:
          type: string
      - name: event
        in: query
        required: false
        schema:
          type: string
      - name: distinctId
        in: query
        required: false
        schema:
          type: string
      - name: utmSource
        in: query
        required: false
        schema:
          type: string
      - name: utmMedium
        in: query
        required: false
        schema:
          type: string
      - name: utmCampaign
        in: query
        required: false
        schema:
          type: string
      - name: utmContent
        in: query
        required: false
        schema:
          type: string
      - name: utmTerm
        in: query
        required: false
        schema:
          type: string
      - name: segment
        in: query
        required: false
        schema:
          type: string
          format: uuid
          pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
      - name: cohort
        in: query
        required: false
        schema:
          type: string
          format: uuid
          pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
      - name: unit
        in: query
        required: true
        schema:
          type: string
          enum:
          - year
          - month
          - day
          - hour
          - minute
      - name: timezone
        in: query
        required: false
        schema:
          type: string
          minLength: 1
      - name: maxPoints
        in: query
        required: false
        schema:
          default: 30
          type: integer
          minimum: 1
          maximum: 500
      - name: series
        in: query
        required: true
        schema:
          type: string
          enum:
          - pageviews
          - events
          description: 'Which time series to return: `pageviews` for page views and sessions per bucket, `events` for tracked custom-event counts per event name per bucket.'
      - name: compare
        in: query
        required: false
        schema:
          description: 'Request comparison data alongside the primary series: `prev` for the previous period, `yoy` for the same range one year earlier. Only valid when `series` is `pageviews`.'
          type: string
          enum:
          - prev
          - yoy
      responses:
        '200':
          description: 'The requested time series: `pageviews` and `sessions` per bucket, or `events` per event name per bucket.'
          content:
            application/json:
              schema:
                type: object
                properties:
                  pageviews:
                    description: Page views per time bucket. Present only when `series` is `pageviews`.
                    type: array
                    items:
                      type: object
                      properties:
                        x:
                          type: string
                          description: Start of the time bucket.
                        y:
                          type: number
                          description: Count in the bucket.
                      required:
                      - x
                      - y
                      additionalProperties: false
                  sessions:
                    description: Distinct sessions per time bucket. Present only when `series` is `pageviews`.
                    type: array
                    items:
                      type: object
                      properties:
                        x:
                          type: string
                          description: Start of the time bucket.
                        y:
                          type: number
                          description: Count in the bucket.
                      required:
                      - x
                      - y
                      additionalProperties: false
                  events:
                    description: One point per event name per time bucket. Present only when `series` is `events`.
                    type: array
                    items:
                      type: object
                      properties:
                        x:
                          type: string
                          description: Event name.
                        t:
                          type: string
                          description: Start of the time bucket.
                        y:
                          type: number
                          description: Number of events in the bucket.
                      required:
                      - x
                      - t
                      - y
                      additionalProperties: false
                  truncated:
                    description: Present only when the series exceeded `maxPoints` and was capped to the most recent time buckets.
                    type: object
                    properties:
                      shown:
                        type: integer
                        description: Time buckets returned.
                      total:
                        type: integer
                        description: Time buckets the range produced.
                      hint:
                        type: string
                        description: How to retrieve the rest.
                    required:
                    - shown
                    - total
                    - hint
                    additionalProperties: false
                additionalProperties: false
        '400':
          description: Validation failed. The response `message` names the first invalid field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '401':
          description: Missing, invalid, expired, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '403':
          description: The authenticated principal lacks the required capability.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '404':
          description: The resource does not exist or is outside the principal’s access scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '429':
          description: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
      x-cactal-required-capability: websiteAnalytics.view
      x-cactal-read-only: true
      x-cactal-destructive: false
      x-cactal-idempotent: true
    servers:
    - url: https://api.cactal.ai/v1
  /websites/{websiteId}/analytics/realtime:
    get:
      operationId: websiteAnalytics.realtime.get
      summary: Get a realtime traffic snapshot
      description: 'Returns a compact snapshot of traffic over Umami''s trailing 30-minute realtime window: total page views, distinct visitors, tracked custom events, and distinct countries, plus the snapshot timestamp. The visitor total is not directly comparable to the removed `active` endpoint''s five-minute count. Use it to see recent activity; use the query endpoint for historical ranges. Requires a plan that includes analytics (403 otherwise); all-zero totals until the website is published and has traffic.'
      tags:
      - Analytics
      parameters:
      - name: websiteId
        in: path
        required: true
        schema:
          type: string
          minLength: 1
      responses:
        '200':
          description: Traffic totals for the trailing 30-minute window.
          content:
            application/json:
              schema:
                type: object
                properties:
                  views:
                    type: number
                    description: Page views in the trailing 30-minute window.
                  visitors:
                    type: number
                    description: Distinct visitors in the trailing 30-minute window.
                  events:
                    type: number
                    description: Tracked custom events in the trailing 30-minute window.
                  countries:
                    type: number
                    description: Distinct countries in the trailing 30-minute window.
                  timestamp:
                    type: string
                    description: Snapshot time as an ISO 8601 timestamp.
                required:
                - views
                - visitors
                - events
                - countries
                - timestamp
                additionalProperties: false
        '400':
          description: Validation failed. The response `message` names the first invalid field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '401':
          description: Missing, invalid, expired, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '403':
          description: The authenticated principal lacks the required capability.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '404':
          description: The resource does not exist or is outside the principal’s access scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
        '429':
          description: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceError'
      x-cactal-required-capability: websiteAnalytics.view
      x-cactal-read-only: true
      x-cactal-destructive: false
      x-cactal-idempotent: true
    servers:
    - url: https://api.cactal.ai/v1
components:
  schemas:
    ServiceError:
      type: object
      required:
      - kind
      - message
      description: Canonical error body returned by every non-2xx response. Extra fields carry error-specific details.
      properties:
        kind:
          type: string
          enum:
          - validation
          - unauthorized
          - forbidden
          - not_found
          - conflict
          - rate_limited
          - internal
          description: Stable, machine-readable error category.
        message:
          type: string
          description: Human-readable explanation of the failure.
        suggestion:
          type: string
          description: What to do next when the failure has a known fix; may name the exact operation to call.
        validValues:
          type: array
          items:
            type: string
          description: The acceptable values for the failing field, when the set is closed.
      additionalProperties: true
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: Cactal API key. Create one in the dashboard or via `POST /apiKeys`. The plaintext key is shown once at creation.
x-refined-from:
- openapi.json
- cactal-ai-openapi.json