Installation

Install with your package manager of choice:

npm install raindrop-ai
import Raindrop from "raindrop-ai";

// Replace with the key from your Raindrop dashboard
const raindrop = new Raindrop({ writeKey: RAINDROP_API_KEY });

Quick-start: the Interaction API

The new interaction workflow is a three-step pattern:

  1. begin() - creates an interaction object and logs the initial user input.
  2. Update - optionally call setProperty, setProperties, or addAttachments.
  3. finish() - records the AI’s final output and closes the interaction.

Example: chat completion with the ai SDK

import { openai } from '@ai-sdk/openai';
import { randomUUID } from "crypto";

const message = "What is love?"
const eventId = randomUUID() // generate your own ID so you can correlate logs

// 1️. Start the interaction
const interaction = raindrop.begin({
  eventId,
  event: "chat_message",
  userId : "user_123",
  input: message,
  model: "gpt-4o",
  convoId: "convo_123",
});

const { text } = await generateText({
  model: openai("gpt-4o"),
  prompt: message
})

// 3️ Finish and ship the event
interaction.finish({
  output: text,
});

Updating an interaction

You can update an interaction at any time using setProperty, setProperties, or addAttachments.

interaction.setProperty("stage", "embedding");
interaction.addAttachments([
  {
    type: "text",
    name: "Additional Info",
    value: "A very long document",
    role: "input",
  },
  { type: "image", value: "https://example.com/image.png", role: "output" },
  {
    type: "iframe",
    name: "Generated UI",
    value: "https://newui.generated.com",
    role: "output",
  },
]);

Resuming an interaction

If you don’t have access to the interaction object that was returned from begin(), you can resume an interaction by calling resumeInteraction().

const interaction = raindrop.resumeInteraction(eventId);

Interactions are subject to the global 1 MB event limit; oversized payloads will be truncated.


Single-shot tracking (legacy trackAi)

If your interaction is atomic (e.g. “user asked, model answered” in one function) you can still call trackAi() directly:

raindrop.trackAi({
  event: "user_message",
  userId: "user123",
  model: "gpt-4o-mini",
  input: "Who won the 2023 AFL Grand Final?",
  output: "Collingwood by four points!",
});

Heads‑up: We recommend migrating to begin()finish() for all new code so you gain partial‑event buffering, tracing helpers, and upcoming features such as automatic token counts.


Tracking Signals (feedback)

Signals capture explicit or implicit quality ratings on an earlier AI event. Use trackSignal() with the same eventId you used in begin() or trackAi().

ParameterTypeDescription
eventIdstringThe ID of the AI event you’re evaluating
name"thumbs_up" | "thumbs_down" | stringName of the signal (e.g. "thumbs_up")
type"default" | "feedback" | "edit"Optional, defaults to "default"
commentstringFor feedback signals
afterstringFor edit signals – the user’s final content
…othersSee API reference
// User clicks a thumbs‑down button
await raindrop.trackSignal({
  eventId: "my_event_id",
  name: "thumbs_down",
  comment: "Answer was offtopic",
});

Attachments

Attachments allow you to include context from the user or that hte model outputted. These could be documents, generated images, code, or even an entire web page. They work the same way in begin() interactions and in single‑shot trackAi calls.

Each attachment is an object with the following properties:

  • type (string): The type of attachment. Can be “code”, “text”, “image”, or “iframe”.

  • name (optional string): A name for the attachment.

  • value (string): The content or URL of the attachment.

  • role (string): Either “input” or “output”, indicating whether the attachment is part of the user input or AI output.

  • language (optional string): For code attachments, specifies the programming language.

interaction.addAttachments([
  {
    type: "code",
    role: "input",
    language: "typescript",
    name: "example.ts",
    value: "console.log('hello');",
  },
  {
    type: "text",
    name: "Additional Info",
    value: "Some extra text",
    role: "input",
  },
  { type: "image", value: "https://example.com/image.png", role: "output" },
  { type: "iframe", value: "https://example.com/embed", role: "output" },
]);

Supported types: code, text, image, iframe.


Identifying users

raindrop.setUserDetails({
  userId: "user123",
  traits: {
    name: "Jane",
    email: "jane@example.com",
    plan: "pro",
    os: "macOS",
  },
});

PII redaction

Read more on how Raindrop handles privacy and PII redaction here. You can enable client-side PII redaction when intializing the Analytics class like so:

new Raindrop({
  writeKey: RAINDROP_API_KEY,
  redactPii: true,
});

Error Handling

If an error occurs while sending events to Raindrop, an exception will be raised. Make sure to handle exceptions appropriately in your application.


Configuration & helpers

  • Debug logsdebugLogs: true prints every queued event.
  • Closing – call await raindrop.close() before your process exits to flush buffers.
new Raindrop({
  writeKey: RAINDROP_API_KEY,
  debugLogs: process.env.NODE_ENV !== "production",
});

That’s it! You’re ready to explore your events in the Raindrop dashboard. Ping us on Slack or email us if you get stuck!