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

zookish

v0.2.9

Published

TypeScript SDK for the Zookish API

Downloads

61

Readme

Zookish SDK

A TypeScript SDK for interacting with the Zookish API. Compatible with both Node.js and browser environments.

New: Improved TypeScript support! See TYPESCRIPT.md for detailed TypeScript integration guide.

Changelog

v0.2.5

  • Added direct export of MessagingClient class to enable access to static methods like parseWebhookPayload
  • Fixed TypeScript issue with accessing static methods on client classes

v0.3.0

  • Added comprehensive TypeScript type definitions
  • Created dedicated TypeScript integration guide (TYPESCRIPT.md)
  • Fixed type assertion issues when using the SDK in TypeScript projects
  • Added example TypeScript usage file

v0.2.0

  • Added Memory API for semantic search functionality
  • Added Messaging API for SMS functionality

v0.1.2

  • Refactored getPhoneNumbersByOrbId to be a method of the OrbClient instead of the PhoneNumberClient.

v0.1.1

  • Fixed phone number search functionality to properly handle the orbId parameter when searching for phone numbers
  • Added better handling of combined search parameters
  • Improved documentation for phone number search functionality

Installation

npm install zookish
# or
pnpm add zookish
# or
yarn add zookish

Usage

Initialize the SDK

import Zookish from 'zookish';

// Initialize the SDK
const zookish = new Zookish({
  apiKey: 'your-api-key',
  // Optional: Override the default API URL
  // baseUrl: 'https://custom-api.example.com/api/v1'
});

Orbs API

Create an Orb (Simplified API)

You can create an orb with minimal configuration:

// Create an orb with just instructions
const orb = await zookish.orbs.create({
  instructions: 'You are an elephant'
});

// Create an orb with partial configuration
const orb = await zookish.orbs.create({
  instructions: 'You are a helpful assistant',
  config: {
    gradient: ['#000000', '#ffffff'],
    firstMessage: 'How can I help you today?'
  }
});

This method calls the /api/v1/orbs endpoint.

Create an Orb (Full Configuration)

For complete control, you can specify all configuration options:

const orbData = {
  config: {
    gradient: ["#ff0000", "#00ff00"],
    voiceId: "123",
    voiceProvider: "provider",
    externalVoiceId: "456",
    widget: {
      containerType: "button",
      buttonText: "Click Me",
      buttonBackgroundColor: "#ffffff",
      buttonTextColor: "#000000",
      buttonSize: "medium",
      startPage: "home",
      position: "bottom-right",
      embedType: "inline",
      isExpandable: true,
      startExpanded: false,
      isDraggable: true,
      startOnLoad: false,
      mobileStyles: {
        buttonSize: "small",
        position: "bottom-center"
      },
      transcript: {
        containerColor: "#f0f0f0",
        type: "text",
        showTimestamps: true,
        fontStyle: "Arial"
      }
    },
    language: "en-US",
    speed: 1.0,
    enableBackgroundNoises: false,
    allowInterruptions: true,
    interruptionSensitivity: 0.8,
    instructions: "Instructions for the orb",
    firstMessage: "Hello!",
    userAwayTimeout: 300
  },
  instructions: 'Instructions for the orb',
  shortlink: 'my-orb',
};

const orb = await zookish.orbs.create(orbData);

Create an Orb with Phone Number and SIP Trunk

You can create an orb and automatically set up a phone number and SIP trunk for it in one step:

// Create an orb with a phone number and SIP trunk
const result = await zookish.orbs.createWithPhoneNumber({
  instructions: 'You are a helpful assistant',
  config: {
    gradient: ['#000000', '#ffffff'],
    firstMessage: 'How can I help you today?'
  }
}, {
  areaCode: '415',  // Optional: Specify a preferred area code
  capability: 'voice'  // Optional: Specify the capability (default is 'voice')
});

// The result contains the orb, phone number, and SIP trunk
console.log('Orb:', result.orb);
console.log('Phone number:', result.phoneNumber);
console.log('SIP trunk:', result.sipTrunk);

This method:

  1. Creates an orb using the provided configuration
  2. Searches for available phone numbers matching the specified criteria
  3. Purchases the first available phone number
  4. Sets up a SIP trunk for the phone number
  5. Returns the orb, phone number, and SIP trunk details

If no phone numbers are available or an error occurs during the phone number or SIP trunk setup, the method will still return the created orb.

Get an Orb by ID

const orb = await zookish.orbs.get('orb-id');

This method calls the /api/v1/orbs/{id} endpoint.

Get Phone Numbers by Orb ID

Retrieve all phone numbers associated with a specific orb ID. This endpoint requires authentication.

const phoneNumbers = await zookish.orbs.getPhoneNumbersByOrbId('orb-id');

This method calls the /api/v1/phone-numbers/orb/{orbId} endpoint.

Get Conversations by Orb ID

Retrieve a paginated list of conversations for a specific orb ID. This endpoint requires authentication.

const conversations = await zookish.orbs.getConversations('orb-id');

This method calls the /api/v1/orbs/{orbId}/conversations endpoint.

Telephony API

The SDK now includes telephony functionality for managing phone numbers, SIP trunks, and making outbound calls.

Get SIP Trunk Details

Retrieve SIP trunk details by ID or phone number. This endpoint does not require authentication.

// Get SIP trunk details by ID
const sipTrunk = await zookish.phoneNumbers.getSipTrunkDetails({
  sipTrunkId: 'trunk-id'
});

// Get SIP trunk details by phone number
const sipTrunk = await zookish.phoneNumbers.getSipTrunkDetails({
  phoneNumber: '+15551234567'
});

This method calls the /api/v1/phone-numbers/sip-trunk-details endpoint.

Get Available Phone Numbers

Search for available phone numbers with optional filtering. This endpoint requires authentication.

// Get all phone numbers
const phoneNumbers = await zookish.phoneNumbers.getPhoneNumbers();

// Get phone numbers with filtering
const phoneNumbers = await zookish.phoneNumbers.getPhoneNumbers({
  areaCode: '555',
  location: 'New York',
  capability: 'voice',
  onlyAvailable: true,
  orbId: 'orb-id'
});

When multiple parameters are provided, the search will return phone numbers that match all the criteria. For example, when both orbId and onlyAvailable: true are specified, the results will include both:

  • Phone numbers associated with the specified orb
  • Available phone numbers that match the other criteria (areaCode, location, capability)

This method calls the /api/v1/phone-numbers endpoint.

Make Outbound Calls

Initiate an outbound call to a phone number using an orb. This endpoint requires authentication.

// Make an outbound call with minimal configuration
const callResponse = await zookish.phoneNumbers.makeOutboundCall({
  phone_number: '+15551234567',
  orb_id: 'orb-id'
});

// Make an outbound call with full configuration
const callResponse = await zookish.phoneNumbers.makeOutboundCall({
  phone_number: '+15551234567',
  orb_id: 'orb-id',
  caller_id: 'Company Name',
  sip_trunk_id: 'trunk-id',
  from_phone_number: '+15557654321',
  destination_phone_number: '+15559876543',
  instructions: 'You are a pirate.',
  greeting: 'Ahoy, matey!'
});

This method calls the /api/v1/telephony/outbound-call endpoint.

Messaging API

The SDK provides simple methods for SMS messaging functionality using phone numbers in E.164 format (e.g., "+15551234567").

Store a Message

Store a message in the database:

const message = await zookish.messaging.store(
  '+15551234567', // from
  '+18005550199', // to
  'orb_123',      // orbId
  'Hello, this is a test message!',
  'outbound'      // direction
);

console.log('Stored message ID:', message.id);

Get Messages

Get messages from the database:

const messages = await zookish.messaging.get(
  '+15551234567', // phone number (from or to)
  'orb_123'       // orbId
);

console.log('Retrieved messages:', messages);

Create a Messaging Profile

Create a messaging profile for a phone number:

const profile = await zookish.messaging.createMessagingProfile(
  '+15551234567',
  {
    name: 'My Messaging Profile',
    whitelistedDestinations: ['US', 'CA']
  }
);

console.log('Messaging profile ID:', profile.id);
console.log('Phone number:', profile.phoneNumber.number);

This method calls the /api/v1/messaging/profiles endpoint.

Send an SMS Message

Send an SMS message from one of your phone numbers:

// Simple usage
const message = await zookish.messaging.sendSmsMessage(
  '+15551234567', // from
  '+15559876543', // to
  'Hello, this is a test message with # special character!'
);

// With additional options
const message = await zookish.messaging.sendSmsMessage(
  '+15551234567', // from
  '+15559876543', // to
  'Hello, this is a test message with # special character!',
  {
    messagingProfileId: 'profile-id', // Optional override
    webhookUrl: 'https://your-webhook.com/sms-callback' // Optional custom webhook
  }
);

console.log('Message ID:', message.id);
console.log('Message status:', message.status);

This method calls the /api/v1/messaging/send endpoint.

Set Up a Messaging Trunk

Set up a combined inbound/outbound SIP trunk for a phone number:

const trunk = await zookish.messaging.setupMessagingTrunk(
  '+15551234567',
  {
    connectionName: 'My Messaging Trunk'
  }
);

console.log('SIP trunk ID:', trunk.id);
console.log('SIP trunk address:', trunk.address);

This method calls the /api/v1/messaging/setup-trunk endpoint.

Set Up Complete Messaging in One Call

Set up everything needed for messaging with a single call:

const result = await zookish.messaging.setupCompleteMessaging(
  '+15551234567',
  {
    profileName: 'My Messaging Setup',
    whitelistedDestinations: ['US', 'CA'],
    setupTrunk: true,
    trunkConnectionName: 'My Combined Trunk'
  }
);

console.log('Messaging profile:', result.messagingProfile);
console.log('SIP trunk:', result.sipTrunk);

This method combines multiple API calls:

  1. Creates a messaging profile using /api/v1/messaging/profiles
  2. Optionally sets up a SIP trunk using /api/v1/messaging/setup-trunk

Error Handling

try {
  const orb = await zookish.orbs.create({
    instructions: 'You are a helpful assistant'
  });
  console.log('Orb created:', orb);
} catch (error) {
  console.error('Error creating orb:', error);
}

Memory API

The SDK provides methods for storing and retrieving memories using vector embeddings for semantic search.

Store a Memory

Store a memory for a phone number and orb:

const memory = await zookish.memory.store(
  '+15551234567', // phone number
  'orb_123',      // orbId
  'The customer is interested in our enterprise plan.'
);

console.log('Stored memory ID:', memory.id);

Find Memories

Find memories using semantic search:

const memories = await zookish.memory.find(
  '+15551234567', // phone number
  'orb_123',      // orbId
  'What is the customer interested in?'
);

console.log('Found memories:', memories);

API Reference

Initialization

const zookish = new Zookish({
  apiKey: string,  // Required: Your API key
  baseUrl?: string // Optional: Override the default API URL
});

Orbs

Create an Orb

// Simplified API
const orb = await zookish.orbs.create({
  instructions: string  // The only required field
});

// Full API
const orb = await zookish.orbs.create(orbData);

Endpoint: /api/v1/orbs

Create an Orb with Phone Number and SIP Trunk

const result = await zookish.orbs.createWithPhoneNumber(
  orbData,  // Same as the create method
  {
    areaCode?: string,    // Optional: Filter by area code
    capability?: string   // Optional: Filter by capability (default: 'voice')
  }
);

This method combines multiple API calls:

  1. Creates an orb using /api/v1/orbs
  2. Searches for phone numbers using /api/v1/phone-numbers
  3. Purchases a phone number using /api/v1/phone-numbers
  4. Sets up a SIP trunk using /api/v1/sip-trunks/setup

Get an Orb

const orb = await zookish.orbs.get(id);

Endpoint: /api/v1/orbs/{id}

Get Phone Numbers by Orb ID

const phoneNumbers = await zookish.orbs.getPhoneNumbersByOrbId(orbId);

Endpoint: /api/v1/phone-numbers/orb/{orbId}

Get Conversations by Orb ID

const conversations = await zookish.orbs.getConversations(orbId, page, limit);

Endpoint: /api/v1/orbs/{orbId}/conversations

Phone Numbers

Get SIP Trunk Details

const sipTrunk = await zookish.phoneNumbers.getSipTrunkDetails({
  sipTrunkId?: string,  // Either sipTrunkId or phoneNumber must be provided
  phoneNumber?: string
});

Endpoint: /api/v1/phone-numbers/sip-trunk-details

Get Phone Numbers

const phoneNumbers = await zookish.phoneNumbers.getPhoneNumbers({
  areaCode?: string,      // Filter by area code
  location?: string,      // Filter by location (city, state, etc.)
  capability?: string,    // Filter by capability (voice, sms, etc.)
  onlyAvailable?: boolean, // Only show available numbers
  orbId?: string          // Filter by orb ID
});

Endpoint: /api/v1/phone-numbers

Make Outbound Call

const callResponse = await zookish.phoneNumbers.makeOutboundCall({
  phone_number: string,           // Required: Phone number to call
  orb_id: string,                 // Required: ID of the orb to use for the call
  caller_id?: string,             // Optional: Caller ID to display to the recipient
  sip_trunk_id?: string,          // Optional: ID of the SIP trunk to use for the call
  from_phone_number?: string,     // Optional: Phone number to use as the caller
  destination_phone_number?: string, // Optional: Alternative destination phone number
  instructions?: string,          // Optional: Instructions to override the default
  greeting?: string               // Optional: Greeting to override the default
});

Endpoint: /api/v1/telephony/outbound-call

Messaging

Create a Messaging Profile

const profile = await zookish.messaging.createMessagingProfile(
  phoneNumber: string,  // Required: Phone number in E.164 format
  options?: {
    name?: string,                    // Optional: Name for the messaging profile
    whitelistedDestinations?: string[], // Optional: Array of allowed destination country codes
    webhookUrl?: string,              // Optional: Custom webhook URL
    webhookFailoverUrl?: string       // Optional: Custom failover webhook URL
  }
);

Endpoint: /api/v1/messaging/profiles

Send an SMS Message

const message = await zookish.messaging.sendSmsMessage(
  from: string,    // Required: Phone number to send from in E.164 format
  to: string,      // Required: Phone number to send to in E.164 format
  text: string,    // Required: Message text
  options?: {
    messagingProfileId?: string,      // Optional: Override messaging profile
    webhookUrl?: string,              // Optional: Custom webhook for this message
    metadata?: Record<string, any>    // Optional: Metadata to attach to the message
  }
);

Endpoint: /api/v1/messaging/send

Set Up a Messaging Trunk

const trunk = await zookish.messaging.setupMessagingTrunk(
  phoneNumber: string,  // Required: Phone number in E.164 format
  options?: {
    connectionName?: string  // Optional: Name for the SIP trunk connection
  }
);

Endpoint: /api/v1/messaging/setup-trunk

Set Up Complete Messaging

const result = await zookish.messaging.setupCompleteMessaging(
  phoneNumber: string,  // Required: Phone number in E.164 format
  options?: {
    profileName?: string,              // Optional: Name for the messaging profile
    whitelistedDestinations?: string[], // Optional: Array of allowed destination country codes
    webhookUrl?: string,               // Optional: Custom webhook URL
    webhookFailoverUrl?: string,       // Optional: Custom failover webhook URL
    setupTrunk?: boolean,              // Optional: Whether to set up a SIP trunk
    trunkConnectionName?: string       // Optional: Name for the SIP trunk connection
  }
);

This method combines multiple API calls.

Get Message History

const messages = await zookish.messaging.getMessageHistory(
  phoneNumber: string,  // Required: Phone number in E.164 format
  options?: {
    to?: string,        // Optional: Filter by recipient
    startDate?: Date,   // Optional: Filter by start date
    endDate?: Date,     // Optional: Filter by end date
    limit?: number,     // Optional: Maximum number of messages to return
    offset?: number     // Optional: Offset for pagination
  }
);

Get Message Status

const status = await zookish.messaging.getMessageStatus(
  messageId: string  // Required: ID of the message to check
);

Conversations

Get Transcript

const transcript = await zookish.conversations.getTranscript(conversationId);

Endpoint: /api/v1/conversations/{conversationId}/transcript

Get Recording URL

const recordingUrl = await zookish.conversations.getRecordingUrl(conversationId);

Endpoint: /api/v1/conversations/{conversationId}/recording-url

Default Values

When creating an orb with minimal configuration, the following default values are used:

{
  gradient: ["#141414", "#2D2D2D"],
  voiceId: "8d8ce8c9-44a4-46c4-b10f-9a927b99a853",
  voiceProvider: "cartesia",
  externalVoiceId: "",
  widget: {
    containerType: "pill",
    buttonText: "Hello",
    buttonBackgroundColor: "#141414",
    buttonTextColor: "#ffffff",
    buttonSize: "small",
    startPage: "profilePageAllServices",
    position: "bottomRight",
    embedType: "slideIn",
    isExpandable: true,
    startExpanded: false,
    isDraggable: true,
    startOnLoad: false,
    mobileStyles: {
      buttonSize: "small",
      position: "bottomRight"
    },
    transcript: {
      containerColor: "#ffffff",
      type: "expandedCard",
      showTimestamps: true,
      fontStyle: "default"
    }
  },
  language: "en",
  speed: 1,
  enableBackgroundNoises: false,
  allowInterruptions: true,
  interruptionSensitivity: 0.3,
  firstMessage: "Hey",
  userAwayTimeout: 14
}

You can override any of these values by providing them in the config object.

Type Definitions

Create Orb with Phone Number Result

interface CreateOrbWithPhoneNumberResult {
  orb: OrbData;           // The created orb
  phoneNumber?: PhoneNumber; // The purchased phone number (if available)
  sipTrunk?: SipTrunk;    // The set up SIP trunk (if available)
}

SIP Trunk

interface SipTrunk {
  id: string;
  name: string;
  provider: string;
  providerTrunkId: string;
  address: string;
  username: string;
  password: string;
  outboundProfileId?: string;
  orbId: string;
  active: boolean;
  createdAt: string;
  updatedAt: string;
  phoneNumbers?: PhoneNumber[];
}

Phone Number

interface PhoneNumber {
  id: string;
  number: string;
  provider: string;
  providerId: string;
  active: boolean;
  available: boolean;
  capabilities: string[];
  areaCode?: string;
  location?: string;
  orbId?: string;
  sipTrunkId?: string;
  sipTrunk?: SipTrunk;
  cost?: {
    upfront?: string;
    monthly?: string;
    currency?: string;
  };
  createdAt: string;
  updatedAt: string;
}

Outbound Call Request

interface OutboundCallRequest {
  phone_number: string;
  orb_id: string;
  caller_id?: string;
  sip_trunk_id?: string;
  from_phone_number?: string;
  destination_phone_number?: string;
  instructions?: string;
  greeting?: string;
}

Outbound Call Response

interface OutboundCallResponse {
  callId: string;
  roomName: string;
  status: string;
  message: string;
}

Messaging Profile

interface MessagingProfile {
  id: string;
  name: string;
  enabled: boolean;
  webhook_url: string;
  webhook_failover_url: string;
  webhook_api_version: string;
  whitelisted_destinations: string[];
  mms_fall_back_to_sms: boolean;
  mms_transcoding: boolean;
  createdAt: string;
  updatedAt: string;
}

SMS Message

interface SmsMessage {
  id: string;
  from: string;
  to: string;
  text: string;
  status: string;
  messagingProfileId: string;
  createdAt: string;
  updatedAt: string;
  sentAt: string;
  deliveredAt?: string;
  metadata?: Record<string, any>;
}

Message Log

interface MessageLog {
  id: string;
  messageId: string;
  from: string;
  to: string;
  body: string;
  direction: 'inbound' | 'outbound';
  status: string;
  phoneNumberId: string;
  identityId: string;
  orbId: string;
  createdAt: string;
  updatedAt: string;
  sentAt?: string;
  deliveredAt?: string;
  metadata?: Record<string, any>;
}

Webhook Event

interface WebhookEvent {
  messageId: string;
  from: string;
  to: string;
  text: string;
  status: string;
  direction: 'inbound' | 'outbound';
  timestamp: string;
  metadata?: Record<string, any>;
}

## Browser Compatibility

This SDK is designed to work in both Node.js and browser environments. It automatically uses the appropriate implementation based on your environment:

- In Node.js, it uses `node-fetch` for making HTTP requests
- In browsers, it uses the native `fetch` API

No additional configuration is needed - the package will detect the environment and use the appropriate implementation.

## License

MIT