What tinymon collects (and how to control it)

We try to be the boring, predictable choice on data. Defaults are privacy-preserving, controls are obvious, and the server applies the same scrubs your SDK does — so a misconfigured SDK never bypasses the protection.

What's collected

Every event the SDK sends contains:

FieldWhat it is
exception.type / valueThe error class name and message text.
stacktrace.framesFilename, function, line, column for each frame.
breadcrumbsUp to 30 recent breadcrumb messages.
tagsKey/value strings you attach via setTag.
user.idWhatever identifier you pass to setUser({id}). No email/name unless you put it there.
request.urlPage URL the error happened on (browser SDK only). Query string is stripped by default.
release, environmentFree-form strings you pass to init().

We do not collect: request body, headers, cookies, OS version, device fingerprint, or any analytics-style data. The client IP is not collected unless you explicitly opt in (see below).

Default scrubs (on for every SDK, every version)

Before an event is sent — and again at the server before it's stored — tinymon redacts:

Stack frame file paths and code are not scrubbed — doing so would break traces.

You can extend the pattern set with scrub_patterns, or turn off URL-query stripping with scrub_url_query: false. The server-side scrubs always run regardless of SDK config.

send_default_pii (default false)

Out of the box, tinymon does not attach the client IP to any event. To allow IP capture, pass send_default_pii: true in your init() call. This flag travels with the event; the server only stores IP when it sees the flag.

beforeSend — the escape hatch

For anything the defaults don't cover, supply a beforeSend callback. It receives the fully-built (and already-scrubbed) event, can mutate any field, and can return null to drop the event entirely.

import { init } from 'tinymonjs';

init({
  dsn: process.env.TINYMON_DSN,
  // Drop events from health-check requests entirely.
  beforeSend(event) {
    if (event.request?.url?.endsWith('/health')) return null;
    // Redact a custom internal field name.
    if (event.tags?.customer_email) event.tags.customer_email = '[redacted]';
    return event;
  },
});

Server-side defense-in-depth

Every event that reaches our ingest endpoint is scrubbed again on the server using the same default patterns. This means even if a customer is on an older SDK version, has misconfigured beforeSend, or sends data with curl, emails / card-like numbers / bearer tokens never end up stored.

What's stored is what you see in the dashboard. Issue detail shows the final scrubbed payload — there is no separate "raw" PII archive.