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

# Choosing between Manual and Hub

> The same Corsair instance, two ways to handle the surfaces that need a public URL. Here is exactly what each mode asks you to build.

Corsair only differs between modes in one place: the surfaces that need a public URL (OAuth callbacks, approval pages). Everything else (calling APIs, `withTenant`, hooks, the database layer, encryption) is identical.

* **Hub** is the recommended path. Corsair hosts the connect, callback, and approval surfaces for you, and your users' API tokens land in your database, not Hub. See [Hub overview](/hub/overview#where-your-credentials-live) for the credential split.
* **Manual** is the self-hosted alternative. You host those surfaces yourself. It is fully featured, with no external dependency.

The picker is config on `createCorsair`: pass `manual` or `hub`.

## What each mode asks you to build

| Surface | Manual (you host it) | Hub (Corsair hosts it) |
| - | - | - |
| OAuth callback URL | One per environment, registered with each provider | One callback for [development and production](/hub/environments) |
| Connect page | You build it (`resolve` the signed state, redirect to provider) | Hosted by Hub |
| OAuth callback route | You build it (`oauthCallback` exchanges the code) | Hosted by Hub, result delivered to you |
| Approval UI | You build a review page and wire `onApprovalRequired` | Hosted approve/deny page, link auto-generated |
| Missing-connection error | You craft the message and build the connect page | You call `createLink()` for a sign-in link; Hub hosts the connect page |
| Credential storage | Your database | Your database. Hub delivers your tenants' tokens to you and keeps zero copies; it holds only the OAuth client id/secret |

Credential storage barely changes. Your users' API tokens live in your database under your KEK in both modes. Hub relays the public-URL surfaces and hands the tokens to your app, keeping none itself. It does hold the app-level OAuth client id and secret (managed or bring-your-own) that run the flow. See [Where your credentials live](/hub/overview#where-your-credentials-live).

## Config side by side

<Tabs>
  <Tab title="Manual (self-hosted)">
    ```ts corsair.ts theme={null}
    import { createCorsair } from 'corsair';
    import { github } from '@corsair-dev/github';

    export const corsair = createCorsair({
        plugins: [github()],
        database: db,
        kek: process.env.CORSAIR_KEK!,
        manual: {
            baseUrl: `${appUrl}/connect`,
            redirectUri: `${appUrl}/api/oauth/callback`,
            approvalBaseUrl: `${appUrl}/approve`,
        },
    });
    ```

    You also build the connect page, the OAuth callback route, and the approval review page. See [OAuth Process](/concepts/oauth-process) for the full implementation.
  </Tab>

  <Tab title="Hub (hosted)">
    ```ts corsair.ts theme={null}
    import { createCorsair } from 'corsair';
    import { github } from '@corsair-dev/github';

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

    No connect page, callback route, or approval page to build. Mount the handler once and Hub [delivers results](/hub/delivery-urls) to it (auto-detected locally, registered in the dashboard for production).
  </Tab>
</Tabs>

Both modes use the same `createLink` API to start a connect flow. Only where the returned `connectUrl` points changes. See [Connect / OAuth](/management/connect).

## The connect flow in each mode

```mermaid theme={null}
sequenceDiagram
    actor User
    participant App as Your App
    participant Surface as Connect surface
    participant Provider as OAuth Provider

    Note over App,Surface: Manual — you host the connect surface
    User->>App: Click "Connect"
    App->>App: createLink()
    App->>Surface: Redirect to your /connect page
    Surface->>Provider: resolve() then redirect
    Provider->>App: callback ?code — you call oauthCallback()
    App->>App: tokens encrypted into your DB

    Note over App,Surface: Hub — Corsair hosts the connect surface
    User->>App: Click "Connect"
    App->>App: createLink()
    App->>Surface: Redirect to Hub connect page
    Surface->>Provider: Hub handles resolve and callback
    Provider->>Surface: callback ?code
    Surface->>App: delivers result to your handler
    App->>App: tokens encrypted into your DB
```

In both lanes the tokens end up in your database. Hub removes the two pages you would otherwise build, nothing more.

## Choosing a mode

Choose **manual** when you want full control of the connect and approval surfaces, need everything inside your own domain, or cannot add an external hop in the auth path.

Choose **hub** when you would rather not build and host those surfaces, or when you want one provider callback to cover [local development and production](/hub/environments) at once.

You can also mix: connect through Hub while keeping approvals manual, or the reverse. The two surfaces are configured independently.

## What's next

<CardGroup cols={2}>
  <Card title="Hub overview" href="/hub/overview">
    What Hub is and where your credentials live.
  </Card>

  <Card title="Environments" href="/hub/environments">
    Development vs production keys and delivery.
  </Card>

  <Card title="OAuth process" href="/concepts/oauth-process">
    The full manual-mode implementation with security best practices.
  </Card>

  <Card title="Connect / OAuth" href="/management/connect">
    The unified createLink API and its error codes.
  </Card>

  <Card title="Permissions" href="/concepts/permissions">
    Approval policies, modes, and the review flow.
  </Card>
</CardGroup>


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