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

@surajrasaili/shipengine

v1.0.1

Published

A TypeScript-first Node.js client for the ShipEngine API with full type safety.

Downloads

4

Readme

ShipEngine SDK for Node.js

A type-safe, production-ready Node.js SDK for the ShipEngine API with a Stripe-like developer experience.

Features

  • 🔒 Fully Type-Safe - Built with TypeScript, all requests and responses are strictly typed
  • 🎯 Stripe-like DX - Intuitive resource-based API (shipengine.shipments.create())
  • 🔄 Automatic Retries - Exponential backoff for rate limits (429) and server errors (5xx)
  • 🔑 Idempotency Support - Prevent duplicate operations with idempotency keys
  • Modern JavaScript - Uses native fetch, no external HTTP dependencies
  • 📝 JSDoc Comments - Full IntelliSense support in VS Code

Installation

npm install @surajrasaili/shipengine

Quick Start

import { ShipEngine } from '@surajrasaili/shipengine';

const shipengine = new ShipEngine('your-api-key');

// Validate an address
const validated = await shipengine.addresses.validate([
  {
    name: 'John Doe',
    address_line1: '123 Main St',
    city_locality: 'Austin',
    state_province: 'TX',
    postal_code: '78701',
    country_code: 'US',
  },
]);

// Get shipping rates
const rates = await shipengine.rates.estimate({
  carrier_ids: ['se-123456'],
  from_postal_code: '78702',
  from_country_code: 'US',
  to_postal_code: '78701',
  to_country_code: 'US',
  weight: { value: 1, unit: 'pound' },
});

// Create a shipping label
const label = await shipengine.labels.create({
  shipment: {
    carrier_id: 'se-123456',
    service_code: 'usps_priority_mail',
    ship_to: {
      name: 'John Doe',
      address_line1: '123 Main St',
      city_locality: 'Austin',
      state_province: 'TX',
      postal_code: '78701',
      country_code: 'US',
    },
    ship_from: {
      name: 'Warehouse',
      address_line1: '456 Warehouse Ave',
      city_locality: 'Austin',
      state_province: 'TX',
      postal_code: '78702',
      country_code: 'US',
    },
    packages: [{ weight: { value: 1, unit: 'pound' } }],
  },
});

console.log(`Label created: ${label.label_id}`);
console.log(`Tracking: ${label.tracking_number}`);

Configuration

const shipengine = new ShipEngine('your-api-key', {
  baseUrl: 'https://api.shipengine.com', // API base URL (default)
  timeout: 30000,                         // Request timeout in ms (default: 30000)
  maxRetries: 3,                          // Max retry attempts (default: 3)
  retryDelay: 500,                        // Initial retry delay in ms (default: 500)
});

Available Resources

| Resource | Description | |----------|-------------| | account | Account settings and images | | addresses | Address validation and parsing | | batches | Bulk label operations | | carriers | Carrier management and connections | | documents | Combined label documents | | insurance | Shipsurance account management | | labels | Shipping label creation and management | | manifests | End-of-day manifests | | packages | Custom package types | | pickups | Carrier pickup scheduling | | rates | Shipping rate calculation | | servicePoints | PUDO locations | | shipments | Shipment management | | tags | Shipment tagging | | tracking | Package tracking | | warehouses | Warehouse/origin management | | webhooks | Event webhooks |

API Reference

Addresses

// Validate addresses
const results = await shipengine.addresses.validate([
  { name: 'John Doe', address_line1: '123 Main St', ... }
]);

// Parse address from text
const parsed = await shipengine.addresses.parse({
  text: 'Ship to John Doe at 123 Main St, Austin TX 78701',
});

Shipments

// List shipments
const shipments = await shipengine.shipments.list({
  page: 1,
  page_size: 25,
  shipment_status: 'pending',
});

// Create shipments
const created = await shipengine.shipments.create({
  shipments: [{ ... }],
});

// Get shipment by ID
const shipment = await shipengine.shipments.get('se-123456');

// Update shipment
await shipengine.shipments.update('se-123456', { ... });

// Cancel shipment
await shipengine.shipments.cancel('se-123456');

// Get shipment rates
const rates = await shipengine.shipments.listRates('se-123456');

// Add/remove tags
await shipengine.shipments.addTag('se-123456', 'priority');
await shipengine.shipments.removeTag('se-123456', 'priority');

Labels

// List labels
const labels = await shipengine.labels.list({
  label_status: 'completed',
  carrier_id: 'se-123456',
});

// Create label
const label = await shipengine.labels.create({
  shipment: { ... },
});

// Create label from rate
const label = await shipengine.labels.createFromRate('se-rate-123', {
  validate_address: 'validate_and_clean',
});

// Create label from shipment
const label = await shipengine.labels.createFromShipment('se-ship-123', {});

// Create return label
const returnLabel = await shipengine.labels.createReturnLabel('se-label-123', {});

// Void label
const voidResult = await shipengine.labels.void('se-label-123');

// Get tracking for label
const tracking = await shipengine.labels.getTracking('se-label-123');

Rates

// Calculate rates
const rates = await shipengine.rates.calculate({
  shipment: { ... },
  rate_options: { carrier_ids: ['se-123'] },
});

// Estimate rates (simplified)
const estimates = await shipengine.rates.estimate({
  carrier_ids: ['se-123'],
  from_postal_code: '78702',
  to_postal_code: '78701',
  from_country_code: 'US',
  to_country_code: 'US',
  weight: { value: 1, unit: 'pound' },
});

// Bulk rate comparison
const bulk = await shipengine.rates.compareBulk({
  shipments: [...],
  rate_options: {},
});

// Get rate by ID
const rate = await shipengine.rates.get('se-rate-123');

Carriers

// List carriers
const carriers = await shipengine.carriers.list();

// Get carrier by ID
const carrier = await shipengine.carriers.get('se-carrier-123');

// Get carrier services
const services = await shipengine.carriers.listServices('se-carrier-123');

// Get carrier package types
const packages = await shipengine.carriers.listPackageTypes('se-carrier-123');

// Add funds to carrier
const balance = await shipengine.carriers.addFunds('se-carrier-123', {
  amount: 100,
  currency: 'usd',
});

// Connect a carrier
const connected = await shipengine.carriers.connect('ups', {
  nickname: 'My UPS Account',
  account_number: '123456',
  ...
});

Tracking

// Get tracking info
const tracking = await shipengine.tracking.get({
  carrier_code: 'ups',
  tracking_number: '1Z999AA10123456784',
});

// Subscribe to tracking updates
await shipengine.tracking.startTracking({
  carrier_code: 'ups',
  tracking_number: '1Z999AA10123456784',
});

// Unsubscribe from tracking
await shipengine.tracking.stopTracking({
  carrier_code: 'ups',
  tracking_number: '1Z999AA10123456784',
});

Warehouses

// List warehouses
const warehouses = await shipengine.warehouses.list();

// Create warehouse
const warehouse = await shipengine.warehouses.create({
  name: 'East Coast Warehouse',
  origin_address: { ... },
});

// Update warehouse
await shipengine.warehouses.update('se-wh-123', { name: 'Updated Name' });

// Delete warehouse
await shipengine.warehouses.delete('se-wh-123');

Webhooks

// List webhooks
const webhooks = await shipengine.webhooks.list();

// Create webhook
const webhook = await shipengine.webhooks.create({
  url: 'https://example.com/webhook',
  event: 'track',
});

// Update webhook
await shipengine.webhooks.update('se-wh-123', {
  url: 'https://example.com/new-webhook',
});

// Delete webhook
await shipengine.webhooks.delete('se-wh-123');

Idempotency

For POST/PUT requests, you can pass an idempotency key to prevent duplicate operations:

const label = await shipengine.labels.create(
  { shipment: { ... } },
  { idempotencyKey: 'order-12345-label' }
);

Error Handling

The SDK provides typed error classes for different error scenarios:

import {
  ShipEngineError,
  ShipEngineApiError,
  ShipEngineAuthenticationError,
  ShipEngineInvalidRequestError,
  ShipEngineRateLimitError,
} from '@surajrasaili/shipengine';

try {
  await shipengine.labels.create({ ... });
} catch (error) {
  if (error instanceof ShipEngineAuthenticationError) {
    // 401 - Invalid API key
    console.error('Authentication failed:', error.message);
  } else if (error instanceof ShipEngineInvalidRequestError) {
    // 400/422 - Validation error
    console.error('Invalid request:', error.message);
    console.error('Field:', error.fieldName);
  } else if (error instanceof ShipEngineRateLimitError) {
    // 429 - Rate limited (auto-retried by default)
    console.error('Rate limited, retry after:', error.retryAfter);
  } else if (error instanceof ShipEngineApiError) {
    // Other API errors
    console.error('API error:', error.statusCode, error.message);
    console.error('Request ID:', error.requestId);
    console.error('Errors:', error.errors);
  } else if (error instanceof ShipEngineError) {
    // Network/timeout errors
    console.error('SDK error:', error.message);
  }
}

Automatic Retries

The SDK automatically retries requests that fail due to:

  • 429 Too Many Requests - Uses Retry-After header or exponential backoff
  • 5xx Server Errors - Exponential backoff with jitter

Configure retry behavior:

const shipengine = new ShipEngine('your-api-key', {
  maxRetries: 5,    // Max retry attempts (default: 3)
  retryDelay: 1000, // Initial delay in ms (default: 500)
});

Set maxRetries: 0 to disable retries.

TypeScript Support

All types are exported for use in your application:

import type {
  components,
  operations,
  paths,
} from '@surajrasaili/shipengine';

// Use component schemas
type Address = components['schemas']['address'];
type Shipment = components['schemas']['shipment'];
type Label = components['schemas']['label'];

// Use operation types
type CreateShipmentBody = components['schemas']['create_shipments_request_body'];
type CreateShipmentResponse = components['schemas']['create_shipments_response_body'];

Development

# Install dependencies
npm install

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Type check
npm run build

# Regenerate types from OpenAPI spec
npm run generate:types

License

ISC

Links