# TypeScript SDK

Source: https://webagent-docs-staging.lookover.ai/sdk

> The @lookover-ai/webagent-sdk package. How to get it today, what it can do and what it cannot.

`@lookover-ai/webagent-sdk` is a TypeScript client for the public `/v1` API. It works in Node 22 and in browsers (it uses the global `fetch`). Request and reply shapes come from the webagent contracts package, and every reply is checked against its schema.

> **Warning:** The SDK is a private package today. It is published to GitHub Packages for the `lookover-ai` organization, not to the public npm registry. You need access to that organization and a GitHub token with `read:packages`. If you do not have access, use the [REST API](/api-reference), the [MCP server](/mcp) or the curl script in [Smoke tests in CI](/guides/ci).

The version in the repository is 0.3.0.

## Install [#install]

Add this to the `.npmrc` of your project:

```ini title=".npmrc"
@lookover-ai:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
```

Set `NODE_AUTH_TOKEN` to your GitHub token. Then install the package. It needs `zod` as a peer dependency.

```bash
pnpm add @lookover-ai/webagent-sdk zod
```

## First calls [#first-calls]

```ts
import { WebagentClient, WebagentApiError } from "@lookover-ai/webagent-sdk";

const client = new WebagentClient({
  apiKey: process.env.WEBAGENT_API_KEY!, // wa_us_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
});

// A browser session you drive with actions.
const session = await client.createSession({ startUrl: "https://example.com" });
try {
  console.log(await session.snapshotText());
  const png = await session.screenshot({ format: "png" });
} finally {
  await session.close();
}

// A skill run: start it, then wait for the verdict.
const { runId } = await client.runSkill("smoke-uat", {
  inputs: { url: "https://example.com" },
});
const run = await client.waitForSkillRun(runId);
console.log(run.status, run.summary);

// The test report: one verdict, the failed steps, console errors and failed network calls.
const report = await client.getSkillRunReport(runId);
console.log(report.verdict, report.summary);

// Errors carry the API error code.
try {
  await client.getSession("sess_us_000000000000000000000000");
} catch (e) {
  if (e instanceof WebagentApiError && e.code === "not_found") console.log("gone", e.requestId);
}
```

## The API host [#the-api-host]

The key picks the host. A key `wa_us_...` goes to `https://api.us.webagent.lookover.ai`. To use another host, for example a local stack or a proxy, pass `baseUrl`:

```ts
const client = new WebagentClient({ apiKey, baseUrl: "http://localhost:4400" });
```

Other options: `fetch` (your own implementation) and `timeoutMs` (per request, default 60 seconds).

## Methods [#methods]

| Area | Methods |
|---|---|
| Sessions | `createSession`, `listSessions`, `getSession`, `closeSession` |
| Session handle | `act`, `snapshot`, `snapshotText`, `screenshot`, `cookies`, `setCookies`, `clearCookies`, `tabs`, `openTab`, `activateTab`, `closeTab`, `pause`, `resume`, `refreshToken`, `close`, and the properties `id`, `endpoints`, `token` |
| Skills | `listSkills`, `getSkill`, `validateSkill`, `runSkill`, `getSkillRun`, `waitForSkillRun`, `listSkillRuns`, `skillRunReport`, `getSkillRunReport` |
| Tasks | `listTasks`, `getTaskReport` |
| Quick tools | `scrape`, `crawl`, `screenshot`, `pdf` |
| Schedules | `listSchedules`, `createSchedule`, `getSchedule`, `updateSchedule`, `deleteSchedule`, `runScheduleNow` |
| Account | `tenant`, `billing`, `usage` |

What the less obvious ones do:

- `createSession(request?, { idempotencyKey })` starts a session with any [session option](/concepts/sessions) (`startUrl`, `headers`, `credentials`, `proxyUrl`, and more). It returns a handle. The handle sends actions to the session's own host and refreshes its token for you.
- `runSkill(name, { inputs, session, ... }, { idempotencyKey })` starts a run and returns `{ runId, sessionId, status }` at once.
- `waitForSkillRun(runId, { pollMs, timeoutMs })` polls until the run is not `running`. Defaults: 1 second, 5 minutes. It throws a `timeout` error after that.
- `listSkillRuns({ status, skill, limit, cursor })` returns `{ runs, next }`. Pass `next` as `cursor` for the following page.
- `skillRunReport(runId)` returns the HTML report of a finished run.
- `getSkillRunReport(runId)` returns the JSON test report of a skill run: `verdict` (`pass`, `fail`, `error` or `running`), `summary`, `steps`, `findings`, `consoleErrors`, `networkFailures` and `evidence`. It calls `GET /v1/skill-runs/:id/report.json` and checks the reply against its schema. See [Reading results](/qa-testing/reading-results#the-test-report).
- `getTaskReport(taskId)` returns the same report for a goal task, from `GET /v1/tasks/:id/report.json`. A task has no assertions: `pass` means the agent says it is done. The console and network lists come from the session log, which is saved when the session ends, so read a report again if its `notes` say the log is not available.
- `listTasks(sessionId?)` lists goal tasks, newest first, at most 200.
- `createSession`, `runSkill` and `createSchedule` accept an `idempotencyKey`, so a retry does not make a second run.

## Errors [#errors]

A failed call throws `WebagentApiError` with `code` (an [error code](/reference/errors)), `status` (0 when no reply arrived), `details`, `requestId` and `retryAfterS`. The SDK does not retry for you. Retry on `rate_limited`, `capacity_exceeded` and `runner_unavailable` as your app needs, with the same `idempotencyKey`.

## What the SDK does not cover [#what-the-sdk-does-not-cover]

- **Goal tasks.** There is no method to start a task (`run_task`). Use the [MCP tools](/mcp/tools) for that, or drive the session with `act` yourself. `listTasks` lists tasks and `getTaskReport` reads the report of one.
- **Operator routes.** `/v1/admin/*` is not covered.
- **Vault, proxies, keys, profiles, replay, logs and share links.** There are no methods for them. Use the REST API.
- **Public npm release.** See the note at the top.
