SDK & API
SDK Installation
The @recurcite/sdk is a server-first Node.js package for sending evidence events to RecurCite. It handles authentication, payload validation, HMAC signing, and batch operations.
Installation
npm install @recurcite/sdkOr with your preferred package manager:
yarn add @recurcite/sdk
# or
pnpm add @recurcite/sdkInitialization
Import and initialize the SDK with your API key. The client is stateless — you can create it once and reuse across your application.
import { init } from "@recurcite/sdk";
export const recurcite = init({
apiKey: process.env.RECURCITE_API_KEY!,
// Optional: HMAC signing for tamper-proof events
signingSecret: process.env.RECURCITE_SIGNING_SECRET,
});Server-side only
Never expose your API key or signing secret in client-side code. The SDK is designed for Node.js server environments only.
Sending events
track()
Send a single evidence event. Every event must include a type, payload, and ideally stripe_refs to link it to a Stripe customer.
await recurcite.track({
type: "terms.accepted",
payload: {
version: "2.0",
accepted_at: new Date().toISOString(),
},
stripe_refs: {
stripe_customer_id: "cus_abc123",
},
});batchTrack()
Send multiple events in a single request. Useful for bulk imports or high-throughput scenarios.
await recurcite.batchTrack([
{
type: "product.used",
payload: {
feature_key: "api_calls",
count: 150,
occurred_at: new Date().toISOString(),
},
stripe_refs: { stripe_customer_id: "cus_abc123" },
},
{
type: "user.login",
payload: {
occurred_at: new Date().toISOString(),
ip: "203.0.113.42",
},
stripe_refs: { stripe_customer_id: "cus_abc123" },
},
]);Idempotency
By default, the SDK generates a unique event_id for each event. To ensure retries don't create duplicates, provide your own deterministic ID:
import { generateEventId } from "@recurcite/sdk";
await recurcite.track({
event_id: generateEventId("terms.accepted", userId),
type: "terms.accepted",
payload: {
version: "2.0",
accepted_at: new Date().toISOString(),
},
});Tip
Use generateEventId(type, uniqueKey) to create deterministic IDs based on the event type and a unique identifier like the user ID or transaction ID.
HMAC signing
When you provide a signingSecret during initialization, the SDK automatically signs every request with an X-Recurcite-Signature header. The server verifies the signature and stores the verification status. Events with verified signatures carry more weight in evidence Packets.
const recurcite = init({
apiKey: process.env.RECURCITE_API_KEY!,
signingSecret: process.env.RECURCITE_SIGNING_SECRET,
});
// All subsequent track() calls are automatically signedError handling
The SDK throws typed errors for common failure cases:
try {
await recurcite.track({ ... });
} catch (err) {
if (err instanceof Error) {
// err.message contains the server error detail
console.error("RecurCite error:", err.message);
}
}| Status | Meaning | Action |
|---|---|---|
400 | Invalid payload — missing required fields or unknown event type | Fix the payload and retry |
401 | Invalid or missing API key | Check your RECURCITE_API_KEY |
409 | Duplicate event_id (idempotency conflict) | Event already recorded — safe to ignore |
429 | Rate limited | Back off and retry with exponential delay |
500 | Server error | Retry with backoff; contact support if persistent |
TypeScript types
The SDK is fully typed. Key types you'll work with:
import type {
TrackEvent,
StripeRefs,
EventType,
} from "@recurcite/sdk";
// EventType: "terms.accepted" | "user.login" | "product.used" | ...
// StripeRefs: { stripe_customer_id?, stripe_subscription_id?, ... }
// TrackEvent: { type, payload, stripe_refs?, event_id? }Integration examples
Express middleware
import { recurcite } from "../lib/recurcite";
// Track logins on authentication
app.post("/auth/login", async (req, res) => {
const user = await authenticate(req.body);
await recurcite.track({
type: "user.login",
payload: {
occurred_at: new Date().toISOString(),
ip: req.ip,
user_agent: req.headers["user-agent"],
},
stripe_refs: {
stripe_customer_id: user.stripeCustomerId,
},
});
res.json({ token: generateToken(user) });
});Next.js API route
import { recurcite } from "@/lib/recurcite";
export async function POST(req: Request) {
const { userId, stripeCustomerId, termsVersion } = await req.json();
await recurcite.track({
type: "terms.accepted",
payload: {
version: termsVersion,
accepted_at: new Date().toISOString(),
},
stripe_refs: {
stripe_customer_id: stripeCustomerId,
},
});
return Response.json({ success: true });
}Get your API key
- Go to Dashboard → Developers
- Click Create key
- Copy the key (shown only once)
- Add to your environment:
RECURCITE_API_KEY=rc_live_…
Next steps
- Event Reference — all event types, required fields, and JSON examples
- Security & Data — HMAC signing, encryption, and privacy details