npm package: @mailjunky/sdk
Description: Official Node.js SDK for MailJunky - AI-powered email automation
Author: MailJunky
Latest version: 0.8.0

# @mailjunky/sdk

Official Node.js SDK for [MailJunky](https://mailjunky.ai) - AI-powered email automation.

## Installation

```bash
npm install @mailjunky/sdk
# or
pnpm add @mailjunky/sdk
# or
yarn add @mailjunky/sdk
```

## Quick Start

```typescript
import { MailJunky } from '@mailjunky/sdk'

const client = new MailJunky({
  apiKey: 'mj_live_your_api_key'
})

// Send an email
await client.emails.send({
  from: 'hello@yourapp.com',
  to: 'user@example.com',
  subject: 'Welcome!',
  html: '<h1>Welcome aboard!</h1>'
})
```

## Features

- **Send Emails** - Transactional and marketing emails
- **Track Events** - User behavior tracking for automated workflows
- **Manage Contacts** - Store and segment your recipients
- **TypeScript** - Full type definitions included

## API Reference

### Emails

```typescript
// Send a single email
await client.emails.send({
  from: 'hello@yourapp.com',
  to: 'user@example.com',
  subject: 'Hello!',
  html: '<p>Hello World</p>',
  text: 'Hello World' // optional plain text fallback
})

// Send to multiple recipients
await client.emails.send({
  from: 'hello@yourapp.com',
  to: ['user1@example.com', 'user2@example.com'],
  cc: 'manager@example.com',
  bcc: ['analytics@yourapp.com'],
  subject: 'Team Update',
  html: '<p>Important announcement...</p>'
})
```

### Events

Track user events to trigger automated email workflows:

```typescript
// Track a custom event
await client.events.track({
  event: 'product_viewed',
  user: 'user@example.com',
  properties: {
    product_id: 'prod_123',
    price: 49.99
  }
})

// Track with session
await client.events.track({
  event: 'cart_added',
  user: 'user@example.com',
  session_id: 'sess_abc123',
  properties: {
    product_id: 'prod_456',
    quantity: 2
  }
})
```

### Contacts

Manage your recipient list:

```typescript
// Create or update a contact
await client.contacts.upsert({
  email: 'user@example.com',
  first_name: 'John',
  last_name: 'Doe',
  properties: {
    company: 'Acme Inc',
    plan: 'pro'
  },
  tags: ['customer', 'newsletter']
})

// Create a contact scoped to a specific domain
await client.contacts.upsert({
  email: 'user@example.com',
  first_name: 'John',
  domain: 'yourapp.com', // Associates contact with this verified domain
  tags: ['customer']
})

// List contacts
const { data, pagination } = await client.contacts.list({
  page: 1,
  limit: 25,
  status: 'active',
  tag: 'customer'
})

// List contacts for a specific domain
const domainContacts = await client.contacts.list({
  domain: 'yourapp.com'
})

// Get a specific contact
const contact = await client.contacts.get('contact_id')

// Update a contact
await client.contacts.update('contact_id', {
  tags: ['customer', 'vip'],
  properties: { plan: 'enterprise' }
})

// Delete a contact
await client.contacts.delete('contact_id')

// Batch upsert contacts (all scoped to same domain)
await client.contacts.batch({
  domain: 'yourapp.com',
  contacts: [
    { email: 'user1@example.com', first_name: 'User', last_name: 'One' },
    { email: 'user2@example.com', first_name: 'User', last_name: 'Two' }
  ]
})

// Batch upsert with per-contact domain overrides
await client.contacts.batch({
  contacts: [
    { email: 'user1@example.com', domain: 'app1.com', first_name: 'User One' },
    { email: 'user2@example.com', domain: 'app2.com', first_name: 'User Two' }
  ]
})
```

> **Domain scoping:** When your team has multiple verified domains, you can scope contacts to specific domains using the `domain` parameter. Pass the domain name (e.g. `'yourapp.com'`) — the server resolves it to the correct domain ID. Contacts without a domain are team-wide.

## Error Handling

```typescript
import { MailJunky, MailJunkyError } from '@mailjunky/sdk'

try {
  await client.emails.send({ /* ... */ })
} catch (error) {
  if (error instanceof Error && 'status' in error) {
    const apiError = error as MailJunkyError
    console.error(`API Error: ${apiError.message}`)
    console.error(`Status: ${apiError.status}`)
    console.error(`Code: ${apiError.code}`)
  }
}
```

## Configuration

```typescript
const client = new MailJunky({
  apiKey: 'mj_live_your_api_key',
  baseUrl: 'https://api.mailjunky.ai' // Optional, for self-hosted
})
```

## License

MIT