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

@interxact/sdk

v1.0.6

Published

Official SDK for Interxact Messaging API - Send emails and WhatsApp messages

Readme

@interxact/sdk

Version License TypeScript Node.js

Official TypeScript SDK for Interxact Messaging API

Send emails, WhatsApp messages, and manage contacts and companies programmatically with a clean, type-safe API.

FeaturesInstallationQuick StartDocumentationExamples


Features

  • 📧 Email Messaging - Send transactional emails and template-based emails
  • 💬 WhatsApp Integration - Send text messages and WhatsApp templates
  • 👥 Contact Management - Full CRUD operations for contacts
  • 🏢 Company Management - Full CRUD operations for companies
  • 📋 Template Management - List and use email and WhatsApp templates with variable information
  • 🔒 Type-Safe - Full TypeScript support with comprehensive type definitions
  • 🌐 Universal - Works in both Node.js and browser environments
  • Lightweight - Zero dependencies, uses native fetch API
  • 🛡️ Error Handling - Comprehensive error handling with custom error classes

Installation

npm install @interxact/sdk
yarn add @interxact/sdk
pnpm add @interxact/sdk

Quick Start

import { InterxactClient } from '@interxact/sdk';

// Initialize the client
const client = new InterxactClient(process.env.INTERXACT_API_KEY!);

// Send an email
await client.sendMessage.email({
  to: '[email protected]',
  from: '[email protected]',
  subject: 'Hello World',
  body: 'This is a test email',
});

// Send a WhatsApp message
await client.sendMessage.whatsapp({
  to: '+1234567890',
  message: 'Hello from Interxact!',
});

// List contacts
const contacts = await client.contact.list({ limit: 10 });

// List templates
const templates = await client.listTemplates('all');

Authentication

You need an API key to use this SDK. Get your API key from the Interxact Dashboard.

API keys are in the format: clientId:secret

Using Environment Variables (Recommended)

Store your API key securely in an environment variable:

# .env file
INTERXACT_API_KEY=ix_abc123:your-secret-key
import { InterxactClient } from '@interxact/sdk';

const apiKey = process.env.INTERXACT_API_KEY;
if (!apiKey) {
  throw new Error('INTERXACT_API_KEY environment variable is required');
}

const client = new InterxactClient(apiKey);

Direct API Key

You can also pass the API key directly (not recommended for production):

const client = new InterxactClient('ix_abc123:your-secret-key');

⚠️ Security Note: Never commit API keys to version control. Always use environment variables or secure secret management systems.

API Reference

📧 Messaging

Send Transactional Email

Send a plain text or HTML email with optional attachments.

await client.sendMessage.email({
  to: '[email protected]',
  from: '[email protected]',
  subject: 'Email Subject',
  body: 'Plain text body',
  html: '<h1>HTML body</h1>', // Optional
  fromName: 'Sender Name', // Optional
  replyTo: '[email protected]', // Optional
  contactId: 'contact-id', // Optional, link to contact
  files: [ // Optional attachments
    {
      buffer: 'base64-encoded-file-content',
      originalname: 'document.pdf',
      mimetype: 'application/pdf',
      size: 1024,
    },
  ],
});

Required Fields:

  • to - Recipient email address
  • from - Sender email address (must be verified)
  • subject - Email subject line
  • body OR html - Email content (at least one required)

Optional Fields:

  • fromName - Sender display name
  • replyTo - Reply-to email address
  • contactId - Contact ID to link this email
  • files - Array of file attachments (base64 encoded)

Send Email Using Template

Send an email using a pre-configured template with variable substitution.

await client.sendMessage.emailTemplate({
  templateId: 'template-id',
  to: '[email protected]', // OR use contactId
  from: '[email protected]',
  variables: {
    firstName: 'John',
    lastName: 'Doe',
    company: 'Acme Corp',
  },
  fromName: 'Sender Name', // Optional
  replyTo: '[email protected]', // Optional
  subject: 'Custom Subject', // Optional, overrides template subject
});

Required Fields:

  • templateId - Template ID to use
  • from - Sender email address
  • to OR contactId - Recipient (use one, not both)

Optional Fields:

  • variables - Object with template variables for personalization
  • fromName - Sender display name
  • replyTo - Reply-to email address
  • subject - Override template subject

💬 WhatsApp

Send WhatsApp Message

Send a text or media WhatsApp message.

await client.sendMessage.whatsapp({
  to: '+1234567890', // Phone number with country code
  message: 'Hello from Interxact!',
  type: 'text', // Optional, default: 'text'
  conversationId: 'conversation-id', // Optional
  file: { // Optional file attachment
    buffer: 'base64-encoded-file',
    originalname: 'image.jpg',
    mimetype: 'image/jpeg',
    size: 1024,
  },
});

Required Fields:

  • to - Recipient phone number (with country code, e.g., '+1234567890')
  • message - Message text (required for text messages)

Optional Fields:

  • type - Message type ('text' | 'image' | 'video' | 'audio' | 'document')
  • mediaData - Media data for non-text messages
  • conversationId - Conversation ID to link this message
  • file - File attachment

Send WhatsApp Template

Send a WhatsApp message using an approved template.

await client.sendMessage.whatsappTemplate({
  to: '+1234567890',
  templateName: 'welcome_template',
  language: 'en_US', // Optional, default: 'en_US'
  variables: {
    '1': 'John',
    '2': 'Acme Corp',
  },
  components: [ // Optional template components
    {
      type: 'header',
      parameters: [
        { type: 'text', text: 'Welcome' },
      ],
    },
    {
      type: 'body',
      parameters: [
        { type: 'text', text: 'John' },
      ],
    },
  ],
  mediaIds: { // Optional media IDs
    header: 'media-id-123',
  },
});

Required Fields:

  • to - Recipient phone number (with country code)
  • templateName - Name of approved template

Optional Fields:

  • language - Template language code (default: 'en_US')
  • variables - Variables for template personalization
  • components - Template components (header, body, buttons)
  • mediaIds - Media IDs for template media

👥 Contact Management

List Contacts

Get a paginated list of contacts with optional filters.

// Get all contacts (default limit: 10)
const result = await client.contact.list();

// Get contacts with filters
const filteredContacts = await client.contact.list({
  limit: 20,
  search: 'john',
  tags: 'vip,customer',
  status: 'active',
  sort: 'asc',
  cursor: 'next-page-cursor', // For pagination
});

Response:

{
  contacts: [
    {
      _id: 'contact-id',
      email: ['[email protected]'],
      firstName: 'John',
      lastName: 'Doe',
      phone: ['+1234567890'],
      company: 'Acme Inc',
      companyRef: '507f1f77bcf86cd799439011',
      tags: ['customer', 'vip'],
      // ... other fields
    },
  ],
  hasMore: true,
  nextCursor: 'cursor-string',
  totalCount: 100,
}

Filter Options:

  • listId - Filter by list ID
  • limit - Maximum number of contacts (default: 10)
  • sort - Sort order: 'asc' or 'desc' (default: 'desc')
  • search - Search query for firstName, lastName, email, or phone
  • tags - Filter by tags (comma-separated)
  • status - Filter by status
  • company - Filter by company name
  • cursor - Cursor for pagination

Get Contact by ID

Retrieve a specific contact by its ID.

const contact = await client.contact.get('contact-id');

Create Contact

Create a new contact with all relevant information.

const newContact = await client.contact.create({
  email: '[email protected]',
  firstName: 'John',
  lastName: 'Doe',
  phone: '+1234567890',
  company: 'Acme Inc',
  companyRef: '507f1f77bcf86cd799439011', // Company ID to link contact to a Company record
  position: 'Software Engineer',
  tags: ['customer', 'vip'],
  notes: 'Important customer',
  country: 'US',
  website: 'https://example.com',
  subscribedToEmail: true,
  subscribedToWhatsApp: true,
  subscribedToSMS: false,
  customFields: {
    customField1: 'value1',
  },
});

Required Fields:

  • email OR phone - At least one is required

Optional Fields:

  • email - Contact email(s) - can be string or array
  • firstName - First name
  • lastName - Last name
  • phone - Phone number(s) - can be string or array
  • company - Company name (string)
  • companyRef - Company ID reference (links contact to a Company record)
  • position - Job position
  • tags - Array of tags
  • notes - Notes to add to the contact
  • country - Country code
  • website - Website URL
  • list or listId - List ID or name
  • subscribedToSMS - Subscribe to SMS (default: false)
  • subscribedToEmail - Subscribe to email (default: false)
  • subscribedToWhatsApp - Subscribe to WhatsApp (default: false)
  • customFields - Custom fields object

Update Contact

Update an existing contact's information.

const updatedContact = await client.contact.update('contact-id', {
  firstName: 'Jane',
  lastName: 'Smith',
  company: 'New Company',
  companyRef: '507f1f77bcf86cd799439011', // Link to a Company record
  tags: ['updated-tag', 'customer'],
});

Delete Contact

Delete a contact by ID.

const result = await client.contact.delete('contact-id');
// { success: true, deletedCount: 1 }

Bulk Delete Contacts

Delete multiple contacts at once.

const result = await client.contact.bulkDelete({
  contactIds: ['id1', 'id2', 'id3'],
});
// { success: true, deletedCount: 3 }

🏢 Company Management

List Companies

Get a paginated list of companies with optional filters.

// Get all companies (default limit: 50)
const result = await client.company.list();

// Get companies with filters
const filteredCompanies = await client.company.list({
  limit: 20,
  search: 'acme',
  industry: 'Technology',
  size: '50-100',
  sort: 'asc',
  cursor: 'next-page-cursor', // For pagination
});

Response:

{
  companies: [
    {
      _id: 'company-id',
      name: 'Acme Inc',
      domain: 'acme.com',
      industry: 'Technology',
      size: '50-100',
      website: 'https://acme.com',
      tags: ['enterprise', 'saas'],
      contactsCount: 25,
      dealsTotalValue: 50000,
      // ... other fields
    },
  ],
  hasMore: true,
  nextCursor: 'cursor-string',
  totalCount: 100,
}

Filter Options:

  • limit - Maximum number of companies (default: 50)
  • sort - Sort order: 'asc' or 'desc' (default: 'desc')
  • search - Search query for name or domain
  • industry - Filter by industry
  • size - Filter by company size
  • cursor - Cursor for pagination

Get Company by ID

Retrieve a specific company by its ID.

const company = await client.company.get('company-id');

Create Company

Create a new company with all relevant information.

const newCompany = await client.company.create({
  name: 'Acme Inc', // Required
  domain: 'acme.com',
  industry: 'Technology',
  size: '50-100',
  website: 'https://acme.com',
  address: '123 Main St',
  description: 'Leading technology company',
  tags: ['enterprise', 'saas'],
  linkedinUrl: 'https://linkedin.com/company/acme',
  twitterUrl: 'https://twitter.com/acme',
  techStack: ['React', 'Node.js'],
  revenue: '$10M',
  foundedYear: 2020,
  customFields: {
    customField1: 'value1',
  },
});

Required Fields:

  • name - Company name

Optional Fields:

  • domain - Company domain
  • industry - Industry
  • size - Company size
  • website - Website URL
  • address - Address
  • description - Description
  • tags - Array of tags
  • logoUrl - Logo URL
  • linkedinUrl - LinkedIn URL
  • twitterUrl - Twitter URL
  • facebookUrl - Facebook URL
  • techStack - Tech stack array
  • fundingInfo - Funding information
  • revenue - Revenue
  • foundedYear - Founded year
  • headquarters - Headquarters location
  • keyPeople - Array of key people
  • recentNews - Array of recent news
  • competitors - Array of competitors
  • customFields - Custom fields object

Update Company

Update an existing company's information.

const updatedCompany = await client.company.update('company-id', {
  name: 'New Company Name',
  industry: 'New Industry',
  size: '100-500',
  tags: ['updated-tag', 'enterprise'],
});

Delete Company

Delete a company by ID.

const result = await client.company.delete('company-id');
// { success: true, deletedCount: 1 }

📋 Templates

List Available Templates

Get a list of available email and WhatsApp templates.

// Get all templates
const templates = await client.listTemplates('all');

// Get only email templates
const emailTemplates = await client.listTemplates('email');

// Get only WhatsApp templates
const whatsappTemplates = await client.listTemplates('whatsapp');

Response:

{
  email: [
    {
      id: 'template-id',
      name: 'Welcome Email',
      subject: 'Welcome to our platform',
      sampleData: { firstName: 'John', company: 'Acme' },
      variables: ['firstName', 'company'],
    },
  ],
  whatsapp: [
    {
      name: 'welcome_template',
      language: 'en_US',
      category: 'UTILITY',
      components: [
        {
          type: 'BODY',
          text: 'Hello {{1}}, welcome to {{2}}!',
        },
      ],
      sampleData: { '1': 'John', '2': 'Acme' },
      variables: ['1', '2'],
    },
  ],
}

Template Fields:

  • variables - Array of variable keys/numbers found in the template
  • components - Full component structure (WhatsApp templates only)
  • sampleData - Example data showing available variables

Configuration

Custom Base URL

For development or testing, you can use a custom base URL:

const client = new InterxactClient('clientId:secret', {
  baseURL: 'http://localhost:3000/api/v1/public',
});

Request Timeout

Set a custom timeout for requests (default: 30000ms):

const client = new InterxactClient('clientId:secret', {
  timeout: 60000, // 60 seconds
});

Error Handling

The SDK throws custom error classes for different error scenarios:

import {
  InterxactError,
  AuthenticationError,
  PermissionError,
  ValidationError,
  RateLimitError,
  ServerError,
  NetworkError,
} from '@interxact/sdk';

try {
  await client.sendMessage.email({ /* ... */ });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key:', error.message);
  } else if (error instanceof PermissionError) {
    console.error('Insufficient permissions:', error.message);
  } else if (error instanceof ValidationError) {
    console.error('Invalid request:', error.message);
  } else if (error instanceof RateLimitError) {
    console.error('Rate limit exceeded:', error.message);
  } else if (error instanceof NetworkError) {
    console.error('Network error:', error.message);
  } else if (error instanceof ServerError) {
    console.error('Server error:', error.message);
  } else {
    console.error('Unknown error:', error);
  }
}

Error Types

| Error Class | Status Code | Description | |------------|------------|-------------| | AuthenticationError | 401 | Invalid, expired, or revoked API key | | PermissionError | 403 | API key doesn't have required permissions | | ValidationError | 400 | Invalid request parameters | | RateLimitError | 429 | API rate limit exceeded | | ServerError | 500+ | Server-side error | | NetworkError | - | Network request failed or timed out |

TypeScript Support

The SDK is written in TypeScript and provides full type definitions:

import {
  InterxactClient,
  SendEmailOptions,
  SendWhatsAppOptions,
  CreateContactOptions,
  Contact,
} from '@interxact/sdk';

const emailOptions: SendEmailOptions = {
  to: '[email protected]',
  from: '[email protected]',
  subject: 'Test',
  body: 'Test email',
};

await client.sendMessage.email(emailOptions);

Browser & Node.js Compatibility

The SDK works in both browser and Node.js environments:

  • Node.js: Requires Node.js 18+ (uses native fetch)
  • Browser: Works in all modern browsers

Note: For older Node.js versions (< 18), you may need a fetch polyfill like node-fetch.

Examples

Complete Example: Send Email with Attachment

import { InterxactClient } from '@interxact/sdk';

const client = new InterxactClient(process.env.INTERXACT_API_KEY!);

// In browser
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const reader = new FileReader();

reader.onload = async () => {
  const base64 = reader.result as string;
  const base64Content = base64.split(',')[1]; // Remove data URL prefix

  await client.sendMessage.email({
    to: '[email protected]',
    from: '[email protected]',
    subject: 'Email with attachment',
    body: 'Please find attached.',
    files: [
      {
        buffer: base64Content,
        originalname: file.name,
        mimetype: file.type,
        size: file.size,
      },
    ],
  });
};

reader.readAsDataURL(file);

Complete Example: Send Personalized Email Template

await client.sendMessage.emailTemplate({
  templateId: 'welcome-email-template',
  to: '[email protected]',
  from: '[email protected]',
  variables: {
    firstName: 'John',
    lastName: 'Doe',
    company: 'Acme Corp',
  },
});

Complete Example: Send WhatsApp Template

await client.sendMessage.whatsappTemplate({
  to: '+1234567890',
  templateName: 'order_confirmation',
  language: 'en_US',
  variables: {
    '1': 'ORD-12345',
    '2': '$99.99',
  },
});

Complete Example: Contact Management Workflow

// Create a contact
const contact = await client.contact.create({
  email: '[email protected]',
  firstName: 'John',
  lastName: 'Doe',
  phone: '+1234567890',
  company: 'Acme Inc',
  companyRef: '507f1f77bcf86cd799439011',
  tags: ['customer'],
  subscribedToEmail: true,
});

// Update the contact
const updated = await client.contact.update(contact._id, {
  tags: ['customer', 'vip'],
  company: 'New Company',
  companyRef: '507f1f77bcf86cd799439012',
});

// List contacts with filters
const contacts = await client.contact.list({
  search: 'john',
  tags: 'vip',
  limit: 20,
});

// Delete contact
await client.contact.delete(contact._id);

Complete Example: Company Management Workflow

// Create a company
const company = await client.company.create({
  name: 'Acme Inc',
  domain: 'acme.com',
  industry: 'Technology',
  size: '50-100',
  website: 'https://acme.com',
  tags: ['enterprise', 'saas'],
  linkedinUrl: 'https://linkedin.com/company/acme',
});

// Update the company
const updated = await client.company.update(company._id, {
  size: '100-500',
  tags: ['enterprise', 'saas', 'unicorn'],
  revenue: '$50M',
});

// List companies with filters
const companies = await client.company.list({
  search: 'acme',
  industry: 'Technology',
  limit: 20,
});

// Get company by ID
const companyDetails = await client.company.get(company._id);

// Delete company
await client.company.delete(company._id);

API Permissions

Your API key must have the appropriate permissions to use different SDK features:

Messaging:

  • message.send - Required for sending emails and WhatsApp messages

Contacts:

  • contact.read - Required for listing and reading contacts
  • contact.create - Required for creating contacts
  • contact.update - Required for updating contacts
  • contact.delete - Required for deleting contacts

Companies:

  • company.read - Required for listing and reading companies
  • company.create - Required for creating companies
  • company.update - Required for updating companies
  • company.delete - Required for deleting companies

You can manage API keys and permissions in the Interxact Dashboard.

Rate Limiting

The API has rate limits per API key. If you exceed the limit, a RateLimitError will be thrown. Check the error response for retry information.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

Changelog

[1.0.3] - 2026-02-11

Added

  • 🏢 Company Management API - Full CRUD operations for companies
    • client.company.list() - List companies with filters (search, industry, size, pagination)
    • client.company.get(id) - Get company by ID
    • client.company.create(options) - Create a new company
    • client.company.update(id, options) - Update an existing company
    • client.company.delete(id) - Delete a company
  • 📋 Enhanced Template API - Templates now include variable information
    • Templates return variables array showing available template variables
    • WhatsApp templates include components structure
    • Email templates include sampleData for variable examples
  • 🔍 Source Tracking - All API calls are tagged with source (sdk vs api)
    • Requests from SDK automatically include X-Interxact-Source: sdk header
    • Source is visible in developer logs and webhook events
  • 👥 Contact Company Linking - Contacts can now be linked to companies via companyRef
    • companyRef field added to contact create and update operations
    • Links contacts to Company records for better relationship management

Changed

  • client.listTemplates() moved from client.sendMessage.listTemplates() to direct client method
  • Template responses now include variables, components, and sampleData fields

[1.0.1] - 2026-02-11

Added

  • 👥 Contact Management API - Full CRUD operations for contacts
    • client.contact.list() - List contacts with filters
    • client.contact.get(id) - Get contact by ID
    • client.contact.create(options) - Create a new contact
    • client.contact.update(id, options) - Update an existing contact
    • client.contact.delete(id) - Delete a contact
    • client.contact.bulkDelete(options) - Bulk delete contacts
  • 📋 Template Listing API
    • client.listTemplates(channel) - List available email and WhatsApp templates
    • Supports filtering by channel: 'email', 'whatsapp', or 'all'

[1.0.0] - 2026-02-11

Added

  • 🎉 Initial Release
  • 📧 Email Messaging
    • client.sendMessage.email() - Send transactional emails
    • client.sendMessage.emailTemplate() - Send emails using templates
  • 💬 WhatsApp Messaging
    • client.sendMessage.whatsapp() - Send WhatsApp messages
    • client.sendMessage.whatsappTemplate() - Send WhatsApp templates
  • 🔒 Authentication - API key authentication with clientId:secret format
  • 🛡️ Error Handling - Custom error classes for different error scenarios
  • 📝 TypeScript Support - Full type definitions for all API methods
  • ⚙️ Configuration - Customizable base URL and request timeout

Legend:

  • 🎉 Major features
  • ✨ New features
  • 🐛 Bug fixes
  • 🔧 Improvements
  • 📝 Documentation
  • 🔒 Security

License

MIT License - see LICENSE file for details.


Made with ❤️ by the Interxact team

WebsiteDashboardDocumentation