SPOT TAPE
FRNT-200K2.180+1.42%
MID-128K0.4204−0.81%
OW-70B0.0840+3.11%
OW-8B0.0191+0.44%
VIS-1M1.6400−2.19%
RSN-XL6.9000+0.93%
EMB-S0.01100.00%
14:02:07 UTC
Documentation v1 · UPDATED 21 AUG 2026
Get an API key
On this page

SDK telemetry event schema

This page is the binding contract for telemetry in the Rust, Python, and TypeScript SDKs. All three SDKs capture the same PostHog event names with the same properties so cross-SDK funnel analysis — init → first API call → first order placed → first order settled — works without drift. Every SDK implementer lands here first; no SDK ships telemetry that disagrees with this page.

Current schema_version: 2.

SDK-side capture POSTs directly to PostHog and bypasses the Rust gateway capture() allow-list. SDK authors must construct property bags that stay within the per-event allow-list below. distinct_id, trace_id, and timestamp are required identity fields on every event and are not listed in the per-event tables.

SDK onboarding funnel events

Each of the four funnel events fires once per install (once per distinct_id). SDKs track whether a step has been sent and never re-emit it. Every event also carries the shared identity fields. All four events are a no-op when telemetry is disabled or no PostHog project key is configured.

sdk.initialized

Fires the first time the SDK client is constructed after installation.

PropertyTypeRequiredDescription
languagestring (rust | typescript | python)requiredEmitting SDK.
versionstringrequiredSDK package version.
environmentstring (prod | dev)requiredCoarse run context.
user_idstringrequiredCarries the distinct_id value (never an email or db id).

sdk.first_api_call

Fires on the first completed HTTP call after initialization, regardless of success.

PropertyTypeRequiredDescription
latency_msintegerrequiredRequest round-trip in milliseconds.
endpointstringrequiredPath only; query string stripped.
response_statusintegerrequiredHTTP status code.

sdk.first_order_placed

Fires the first time the buyer submits a non-streaming POST /v1/chat/completions. The streaming path does not emit this event.

PropertyTypeRequiredDescription
successbooleanrequiredWhether placement succeeded.
model_tierstringrequiredRequested model / tier.
order_sizeintegerrequiredRequested token quantity (max_tokens, or 0 when unset).

sdk.first_order_settled

Fires the first time that first order is observed as settled — the first successful (2xx) non-streaming POST /v1/chat/completions response. The gateway only returns the completion after the match is fulfilled and settlement has been spawned. The streaming path does not emit this event.

PropertyTypeRequiredDescription
end_to_end_latency_msintegerrequiredPlacement → settlement observed by the SDK, in ms.
settlement_statusstringrequired"success" or "failed".

API call pattern event

api_call

Fires on every SDK HTTP call after opt-in, success or failure. Powers SDK API coverage and health/usage analysis.

PropertyTypeRequiredDescriptionRationale
endpointstringrequiredCanonicalised path template, not a concrete URL.Groups calls by route without leaking ids or query data.
methodstringrequiredHTTP method (POST, GET, DELETE).Distinguishes operations on the same path.
response_time_msintegerrequiredSend-to-response wall-clock time in ms.Feeds latency/health analysis.
successbooleanrequiredtrue when status_code is 2xx.One-field funnel/health filter.
status_codeintegerrequiredHTTP status returned.Distinguishes failure modes (408 vs 502 vs 429).

What endpoint means: the canonicalised HTTP method target — a path template, never user data. Path parameters are replaced with placeholders and query strings are dropped. Canonical templates:

TemplateMethods
/v1/chat/completionsPOST
/v1/sellers/registerPOST
/v1/sellers/{id}/asksPOST
/v1/sellers/{id}/asks/{ask_id}DELETE
/v1/sellers/{id}/capacityPOST
/v1/sellers/{id}/tradesGET

Shared property schema

Present on every sdk.* funnel event. The orthogonal api_call pattern event may also include these plus its own keys.

PropertyWire typeRequiredDescription / redaction
distinct_idstringrequiredStable per-developer install-correlation id. See opt-in and identity. Contains no secret.
trace_idstringrequiredFresh UUID generated per emission so the four funnel steps can be correlated.
timestampstring (ISO-8601 / RFC 3339 UTC)requiredWhen the event occurred, e.g. 2026-08-21T12:00:00Z.

No API keys, request bodies, response bodies, or query parameters are ever included in any property.

PostHog config convention

All three SDKs read PostHog configuration from the same environment variables and expose the same client-config field, so telemetry setup is identical across languages. Names are namespaced under TOKEN_GATEWAY_ to avoid colliding with a developer's own PostHog environment variables.

SettingCanonical env varDefault
PostHog project API keyTOKEN_GATEWAY_POSTHOG_API_KEYnone — no events sent if unset
PostHog hostTOKEN_GATEWAY_POSTHOG_HOSThttps://app.posthog.com

Per-SDK client-config field for the project API key: Rust posthog_api_key (snake_case), Python posthog_api_key (snake_case kwarg), TypeScript posthogApiKey (camelCase). The project API key must be configurable, never hardcoded; a config field, when provided, takes precedence over the env var.

Opt-in default and disclosure

Sourced from the ADR docs/decisions/sdk-telemetry-opt-in.md in the repo (see also the working decision record):

  • Default: opt-in by default — telemetry is off unless explicitly enabled.
  • Enable via the telemetry_enabled config flag (TypeScript: telemetryEnabled; default false) or the TOKEN_GATEWAY_TELEMETRY env var. The env var wins when both are set.
  • Identity: distinct_id is a locally-generated persisted UUIDv4 stored at <config_dir>/token-gateway/telemetry-id, overridable via TOKEN_GATEWAY_TELEMETRY_DISTINCT_ID, with a per-process ephemeral UUID fallback when the config dir is unavailable. Never derived from a secret.

Disclosure copy template

Each SDK README pastes this verbatim (swap the enable snippet for the language):

## Telemetry

This SDK can send anonymous usage telemetry (onboarding milestones and API call
patterns) to help improve the AI Token Gateway. **Telemetry is off by default.**
No API keys, request bodies, or response bodies are ever collected.

To enable it, set the telemetry flag when constructing the client, or set the
`TOKEN_GATEWAY_TELEMETRY=1` environment variable. See the
[SDK telemetry event schema](/docs/sdk/telemetry) for the full list of events and
properties.
use token_gateway_sdk::{BuyerClient, BuyerKey, TelemetryConfig};

let client = BuyerClient::new("http://127.0.0.1:8080", BuyerKey("sk-buyer".into()))
    .with_telemetry(TelemetryConfig::from_env().with_enabled(true));
from token_gateway import BuyerAuth, BuyerTokenGateway, TelemetryConfig

gw = BuyerTokenGateway(
    "http://127.0.0.1:8080",
    buyer=BuyerAuth("sk-buyer"),
    telemetry=TelemetryConfig(enabled=True),
)
import { BuyerClient } from "@ai-token-gateway/sdk";

const buyer = new BuyerClient({
  baseUrl: "http://127.0.0.1:8080",
  apiKey: "sk-buyer",
  telemetry: { enabled: true },
});

Change control

When the schema changes:

  1. Bump the schema_version at the top of this page and the schema_version property value SDKs emit.
  2. Update all three SDKs to emit the new version and any changed properties in the same release train, so no SDK emits a mismatched schema.
  3. Update this page and re-request reviewer sign-off below.

Additive, backward-compatible property additions may keep the same schema_version at the reviewers' discretion; renames or removals must bump it.

Reviewer sign-off

This contract must be reviewed and approved before any per-SDK telemetry implementation task begins ("reviewed before implementation begins" gate).

Reviewer roleNameApproved (Y/N)Date
Rust SDK owner
Python SDK owner
TypeScript SDK owner
Platform lead