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

@dotbots-boutique/server-sdk

v1.8.0

Published

DotBots Backend SDK — server-side AI calls, payments, and user lookups via the DotBots proxy

Readme

@dotbots-boutique/server-sdk

The official backend SDK for DotBots Boutique. Use this package to make AI calls, trigger payments and retrieve user information from your Deno backend — without a browser or user session.

When to use this SDK

Use the backend SDK when logic must run server-side:

  • Webhook handlers
  • Background jobs and scheduled tasks
  • Multi-step backend processing flows
  • Any operation that runs without a user actively waiting in the browser

For user-facing interactions in the browser, use the frontend SDK (@dotbots-boutique/auth-sdk).

Installation

npm install @dotbots-boutique/server-sdk

Always use the latest version — check the current version before installing:

https://www.npmjs.com/package/@dotbots-boutique/server-sdk

Pin the exact version in package.json — do not use @latest. Update regularly.

Or in Deno:

import { DotBotsBackend } from 'npm:@dotbots-boutique/server-sdk';

Environment variables

These are injected automatically by the DotBots platform — no manual configuration needed:

DOTBOTS_APP_ID=uuid
DOTBOTS_APP_SECRET=...
DOTBOTS_API_URL=https://api.dotbots.boutique
ENVIRONMENT=test|prod

Setup

Initialise once at app startup, before handling any requests:

import { DotBotsBackend } from 'npm:@dotbots-boutique/server-sdk';

const dotbots = new DotBotsBackend({
  appId: Deno.env.get('DOTBOTS_APP_ID')!,
  appSecret: Deno.env.get('DOTBOTS_APP_SECRET')!,
  apiUrl: Deno.env.get('DOTBOTS_API_URL') ?? 'https://api.dotbots.boutique',
  environment: Deno.env.get('ENVIRONMENT') ?? 'prod'
});

// Must be called before any other methods
await dotbots.initialize();

initialize() fetches the proxy URL from the platform. It must complete before any AI calls, payments or user lookups are made.

AI calls

// orgId required when feature is configured as paidBy = 'org' in the platform (default)
const response = await dotbots.ai('generate-summary', {
  messages: [
    { role: 'user', content: 'Summarise the following document: ...' }
  ],
  orgId: user.orgId
});

console.log(response.content);
console.log(`Cost: ${response.cost.tokens} tokens`);

// Feature configured as paidBy = 'app' in platform — no orgId needed
const response = await dotbots.ai('internal-classification', {
  messages: [{ role: 'user', content: 'Classify this text...' }]
});

Streaming

let result = '';

await dotbots.aiStream(
  'generate-text',
  {
    messages: [{ role: 'user', content: 'Write a report...' }],
    orgId: user.orgId
  },
  (delta) => {
    result += delta;
    // optionally forward to client via SSE
  },
  (finalResponse) => {
    console.log(`Completed — cost: ${finalResponse.cost.tokens} tokens`);
  }
);

Payments

The paidBy value is configured per feature in the platform — default is org. Your code only needs to provide orgId when the feature charges the organisation:

// orgId is optional — SDK sends default org from app secret context
await dotbots.charge('data-export', { quantity: 1 });

// Explicitly provide orgId when charging a specific org
await dotbots.charge('data-export', {
  orgId: user.orgId,
  quantity: 1
});

// Feature paidBy = 'app' — no orgId needed
await dotbots.charge('internal-job');

Getting user info

const user = await dotbots.getUser(userId);
console.log(user.name, user.orgId, user.roles);

Error handling

import { DotBotsBackend, DotBotsBackendError } from 'npm:@dotbots-boutique/server-sdk';

try {
  const response = await dotbots.ai('generate-text', { messages, orgId });
} catch (error) {
  if (error instanceof DotBotsBackendError) {
    switch (error.code) {
      case 'AI_INSUFFICIENT_BALANCE':
        // Org has no tokens — notify user
        break;
      case 'AI_FEATURE_NOT_FOUND':
        // Feature not configured in platform — developer error
        console.error('AI feature not configured in DotBots platform');
        break;
      case 'AI_CALL_FAILED':
        // Provider error — retry or fallback
        break;
      case 'UNAUTHORIZED':
        // Invalid app secret — check DOTBOTS_APP_SECRET env variable
        break;
    }
  }
}

Sending notifications

Send a notification to a user. The notification type (email, SMS, platform), templates and placeholders are configured in the DotBots platform — your code only provides the parameters.

const notificationAppSecret = Deno.env.get('DOTNOTIFICATIONS_APP_SECRET')!;

// Platform notification — userExternalId required
await dotbots.sendNotification({
  notificationAppSecret,
  userOrganisationExternalId: user.orgId,
  userExternalId: user.id,
  code: 'invoice.created',
  language: 'nl',
  parameters: { invoiceNr: 'INV-42', amount: '99,50' }
});

// Email notification — email required
await dotbots.sendNotification({
  notificationAppSecret,
  userOrganisationExternalId: user.orgId,
  email: user.email,
  code: 'invoice.created',
  parameters: { invoiceNr: 'INV-42', amount: '99,50' }
});

// SMS notification — phone required
await dotbots.sendNotification({
  notificationAppSecret,
  userOrganisationExternalId: user.orgId,
  phone: user.phone,
  code: 'invoice.created',
  parameters: { invoiceNr: 'INV-42', amount: '99,50' }
});

Which identifier to include depends on the notification type configured in dotNotifications. Use code to identify the notification. In the platform admin you can copy a ready-made example payload per notification with the correct code and parameter keys.

Always call this server-to-server — the app secret must never appear in the browser.


Error codes

| Code | Description | |------|-------------| | AI_FEATURE_NOT_FOUND | Feature not configured in the platform | | AI_PROVIDER_NOT_CONFIGURED | API key not set for the AI provider | | AI_INSUFFICIENT_BALANCE | Organisation balance is 0 and awaiting top-up | | AI_CALL_FAILED | AI provider returned an error | | CHARGE_FAILED | Payment failed | | USER_NOT_FOUND | User not found | | UNAUTHORIZED | Invalid app secret | | NOTIFICATION_NOT_FOUND | Notification code does not belong to this app | | NO_TEMPLATE_CONFIGURED | No template configured for this notification |

Frontend SDK vs Backend SDK

| | Frontend SDK | Backend SDK | |--|-------------|-------------| | Package | @dotbots-boutique/auth-sdk | @dotbots-boutique/server-sdk | | Runtime | Browser | Deno / Node | | Auth | User JWT (iframe) | App secret | | AI calls | ✅ | ✅ | | Payments | ✅ | ✅ | | User context | Automatic | Manual via orgId | | Use case | User interactions | Webhooks, jobs, server logic |

Rule of thumb: if there is a user actively waiting in the browser, use the frontend SDK. If the logic runs in the background or server-side, use the backend SDK.

Security

  • DOTBOTS_APP_SECRET is injected by the platform and must never be logged, returned in API responses or stored anywhere other than environment variables.
  • The proxy URL is fetched dynamically at startup — never hardcode it.
  • All communication between the backend SDK and the proxy is server-to-server. The app secret is never exposed to the browser.

Links