> ## Documentation Index
> Fetch the complete documentation index at: https://docs.profy.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK 快速开始

> 使用 Profy SDK 快速接入：安装、初始化、OAuth 授权、事件上报。

# SDK 快速开始

官方 TypeScript SDK 封装了 OAuth Token 管理和事件上报，让你专注于业务逻辑。

## 安装

<CodeGroup>
  ```bash npm theme={null}
  npm install @profy-ai/sdk
  ```

  ```bash bun theme={null}
  bun add @profy-ai/sdk
  ```
</CodeGroup>

## 初始化

```typescript theme={null}
import { ProfyApp } from "@profy-ai/sdk";

const profy = new ProfyApp({
  clientId: process.env.PROFY_APP_ID!,
  clientSecret: process.env.PROFY_APP_SECRET!,
  baseUrl: "https://app.profy.cn",       // 可选，默认 profy.cn
  onTokenRefresh: (newToken) => {         // 可选，Token 轮换时触发
    saveToDatabase(newToken);             // 持久化新 Token
  },
});
```

## OAuth 授权码交换

用户授权后，回调地址会收到 `code` 参数。在后端将其换成 Token：

```typescript theme={null}
const token = await profy.exchangeCode(code, redirectUri);
// → { accessToken, refreshToken, expiresAt }
```

| 字段             | 类型     | 说明             |
| -------------- | ------ | -------------- |
| `accessToken`  | string | JWT 格式，1 小时有效  |
| `refreshToken` | string | 90 天有效，每次使用后轮换 |
| `expiresAt`    | number | 过期时间戳（毫秒）      |

<Warning>
  `exchangeCode` 必须在后端调用。App Secret 不能暴露在前端。
</Warning>

## 上报计费事件

```typescript theme={null}
const result = await profy.reportEvent("generate_report", {
  token,
  idempotencyKey: "order-12345",  // 可选，防重复扣费
  metadata: { plan: "pro" },      // 可选，业务追踪
});
```

SDK 会自动处理 Token 过期：Access Token 过期时自动用 Refresh Token 续期，再重试请求。

## 错误处理

```typescript theme={null}
import {
  AuthExpired,
  InsufficientBalance,
  InvalidEvent,
  ProfyApiError,
} from "@profy-ai/sdk";

try {
  await profy.reportEvent("action", { token });
} catch (err) {
  if (err instanceof AuthExpired) {
    // Token 过期且无法刷新 → 引导用户重新授权
  } else if (err instanceof InsufficientBalance) {
    // 用户积分不足 → 提示充值
  } else if (err instanceof InvalidEvent) {
    // 事件名未配置 → 检查 Studio 计费事件设置
  } else if (err instanceof ProfyApiError) {
    // 其他 API 错误
    console.error(err.statusCode, err.body);
  }
}
```

## 错误类速查

| 错误类                   | HTTP 状态码 | 触发条件          | 处理方式            |
| --------------------- | -------- | ------------- | --------------- |
| `AuthExpired`         | 401      | Token 过期且刷新失败 | 重新授权            |
| `InsufficientBalance` | 402      | 用户积分不足        | 提示充值            |
| `InvalidEvent`        | 400      | 事件名未注册        | 检查 Meter 配置     |
| `ProfyApiError`       | \*       | 通用 API 错误     | 按 statusCode 处理 |

## 完整示例

→ [profy-app-template](https://github.com/user/profy-app-template)（Vite + Hono 全栈脚手架）

<CardGroup cols={2}>
  <Card title="应用接入教程" icon="rocket" href="/zh/documentation/integration-quickstart">
    5 分钟走通完整接入流程
  </Card>

  <Card title="API 参考" icon="code" href="/zh/api/oauth">
    OAuth 端点与 Events API 详细文档
  </Card>
</CardGroup>
