npm package: @reduck-ai/sdk
Description: TypeScript SDK for Reduck — run browser automations programmatically.
Author: Reduck AI
Latest version: 1.1.0

<p align="center">
  <img src="https://cdn.reduck.ai/logo-full-dark.png" alt="Reduck" width="300" />
</p>

# @reduck-ai/sdk

TypeScript SDK for [Reduck](https://reduck.ai) — run browser automations programmatically.

## Installation

```bash
npm install @reduck-ai/sdk
```

## Quick Start

```typescript
import { ReduckClient } from "@reduck-ai/sdk"

const client = new ReduckClient({
  apiKey: "your-api-key",
})

const devices = await client.listDevices()

const run = client.run("Go to google.com and search for 'reduck ai'", {
  deviceId: devices[0].id,
})

for await (const event of run) {
  if (event.type === "progress") console.log(event.text)
  if (event.type === "done") console.log(event.success ? "Done" : "Failed")
}
```

## Authentication

Pass either an API key or an OAuth token:

```typescript
// API key (recommended for server-side)
const client = new ReduckClient({ apiKey: "rk_..." })

// OAuth token (for user-facing apps)
const client = new ReduckClient({ oauthToken: "..." })
```

Generate an API key from your [Reduck dashboard](https://reduck.ai).

## API

### `new ReduckClient(options)`

| Option | Type | Description |
|---|---|---|
| `apiKey` | `string` | API key authentication |
| `oauthToken` | `string` | OAuth bearer token authentication |

One of `apiKey` or `oauthToken` is required.

### `client.listDevices()`

Returns `Promise<Device[]>` — all devices for the authenticated user.

```typescript
interface Device {
  id: string
  name: string | null
  browser: string | null
  os: string | null
  reachable: boolean
  created_at: string
}
```

### `client.run(prompt, options)`

Starts an automation and returns a `Run` — an `AsyncIterable<RunEvent>` that streams events in real-time via WebSocket.

| Option | Type | Description |
|---|---|---|
| `deviceId` | `string` | Target device ID (required) |
| `mount` | `string[]` | Local file paths to upload and make available |

### `run.id`

`Promise<string>` — resolves to the run ID once the server accepts it.

### `run.cancel()`

Cancels the running automation.

### `client.listRuns(page?)`

Returns `Promise<RunsPage>` — a paginated list of runs (sessions) for the authenticated user.

```typescript
interface RunsPage {
  data: RunRecord[]
  hasNextPage: boolean
}
```

| Option | Type | Default | Description |
|---|---|---|---|
| `page` | `number` | `0` | Zero-based page index |

### `client.getRun(runId)`

Returns `Promise<RunRecord>` — a single run by ID.

```typescript
interface RunRecord {
  id: string
  started_at: string
  finished_at: string | null
  result: {
    success?: boolean
    cancelled?: boolean
    reason?: string
    output?: string
  } | null
  resolved: {
    url?: string
    prompt?: string
  } | null
}
```

### `client.interrupt(runId)`

Interrupts a run by ID.

## Events

The `run` async iterable yields these events:

| Type | Fields | Description |
|---|---|---|
| `run_started` | `timestamp` | Automation has started |
| `progress` | `text`, `timestamp` | Step-by-step progress update |
| `assistant` | `text`, `timestamp` | Assistant message |
| `turn_completed` | `timestamp` | Agent turn completed |
| `run_completed` | `timestamp` | Automation finished executing |
| `done` | `success`, `output?` | Final result |
| `failure` | `error` | Automation failed |
| `cancel` | — | Automation was cancelled |

## License

Apache-2.0