# Data and privacy

bugstack sends error metadata, stack traces, environment info, and optional sanitized request context. It does not send cookies, IP addresses, or user data unless you explicitly enable capture.

## What gets sent

Each SDK sends a different payload shape. Below is the exact data transmitted by each language.

### JavaScript / TypeScript

The JS SDK sends the richest payload by default, including request context:

json

```
{
  "id": "unique-error-id",
  "fingerprint": "hash-for-deduplication",
  "name": "TypeError",
  "message": "Cannot read properties of undefined (reading 'name')",
  "stack": "TypeError: Cannot read properties of undefined ...",
  "stackFrames": [
    { "file": "src/users.ts", "function": "getUserName", "line": 42, "column": 12 }
  ],
  "route": "/api/users/:id",
  "method": "GET",
  "statusCode": 500,
  "url": "/api/users/123",
  "queryParams": { "include": "profile" },
  "requestBody": { "...redacted fields removed..." },
  "requestHeaders": { "...sensitive headers removed..." },
  "routeParams": { "id": "123" },
  "environment": "production",
  "projectId": "proj_xxx",
  "metadata": {}
}
```

### Python

json

```
{
  "apiKey": "...",
  "error": {
    "message": "AttributeError: 'NoneType' object has no attribute 'name'",
    "stackTrace": "Traceback (most recent call last): ...",
    "file": "app/models/user.py",
    "function": "get_display_name",
    "fingerprint": "hash-for-deduplication"
  },
  "environment": {
    "language": "python",
    "languageVersion": "3.12.0",
    "framework": "django",
    "frameworkVersion": "5.0.1",
    "os": "linux",
    "sdkVersion": "0.1.0"
  },
  "timestamp": "2026-04-18T12:00:00Z"
}
```

### Ruby

json

```
{
  "apiKey": "...",
  "error": {
    "message": "NoMethodError: undefined method 'name' for nil:NilClass",
    "stackTrace": "app/models/user.rb:12:in 'get_display_name' ...",
    "file": "app/models/user.rb",
    "function": "get_display_name",
    "fingerprint": "hash-for-deduplication"
  },
  "environment": {
    "language": "ruby",
    "languageVersion": "3.3.0",
    "framework": "rails",
    "frameworkVersion": "7.1.2",
    "os": "linux",
    "sdkVersion": "0.1.0"
  },
  "timestamp": "2026-04-18T12:00:00Z"
}
```

### Go

json

```
{
  "apiKey": "...",
  "error": {
    "message": "runtime error: invalid memory address or nil pointer dereference",
    "stackTrace": "goroutine 1 [running]: main.getUserName(...) ...",
    "file": "handlers/user.go",
    "function": "getUserName",
    "fingerprint": "hash-for-deduplication"
  },
  "environment": {
    "language": "go",
    "languageVersion": "1.22.0",
    "framework": "gin",
    "frameworkVersion": "1.9.1",
    "os": "linux",
    "sdkVersion": "0.1.0"
  },
  "timestamp": "2026-04-18T12:00:00Z"
}
```

## What is never sent

-   **Cookies** — never transmitted by any of the four SDKs
-   **IP addresses** — never transmitted by any of the four SDKs
-   **User data** — never transmitted by any of the four SDKs
-   **Request bodies** — off by default in Python, Ruby, and Go. The JavaScript SDK has `captureRequestBody: true` by default — set it to `false` to disable. Note this difference if your JS app handles sensitive form data.

## Automatic redaction

The JavaScript SDK automatically redacts the following fields from request bodies and headers before transmission:

**Redacted body fields:** `password`, `secret`, `token`, `apikey`, `api_key`, `apiKey`, `authorization`, `auth`, `credential`, `private`, `credit_card`, `creditcard`, `card_number`, `cvv`, `ssn`, `social_security`

**Always-redacted headers:** `authorization`, `cookie`, `set-cookie`, `x-api-key`, `x-auth-token`, `proxy-authorization`

The Python, Ruby, and Go SDKs accept custom redaction via the `redact_fields` configuration option, letting you specify additional fields to strip before transmission.

## Inspect or drop events with before\_send

Every SDK supports a `before_send` hook that lets you inspect, modify, or drop error events before they leave your server.

### JavaScript / TypeScript

javascript

```
const { initBugStack } = require('bugstack-sdk');

initBugStack({
  apiKey: process.env.BUGSTACK_API_KEY,
  beforeSend(event) {
    // Drop health-check errors
    if (event.route === '/health') return null;
    return event;
  }
});
```

### Python

python

```
import bugstack

def before_send(event):
    # Drop health-check errors
    if "health" in event.get("error", {}).get("message", ""):
        return None
    return event

bugstack.init(
    api_key="your-api-key",
    before_send=before_send
)
```

### Ruby

ruby

```
require "bugstack"

Bugstack.configure do |config|
  config.api_key = "your-api-key"
  config.before_send = Proc.new do |event|
    # Drop health-check errors
    next nil if event["error"]["message"].include?("health")
    event
  end
end
```

### Go

go

```
import "github.com/bugstackai/bugstack-go"

bugstack.Init(bugstack.Config{
    APIKey: "your-api-key",
    BeforeSend: func(event map[string]interface{}) map[string]interface{} {
        // Drop health-check errors
        if strings.Contains(event["error"].(map[string]interface{})["message"].(string), "health") {
            return nil
        }
        return event
    },
})
```

## Preview without sending: dry run mode

Dry run mode lets you see exactly what the SDK would send without actually transmitting data. The payload is logged locally so you can inspect it. The JavaScript SDK does not currently support dry run mode.

### Python

python

```
bugstack.init(
    api_key="your-api-key",
    dry_run=True
)
```

### Ruby

ruby

```
Bugstack.configure do |config|
  config.api_key = "your-api-key"
  config.dry_run = true
end
```

### Go

go

```
bugstack.Init(bugstack.Config{
    APIKey: "your-api-key",
    DryRun: true,
})
```

## Encryption at rest

All sensitive credentials stored by bugstack — your API keys and GitHub tokens — are encrypted at rest using AES-256-GCM. Each user account has isolated encryption keys. bugstack never stores your source code; files are retrieved transiently per fix and discarded after the pull request is created.

## Next steps

-   [How bugstack works](/docs/how-it-works) — the full capture-to-PR pipeline
-   [JavaScript SDK installation](/docs/installation/javascript)
-   [Python SDK installation](/docs/installation/python)
-   [Ruby SDK installation](/docs/installation/ruby)
-   [Go SDK installation](/docs/installation/go)
-   [Security](/security) — encryption, isolation, and compliance

## Ship with confidence

bugstack captures only what it needs to fix your errors. No cookies, no IP addresses, no user data by default.

[Start Free](https://dashboard.bugstack.ai/login)

14-day free trial · No credit card required