npm package: @sendsend.io/node
Description: TypeScript SDK for the SendSend delivery API
Latest version: 0.1.1

# SendSend Node.js SDK

[![npm version](https://img.shields.io/npm/v/@sendsend.io/node.svg)](https://www.npmjs.com/package/@sendsend.io/node)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@sendsend.io/node)](https://bundlephobia.com/package/@sendsend.io/node)

The official Node.js / TypeScript SDK for the [SendSend](https://sendsend.io) delivery API.

## Install

```bash
npm install @sendsend.io/node
```

## Setup

```ts
import { SendSend } from "@sendsend.io/node";

const sendsend = new SendSend({ apiKey: "ss_live_..." });
```

## Usage

### Send a webhook

```ts
const { jobId } = await sendsend.webhooks.send({
  configId: "cfg_abc123",
  items: [
    { id: "evt_1", payload: { userId: "u_42", event: "signup" } },
    { id: "evt_2", payload: { userId: "u_43", event: "purchase" } },
  ],
});

console.log(jobId); // "job_k7x..."
```

### Send an email

```ts
const { jobId } = await sendsend.email.send({
  configId: "cfg_email",
  from: "hello@yourapp.com",
  subject: "Welcome!",
  html: "<h1>Hi {{name}}</h1>",
  recipients: [
    { to: "alice@example.com", variables: { name: "Alice" } },
    { to: "bob@example.com", variables: { name: "Bob" } },
  ],
});
```

### Send an email with a template

```ts
await sendsend.email.send({
  configId: "cfg_email",
  templateId: "tmpl_welcome",
  recipients: [{ to: "alice@example.com", variables: { name: "Alice" } }],
  attachments: [
    {
      filename: "invoice.pdf",
      content: base64String,
      contentType: "application/pdf",
    },
  ],
});
```

### Check job status

```ts
const job = await sendsend.jobs.get("job_k7x...");

console.log(job.status); // "completed"
console.log(job.processedItems); // 2
console.log(job.failedItems); // 0
```

### Check bulk send status

```ts
const bulk = await sendsend.bulkSends.get("bulk_abc...");

console.log(bulk.status); // "completed"
console.log(bulk.totalItems); // 10000
console.log(bulk.jobs); // individual job breakdowns
```

### Manage configs

```ts
// List all configs
const configs = await sendsend.configs.list();

// Create a webhook config
const config = await sendsend.configs.create({
  name: "My Webhook",
  channel: "webhook",
  credentials: {
    authType: "bearer",
    apiKey: "your-endpoint-token",
  },
  settings: {
    webhookUrl: "https://api.yourapp.com/webhook",
    retryAttempts: 3,
    timeoutMs: 5000,
  },
  rateLimit: { burst: 50, rate: 100, periodSeconds: 60 },
});

// Update a config
await sendsend.configs.update(config.id, {
  settings: { retryAttempts: 5 },
});

// Delete a config
await sendsend.configs.delete(config.id);
```

## Error handling

All API errors throw a `SendSendError` with the HTTP status and response body.

```ts
import { SendSendError } from "@sendsend.io/node";

try {
  await sendsend.webhooks.send({ configId: "bad", items: [] });
} catch (err) {
  if (err instanceof SendSendError) {
    console.log(err.status); // 400, 401, 404, 429, etc.
    console.log(err.message);

    if (err.isAuthError) {
      // 401 — invalid or expired API key
    }
    if (err.isRateLimitError) {
      // 429 — slow down
    }
    if (err.isValidationError) {
      // 400 — bad request params
    }
  }
}
```

Timeout and connection errors throw `SendSendTimeoutError` and `SendSendConnectionError` respectively.

## Configuration

```ts
const sendsend = new SendSend({
  apiKey: "ss_live_...",
  baseUrl: "https://api.sendsend.dev", // default
  timeout: 30_000, // 30s default
  maxRetries: 2, // default, with exponential backoff
});
```

**Retries**: Server errors (5xx) and timeouts are retried automatically with exponential backoff (up to 8s between attempts). Client errors (4xx) are never retried.

## Requirements

- Node.js 18+ (uses native `fetch`)
- TypeScript 5.0+ (optional)

## License

MIT