Phân tích: một góc nhìn
Phân tích là đọc trạng thái người dùng. Phễu, giữ chân và nhóm là các truy vấn trên cùng một phép chiếu trực tiếp mà phần còn lại của engine hành động.
At a glance
- Host
https://eu.api.prodantix.com- Ingest
POST /v1/eventsand its rules: Ingest API- Query
analyticsandeventsqueries: GraphQL reference
- Phễu và giữ chân được tính trên trạng thái trực tiếp, không phải bản tổng hợp kho dữ liệu hằng đêm
- Nhóm được định nghĩa một lần và luôn được cập nhật khi sự kiện đến
- Không vòng lặp SQL, trạng thái đã được định hình sẵn cho câu hỏi
Cách hoạt động
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.
202: acceptance for processing, not proof of storage. The Ingest API page carries the full contract.Truy cập ở đâu
| Surface | Operation |
|---|---|
| REST | POST /v1/events · POST /v1/identify · POST /v1/group |
| GraphQL | runQuery · runFunnel · runRetention · runPaths · runStickiness · runLifecycle · events · dashboards, cohorts |
| MCP | prodantix.analytics.runQuery |
Ví dụ
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"
}'prodantix.capture('order.completed', {
properties: { amount: 4200 },
});await prodantix.capture(
'order.completed',
properties: {'amount': 4200},
);prodantix.capture(
"order.completed",
distinct_id="u_8f3a",
properties={"amount": 4200},
)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.
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
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.
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" }
}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" }
}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" }
}