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

# TypeScript SDK 接入教程

> Platform 整合指南 - Ace Data Cloud

[`@acedatacloud/sdk`](https://www.npmjs.com/package/@acedatacloud/sdk) 是 Ace Data Cloud 官方 TypeScript / JavaScript SDK，把 `api.acedata.cloud` 上所有服务封装成类型化的 `client.openai.chat.completions.create(...)`、`client.images.generate(...)`、`client.search.google(...)` 等方法，自带 SSE 流式、重试退避、类型化异常。

可以在 Node.js、Deno、Bun 和现代浏览器（带 bundler）中使用。

源码与包地址：

* SDK 仓库：[https://github.com/AceDataCloud/SDK](https://github.com/AceDataCloud/SDK)
* npm SDK：[https://www.npmjs.com/package/@acedatacloud/sdk](https://www.npmjs.com/package/@acedatacloud/sdk)

## 安装

```bash theme={null}
npm install @acedatacloud/sdk
# 或 pnpm add / yarn add / bun add
```

如果需要 X402 链上付费（无 API Token 路径），再装一个：

```bash theme={null}
npm install @acedatacloud/x402-client ethers
```

干净 npm 项目的版本检查输出：

```text theme={null}
$ npm ls @acedatacloud/sdk
└── @acedatacloud/sdk@2026.504.2

$ node -e "console.log(require('@acedatacloud/sdk').AceDataCloud?.name)"
AceDataCloud
```

结果说明：

* 包版本是 `2026.504.2`（CalVer，2026 年第 504 个 ISO 周的第 2 个修订）。
* `AceDataCloud` 是构造客户端用的主 class，从默认导出可访问。

## 准备 API Token

参考 [SDK 总览 - 申请 API Token](https://platform.acedata.cloud/documents/acedatacloud-sdk#申请-api-token) 取到 token，然后在 shell 里 `export`：

```bash theme={null}
export ACEDATACLOUD_API_TOKEN={token}
```

构造客户端时不传 `apiToken`，SDK 会自动读取 `ACEDATACLOUD_API_TOKEN` 环境变量。如果你的环境里已经存了 `ACEDATACLOUD_API_KEY`（项目仓库约定），可以显式传入：`new AceDataCloud({ apiToken: process.env.ACEDATACLOUD_API_KEY })`。

## 示例 1：chat.completions（非流式）

```ts theme={null}
import { AceDataCloud } from '@acedatacloud/sdk';

const client = new AceDataCloud();

const t0 = Date.now();
const res = await client.openai.chat.completions.create({
  model: 'gpt-4o-mini',
  messages: [
    { role: 'user', content: 'Reply with exactly: ADC_TS_SDK_OK' }
  ],
  max_tokens: 20,
  temperature: 0
});
console.log('elapsed_ms', Date.now() - t0);
console.log('id', res.id);
console.log('model', res.model);
console.log('content', res.choices[0].message.content);
console.log('usage', JSON.stringify(res.usage));
```

程序运行结果：

```text theme={null}
elapsed_ms 2543
id chatcmpl-DldCcLvkTFaioST8e6SjOl0wJScQA
model gpt-4o-mini
content ADC_TS_SDK_OK
usage {"prompt_tokens":16,"completion_tokens":6,"total_tokens":22}
```

结果说明：

* `id chatcmpl-DldCcLvkTFaioST8e6SjOl0wJScQA` 是 OpenAI 兼容响应 ID，可以在控制台 [使用历史](https://platform.acedata.cloud/console/usages) 里搜到对应记录。
* `content ADC_TS_SDK_OK` 是模型真实返回的固定标识，证明响应没有被 SDK 篡改。
* 一次 chat completion 大约消耗 22 token，按 gpt-4o-mini 单价计费。
* SDK 将响应声明为 `Record<string, unknown>`，运行时就是 JSON 对象，`.id` / `.choices[0].message.content` 这种点访问在 `.mjs`、Node REPL、Bun 下都能跑；严格 TypeScript 项目下可能需要 `(res as any).id` 或在 tsconfig 关闭 `noImplicitAny`。

## 示例 2：chat.completions（SSE 流式）

将 `stream: true` 打开后，`create` 返回一个异步迭代器，每一帧都是一个 `ChatCompletionChunk`。

```ts theme={null}
import { AceDataCloud } from '@acedatacloud/sdk';

const client = new AceDataCloud();

const t0 = Date.now();
let firstChunkMs: number | null = null;
let chunks = 0;
const collected: string[] = [];

const stream = await client.openai.chat.completions.create({
  model: 'gpt-4o-mini',
  messages: [
    { role: 'user', content: 'Count from 1 to 5, separated by single spaces, no extra text.' }
  ],
  max_tokens: 20,
  stream: true
});

for await (const chunk of stream) {
  if (firstChunkMs === null) firstChunkMs = Date.now() - t0;
  chunks++;
  const delta = chunk.choices[0]?.delta?.content;
  if (delta) collected.push(delta);
}

console.log('total_elapsed_ms', Date.now() - t0);
console.log('first_chunk_ms', firstChunkMs);
console.log('chunks', chunks);
console.log('collected', collected.join('').trim());
```

程序运行结果：

```text theme={null}
total_elapsed_ms 2616
first_chunk_ms 2481
chunks 13
collected 1 2 3 4 5
```

结果说明：

* 首帧延迟 2481 ms 是模型生成第一个 token 的时间；后续 12 帧在 135 ms 内全部到达。
* 13 帧合起来是 `"1 2 3 4 5"`，每个 token 单独成帧 + 最后一帧带 `finish_reason`。
* 流式没有比非流式更省 token，但首字延迟显著降低，适合做实时 UI。

## 示例 3：images.generate（NanoBanana）

`client.images.generate({ provider: 'nano-banana', ... })` 直接同步返回，**不需要传 `wait` 参数**——NanoBanana API 本身就是同步生成。

```ts theme={null}
import { AceDataCloud } from '@acedatacloud/sdk';

const client = new AceDataCloud();

const t0 = Date.now();
const img = await client.images.generate({
  provider: 'nano-banana',
  prompt: 'A minimalist logo of a yellow banana on a white background, flat design'
});
console.log('elapsed_ms', Date.now() - t0);
console.log('task_id', img.task_id);
console.log('trace_id', img.trace_id);
console.log('image_url', img.data[0].image_url);
```

程序运行结果：

```text theme={null}
elapsed_ms 16634
task_id 8e4b44a6-5ece-46a4-9013-9e0c8aca2217
trace_id 9529e241-54fe-40da-98a2-871e14989fb5
image_url https://platform.cdn.acedata.cloud/nanobanana/331be1d3-3330-4196-bd1c-aa75717c549c.png
```

结果说明：

* `image_url` 是 CDN 上的稳定地址，可以直接 `<img src />` 或下载。
* 16.6 秒里大部分时间是模型推理，本地 SDK 开销可忽略。
* `trace_id` 是平台分配的请求 ID，如果出问题贴这个 ID 给客服可以最快定位。
* 对于异步类服务（Midjourney、Sora、Veo 等）需要 TaskHandle 轮询，详见 [SDK 任务轮询与流式响应](https://platform.acedata.cloud/documents/sdk-tasks-and-streaming)。

## 示例 4：类型化错误处理

SDK 会按 HTTP 状态把错误抛成具体的子类（`AuthenticationError` / `BadRequestError` / `RateLimitError` / `InternalServerError` / `APIConnectionError` 等），可以用 `instanceof` 精确分支。

```ts theme={null}
import { AceDataCloud, AuthenticationError } from '@acedatacloud/sdk';

const bad = new AceDataCloud({ apiToken: 'definitely-not-a-real-token' });

try {
  await bad.openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: 'hi' }],
    max_tokens: 5
  });
} catch (err: any) {
  console.log('err_class', err.constructor.name);
  console.log('status', err.statusCode);
  console.log('code', err.code);
  console.log('instanceof AuthenticationError =', err instanceof AuthenticationError);
}
```

程式運行結果：

```text theme={null}
A. err_class AuthenticationError
A. status 401
A. code invalid_token
A. instanceof AuthenticationError = true
```

結果說明：

* 401 自動映射為 `AuthenticationError`，業務代碼可以用 `instanceof` 精確分支。
* `code: invalid_token` 來自 PlatformGateway，便於和後端日誌對照。
* 同理 429 → `RateLimitError`、400 → `BadRequestError`、5xx → `InternalServerError`。

## 示例 5：多模型路由

同一個客戶端可以在多個服務之間隨意切換，模型名一致就行。

```ts theme={null}
import { AceDataCloud } from '@acedatacloud/sdk';

const client = new AceDataCloud();

const MODELS = ['gpt-4o-mini', 'gemini-2.5-flash', 'deepseek-v3', 'grok-3-fast'];

for (const model of MODELS) {
  const t0 = Date.now();
  try {
    const r = await client.openai.chat.completions.create({
      model,
      messages: [{ role: 'user', content: 'Reply with exactly: ADC_OK' }],
      max_tokens: 5
    });
    console.log(model.padEnd(28), `${Date.now() - t0}ms`, `content="${r.choices[0].message.content}"`);
  } catch (err: any) {
    console.log(model.padEnd(28), `${Date.now() - t0}ms`, 'ERR', err.statusCode, err.code);
  }
}
```

程式運行結果：

```text theme={null}
gpt-4o-mini                  2189ms   content="ADC_OK"
gemini-2.5-flash             2569ms   content=""
deepseek-v3                  2047ms   content="ADC_OK"
grok-3-fast                  3598ms   content="ADC_OK"
```

結果說明：

* 一份代碼、一份 token，覆蓋 OpenAI / Google / DeepSeek / xAI 四類模型服務。
* `gemini-2.5-flash` 這次沒返回 `ADC_OK`，是模型自身的輸出風格差異——SDK 沒有靜默吞掉任何東西，把模型原話忠實透傳給業務。
* 價格按各自的真實 token 單價計費，路徑只過一次 PlatformGateway。

## 示例 6：Google 搜索

```ts theme={null}
import { AceDataCloud } from '@acedatacloud/sdk';

const client = new AceDataCloud();

const t0 = Date.now();
const r = await client.search.google({
  query: 'Ace Data Cloud',
  resource: 'web'
});
const items = (r as any).organic ?? [];
console.log('elapsed_ms', Date.now() - t0);
console.log('organic_count', items.length);
items.slice(0, 2).forEach((it: any, i: number) => {
  console.log(`#${i + 1}`, it.title, '->', it.link);
});
```

程式運行結果：

```text theme={null}
elapsed_ms 2382
organic_count 10
#1 Ace Data Cloud -> https://platform.acedata.cloud/
#2 Ace Data Cloud - GitHub -> https://github.com/acedatacloud
```

結果說明：

* 一次請求拿到 10 條 organic 結果，字段名 `organic`（不是 `organic_results`）。
* 搜索通過 [Serp 服務](https://platform.acedata.cloud/services/serp) 走的，按次計費。
* 同一個客戶端實例既能 chat 又能搜，token 一份就夠。

## 配置選項

```ts theme={null}
const client = new AceDataCloud({
  // 必填之一：顯式 token 或環境變量 ACEDATACLOUD_API_TOKEN
  apiToken: process.env.MY_TOKEN,

  // 平台 API 根地址，默認 https://api.acedata.cloud
  baseURL: 'https://api.acedata.cloud',

  // 部分服務（如 dashboard 元數據）走 platform 域名
  platformBaseURL: 'https://platform.acedata.cloud',

  // 單次請求超時，毫秒；默認 300_000（5 分鐘）
  timeout: 300_000,

  // 自動重試次數，默認 2；重試條件：408 / 409 / 429 / 5xx / 網絡錯誤
  maxRetries: 2,

  // 自定義請求頭
  defaultHeaders: { 'x-app': 'my-service/1.0' }
});
```

## 瀏覽器使用

`@acedatacloud/sdk` 是 ESM + ISO（同構）包，可以在帶 bundler 的現代瀏覽器裡直接 `import`。注意：**不要在前端代碼裡把 API Token 硬編碼**。前端推薦：

1. 用 [X402 `paymentHandler`](https://platform.acedata.cloud/documents/sdk-x402-payment) —— 用戶錢包按次簽 USDC，無需 token。
2. 或在自己服務端用 SDK，瀏覽器只調你自己的後端。

## 進階：任務輪詢和流式響應

* 任務類服務（Midjourney、Sora、Veo、Suno）：用 `TaskHandle` 輪詢，單位、超時和重試細節見 [SDK 任務輪詢與流式響應](https://platform.acedata.cloud/documents/sdk-tasks-and-streaming)。
* 流式 chat：本頁示例 2 已演示；流式 audio / video 同樣支持。

## 進階：X402 支付鉤子

如果不想申請 API Token、想按次鏈上付費，可以用 `paymentHandler`：

```ts theme={null}
import { AceDataCloud } from '@acedatacloud/sdk';
import { createX402PaymentHandler } from '@acedatacloud/x402-client';

const client = new AceDataCloud({
  paymentHandler: createX402PaymentHandler({
    network: 'base',
    evmProvider: (window as any).ethereum,  // EIP-1193 provider，或 viem walletClient
    evmAddress: userAddress
  })
});
```

> `createX402PaymentHandler` 在 TypeScript 端接受 `{ network, evmProvider, evmAddress, preferScheme? }`（EVM 鏈）或 `{ network: 'solana', solanaWallet }`（Solana）。Node 服務端沒有 `window.ethereum` 時，請用 `viem` 的 `createWalletClient`（基於私鑰）封裝一個 EIP-1193 兼容的 provider 再傳進來；詳細做法和真實鏈上結果見 [SDK + X402 支付鉤子](https://platform.acedata.cloud/documents/sdk-x402-payment)。

## 如何查看剩餘額度

通過 [Ace Data Cloud 控制台 - 應用列表](https://platform.acedata.cloud/console/applications)，即可查看當前賬戶的剩餘額度。

通過 [Ace Data Cloud 控制台 - 使用歷史](https://platform.acedata.cloud/console/usages) 即可查看所有使用歷史和扣費詳情。

## 了解更多

* 📦 [`@acedatacloud/sdk` on npm](https://www.npmjs.com/package/@acedatacloud/sdk)
* 🗂 [SDK 源碼](https://github.com/AceDataCloud/SDK/tree/main/typescript)
* 🐍 [Python SDK 接入教程](https://platform.acedata.cloud/documents/sdk-python)
* 🟦 [Go SDK 接入教程](https://platform.acedata.cloud/documents/sdk-go)
* 🔌 [SDK + X402 支付鉤子](https://platform.acedata.cloud/documents/sdk-x402-payment)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.