> ## 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.

# Kickbox plugin

> Email verification with Kickbox - verify a single address for deliverability, role, free and disposable flags, typo suggestions and a Sendex quality score, and check whether a domain is a known disposable one for free.

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

Create a key in Kickbox under API Keys, then Add. The key is sent in the query string as `apikey`, which is how the verification endpoint documents it.

Things to know before you call:

* **A refused key and a spent balance are both a 403.** A refused key carries `code: "FORBIDDEN"`; a spent balance carries only `message: "Insufficient balance"`, which the plugin reports as `INSUFFICIENT_BALANCE` (`isQuotaError`), not as an auth error. The plugin also throws on any `200` whose body says `"success": false`, so a verification result with every field missing is never returned as an answer.
* **Testing without credits.** A Sandbox key (it starts with `test_`) returns mock results and spends nothing. Addresses such as `rejected-email@example.com`, `low-quality@example.com` or `insufficient-balance@example.com` force each result; anything else comes back `deliverable`.
* **`verify.verify` spends one credit.** It is a write for that reason. `verify.disposable` is free and uses Kickbox's open host, which takes no key.
* **The four results.** `deliverable` means accepted by the SMTP server; `undeliverable` rejected; `risky` accepted but with a quality problem such as an accept-all domain; `unknown` when the server could not be reached. `reason` says which of those applied.
* **Accept-all domains.** `accept_all: true` means the domain accepts every address, so `deliverable` there is weaker evidence than elsewhere. Kickbox usually reports that as `risky`.
* **The Sendex score** runs from 0 (no quality) to 1 (perfect) and is a different measure from the verdict: a `deliverable` address can still score low.
* **No automatic replay of a paid check.** A verification that times out or loses its connection is not retried, because Kickbox may already have charged for it; retry it yourself if you want to. A 429 or a 5xx, which carry no verdict, are retried. The free disposable check is retried on any of these.
* **A refused key is not retried.** Regenerating a key in the dashboard kills the old one, so a 403 usually means it was replaced.
* **The EU host.** An account created at `app.eu.kickbox.com` is served from `api.eu.kickbox.com`, so set the `region` option to `eu` or every verification answers 403 `FORBIDDEN`. A key from one host is refused on the other.
* **The address never reaches a log.** The plugin logs the domain and the verdict rather than the address, because an email is personal data.
* **Webhooks.** The plugin does not receive Kickbox webhooks; none are configured here.

**What you get:**

* 2 typed API operations

## Setup

**1. Install**

```bash npm theme={null}
npm install corsair @corsair-dev/kickbox better-sqlite3
npm install --save-dev @types/better-sqlite3
```

```bash yarn theme={null}
yarn add corsair @corsair-dev/kickbox better-sqlite3
yarn add --dev @types/better-sqlite3
```

```bash pnpm theme={null}
pnpm install corsair @corsair-dev/kickbox better-sqlite3
pnpm install --save-dev @types/better-sqlite3
```

```bash bun theme={null}
bun add corsair @corsair-dev/kickbox better-sqlite3
bun add --dev @types/better-sqlite3
```

**2. Add the plugin**

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

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

With `multiTenancy: true`, 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)
>
> Store the Kickbox API key before the first call: `pnpm corsair setup --plugin=kickbox --tenant=acme api_key=<your-key>` (leave out `--tenant` without `multiTenancy`), or pass it as `key` in the plugin options. With Hub, each tenant enters their own key on the connect page. See [API key auth](https://docs.corsair.dev/concepts/api-key).
>
> ```ts theme={null}
> kickbox()
> ```
>
> 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: 'kickbox',
	tenantId: 'acme',
});
// redirect the user's browser to connectUrl
```

## Example API calls

**Check a disposable domain**

```ts theme={null}
const tenant = corsair.withTenant('acme');
await tenant.kickbox.api.verify.disposable({ address: 'mailinator.com' });
```

**Verify one address**

```ts theme={null}
const tenant = corsair.withTenant('acme');
await tenant.kickbox.api.verify.verify({ email: 'test@example.com' });
```

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

## What's next

> [card] [API reference](https://docs.corsair.dev/plugins/kickbox/api.md)
>
> Every `kickbox.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.