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

byo-sdk

v0.4.0

Published

BYO - TypeScript/Node.js SDK for BYOK

Readme

BYO TS/JS SDK for BYOK

Official TypeScript/Node.js SDK for BYO — BYOK (Bring Your Own Key).

Installation

npm install byo-sdk

Quick Start

import { BYOK } from 'byo-sdk';

const byok = new BYOK({
  apiKey: process.env.BYOK_API_KEY!,
  // baseURL defaults to BYO_BASE_URL env var, or http://localhost:3000 for local dev
});

// Proxy an OpenAI request using a customer's stored key
const openai = byok.openai({ refId: 'customer_123' });

const response = await openai.responses.create({
  model: 'gpt-4.1',
  input: 'Hello, world!',
});

console.log(response);

OpenAI

Responses API

const openai = byok.openai({ refId: 'customer_123' });
const response = await openai.responses.create({
  model: 'gpt-4.1',
  input: 'What is BYOK?',
});

Chat Completions API

const openai = byok.openai({ refId: 'customer_123' });
const response = await openai.chat.completions.create({
  model: 'gpt-4.1',
  messages: [{ role: 'user', content: 'Hello!' }],
});

Custom OpenAI-compatible Endpoint

Customers can connect a key for any OpenAI-compatible server (vLLM, OpenRouter, Ollama, Together AI, etc.) by providing a baseUrl in providerConfig when connecting:

await byok.keys.connect({
  provider: 'openai',
  refId: 'customer_123',
  providerKey: 'key-...',
  providerConfig: { baseUrl: 'https://openrouter.ai/api/v1' },
});

Once connected, proxy calls work the same way — BYO routes to the custom endpoint automatically:

const openai = byok.openai({ refId: 'customer_123' });
const response = await openai.chat.completions.create({
  model: 'meta-llama/llama-3-70b',
  messages: [{ role: 'user', content: 'Hello!' }],
});

Anthropic

Messages API

const claude = byok.anthropic({ refId: 'customer_123' });
const response = await claude.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Hello!' }],
});

Google AI Studio

Generate Content

const gemini = byok.google({ refId: 'customer_123' });
const response = await gemini.generateContent.create({
  model: 'gemini-2.0-flash',
  contents: [{ parts: [{ text: 'Hello!' }] }],
});

Azure OpenAI

Chat Completions

const azure = byok.azureOpenai({ refId: 'customer_123' });
const response = await azure.chat.completions.create({
  model: 'gpt-4',
  messages: [{ role: 'user', content: 'Hello!' }],
});

Azure OpenAI requires providerConfig when connecting the key:

await byok.keys.connect({
  provider: 'azure-openai',
  refId: 'customer_123',
  providerKey: 'your-azure-api-key',
  providerConfig: {
    baseUrl: 'https://your-resource.openai.azure.com',
    deploymentName: 'gpt-4',
  },
});

AWS Bedrock

Converse

const bedrock = byok.bedrock({ refId: 'customer_123' });
const response = await bedrock.converse.create({
  modelId: 'anthropic.claude-3-haiku-20240307-v1:0',
  messages: [{ role: 'user', content: [{ text: 'Hello!' }] }],
});

AWS Bedrock requires providerConfig when connecting the key:

await byok.keys.connect({
  provider: 'bedrock',
  refId: 'customer_123',
  providerKey: 'your-aws-secret-access-key',
  providerConfig: {
    accessKeyId: 'AKIA...',
    region: 'us-east-1',
  },
});

Key Management

// Connect a provider key (typically called from customer frontend → your API → BYO)
await byok.keys.connect({
  provider: 'openai',
  refId: 'customer_123',
  providerKey: 'sk-...',
});

// Validate a stored key
const result = await byok.keys.validate({
  provider: 'openai',
  refId: 'customer_123',
});

// Revoke a stored key
await byok.keys.revoke({
  provider: 'openai',
  refId: 'customer_123',
});

Usage and cost

Every proxied LLM call captures the model, prompt/completion tokens and an estimated USD cost. Read it back per customer (refId) to power your own billing UI:

const usage = await byok.usage.get({ refId: 'customer_123' });
console.log(usage.totals.costUsd, usage.byModel, usage.daily);

// Filter by date range and provider; pass Date or ISO string.
const last7d = await byok.usage.get({
  refId: 'customer_123',
  provider: 'openai',
  since: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
});

// 24-hour rollup used by the dashboard overview.
const stats = await byok.usage.stats();

The cost is calculated server-side using BYO's built-in pricing table. If you call a model BYO doesn't have a price for (a fine-tune, a fresh model release, an OpenAI-compatible local server), it'll show up in usage.unknownModels so you know exactly what to add — and the cost row will be null until you patch it:

console.log(usage.unknownModels);
// [{ provider: 'openai', model: 'ft:gpt-4o-...:abc',
//    requests: 142, totalTokens: 184230 }]

Custom model prices

Patch in custom prices per project, useful for fine-tunes, niche OpenAI-compatible endpoints, or anything BYO ships without a default for. The shape mirrors the BYO_MODEL_PRICING env var; numbers are USD per 1,000,000 tokens. Changes take effect within ~60s on every API instance.

await byok.pricing.update(projectId, {
  openai: { 'my-finetune': { input: 0.5, output: 2.0 } },
});

const { overrides } = await byok.pricing.get(projectId);

await byok.pricing.clear(projectId); // back to BYO's defaults

Streaming note: to capture token counts on streamed OpenAI Chat Completions, include stream_options: { include_usage: true } in the request — otherwise providers don't return a usage block and the log row will have tokens and costUsd set to null.

Logs

Inspect individual proxied requests, including the captured tokens and cost:

const { data, total } = await byok.logs.list({
  refId: 'customer_123',
  success: false,
  limit: 50,
});

const log = await byok.logs.get(data[0].id);
console.log(log.model, log.totalTokens, log.costUsd);

Error Handling

The SDK throws typed errors so you can branch on the failure mode without parsing status codes by hand:

| Class | When it's thrown | | ---------------------- | -------------------------------------------------- | | AuthenticationError | 401 — invalid or missing API key | | AuthorizationError | 403 — key isn't allowed to perform this action | | ValidationError | 400 / 422 — bad payload | | NotFoundError | 404 — project / log / endpoint missing | | RateLimitError | 429 — includes retryAfterMs from Retry-After | | ProviderError | Upstream provider (OpenAI, Anthropic, …) rejected | | ServerError | 5xx from the BYO API | | NetworkError | Connection failure (fetch threw) | | TimeoutError | Hit the SDK request timeout | | BYOKError | Base class — catch this for "anything from BYO" |

import {
  BYOK,
  BYOKError,
  AuthenticationError,
  RateLimitError,
  ProviderError,
} from 'byo-sdk';

try {
  const response = await openai.responses.create({ ... });
} catch (err) {
  if (err instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (err instanceof RateLimitError) {
    console.error(`Rate limited, retry after ${err.retryAfterMs ?? 'unknown'}ms`);
  } else if (err instanceof ProviderError) {
    console.error(`Upstream ${err.provider} rejected the request: ${err.message}`);
  } else if (err instanceof BYOKError) {
    console.error(`Error ${err.statusCode}: ${err.message}`);
  }
}

Webhooks

Verify webhook deliveries from BYO with a single call. The signature is a constant-time HMAC-SHA256 over the raw request body using the endpoint's signing secret:

import { constructWebhookEvent } from 'byo-sdk';

app.post('/webhooks/byo', express.raw({ type: 'application/json' }), (req, res) => {
  try {
    const event = constructWebhookEvent(
      req.body,                       // raw Buffer, do NOT parse first
      req.header('X-BYO-Signature'),
      process.env.BYO_WEBHOOK_SECRET!,
    );
    handleEvent(event);
    res.status(200).end();
  } catch {
    res.status(400).end();
  }
});

Need just the boolean? Use verifyWebhookSignature(payload, header, secret).

Project Origin Allowlist

When you ship a publishable key (byo_pk_*) into a frontend, lock it down to the origins that should be allowed to call /keys/connect and /connect/form:

await byok.origins.update('proj_123', [
  'https://app.example.com',
  'https://staging.example.com',
]);

// Empty list = unrestricted (back to the previous behaviour)
await byok.origins.clear('proj_123');

Audit Log

Every security-relevant mutation (project changes, key revokes, pricing updates, origin allowlist edits, webhook config changes) is recorded in an append-only audit log:

const { data } = await byok.audit.list({
  projectId: 'proj_123',
  action: 'provider_key.revoked',
  since: new Date(Date.now() - 24 * 60 * 60 * 1000),
});

License

FSL-1.1-MIT