FOR ENGINEERS / LESS TRACKING ARCHAEOLOGY

SHIP EVENTS.
KEEP YOUR
SANITY.

You built the product. You shouldn’t need a second career in tracking forensics.

Collect, validate, and deliver product events into your own storage. Explicit contracts. Visible failures. A pipeline you can reason about.

TYPESCRIPT SDK → GO COLLECTOR → NATS JETSTREAM

ON-CALL SEAGULL / NO SILENT DROPS A seagull in a red beanie riding a red surfboard over event streamsSCHEMA v1tea: "oolong"200 OK ≠ job done.
SMALL PAYLOADS✳EXPLICIT CONTRACTS✳VISIBLE FAILURES✳YOUR STORAGE

01 / FOLLOW THE WIRE

From browser.
Through NATS.
Into your stack.

Your snippet or tag manager sends the event. The Go collector wraps it, publishes it, and waits for JetStream’s acknowledgement.

Tracking snippet, GTM or custom tag manager through an optional server-side handler to Surftrack Go collector, then NATS JetStream. Destination consumers connect to AWS S3, Google Cloud Storage, BigQuery or Snowflake. The schema identifier and event body travel through the stream; validation and destination mapping are the next layer.
Solid path: implemented SDK → collector → JetStream. Dashed routes: integration points and destination consumers to build with pilots. The server-side handler is optional; direct SDK ingestion works too.
TypeScriptGoNATSGoogle Cloud StorageBigQuerySnowflakeApache IcebergAWS S3
POST /api/v1/trackevent.{org}.{event_type}JetStream publish ACK → HTTP 204File-backed stream

02 / PAYLOADS WITH A PAPER TRAIL

Events, not
mystery blobs.

Kafka-style event thinking, powered by NATS JetStream: subjects, message identities, durable storage, and an envelope that keeps the original body.

JetStream message / selected envelope fields
{
  "message_id": "evt_example_001",
  "event_type": "purchase_completed",
  "organization_id": "demo_org",
  "schema": "1.0",
  "collected_at": "2026-09-21T12:00:00Z",
  "body": {
    "order_id": "demo_42",
    "amount": 49.00,
    "currency": "EUR"
  }
}

Keep the identity.
Carry the schema.

The collector carries message_id, event_type, schema, and the JSON body into the stream. Subjects separate organizations and event types.

JetStream uses the message ID for deduplication. Current stream configuration: seven-day retention and a 24-hour duplicate window.

Schema currently travels as metadata. Contract validation, destination mapping, and Iceberg schema evolution belong to the next consumer layer. An event schema and an Iceberg table schema are distinct.

03 / REAL COMPONENTS. OPEN INTEGRATION POINTS.

Small SDK.
Durable backbone.

TSWEB SDK / TYPESCRIPT

Ship the event.
Retry the rough bits.

The SDK persists events in localStorage, coordinates delivery with Web Locks, and retries temporary failures with backoff. Queue limits and retry behaviour are configurable.

Use track(), flush(), and retryFailed(). Currently distributed as a locally built package.

GOSERVER-SIDE COLLECTION

A handler you can trace.

The Go collector checks the write key, message ID, JSON content type, and a 1 MiB body limit. It adds collection metadata and publishes to NATS.

Connect directly, or build a GTM / custom tag-manager route through your server-side handler. Mobile clients can target the HTTP interface; dedicated mobile SDKs are a future extension.

NATSJETSTREAM

Buffer the burst.
Keep the receipt.

File-backed streams, publish acknowledgements, message-ID deduplication, and reconnect handling are implemented. Collection is decoupled from downstream consumers.

High throughput is the goal; no production benchmark is published yet. Measure event rate alongside payload size, p95 latency, queue lag, and delivery errors.

↳DESTINATION CONSUMERS

Your cloud. Your tables.

Target integrations: AWS S3, Google Cloud Storage, BigQuery, and Snowflake. Destination writers are the next layer, connected through NATS consumers.

For a lakehouse route, map event fields into Parquet and Apache Iceberg tables. Preserve schema lineage from the website payload to the destination’s table schema.

04 / LESS DATA. FEWER SURPRISES.

You own the tracking.
We help with sane defaults.

Choose the events and properties you actually need. Make collection, destination access, and retention deliberate. Privacy belongs in the design, alongside reliability.

No promise that a tool alone makes your setup GDPR-compliant. Your configuration and use matter.

BRING ONE FLOW THAT KEEPS BREAKING.

Let’s make it
boringly reliable.

We’re looking for engineers to shape the first pilots. Tell us your event volume, sources, destination, and favourite tracking horror story.

Talk pipeline with us ↗contact@surftrack.io