# TypeScript SDK

> The typed TypeScript client for phones, control, apps, skills, runs, secrets and usage, with retries and idempotency keys built in.

> The SDK is `@distilled/agent-sdk`. It is in private preview and not yet on npm; [ask us](mailto:sales@distilled.cx?subject=A%20plan%20for%20our%20team) for access. Everything it does is also available over REST.

The client covers phones, control, apps, skills, runs, secrets, usage and egress. Allocating and managing phones, proxies and billing are REST only for now. It retries `429`, `502`, `503` and `504`, waiting as long as `Retry-After` asks. Every retry of an action on a phone reuses one idempotency key, so the node plays each action at most once. Every POST gets an idempotency key, and keys never appear in its error messages.

first-phone.ts:

```ts
import { DistilledClient } from "@distilled/agent-sdk"

const distilled = new DistilledClient({ apiKey: process.env.DISTILLED_KEY! })

// Drive a phone yourself.
const [phone] = await distilled.phones.list()
const control = distilled.phones.control(phone.id)
await control.launchApp("com.android.settings")
const screen = await control.screenshot()

// Or hand a task to a run, and wait for it to end.
const run = await distilled.runs.start({ skill: "sk_2hq8", phones: [phone.id] })
const finished = await distilled.runs.wait(run.id)
console.log(finished.state)
```

| Area | Methods |
| --- | --- |
| Client | `me()`, `usage(range)`, `egress({ period })` |
| `phones` | `list()`, `get(id)`, `control(id)` |
| `control(id)` | `observe`, `screenshot`, `uiTree`, `waitForIdle`, `tap`, `longPress`, `swipe`, `type`, `key`, `launchApp`, `openUrl`, `act`, `location`, `setLocation`, `lease`, `release` |
| `apps` | `search(query)`, `get(pkg)`, `install(phoneId, pkg)`, `installs(phoneId)` |
| `skills` | `list()`, `get(id)`, `create(definition)`, `update(id, definition)`, `setEnabled(id, enabled)`, `delete(id)` |
| `runs` | `start`, `list`, `get`, `stop`, `resume`, `steps`, `stepScreenshot`, `wait`, `watch` |
| `secrets` | `list()`, `put(name, value)`, `delete(name)` |

Failures are thrown as `DistilledError`, with the HTTP `status`, the error `code`, its `detail` and whether it is `retryable`.

Source: https://distilled.cx/docs/sdk/
