> ## Documentation Index
> Fetch the complete documentation index at: https://raindrop.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Browser (JavaScript)

> Minimal browser-safe SDK for tracking AI events via /v1/events from web apps.

### **Installation**

Install the browser SDK package:

<CodeGroup>
  ```bash npm theme={null}
  npm install @raindrop-ai/browser-sdk
  ```

  ```bash yarn theme={null}
  yarn add @raindrop-ai/browser-sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @raindrop-ai/browser-sdk
  ```

  ```bash bun theme={null}
  bun add @raindrop-ai/browser-sdk
  ```
</CodeGroup>

### **Quickstart**

```ts theme={null}
import { Raindrop } from '@raindrop-ai/browser-sdk';

const rd = new Raindrop({ apiKey: 'DAWN_xxx' });

// 1) Single-shot AI event (camelCase fields)
const { eventIds } = await rd.trackAi({
  event: 'ai_completion',
  userId: 'user_123',
  model: 'gpt-4o',
  input: 'hello',
  output: 'hi there',
  convoId: 'convo_123',
  properties: { page: '/home' },
});
console.log('trackAi eventIds:', eventIds);

// 2) Partial AI event flow (returned object includes finish())
const eid = crypto.randomUUID();
const partial = await rd.trackAiPartial({
  eventId: eid,
  event: 'chat',
  userId: 'user_123',
  model: 'gpt-4o',
  convoId: 'convo_123',
  output: 'chunk 1',
});

await rd.trackAiPartial({ eventId: eid, output: 'chunk 2' });
const done = await partial.finish({ output: 'final answer' });
console.log('partial finished:', done);

```

### **Application Git provenance**

Browser builds cannot read runtime environment variables, a filesystem, or Git. Inject the
application build identity explicitly; do not expect runtime discovery:

```ts theme={null}
const rd = new Raindrop({
  apiKey: 'YOUR_RAINDROP_WRITE_KEY',
  appGit: {
    commitSha: '0123456789abcdef0123456789abcdef01234567',
    commitDirty: false,
    branch: 'main',
  },
});
```

The emitted properties are `raindrop.app.commit_sha`, `raindrop.app.commit_dirty`, and
`raindrop.app.branch`. Existing canonical event properties win, including null, empty, or invalid
values, and other properties are preserved. `appGit: false` disables all client enrichment;
`autoDetect: false` only disables automatic sources and retains explicit values, although the browser
has no automatic source. `detectBranch` and `sourceDirectory` likewise do not enable browser runtime
discovery. This metadata is for reporting and filtering only and does not select a simulation
checkout or rewrite release/SDK fields.

<Info>
  This option requires the coordinated browser SDK and base-package release that contains application
  Git reporting. No version is documented until it is published.
</Info>

### **Projects**

Pass `projectId` to scope events to a specific [project](/docs/platform/projects). This sets the `X-Raindrop-Project-Id` header on each request.

```ts theme={null}
const rd = new Raindrop({ apiKey: 'DAWN_xxx', projectId: 'support-prod' });
```

Omitting `projectId` (or passing `'default'`) sends to the default **Production** project, which is the existing behavior. See [Projects](/docs/platform/projects) for details.

### **Identify users**

```ts theme={null}
await rd.identify({
  userId: 'user_123',
  traits: {
    name: 'Jane',
    email: 'jane@example.com',
    plan: 'pro',
  },
});

// batch
await rd.identify([
  { userId: 'u1', traits: { plan: 'free' } },
  { userId: 'u2', traits: { plan: 'pro' } },
]);
```

### **Signals**

```ts theme={null}
// thumbs down with a comment
await rd.trackSignal({
  eventId: eid,
  name: 'thumbs_down',
  type: 'feedback',
  comment: 'Answer was off-topic',
});

// edit signal capturing the corrected content
await rd.trackSignal({
  eventId: eid,
  name: 'edit',
  type: 'edit',
  after: 'the corrected final text',
});
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.