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

> Sell software and digital products as a merchant of record. Read stores, products, orders and subscriptions, issue refunds, record metered usage, create checkout links and discount codes, and manage webhook registrations. Inbound webhook deliveries are not handled by this plugin.

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

Every call goes through `https://api.lemonsqueezy.com` with the key as a Bearer token. The API speaks JSON:API 1.0, so responses carry `data`, `links`, `meta` and `jsonapi`, and a write body is `{ data: { type, id?, attributes, relationships? } }`. Those envelopes are returned as they arrive: `data.attributes` holds the fields. Three operations answer with `meta` and no `data`: `subscriptionItems.usage` returns the period's usage in `meta`, and `orders.generateInvoice` and `subscriptionInvoices.generate` return the link in `meta.urls.download_invoice`.

Lists page with `pageNumber` and `pageSize`, capped at 100 per page, and `meta.page.lastPage` says when to stop. Filters are each operation's own camelCase fields, such as `storeId` or `userEmail`, and the plugin sends them as `filter[store_id]` and so on. A field the operation does not define, such as a snake\_case `store_id`, is dropped before the request, so the list comes back unfiltered rather than failing: use the field names in the API reference.

Money is in cents and its currency is the store's. A refund takes an optional `amount`; omit it to refund in full. A partial refund cannot be undone through the API, which is why `orders.refund` and `subscriptionInvoices.refund` are destructive.

A webhook is registered per store through `webhooks.create` with its own `secret`, and Lemon Squeezy signs each delivery with it. Deliveries are not routed through this plugin; verify them where they arrive.

**What you get:**

* 57 typed API operations

## Setup

**1. Install**

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

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

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

```bash bun theme={null}
bun add corsair @corsair-dev/lemonsqueezy 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 { lemonsqueezy } from '@corsair-dev/lemonsqueezy';

export const corsair = createCorsair({
	plugins: [
		lemonsqueezy(),
	],
	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)
>
> No setup required yet. When you make your first request as a tenant, Corsair prompts for the API key. A call with no saved key throws `AuthMissingError`, which may carry a `connectUrl` to send the tenant to.
>
> ```ts theme={null}
> lemonsqueezy()
> ```
>
> 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: 'lemonsqueezy',
	tenantId: 'acme',
});
// redirect the user's browser to connectUrl
```

## Example API calls

**Read the latest orders**

```ts theme={null}
const tenant = corsair.withTenant('acme');
await tenant.lemonsqueezy.api.orders.list({ pageSize: 10 });
```

**Create a checkout link for a variant**

```ts theme={null}
const tenant = corsair.withTenant('acme');
await tenant.lemonsqueezy.api.checkouts.create({ storeId: 1, variantId: 1 });
```

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

## What's next

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