@reduck-ai/sdk
v1.1.21
Published
TypeScript SDK for Reduck — run browser automations programmatically.
Downloads
390
Readme
@reduck-ai/sdk
TypeScript SDK for Reduck — run browser automations programmatically.
Installation
npm install @reduck-ai/sdkQuick Start
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 === "run_requested") console.log("started:", event.run_id)
if (event.type === "progress") console.log(event.text)
if (event.type === "done") {
console.log(event.success ? "Done" : "Failed", event.output)
if (event.extractions) console.log("records:", event.extractions)
}
}
// Site discovery
const sites = await client.searchSites("messaging")
const site = await client.getSite("linkedin.com")Authentication
// API key (recommended for server-side)
const client = new ReduckClient({ apiKey: "<your-api-key>" })
// OAuth token (for user-facing apps)
const client = new ReduckClient({ oauthToken: "<your-oauth-token>" })Generate an API key from your Reduck dashboard.
API
new ReduckClient(options)
| Option | Type | Description |
|---|---|---|
| apiKey | string | API key authentication |
| oauthToken | string | OAuth bearer token authentication |
| runnerBaseUrl | string | Override runner base URL (default: hosted) |
| appBaseUrl | string | Override app base URL (default: hosted) |
| headers | Record<string, string> | Extra headers to send on every request |
One of apiKey or oauthToken is required.
client.run(query, options)
Starts an automation and returns a Run — an AsyncIterable<RunEvent> that streams events in real-time via WebSocket. The first event yielded is run_requested (synchronously after the server accepts the run, before WebSocket events flow).
When invoking a typed method, pass query: "" and set method + methodArgs.
| Option | Type | Description |
|---|---|---|
| deviceId | string | Target device ID (required) |
| method | string | Invoke a typed method <host>/<slug> (mutually exclusive with outputSchema) |
| methodArgs | Record<string, string> | Arguments rendered into the method's prompt_template. Requires method |
| mount | string[] | Local file paths to upload and make available to click_upload |
| pasteSlots | Record<string, string> | Named slots inserted via paste(slot=...) |
| outputSchema | object | Inline vision extractor JSON schema (mutually exclusive with method) |
| slug | string | Custom extractor slug for inline outputSchema (default: summary) |
run.id
Promise<string> — resolves to the run ID once the server accepts the run.
run.cancel()
Cancels the running automation.
client.listDevices()
Returns Promise<Device[]> — all devices for the authenticated user.
interface Device {
id: string
name: string | null
browser: string | null
os: string | null
reachable: boolean
created_at: string
}client.listRuns(page?)
Returns Promise<RunsPage> — a paginated list of runs.
interface RunsPage {
data: RunRecord[]
hasNextPage: boolean
}client.getRun(runId)
Returns Promise<RunRecord> — a single run by ID.
interface RunRecord {
id: string
started_at: string
finished_at: string | null
result: {
success?: boolean
cancelled?: boolean
output?: string
error?: { code: string; message: string } | null
final_url?: string
extractions?: SlugExtraction[]
downloads?: DownloadedFile[]
} | null
resolved: {
url?: string
prompt?: string
} | null
}client.interrupt(runId)
Interrupts a run by ID.
Site discovery
// Sites whose host matches the query
const sites = await client.searchSites("messaging")
// Full surface of a host
const site = await client.getSite("linkedin.com")Site shape:
interface Site {
host: string
notes: string
methods: Method[]
}
interface Method {
method_slug: string
description: string
args: Record<string, unknown> // JSON Schema for method args
output_schema: Record<string, unknown> | null
}Events
The run async iterable yields these events. Every event carries run_id and device_id for correlation.
| Type | Extra fields | Description |
|---|---|---|
| run_requested | query?, args | Server accepted the run; emitted before WebSocket connection |
| run_started | timestamp | Agent loop has started |
| progress | text, timestamp | Step-by-step progress update |
| assistant | text, timestamp | Assistant reasoning between tool calls |
| turn_completed | timestamp | Agent turn (one LLM call) completed |
| run_completed | timestamp | Agent loop finished |
| done | success, output?, final_url?, extractions?, downloads? | Agent called done — final result with collected data |
| failure | error | Run failed |
| cancel | — | Run was cancelled |
type RunEventBase = { run_id: string; device_id: string }
type RunEvent =
| (RunEventBase & { type: "run_requested"; query?: string; args: RunRequestedArgs })
| (RunEventBase & { type: "run_started"; timestamp: number })
| (RunEventBase & { type: "progress"; text: string; timestamp: number })
| (RunEventBase & { type: "assistant"; text: string; timestamp: number })
| (RunEventBase & { type: "turn_completed"; timestamp: number })
| (RunEventBase & { type: "run_completed"; timestamp: number })
| (RunEventBase & {
type: "done"
success: boolean
output?: string
final_url?: string
extractions?: SlugExtraction[]
downloads?: DownloadedFile[]
})
| (RunEventBase & { type: "failure"; error: string })
| (RunEventBase & { type: "cancel" })
interface SlugExtraction {
host: string
slug: string
records: object[]
output_schema: object
}
interface DownloadedFile {
filename: string
path?: string // full path on the runner — re-usable as `mount` in a follow-up run
mimetype?: string
url?: string | null
}final_url, extractions, and downloads on the done event are present only when the run produced them. downloads[].path can be reused as mount in a follow-up client.run(...) to chain workflows.
Schemas as JSON Schema
All public shapes are also exposed as Zod schemas via the schemas namespace:
import { schemas } from "@reduck-ai/sdk"
schemas.RunEventSchema.parse(json) // validate at runtime
schemas.RunResultSchema // the final `done` event shape
schemas.SiteSchema, schemas.MethodSchema, schemas.DeviceSchema, ...The reduck schema <name> CLI command emits these as JSON Schema (draft-7) for non-TS consumers.
License
MIT
