Corsair Example Usage: Complete Guide with Code Samples and Integration Patterns

Corsair example usage starts with creating a type-safe instance via createCorsair(), registering plugins for services like Slack or Linear, then calling APIs through a tenant-scoped interface that automatically persists data to your database.

Corsair is an open-source integration platform that unifies third-party service APIs behind a single, strongly-typed interface. According to the corsairdev/corsair source code, every integration follows the same pattern: initialize the core, register plugins, obtain a tenant-scoped instance, and call service-specific methods with full autocomplete and compile-time safety.

Creating Your First Corsair Instance

The foundation of every Corsair integration is the createCorsair() function exported from the core package. This function accepts a configuration object with your database connection, encryption key, and plugin array.

In packages/corsair/README.md, the minimal setup requires four properties:

  • database — Your Prisma database instance for automatic persistence
  • kek — A secret key used for encryption (environment variable recommended)
  • plugins — Array of initialized plugin instances
  • multiTenancy — Boolean enabling tenant-scoped access
import { createCorsair } from 'corsair';
import { slack } from '@corsair-dev/slack';
import { linear } from '@corsair-dev/linear';
import { resend } from '@corsair-dev/resend';
import { database } from './db';

export const corsair = createCorsair({
  database,
  multiTenancy: true,
  kek: process.env.CORSAIR_KEK!,
  plugins: [slack(), linear(), resend()],
});

This example appears in demo/minimal/corsair.ts and demonstrates the standard pattern for combining multiple services in one instance.

Tenant-Scoped API Calls with Corsair

When multi-tenancy is enabled, all data access must go through a tenant-scoped instance. This ensures complete data isolation between customers or organizations.

Obtaining a Tenant Instance

Call withTenant() on your Corsair instance and pass a unique tenant identifier:

const tenant = corsair.withTenant('tenant_123');

As implemented in demo/minimal/corsair.ts (line 16), this returns an object with the same plugin structure but scoped to the specified tenant.

Calling Plugin APIs

Every plugin exposes identical access patterns: tenant.{plugin}.api.{resource}.{action}. TypeScript generates these types from each service's OpenAPI specification, providing full IntelliSense.

// Send a Slack message
const slackMessage = await tenant.slack.api.messages.post({
  channel: 'C01234567',
  text: 'Hello from Corsair! 🚀',
});

// Create a Linear issue
const linearIssue = await tenant.linear.api.issues.create({
  title: 'New feature request',
  teamId: 'TEAM_ABC',
  description: 'This is a great feature idea!',
});

Both snippets originate from demo/minimal/corsair.ts and showcase the unified syntax across different services.

Database Persistence and Queries

Corsair automatically syncs every API response to your configured database. This creates a local, queryable cache with identical type safety to the remote API.

Querying Cached Data

Access the database layer through tenant.{plugin}.db.{resource}.{operation}:

const issues = await tenant.linear.db.issues.list();
issues.forEach(issue => {
  console.log(issue.data.title);
});

This pattern from demo/minimal/corsair.ts (line 40) demonstrates how to work with persisted data without additional API calls. The .data property contains the full object graph as returned by the original API.

Handling Webhooks in Corsair

Webhook processing uses framework-agnostic handler classes that validate signatures and route events. Each plugin provides its own handler with service-specific validation logic.

Slack Webhook Handler Example

The createWebhookHandler function in demo/sdk/unified-sdk/webhooks/slack.ts demonstrates complete webhook handling:

import { createWebhookHandler } from './webhooks/slack';

const handler = createWebhookHandler({ signingSecret: process.env.SLACK_SECRET });

handler.on('message', async event => {
  console.log('New message from', event.user, ':', event.text);
});

// In an Express route:
app.post('/webhook/slack', async (req, res) => {
  const result = await handler.handleWebhook(req.headers, req.body);
  if (result.success && result.challenge) {
    res.send({ challenge: result.challenge });
  } else {
    res.sendStatus(result.success ? 200 : 400);
  }
});

Key features of this implementation:

  • Signature verification using your Slack signing secret
  • Event routing through the .on() method with typed event payloads
  • URL verification handling for Slack's challenge-response protocol

Gmail SDK Integration

The Gmail plugin follows the same initialization pattern with service-specific API methods. From demo/sdk/gmail/README.md:

import { createCorsair, gmail } from 'corsair';
import { database } from './db';

const corsair = createCorsair({
  database,
  plugins: [gmail()],
  kek: process.env.CORSAIR_KEK!,
});

const tenant = corsair.withTenant('myTenant');

// List recent threads
const threads = await tenant.gmail.api.users.threads.list({
  userId: 'me',
});
console.log('Fetched', threads.length, 'threads');

Additional Corsair Example Implementations

The repository maintains working demos for major integrations. Each demonstrates authentication flows, common API operations, and webhook configuration:

Demo Location Service Key Features Demonstrated
demo/sdk/gmail/README.md Gmail OAuth setup, thread listing, message retrieval
demo/sdk/github/README.md GitHub Repository events, pull request webhooks
demo/sdk/hubspot/README.md HubSpot Contact management, property syncing

These files confirm that Corsair example usage patterns remain consistent regardless of service complexity. The same createCorsair → register plugins → withTenant → API call workflow applies to every integration.

Summary

  • Initialize once with createCorsair() and your plugin array—recommend storing in demo/minimal/corsair.ts pattern
  • Scope by tenant using withTenant() when multiTenancy: true for complete data isolation
  • Call APIs uniformly through tenant.{plugin}.api.{resource}.{action} with full TypeScript support
  • Query local cache via tenant.{plugin}.db.{resource} to avoid redundant API calls
  • Handle webhooks with plugin-specific handlers that validate signatures and route events type-safely

Frequently Asked Questions

What database does Corsair require?

Corsair uses Prisma as its ORM layer. You pass your Prisma client instance to createCorsair(), and the platform handles all schema migrations and query generation automatically. The database stores both cached API responses and internal metadata for tenant isolation.

Can I use Corsair without multi-tenancy?

Yes—set multiTenancy: false in your configuration. However, this is primarily intended for single-tenant applications or testing environments. The withTenant() method becomes unavailable, and you call APIs directly on the main instance instead.

How does Corsair ensure type safety across different service APIs?

Type definitions are generated from OpenAPI specifications for each service. When you import a plugin like @corsair-dev/slack, you receive TypeScript types that match the current Slack API surface. This generation happens at build time, so your IDE provides accurate autocomplete without runtime overhead.

Where are the best places to find working Corsair examples?

Start with demo/minimal/corsair.ts for the simplest complete implementation. For service-specific patterns, consult the /demo/sdk/ directory—each subdirectory contains a README.md with authentication steps and common operations. The demo/sdk/unified-sdk/webhooks/ folder provides production-ready webhook handlers with signature verification.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →