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

# Connect integrations via OAuth

> Wire up Gmail, GitHub, and other services using the SDK

```typescript theme={null}
const session = await airstore.oauth.createSession({
  integrationType: 'gmail',
  workspaceId: 'ws_abc123',
})
// Redirect the user to session.authorize_url
```

Integrations connect external services (Gmail, GitHub, Google Drive, etc.) to a workspace. Once connected, their data becomes available in the virtual filesystem through source views.

The SDK supports two ways to connect integrations:

1. **OAuth flow** -- Redirect the user to authorize access, then poll for completion. Best for interactive setups.
2. **Direct credentials** -- Pass existing OAuth tokens or API keys directly. Best for backend automation where you already have credentials.

## OAuth flow

This is the most common approach. You create a session, send the user to the authorization URL, and poll until they complete it.

### Step 1: Create an OAuth session

```typescript theme={null}
import Airstore from '@airstore/sdk'

const airstore = new Airstore()

const session = await airstore.oauth.createSession({
  integrationType: 'gmail',
  workspaceId: 'ws_abc123',
})

console.log(session.authorize_url)
// "https://accounts.google.com/o/oauth2/v2/auth?..."
```

Redirect the user to `session.authorize_url` in their browser. After they approve access, Airstore handles the callback and stores the credentials.

### Step 2: Poll for completion

```typescript theme={null}
const result = await airstore.oauth.poll(session.session_id)

console.log(result.status)        // "complete"
console.log(result.connection_id) // "conn_xyz789"
```

`poll()` checks the session status every 2 seconds (configurable) and resolves when the user completes or denies authorization. It throws if the session times out or errors.

```typescript theme={null}
// Custom polling options
const result = await airstore.oauth.poll(session.session_id, {
  timeout: 120_000,  // 2 minutes instead of default 5
  interval: 1_000,   // Check every second
})
```

### Step 3: Verify the connection

```typescript theme={null}
const connections = await airstore.connections.list('ws_abc123')
const gmail = connections.find(c => c.integration_type === 'gmail')
console.log(gmail?.external_id)
```

## Direct credentials

If you already have OAuth tokens or an API key, skip the redirect flow entirely:

```typescript theme={null}
// OAuth-based integration (Gmail, GitHub, etc.)
await airstore.connections.create('ws_abc123', {
  integrationType: 'github',
  accessToken: 'ghp_xxxxxxxxxxxx',
})

// API key integration (PostHog, etc.)
await airstore.connections.create('ws_abc123', {
  integrationType: 'posthog',
  apiKey: 'phx_xxxxxxxxxxxx',
})
```

This is useful when your backend already manages OAuth tokens for users and you want to pass them through to Airstore without a second authorization prompt.

## Supported integrations

| Integration  | Type      | Authentication |
| ------------ | --------- | -------------- |
| Gmail        | `gmail`   | OAuth          |
| Google Drive | `gdrive`  | OAuth          |
| GitHub       | `github`  | OAuth or token |
| Notion       | `notion`  | OAuth or token |
| Linear       | `linear`  | OAuth          |
| Slack        | `slack`   | OAuth          |
| PostHog      | `posthog` | API key        |

## Remove a connection

```typescript theme={null}
await airstore.connections.del('ws_abc123', 'conn_xyz789')
```

## Next steps

<CardGroup cols={2}>
  <Card title="Create source views" icon="wand-magic-sparkles" href="/sdk/guides/source-views">
    Turn your connected data into browsable folders.
  </Card>

  <Card title="OAuth reference" icon="book" href="/sdk/reference/oauth">
    Full method reference for `client.oauth`.
  </Card>
</CardGroup>
