npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

crovver-node

v1.2.0

Published

Official Node.js/TypeScript SDK for Crovver subscription management platform

Readme

crovver-node

npm version TypeScript License: MIT

Official Node.js/TypeScript SDK for integrating Crovver subscription management into your backend.

Features

  • Complete API Coverage — tenants, plans, subscriptions, checkout, entitlements, invoices, proration
  • TypeScript Support — full type definitions included
  • B2B & D2C Support — works with both organization types
  • Error HandlingCrovverError class with status codes and retryability flags
  • Automatic Retries — exponential backoff with jitter for transient failures
  • No Checkout Retry — payment-creating endpoints are never retried to prevent duplicate charges
  • ESM & CommonJS — dual module support

Installation

npm install crovver-node
# or
yarn add crovver-node
# or
pnpm add crovver-node

Quick Start

import { CrovverClient } from "crovver-node";

const crovver = new CrovverClient({
  apiKey: "sk_live_your_api_key",
});

const canAccess = await crovver.canAccess("company-123", "advanced-analytics");
if (canAccess) {
  console.log("Access granted!");
}

Configuration

interface CrovverConfig {
  apiKey: string;       // Bearer API key — starts with sk_live_ or sk_test_
  timeout?: number;     // ms, default 30 000
  maxRetries?: number;  // default 3
  debug?: boolean;      // default false
  logger?: (message: string, data?: unknown) => void;
}

Error Handling

import { CrovverClient, CrovverError } from "crovver-node";

try {
  await crovver.canAccess("company-123", "premium-feature");
} catch (error) {
  if (error instanceof CrovverError) {
    console.error(error.message);
    console.error("HTTP status:", error.statusCode);
    console.error("Retryable:", error.isRetryable);
  }
}

Automatic retries apply to 5xx, 429, 408, and network errors. 4xx errors are not retried.


API Reference

Tenant Management (B2B Only)

createTenant

const result = await crovver.createTenant({
  externalTenantId: "company-123",
  name: "Acme Corporation",
  ownerExternalUserId: "user-456",
  ownerEmail: "[email protected]",
  ownerName: "John Doe",
});
console.log("Tenant ID:", result.tenant.id);

getTenant

const { tenant, members } = await crovver.getTenant("company-123");

Plans

getPlans

const { plans } = await crovver.getPlans();
plans.forEach((plan) => {
  console.log(`${plan.name}: ${plan.pricing.currency} ${plan.pricing.amount}/${plan.pricing.interval}`);
});

Subscriptions

getSubscriptions

const { subscriptions } = await crovver.getSubscriptions("company-123");
subscriptions.forEach((sub) => {
  console.log(`${sub.plan.name} — ${sub.status}`);
});

cancelSubscription

Cancels at period end (no immediate termination).

const result = await crovver.cancelSubscription(
  "sub-uuid",
  "too_expensive",
  "Pricing is a bit high for our team size"
);
console.log(`Ends at: ${result.willEndAt}`);

Checkout

createCheckoutSession

B2B:

const checkout = await crovver.createCheckoutSession({
  requestingUserId: "user-456",
  requestingTenantId: "company-123",
  planId: "plan-uuid",
  provider: "stripe",
  successUrl: "https://myapp.com/success",
  cancelUrl: "https://myapp.com/cancel",
});
window.location.href = checkout.checkoutUrl;

D2C (tenant auto-created):

const checkout = await crovver.createCheckoutSession({
  requestingUserId: "user-789",
  userEmail: "[email protected]",
  userName: "John Doe",
  planId: "plan-uuid",
  provider: "stripe",
  successUrl: "https://myapp.com/success",
  cancelUrl: "https://myapp.com/cancel",
});

Entitlements

canAccess

const canAccess = await crovver.canAccess("company-123", "advanced-analytics");

recordUsage

await crovver.recordUsage("company-123", "api-calls", 1, {
  endpoint: "/api/v1/users",
});

checkUsageLimit

const usage = await crovver.checkUsageLimit("company-123", "api-calls");
console.log(`${usage.current} / ${usage.limit} — allowed: ${usage.allowed}`);

Proration (Seat-Based Plans)

createProrationCheckout

Creates a one-time payment session for a mid-cycle seat capacity upgrade. The proration amount is calculated server-side.

const checkout = await crovver.createProrationCheckout({
  requestingEntityId: "company-123",
  newCapacity: 15,
  planId: "plan-uuid",           // optional
  successUrl: "https://myapp.com/success",
  cancelUrl: "https://myapp.com/cancel",
});

if (checkout.checkoutUrl) {
  window.location.href = checkout.checkoutUrl;
}
console.log(`Prorated amount: ${checkout.prorationAmount} ${checkout.prorationDetails.currency}`);

Billing

getInvoices

const { invoices } = await crovver.getInvoices("company-123");
invoices.forEach((inv) => {
  console.log(`${inv.invoice_number}: ${inv.total_amount} ${inv.currency} — ${inv.status}`);
});

Payment Providers

getSupportedProviders

const { providers } = await crovver.getSupportedProviders();
providers.forEach((p) => console.log(`${p.name}: ${p.code}`));

TypeScript Exports

import {
  CrovverClient,
  CrovverError,
  CrovverConfig,
  Plan,
  Subscription,
  Tenant,
  CreateTenantRequest,
  CreateCheckoutSessionRequest,
  CreateProrationCheckoutRequest,
  CreateProrationCheckoutResponse,
  CancelSubscriptionResponse,
  GetInvoicesResponse,
  CheckUsageLimitResponse,
} from "crovver-node";

License

MIT