Серверные SDK
Node.js, Python, Go и Java/Kotlin. Все четыре — тонкие серверные клиенты: пакетная отправка, корректное завершение, проверка флагов функций по запросу. Нет device_id/сессий — всегда передавайте явный userId.
Общее
.tgz / .whl / .jar или git-доступ) после активации подписки. Это стандартная практика для корпоративного плана. Команды ниже показывают установку из локального файла — они работают сразу после того, как вы получили архив.sk_… API-ключ. pk_… для серверов не подходит — у него другой лимит запросов и область доступа.- Нет автозахвата, записей сессий, тепловых карт, подсказок и опросов.
track()асинхронно кладёт в очередь; явныйflush()/shutdown()перед завершением процесса.- Проверка флагов функций по запросу:
getFlag(userId, flagKey). - Корректное завершение: в Node — на SIGTERM/SIGINT, в Python — через
atexit, в Go —defer client.Close(ctx), в Java —trektik.shutdown().
Node.js (@trektik/node 0.1.0)
Требует Node >= 18 (встроенный fetch, crypto.randomUUID).
# менеджер пришлёт trektik-node-0.1.0.tgz
npm install ./vendor/trektik-node-0.1.0.tgzimport { Trektik } from '@trektik/node';
const trektik = new Trektik({
apiKey: 'sk_...',
endpoint: 'https://collect.trektik.ru', // необязательно
flushInterval: 5000, // необязательно
flushSize: 100, // необязательно
maxQueueSize: 10000, // необязательно
debug: false, // необязательно
});
trektik.setProjectId(42); // для флагов функций
trektik.track('user-123', 'order_paid', { amount: 4990, currency: 'RUB' });
await trektik.identify('user-123', { email: 'u@example.com' });
trektik.trackRevenue('user-123', 4990, { currency: 'RUB' });
const value = await trektik.getFlag('user-123', 'checkout_v2');
const detail = await trektik.getFlagDetail('user-123', 'checkout_v2');
await trektik.shutdown(); // flush + stop (автоматически на SIGTERM/SIGINT)Python (trektik 0.1.0)
Python >= 3.9. Zero runtime deps (только stdlib urllib). Thread-safe.
# менеджер пришлёт trektik-0.1.0-py3-none-any.whl
pip install ./vendor/trektik-0.1.0-py3-none-any.whlfrom trektik import Trektik, TrektikConfig
trektik = Trektik(TrektikConfig(
api_key='sk_...',
endpoint='https://collect.trektik.ru', # по умолчанию
flush_interval=5.0,
flush_size=100,
max_queue_size=10_000,
debug=False,
))
trektik.set_project_id(42)
trektik.track('user-123', 'order_paid', {'amount': 4990, 'currency': 'RUB'})
trektik.identify('user-123', {'email': 'u@example.com'})
trektik.track_revenue('user-123', 4990.0, {'currency': 'RUB'})
value = trektik.get_flag('user-123', 'checkout_v2')
detail = trektik.get_flag_detail('user-123', 'checkout_v2')
trektik.shutdown() # также регистрируется через atexitAsync-варианты через run_in_executor:
await trektik.track_async('user-123', 'event', {'k': 'v'})
await trektik.identify_async('user-123', {'email': '...'})
await trektik.flush_async()
await trektik.get_flag_async('user-123', 'flag_key')Поведение при ошибках: 4xx (кроме 408, 429) — permanent, batch дропается; 5xx/network — re-queue. get_flag* при ошибке возвращает False и логирует WARNING.
Go (github.com/trektik/trektik-go 0.1.0)
# менеджер пришлёт trektik-go-0.1.0.tar.gz
mkdir -p vendor && tar -xzf trektik-go-0.1.0.tar.gz -C vendor/// go.mod клиента
require github.com/trektik/trektik-go v0.1.0
replace github.com/trektik/trektik-go => ./vendor/trektik-go-0.1.0import "github.com/trektik/trektik-go"
client, err := trektik.New(trektik.Config{
APIKey: "sk_...",
Endpoint: "https://api.trektik.ru",
BatchSize: 100,
FlushInterval: 5 * time.Second,
FlagPollInterval: 30 * time.Second, // TTL кэша фичефлагов
MaxQueueSize: 10000,
ProjectID: 42,
})
if err != nil { log.Fatal(err) }
defer client.Close(context.Background())
client.Track(ctx, "user-123", "order_paid", trektik.Properties{
"amount": 4990,
"currency": "RUB",
"premium": true, // bool → str_properties "true"/"false"
"meta": someStruct, // struct/map/slice → JSON → str_properties
})
client.Identify(ctx, "user-123", trektik.UserProperties{
"email": "u@example.com",
})
client.Revenue(ctx, "user-123", trektik.RevenueEvent{
Amount: 4990, Currency: "RUB", ProductID: "pro-monthly", Quantity: 1,
})
value, _ := client.GetFlag(ctx, "user-123", "checkout_v2")
detail, _ := client.GetFlagDetail(ctx, "user-123", "checkout_v2")Правила типизации Properties: string → str_properties; bool → str_properties; int/uint/float → num_properties; nil — дропается; остальное — JSON → str_properties. Generic properties на backend игнорируется.
Java / Kotlin (ru.trektik:trektik-java 0.1.0)
Совместим с Java 8+. Kotlin + ktor внутри.
// менеджер пришлёт trektik-java-0.1.0.jar — положите в app/libs/
// build.gradle.kts
dependencies {
implementation(files("libs/trektik-java-0.1.0.jar"))
// транзитивные зависимости (AAR/JAR их не приносит)
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
implementation("io.ktor:ktor-client-core:2.3.8")
implementation("io.ktor:ktor-client-cio:2.3.8")
implementation("io.ktor:ktor-client-content-negotiation:2.3.8")
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.8")
}import ru.trektik.sdk.Trektik
import ru.trektik.sdk.TrektikConfig
val trektik = Trektik(TrektikConfig(
apiKey = "sk_...",
endpoint = "https://api.trektik.ru",
batchSize = 100,
flushIntervalMs = 5000,
flagPollIntervalMs = 30000,
maxQueueSize = 10000,
debug = false,
))
trektik.track("user-123", "order_paid", mapOf(
"amount" to 4990,
"currency" to "RUB",
))
trektik.identify("user-123", mapOf("email" to "u@example.com"))
trektik.trackRevenue("user-123", 4990.0, "RUB")
val value = trektik.getFlag("user-123", "checkout_v2") // String? (null если not found)
val detail = trektik.getFlagDetail("user-123", "checkout_v2")
trektik.shutdown()Из Java:
Trektik trektik = new Trektik(new TrektikConfig("sk_..."));
trektik.track("user-123", "order_paid", Map.of("amount", 4990));
trektik.shutdown();Схема событий
Все серверные SDK шлют на POST /v1/batch и используют одну схему:
{
"events": [
{
"event_name": "order_paid",
"user_id": "user-123",
"timestamp": "2026-04-22T10:15:00.123Z",
"insert_id": "uuid-for-dedup",
"str_properties": { "currency": "RUB" },
"num_properties": { "amount": 4990 },
"sdk_version": "trektik-go/0.1.0",
"platform": "server"
}
]
}Подробная схема — в справочнике API и openapi.yaml.