# SDK TypeScript

> Gói @browlix/sdk — gọi có kiểu cho mọi thao tác, thử lại an toàn, tiện ích phiên và xác minh webhook.

`@browlix/sdk` không có phụ thuộc lúc chạy và dùng được trên Node 20 trở lên, Bun, Deno, Cloudflare Workers và trình duyệt được phép giữ khoá.

## Cài đặt

Gói do Browlix phát hành, có SHA-256 ở [trang tải về](https://browlix.com/download):

```bash
npm i https://browlix.com/api/public/sdk/v1/download/latest
```

## Tạo client

```ts
import { Browlix, BrowlixError } from "@browlix/sdk";

const bx = new Browlix({ apiKey: process.env.BROWLIX_API_KEY! }); // SDK không tự đọc biến môi trường
```

Tuỳ chọn: `baseUrl` (mặc định `https://browlix.com`), `attempts` cho thử lại an toàn (mặc định 3), `timeoutMs` mỗi yêu cầu (mặc định 60 giây) và `fetch` tuỳ chỉnh.

## Gọi mọi thao tác

```ts
const { data, page } = await bx.call("profiles.list", { query: { limit: 20, os: "windows" } });

for await (const profile of bx.paginate("profiles.list", { state: "active" })) {
  console.log(profile);
}
```

`call(id, { path, query, body })` có kiểu theo tài liệu OpenAPI cho từng id thao tác: luôn có kiểu cho đầu vào, và từ SDK `0.9.0` có thêm kiểu cho `data` của mọi thao tác đã công bố trường phản hồi trong [trang tham chiếu](https://browlix.com/en/docs/reference) (profiles, sessions, bindings, devices, feedback, workspace). `OPERATIONS` liệt kê chúng. Trường phản hồi mới có thể xuất hiện không báo trước — xem [Phiên bản và nhật ký thay đổi](https://browlix.com/docs/api-changelog).

## Thao tác ghi

Thao tác ghi tự có `command_id` khi bạn không truyền và trả lại ở `reply.commandId`. Thử lại tự động gửi lại cùng id, nên không có gì bị áp dụng hai lần. Sau `OUTCOME_UNKNOWN`, đọc kết quả bằng `bx.receipt(commandId)`.

## Phiên

```ts
const s = await bx.startSession({ profileId, deviceId, wait: { timeoutMs: 120_000 } });
const a = await bx.attach(s.data.id);
// … gắn Playwright trên máy này với a.endpoint và a.headers …
await bx.stopSession(s.data.id);
```

`waitForSession` và `startSession({ wait })` chỉ chờ. Huỷ bằng `signal` (`INTERRUPTED`) hoặc hết thời gian (`WAIT_TIMEOUT`) vẫn để phiên chạy. `stopSession` là lệnh duy nhất kết thúc phiên.

## Lỗi

Mọi lỗi là `BrowlixError` với `code` của API, `retryable`, và `info` (`status`, `details`, `correlationId`, `commandId`, `retryAfterSeconds`). Chuỗi trông giống khoá được che khỏi thông báo.

```ts
try {
  await bx.call("sessions.start", { body: { profile_id: profileId, device_id: deviceId } });
} catch (e) {
  if (e instanceof BrowlixError && e.code === "BUSY") console.log("BUSY", e.info.details);
  else throw e;
}
```

## Webhook

`verifyWebhook(secret, headers, rawBody)` kiểm chữ ký [Standard Webhooks](https://www.standardwebhooks.com) và thời điểm (lệch tối đa 5 phút) rồi trả về sự kiện đã đọc — xem [Webhook](https://browlix.com/docs/webhooks).
