> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corsair.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Manage eSputnik contacts and segments, send events and orders, edit and send email, SMS, Viber, push and Telegram messages, and run broadcasts.

Use **eSputnik** through Corsair: one client, typed API calls.

**API key.** Create a key in eSputnik under your profile > Settings > API and give it the access rights the operations you call need. The plugin sends it with HTTP Basic auth as the password. Keys have no expiry date, but eSputnik disables a key that goes unused for 90 days; turn it back on in the same place.

**Things to know:**

* **Rate limits.** Message reads (`getEmail`, `getViberMessage` and the like) allow 500 requests an hour. Contact writes allow 200 a second, and `addContact` rejects the same contact twice within a minute (409). Calls that hit 429 are retried with backoff.
* **Acknowledgements.** Deletes, updates and segment or unsubscribe changes return `undefined`: eSputnik answers them with an empty body or a sentence such as "Email with id='42' has been deleted". A failure throws, and the error message carries eSputnik's explanation when it sends one ("Contact not found").
* **Lists.** List operations always return an array, including when eSputnik sends a single match as a bare object (email template search does) or an empty body.
* **Not set up yet.** `site.getScript` and `site.getWebPushScript` fail until a domain is registered, `productFeeds.getProductFeedsConfiguration` answers 404 until a feed is configured, and `contacts.getGroupContacts` works on static segments only.
* **Contact fields.** Additional fields are `{ id, value }` pairs. List the ids with `contacts.getAdditionalFields`.
* **Activity.** `contacts.contactActivity` has to be enabled by eSputnik support first and keeps 90 days. `contacts.contactMessages` needs a contact identifier and a `dateFrom` less than a year old.
* **Broadcasts.** Broadcast ids are strings. `broadcasts.createBroadcast` sends a prepared message (`messageId`) to segment ids (`groups`).
* **Event tokens.** `account.generateApiToken` returns a bearer token for eSputnik's event endpoints. Treat the result as a secret.
* **No local sync.** Data is read from eSputnik on each call; nothing is stored in the Corsair database.

**What you get:**

* 108 typed API operations

## Setup

**1. Install**

```bash npm theme={null}
npm install corsair @corsair-dev/esputnik
```

```bash yarn theme={null}
yarn add corsair @corsair-dev/esputnik
```

```bash pnpm theme={null}
pnpm install corsair @corsair-dev/esputnik
```

```bash bun theme={null}
bun add corsair @corsair-dev/esputnik
```

**2. Add the plugin**

```ts corsair.ts theme={null}
import Database from 'better-sqlite3';
import { createCorsair } from 'corsair';
import { esputnik } from '@corsair-dev/esputnik';

export const corsair = createCorsair({
	plugins: [
		esputnik(),
	],
	database: new Database('corsair.db'),
	kek: process.env.CORSAIR_KEK!,
	hub: {
		projectApiKey: process.env.CORSAIR_API_KEY!,
		signingSecret: process.env.CORSAIR_SIGNING_SECRET!,
	},
});
```

Multi-tenancy is the default — scope calls with `corsair.withTenant(id)`. See [Quick start](https://docs.corsair.dev/quick-start.md) for KEK + Hub keys, and [Multi-tenancy](https://docs.corsair.dev/concepts/multi-tenancy.md) for account isolation.

**3. Choose authentication**

> [tab] API Key (Recommended)
>
> No setup required yet. When you make your first request as a tenant, Corsair prompts for the API key.
>
> ```ts theme={null}
> esputnik()
> ```
>
> More: [API Key](https://docs.corsair.dev/concepts/api-key)

**4. Connect a tenant**

Mint a connect link and send the tenant to it. Hub hosts the page and delivers the result to your app — see [Connect / OAuth](https://docs.corsair.dev/management/connect).

```ts theme={null}
const { connectUrl } = await corsair.manage.connect.createLink({
	plugin: 'esputnik',
	tenantId: 'acme',
});
// redirect the user's browser to connectUrl
```

## Example API calls

**Find a contact by email**

```ts theme={null}
const tenant = corsair.withTenant('acme');
await tenant.esputnik.api.contacts.searchContacts({ email: 'ada@example.com', maxrows: 10 });
```

**Create or update a contact**

```ts theme={null}
const tenant = corsair.withTenant('acme');
await tenant.esputnik.api.contacts.addContact({
	firstName: 'Ada',
	channels: [{ type: 'email', value: 'ada@example.com' }],
	fields: [{ id: 79814, value: 'gold' }],
});
```

See the full list on the [API](https://docs.corsair.dev/plugins/esputnik/api.md) page.

## What's next

> [card] [API reference](https://docs.corsair.dev/plugins/esputnik/api.md)
>
> Every `esputnik.api.*` operation with input and output types.

> [card] [Connect / OAuth](https://docs.corsair.dev/management/connect)
>
> createLink, Hub delivery, and tenant connect flows.

> [card] [Use with agents](https://docs.corsair.dev/mcp-adapters/mcp-adapters)
>
> Expose this plugin's operations as MCP tools.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.