@rippit/sdk
v0.2.1
Published
Rippit SDK for logging conversation data
Keywords
Readme
@rippit/sdk
The official Node.js SDK for shipping conversation data to Rippit -- the platform for analyzing AI conversation quality, identifying trends, and improving your AI products.
Use this SDK to log every turn of a conversation (both user messages and assistant responses) so Rippit can provide analytics, quality scoring, and insights across your conversations.
Quickstart
npm install @rippit/sdk
export RIPPIT_API_TOKEN="rpt_pat_abc123.xyzSecretTokenValue"import { configure, storeConversationMoment } from "@rippit/sdk";
// Pass your token here, or set the RIPPIT_API_TOKEN env var instead (see Configuration).
configure({ apiToken: process.env.RIPPIT_API_TOKEN! });
// Log the user's message
storeConversationMoment({
message: "What's the weather like today?",
role: "user",
conversationId: "conv-123",
});
// Log the assistant's response
storeConversationMoment({
message: "The weather today is sunny with a high of 75F.",
role: "assistant",
conversationId: "conv-123",
attributes: { model: "gpt-4" },
});That's it. Each call sends the data to Rippit in the background without blocking your application.
Requirements
- Node.js 18+
- A Rippit API token (get one from the Rippit app settings page or the Rippit CLI)
Configuration
You must provide an API token through one of the two methods below. No other setup is needed -- just provide the token and start calling storeConversationMoment.
Environment variable (recommended for production/CI -- no setup code required):
export RIPPIT_API_TOKEN="rpt_pat_abc123.xyzSecretTokenValue"When the env var is set, storeConversationMoment picks it up automatically. No call to configure() is needed.
Explicit in code (handy for quick testing):
import { configure } from "@rippit/sdk";
configure({ apiToken: "rpt_pat_abc123.xyzSecretTokenValue" });configure() takes priority over the environment variable.
If neither method is used, storeConversationMoment prints a warning and returns a resolved Promise -- your application keeps running, but no data is sent.
API Reference
storeConversationMoment
Log a single conversation turn.
import { storeConversationMoment } from "@rippit/sdk";
storeConversationMoment({
message: "Hello from support",
role: "user",
conversationId: "conv-456",
attributes: {
userId: "user-789",
messageId: "msg-001",
model: "gpt-4",
},
});Parameters
storeConversationMoment({ message, role, conversationId, attributes? })
| Parameter | Required | Description |
| ---------------- | -------- | ---------------------------------------------------- |
| message | Yes | The message content |
| role | Yes | One of "user", "assistant", "system", "tool" |
| conversationId | Yes | Identifier linking all messages in a conversation |
| attributes | No | Optional object with additional fields (see below) |
Returns Promise<void> -- fire-and-forget by default, or await it if you need confirmation.
Attributes
| Attribute | Default | Description |
| -------------- | --------------- | ------------------------------------------------- |
| appDatasetId | "app_dataset" | Dataset to log to (see Datasets) |
| messageId | "" | Unique identifier for this message |
| userId | "" | Identifier for the user |
| model | "" | Model name (e.g. "gpt-4") |
| rawMessage | "" | Full model response payload, if available |
You can also pass any additional properties on the attributes object. These are stored alongside your log data so you can use them to segment, filter, or analyze your conversations however you like.
storeConversationMoments
Send many moments in a single call. The SDK automatically batches them into groups of 10,000 and sends each batch sequentially.
Note: All moments in a single call must target the same dataset. Specify it once via the top-level
appDatasetId, or uniformly in each moment'sattributes-- do not mix the two approaches.
import { storeConversationMoments } from "@rippit/sdk";
storeConversationMoments({
moments: [
{ message: "Hello!", role: "user", conversationId: "conv-123" },
{ message: "Hi! How can I help?", role: "assistant", conversationId: "conv-123", attributes: { model: "gpt-4" } },
// ... up to any number of moments
],
appDatasetId: "support_logs", // optional, defaults to "app_dataset"
});Parameters
| Parameter | Required | Description |
| -------------- | -------- | --------------------------------------------------------------------- |
| moments | Yes | Array of moment objects (same shape as storeConversationMoment input) |
| appDatasetId | No | Dataset for the entire batch (see resolution rules below) |
Returns Promise<void> -- fire-and-forget by default, or await it if you need confirmation.
Each moment in the moments array accepts the same { message, role, conversationId, attributes? } shape as storeConversationMoment.
appDatasetId
Specify the dataset in one of two ways -- not both:
- Top-level (recommended): pass
appDatasetIdon the options object. All moments in the batch go to that dataset. - Per-moment: set
appDatasetIdin each moment'sattributes. Every moment must specify the same value.
If you mix the two approaches, or if per-moment values disagree with each other, the SDK drops the conflicting moments (or rejects the entire batch) with a warning.
Validation
All moments are validated before any are sent. If any moment has an invalid message, role, conversationId, or reserved field conflict, the entire batch is rejected with a warning citing the failing index.
Concepts
Datasets
The SDK automatically creates and manages datasets in Rippit. On the first call, the SDK calls /sdk/init to ensure the dataset exists, then caches the result for the lifetime of the process. No manual setup needed.
By default, all logs go to a dataset called "app_dataset". If your application has distinct areas you want to analyze separately, pass a different appDatasetId:
storeConversationMoment({ message: "...", role: "user", conversationId: "c-1", attributes: { appDatasetId: "support_logs" } });
storeConversationMoment({ message: "...", role: "user", conversationId: "c-2", attributes: { appDatasetId: "onboarding_logs" } });The following fields are auto-generated by the SDK and do not need to be provided:
| Field | Description |
| ------------- | ---------------------------------------- |
| created_at | UTC timestamp when the log was created |
| updated_at | UTC timestamp (same as created_at) |
Async behavior
Both storeConversationMoment and storeConversationMoments return a Promise<void>. By default this is fire-and-forget -- your application is never blocked.
If you need to wait for the send to complete (e.g. in a script or test):
await storeConversationMoment({ message: "hi", role: "user", conversationId: "c-1" });
await storeConversationMoments({ moments: [...] });Logging
On the first successful send, the SDK prints a one-time confirmation to console.log:
[rippit] Rippit is logging your messagesAfter that it stays silent unless something goes wrong. Validation issues (missing fields, invalid roles, reserved field conflicts) are logged via console.warn. Network-level failures are logged via console.debug.
Error handling
The SDK is designed to never crash your application. All errors -- network failures, timeouts, server errors, missing fields, invalid roles, and reserved field conflicts -- are caught and the returned Promise resolves normally. No exceptions are ever thrown.
Framework compatibility
Zero dependencies + dual ESM/CJS means this SDK works out of the box in:
- Express / Fastify / Koa / Hono
- Next.js (API routes, server actions, middleware)
- NestJS
- Remix / SvelteKit / Nuxt server-side
- AWS Lambda / Vercel / Cloudflare Workers
- Bun and Deno
No special framework adapters needed.
Development Setup
cd sdks/node
npm installBuilding
npm run buildRunning Tests
npm testRunning the Smoke Test
export RIPPIT_API_TOKEN="rpt_pat_abc123.xyzSecretTokenValue"
npm run build
node examples/smokeTest.tsPublishing to npm
Update the version in
package.jsonandsrc/version.ts.Update
CHANGELOG.mdwith the new version and changes.Build the package:
npm run build- Publish:
npm publish --access public