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

credly

v1.0.3

Published

Transform complex LLM token usage into simple credits. Manage user access, track consumption, and implement subscription tiers with ease.

Readme

credly

NPM Version License Website

The credly package provides a simple and powerful way to manage Large Language Model (LLM) token usage as credits. With Credly, you can easily track consumption, manage user access, rate limit based on credits, and implement subscription tiers in your application with ease.

Features

  • Credit-based Usage Tracking: Abstract away complex token counting and manage usage with a simple credit system.
  • User Management: Keep track of your users and their credit balances.
  • Tiered Access: Implement different subscription tiers with varying credit allocations and automatic credit refills.
  • Transaction History: Get a full history of credit transactions.
  • Developer-Focused: Designed with developers in mind for a seamless integration experience.

Quickstart

Go to credly.dev to get your API key and project ID.

Copy-paste this minimal example to get started in seconds.

import { createClient } from "credly";

const credly = createClient({
  apiKey: "YOUR_API_KEY",
  projectId: "YOUR_PROJECT_ID",
});

// Reserve credits, call your LLM, then finalize with actual usage
const start = await credly.startUsageTransaction({
  user_id: "user_123",
  model: "gpt-4",
  // Optionally reserve tokens to pre-check credit availability for the following call.
  provisional_tokens: {
    input_tokens: 100,
    output_tokens: 500,
  },
});
if (!start.continue) throw new Error("Insufficient credits");

// ... call your LLM and compute usage ...
await credly.completeUsageTransaction({
  transaction_id: start.transaction_id,
  success: true,
  finalized_tokens: { input_tokens: 10, output_tokens: 50 },
});

Table of contents

Getting started

Installation

Install with your package manager of choice:

npm install credly
# or
pnpm add credly

Initialization

Create a client with your API key and project id:

import { createClient } from "credly";
const credly = createClient({
  apiKey: "YOUR_API_KEY",
  projectId: "YOUR_PROJECT_ID",
});

Usage

credly's primary pattern is: start a usage transaction, call the LLM, then complete the transaction with the finalized token counts.

captureUsage helper

Use captureUsage to wrap start/execute/finish in one call. It creates the user if needed, reserves provisional tokens, runs your function (if allowed), extracts finalized tokens via your callback, and completes the transaction for success or failure.

Keep the example usage in the package docs; the helper returns a structured result you can branch on (status values include start_failed, insufficient_credits, executed_success, and error variants).

const response = await meteringClient.captureUsage({
  // Identify the user and model for billing
  user_id: userId,
  model: "gpt-4o",

  // Optionally reserve tokens to pre-check credit availability for the following call.
  provisional_tokens: {
    input_tokens: Tiktoken().encode(prompt),
    output_tokens: 500,
  }

  // The core work to be done and metered
  execute: () => await openai.chat.completions.create({
      // ... your parameters
    }),

  // A function to extract the final token count from the result of `execute`
  finalizeTokens: (result) => ({
    input_tokens: result.usage.prompt_tokens,
    output_tokens: result.usage.completion_tokens,
  }),
});

Return shape (with status):

type UsageTransactionStatus =
  | "start_failed"
  | "insufficient_credits"
  | "executed_success"
  | "executed_error"
  | "execution_error_completion_failed";

type CaptureUsageReturn<T> =
  | {
      status: "start_failed";
      started: false;
      continue: false;
      startError: unknown;
    }
  | {
      status: "insufficient_credits";
      started: true;
      continue: false;
      start: StartUsageTransactionResponse;
    }
  | {
      status: "executed_success";
      started: true;
      continue: true;
      start: StartUsageTransactionResponse;
      finish: CompleteUsageTransactionResponse;
      result: T;
    }
  | {
      status: "executed_error" | "execution_error_completion_failed";
      started: true;
      continue: true;
      start: StartUsageTransactionResponse;
      finish?: CompleteUsageTransactionResponse;
      error: unknown;
    };

Status meanings

| Status | Meaning | | --------------------------------- | ------------------------------------------------------- | | start_failed | Start call failed before creating a transaction. | | insufficient_credits | Start succeeded but continue is false (no execution). | | executed_success | Execution + completion (success) succeeded. | | executed_error | Execution failed; failure completion succeeded. | | execution_error_completion_failed | Execution failed AND failure completion also failed. |

Set rethrowOnError: true to rethrow errors; otherwise branch on the returned status.

Basic usage pattern

  1. Call startUsageTransaction to check for sufficient credits and reserve provisional tokens.
  2. If continue is true, call your LLM.
  3. Call completeUsageTransaction with finalized_tokens and success.

See the examples in this README for OpenAI integration patterns.

Error Handling

If a transaction fails, you should still complete it with success: false:

try {
  const startResponse = await credly.startUsageTransaction({
    user_id: userId,
    model: "gpt-4",
  });

  if (startResponse.continue) {
    // Your LLM call here
    const completion = await openai.chat.completions.create({
      // ... your parameters
    });

    await credly.completeUsageTransaction({
      transaction_id: startResponse.transaction_id,
      success: true,
      finalized_tokens: {
        input_tokens: completion.usage?.prompt_tokens,
        output_tokens: completion.usage?.completion_tokens,
      },
    });
  }
} catch (error) {
  // Complete the transaction as failed if it was started
  if (startResponse?.transaction_id) {
    await credly.completeUsageTransaction({
      transaction_id: startResponse.transaction_id,
      success: false,
      finalized_tokens: { input_tokens: 0, output_tokens: 0 },
    });
  }
  throw error;
}

API Reference

createClient(options)

Creates a new Credly client instance.

  • options.apiKey (string, required): Your API key.
  • options.projectId (string, required): Your project ID.

startUsageTransaction(details)

Initiates a new usage transaction.

  • details.user_id (string, required): The ID of the user making the request.
  • details.model (string, required): The model identifier configured in your project.
  • details.provisional_tokens (object, optional): Estimated token usage for credit reservation.
    • input_tokens (number, optional): Estimated input tokens.
    • output_tokens (number, optional): Estimated output tokens.
  • details.feature_identifier (string, optional): Feature identifier for usage tracking.

Returns:

  • transaction_id (string): UUID of the created transaction.
  • continue (boolean): Whether the user has sufficient credits to proceed.
  • balance (number): User's remaining credit balance.
  • credits_used (number): Credits deducted for this transaction.
  • message (string): Status message.

completeUsageTransaction(details)

Finalizes an ongoing transaction with actual usage.

  • details.transaction_id (string, required): UUID of the pending transaction.
  • details.success (boolean, required): Whether the LLM call was successful.
  • details.finalized_tokens (object, required): Actual token usage.
    • input_tokens (number, optional): Actual input tokens used.
    • output_tokens (number, optional): Actual output tokens used.

Returns:

  • credits_used (number): Final credits charged for the transaction.
  • balance (number): User's updated credit balance.
  • balanceAdjustment (number): Credit adjustment (positive if refunded, negative if additional charge).

User Management

createUser(details)

Creates a new user.

  • details.id (string, required): External user ID.

getUser(details)

Retrieves a user by ID.

  • details.id (string, required): External user ID.

getUsers()

Retrieves all users in the project.

deleteUser(details)

Deletes a user.

  • details.id (string, required): External user ID.

Tier Management

changeUserTier(details)

Changes a user's subscription tier.

  • details.user_id (string, required): The ID of the user.
  • details.tier_id (string, required): The ID of the new tier.
  • details.reset_balance (boolean, optional): Whether to reset the user's balance to the new tier's allocation.

Transaction History

getTransactions(filters)

Retrieves transaction history with optional filtering.

  • filters.user_id (string, optional): Filter by user ID.
  • Additional pagination and filtering options available.

getTransaction(details)

Retrieves a single transaction by ID.

  • details.id (string, required): Transaction ID.

Error handling

The client throws CredlyApiError for API errors. Fields include status, title, detail, and type.

Example:

import { CredlyApiError } from "credly";
try {
  await credly.startUsageTransaction({ user_id: "user_123", model: "gpt-4" });
} catch (err) {
  if (err instanceof CredlyApiError)
    console.error(`API Error ${err.status}: ${err.detail}`);
  else console.error("Unexpected:", err);
}

Error types

The client maps HTTP/API problems to strongly-typed error classes derived from CredlyApiError. The table below lists the known subclasses and when they are used.

| Error class | When it's thrown | | ------------------- | --------------------------------------------------------------------------------------------------------------- | | ValidationError | Returned for HTTP 400 responses when the request is invalid or fails schema validation. | | UnauthorizedError | Returned for HTTP 401 responses when the API key is missing or invalid. | | ForbiddenError | Returned for HTTP 403 responses when the caller lacks required permissions. | | NotFoundError | Returned for HTTP 404 responses when a requested resource doesn't exist. | | ConflictError | Returned for HTTP 409 responses when a request conflicts with current server state (e.g., duplicate resources). | | RateLimitError | Returned for HTTP 429 responses when the client has exceeded allowed request rate limits. | | ServerError | Returned for HTTP 5xx responses indicating server-side failure. | | CredlyApiError | Fallback for unknown or unclassified API problems; contains RFC 7807 problem details. |

Support, feedback & feature requests

We want to improve and build credly into the exact package you need. We'd love to hear from you!

Email: [email protected]

License

MIT — see LICENSE.