# Tangent > Tangent is a multi-tenant product analytics platform by Selicatech. All event data arrives > through one authenticated endpoint, `POST /v1/events`, which accepts a JSON batch. The SDKs are > conveniences over that endpoint: they generate and persist an anonymous device id, batch, retry > with backoff, and add identity, groups, entities, revenue, experiments and a plugin pipeline. > Nothing an SDK sends is something the endpoint would not accept from curl. Key model: an event is a name (`eventType`), a time, and an identity. Identity is two fields — `deviceId` (anonymous, per browser or app install) and `userId` (the known person). Keep sending the same `deviceId` after sign-in and the anonymous history joins to the person. Events also carry `properties` (facts about the occurrence), `userProperties` (operations on the person's profile), `groups`, `revenue`, and `entities` (versioned objects with a schema reference). Guarantees: batches are validated per event, so one bad event does not lose the rest, and the response names each refusal by index. Delivery is at-least-once with server-side de-duplication on a client-generated `messageId`, so retrying is always safe. Events accepted but later unstorable are quarantined in `failed_events` for 30 days rather than dropped. Caveat for code generation: no SDK is published to a public registry yet (npm, PyPI, Maven Central, the Go proxy, the Swift Package Index, CocoaPods). Installs are checkouts, path dependencies, or the tag served by the collector. Do not generate `npm install @tangent/analytics-node` or `pip install selica-analytics` as working commands. ## Getting started - [Quickstart](/getting-started/quickstart): install, initialise, track an event, identify a user, and verify it arrived — the same five steps in browser JS, React, Node, Python, Java, Go, Swift and Kotlin. - [Ingest overview](/docs/): the data model, how to choose between a browser SDK, a server SDK and raw HTTP, and what to check when data seems missing. - [Authentication](/docs/authentication): `pk_` public versus `sk_` secret keys, where each may live, the origin allow-list, header versus body placement, rotation, revocation, and `GET /v1/key/validate`. ## SDKs Every SDK page follows the same 16 sections: what you get, install, initialise, full configuration table, tracking, identity, user properties, groups and entities, revenue, experiments, plugins, framework integration, privacy and consent, reliability, troubleshooting, API reference. - [Browser SDK](/docs/browser): JavaScript tag and packages. Durable localStorage queue, autocapture (clicks, scroll, exceptions, rage/dead/error clicks), SPA page views, web attribution, rrweb session replay, per-purpose consent filtering, Do Not Track. - [React SDK](/docs/react): a pattern over the browser client, not a package. Module-scope initialisation that survives StrictMode and Fast Refresh, react-router v6/v7 and Next.js App Router route tracking, error boundaries, testing, React Native. - [Node.js SDK](/docs/node): server SDK with Express/Connect and Koa request trackers and a draining `shutdown()`. In-memory queue, no DOM features. Note the documented module-resolution defect in `sdk/node/src/index.js`. - [Python SDK](/docs/python): non-blocking, non-raising client with a background delivery thread, WSGI and ASGI middleware (Flask, Django, FastAPI, Starlette), Celery and RQ. Honours `Retry-After`. Consent is a signal, not a gate. - [Java SDK](/docs/java): `SelicaClient` builder, daemon delivery thread, `RequestTrackingFilter`, Spring Boot, WebFlux, Jakarta EE. Consent is a signal, not a gate. - [Go SDK](/docs/go): pure standard library. `Track` never blocks and never returns an error. `net/http` middleware and gin. The only server SDK with a real consent gate. - [Swift SDK](/docs/swift): iOS and macOS. Disk-persisted queue, SwiftUI, UIKit, Combine, async/await, app extensions and widgets. Only the initialiser throws, and only on a malformed key. - [Android SDK](/docs/android): Kotlin. Pluggable `Storage` — the default is in-memory and loses events, so pass `SharedPrefsStorage` or `FileStorage`. Compose, Navigation, Coroutines, OkHttp and Hilt as patterns. No automatic screen tracking. ## HTTP API - [Ingest wire format](/docs/http-ingest): every field, every validation rule, every response code, worked curl examples, and the session-replay chunk endpoint. - [Server-side without an SDK](/docs/server-side): integrating from any language over HTTP — batching, retry, and identity that you implement yourself. ## Features Cross-SDK explanations that link into each SDK's corresponding section. - [Experiments](/features/experiments): local evaluation against fetched config, `$exposure` semantics, why there are no standalone feature flags, and why the subject differs between client and server. - [Identity](/features/identity): device id versus user id, how anonymous history joins at sign-in, when to call `reset`, and why server-side `identify()` is wrong inside a request handler. - [Revenue](/features/revenue): field meanings and why the total is computed on ingest rather than in the SDK. - [Groups and entities](/features/groups-and-entities): account-level analysis, and why an entity's schema reference matters. - [Privacy and consent](/features/privacy-and-consent): opt-out, the consent gate, per-purpose filtering, Do Not Track, and which SDKs treat consent as a signal rather than a gate. - [Reliability](/features/reliability): per-event validation, message-id de-duplication, quarantine of unstorable events, and what survives a restart in each SDK. ## Reference - [SDK support matrix](/reference/support-matrix): a per-SDK grid for autocapture, session replay, experiments, consent gating, durable queueing, `Retry-After`, framework helpers and publication status. Cells with no evidence are marked unknown rather than guessed. - [Documentation structure](/docs/STRUCTURE): the house rules every page follows and the 16-section skeleton.