Перейти к основному содержимому

Аналитика: представление

Аналитика: это чтение состояния пользователя. Воронки, удержание и когорты: это запросы к той же живой проекции, на которую действует остальная часть движка.

At a glance

Host
https://eu.api.prodantix.com
Ingest
POST /v1/events and its rules: Ingest API
Query
analytics and events queries: GraphQL reference
  • Воронки и удержание вычисляются на живом состоянии, а не ночной свёрткой хранилища
  • Когорты определяются один раз и остаются актуальными по мере поступления событий
  • Без обращения к SQL, состояние уже сформировано под вопрос

Как это работает

Events land on the EU ingestion host, are buffered through Redpanda and written to ClickHouse. Queries read from ClickHouse, so a funnel over thirty days answers in the same shape whether it spans a thousand events or a billion.

Ingestion answers 202: acceptance for processing, not proof of storage. The Ingest API page carries the full contract.

Где обратиться

SurfaceOperation
RESTPOST /v1/events · POST /v1/identify · POST /v1/group
GraphQLrunQuery · runFunnel · runRetention · runPaths · runStickiness · runLifecycle · events · dashboards, cohorts
MCPprodantix.analytics.runQuery

Пример

curl -X POST "https://eu.api.prodantix.com/v1/events" \
  -H "Authorization: Bearer $PRODANTIX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [{
      "distinct_id": "u_8f3a",
      "event_id": "5f6b2c1e-8f4b-4c6e-9d2a-7b1e3c4d5a6f",
      "event_name": "order.completed",
      "properties": { "amount": 4200 },
      "schema_version": 1,
      "timestamp": "2026-08-31T12:00:00.000Z"
    }],
    "sent_at": "2026-08-31T12:00:01.000Z"
  }'

Querying a trend

A trend takes one or more metrics, each its own event and measure, an optional formula per letter, up to three breakdowns and a comparison against an earlier window. A single metric skips the array: event, measure and, for one breakdown, breakdown stand in for metrics and breakdowns, and the two shapes never mix in the same query.

GraphQL
query RunQuery($projectId: String!, $query: MetricsQueryInput!) {
  runQuery(projectId: $projectId, query: $query) {
    series {
      key
      metric
      breakdown
      past
      points {
        time
        value
      }
    }
  }
}

# $query
{
  "metrics": [
    { "event": "checkout.started", "measure": { "kind": "total" } },
    { "event": "checkout.completed", "measure": { "kind": "total" } }
  ],
  "formulas": [{ "expression": "B / A * 100" }],
  "breakdowns": [{ "property": "plan" }, { "column": "geo_country" }],
  "compare": { "to": "previous_period" },
  "dateRange": { "from": "2026-08-01T00:00:00Z", "to": "2026-09-01T00:00:00Z" },
  "granularity": "day"
}

Querying a funnel

GraphQL
query Funnel($projectId: String!, $query: JSON!) {
  runFunnel(projectId: $projectId, query: $query) {
    step
    event
    users
    conversionFromPrevious
    droppedOff
  }
}

# $query
{
  "steps": [{ "event": "signup.started" }, { "event": "signup.completed" }, { "event": "order.completed" }],
  "conversionWindowSeconds": 2592000,
  "dateRange": { "from": "2026-08-01T00:00:00Z", "to": "2026-09-01T00:00:00Z" }
}

Paths, stickiness and lifecycle

Three more reports take the same shape: a JSON query the server validates against the report's own parser, and a list of rows back. Paths walk one to five steps after (or before) an anchor and rank the top three, five or ten events per step; stickiness counts a period's users by their active days; lifecycle sorts a period's users into new, returning, resurrecting and dormant.

GraphQL
query Paths($projectId: String!, $query: JSON!) {
  runPaths(projectId: $projectId, query: $query) {
    step
    users
    events { event users share }
    otherEvents
    otherUsers
    droppedOff
  }
}

# $query
{
  "anchorEvent": "checkout.started",
  "direction": "after",
  "steps": 3,
  "topN": 5,
  "dateRange": { "from": "2026-08-01T00:00:00Z", "to": "2026-09-01T00:00:00Z" }
}
GraphQL
query Stickiness($projectId: String!, $query: JSON!) {
  runStickiness(projectId: $projectId, query: $query) {
    period
    users
    days { daysActive users }
  }
}

# $query
{
  "event": "session.started",
  "bucket": "week",
  "dateRange": { "from": "2026-07-06T00:00:00Z", "to": "2026-09-01T00:00:00Z" }
}
GraphQL
query Lifecycle($projectId: String!, $query: JSON!) {
  runLifecycle(projectId: $projectId, query: $query) {
    period
    new
    returning
    resurrecting
    dormant
  }
}

# $query
{
  "event": "session.started",
  "bucket": "week",
  "dateRange": { "from": "2026-07-27T00:00:00Z", "to": "2026-09-07T00:00:00Z" }
}