---
name: databuddy
description: Cookieless product analytics SDK. Browser tracking, server-side events, feature flags, AI agent tracking, and REST API.
version: 3.0.0
---

# Databuddy SDK (v3)

Cookieless product analytics SDK. Covers browser tracking, server-side events, feature flags, AI agent tracking, and a REST API.

## External Documentation

- Full docs: https://www.databuddy.cc/llms-full.txt
- Docs index: https://www.databuddy.cc/llms.txt
- Framework guides: https://www.databuddy.cc/docs/Integrations

> There is **no** `@databuddy/sdk/ai/vercel` entry point. The SDK does not trace LLM calls; tracking AI crawlers and agents that read your site is `@databuddy/sdk/agents`.

## SDK Entry Points

| Import | Environment | Description |
|--------|-------------|-------------|
| `@databuddy/sdk` | Browser (Core) | Tracking utilities, types, script injection |
| `@databuddy/sdk/react` | React/Next.js | `<Databuddy />` component, flags hooks, core re-exports |
| `@databuddy/sdk/node` | Node.js/Server | `Databuddy` class (API-key auth), `ServerFlagsManager` |
| `@databuddy/sdk/vue` | Vue 3 | `<Databuddy />` component, flags plugin and composables |
| `@databuddy/sdk/agents` | Server proxy/middleware | `trackAgents` and a drop-in `proxy` that report AI crawlers and agents (GPTBot, ClaudeBot, Claude Code) |

## Quick Start

### React / Next.js

```tsx
import { Databuddy } from "@databuddy/sdk/react";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Databuddy trackWebVitals trackErrors />
      </body>
    </html>
  );
}
```

`clientId` is auto-detected from `NEXT_PUBLIC_DATABUDDY_CLIENT_ID`. Pass it explicitly if needed.

### Script Tag (any website)

```html
<script
  src="https://cdn.databuddy.cc/databuddy.js"
  data-client-id="your-client-id"
  data-track-web-vitals
  data-track-errors
  async
></script>
```

### Node.js (Server-Side)

```typescript
import { Databuddy } from "@databuddy/sdk/node";

const client = new Databuddy({
  apiKey: process.env.DATABUDDY_API_KEY!, // required, format: dbdy_xxx
});

await client.track({
  name: "api_call",
  properties: { endpoint: "/users", method: "GET" },
});

await client.flush();
```

### AI Agent Tracking (server-side, 3.0.0+)

Crawlers and AI agents don't run JavaScript, so the browser script never sees them. Add one line on the server; no API key is needed:

```typescript
// proxy.ts (Next.js 16). Next.js 15: middleware.ts with export { proxy as middleware }
export { proxy } from "@databuddy/sdk/agents";
```

It reads the website ID from `NEXT_PUBLIC_DATABUDDY_CLIENT_ID` (or `DATABUDDY_WEBSITE_ID`). Inside an existing proxy call `event.waitUntil(trackAgents(request))`; in Express, `trackAgents(req)` in a middleware. If the proxy has a `matcher`, don't exclude `.md` and `.txt` paths. Other stacks: https://www.databuddy.cc/docs/sdk/ai-agents.md

### Feature Flags (React)

```tsx
import { FlagsProvider, useFlag } from "@databuddy/sdk/react";

<FlagsProvider clientId="..." user={{ userId: "123" }}>
  <App />
</FlagsProvider>

function MyComponent() {
  const { on, loading } = useFlag("dark-mode");
  if (loading) return <Skeleton />;
  return on ? <DarkTheme /> : <LightTheme />;
}
```

## Custom Event Tracking

```typescript
import { track } from "@databuddy/sdk/react";

track("purchase", { product_id: "sku-123", amount: 99.99 });
```

### Event Design Rules

- Use `snake_case` past-tense names: `signup_completed`, `checkout_started`
- Track decisions, milestones, outcomes -- not every UI interaction
- Properties must be low-cardinality: `plan`, `source`, `method`, `status`
- Never track PII (emails, names, tokens) or high-cardinality values (URLs, IDs)
- Prefer one event with properties over many near-duplicate events

```typescript
// Good
track("feature_used", { feature: "export", format: "csv" });

// Bad
track("csv_export_clicked");
```

### Declarative Tracking (HTML data attributes)

Requires `trackAttributes: true`:

```html
<button data-track="cta_clicked" data-location="hero">Get Started</button>
```

## Browser Config (DatabuddyConfig)

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `clientId` | `string` | Auto-detect | Project Client ID |
| `disabled` | `boolean` | `false` | Disable all tracking |
| `anonymizeVisitorIds` | `boolean \| "auto"` | `true` | Anonymize visitor IDs before storage |
| `apiUrl` | `string` | `https://basket.databuddy.cc` | Event ingestion endpoint |
| `scriptUrl` | `string` | `https://cdn.databuddy.cc/databuddy.js` | Custom browser bundle URL |
| `trackWebVitals` | `boolean` | `false` | Core Web Vitals (FCP, LCP, INP, CLS, TTFB) plus FPS |
| `trackErrors` | `boolean` | `false` | JavaScript error tracking |
| `trackInteractions` | `boolean` | `true` | Rage clicks, dead clicks, and abandoned forms |
| `trackOutgoingLinks` | `boolean` | `false` | External link clicks |
| `trackHashChanges` | `boolean` | `false` | URL hash changes |
| `trackAttributes` | `boolean` | `false` | `data-*` attributes |
| `enableBatching` | `boolean` | `true` | Batch events before sending |
| `batchSize` | `number` | `10` | Events per batch (max 50) |
| `batchTimeout` | `number` | `5000` | Batch flush interval in ms |
| `enableRetries` | `boolean` | `true` | Retry failed requests |
| `maxRetries` | `number` | `3` | Max retries for failed requests |
| `initialRetryDelay` | `number` | `500` | Initial retry delay in ms |
| `ignoreBotDetection` | `boolean` | `false` | Track bots when true |
| `usePixel` | `boolean` | `false` | Use 1x1 pixel image instead of script |
| `filter` | `(event) => boolean` | -- | Return `false` to skip an event |
| `samplingRate` | `number` | `1.0` | Sampling rate (0.0-1.0) |
| `skipPatterns` | `string[]` | -- | Glob patterns to skip tracking |
| `maskPatterns` | `string[]` | -- | Glob patterns to mask paths |
| `debug` | `boolean` | `false` | Console debug logging |

## Node.js Config

```typescript
interface DatabuddyConfig {
  apiKey: string;              // Required. Format: dbdy_xxx
  apiUrl?: string;             // Default: "https://basket.databuddy.cc"
  websiteId?: string;          // Default website scope
  namespace?: string;          // Default namespace (e.g. "billing")
  source?: string;             // Default source (e.g. "backend")
  enableBatching?: boolean;    // Default: true
  batchSize?: number;          // Default: 10, max: 100
  enableDeduplication?: boolean; // Default: true (by eventId)
  middleware?: Middleware[];    // Event transformers
}
```

## Feature Flags Config

```typescript
interface FlagsConfig {
  clientId: string;
  autoFetch?: boolean;      // Default: true (browser), false (server)
  cacheTtl?: number;        // Default: 60000ms
  staleTime?: number;       // Default: cacheTtl / 2
  environment?: string;
  defaults?: Record<string, boolean | string | number>;
  user?: { userId?: string; email?: string; organizationId?: string; properties?: Record<string, unknown> };
}
```

## REST API

### Event Tracking

**POST** `https://basket.databuddy.cc/track`

Auth: `Authorization: Bearer $DATABUDDY_API_KEY` (scope: `track:events`)

```bash
curl -X POST https://basket.databuddy.cc/track \
  -H "Authorization: Bearer $DATABUDDY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "purchase", "properties": {"amount": 99.99}}'
```

Accepts single event or array (max 100). Max payload: 1MB (2MB request body hard cap); batch arrays up to 100 events.

### Feature Flags

**Base URL:** `https://api.databuddy.cc/public/v1/flags`

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/evaluate?key=X&clientId=Y` | GET | Evaluate a single flag |
| `/bulk?clientId=Y` | GET | Evaluate all flags (or `&keys=a,b`) |
| `/definitions?clientId=Y` | GET | List flag definitions |

## Key URLs

| Resource | URL |
|----------|-----|
| Dashboard | https://app.databuddy.cc |
| API | https://api.databuddy.cc |
| OpenAPI spec | https://www.databuddy.cc/openapi.json |
| API reference | https://api.databuddy.cc/ |
| MCP server | https://api.databuddy.cc/v1/mcp |
| MCP manifest | https://www.databuddy.cc/.well-known/mcp.json |
| Event ingestion | https://basket.databuddy.cc |
| CDN script | https://cdn.databuddy.cc/databuddy.js |
| Docs | https://www.databuddy.cc/docs |

## Common Pitfalls

- Do NOT put the Client ID in server-only env vars. Use `NEXT_PUBLIC_DATABUDDY_CLIENT_ID`.
- Do NOT add `<Databuddy />` in multiple layouts. One at the root is enough.
- The script auto-tracks SPA route changes. Do NOT manually call `track` for pageviews.
- `track()` is client-side only. Do NOT call it in server components or API routes.
- For server-side tracking, use `@databuddy/sdk/node` with an API key.
- Always `await client.flush()` before process exit in serverless environments.
- Never hardcode API keys. Use `process.env.DATABUDDY_API_KEY`.

## Supported Frameworks

React, Next.js, Vue, Nuxt, Svelte, SvelteKit, Angular, Shopify, WordPress, Webflow, Wix, Squarespace, Hugo, Jekyll, Framer, Bubble, Mintlify, Laravel, Google Tag Manager.

Dedicated integration guides also cover Cal.com bookings and payments (Stripe and Paddle).
