# Tokenlab API Integration

> 集成 TokenLab（历史名 LemonData）AI API：Chat、Responses、Anthropic Messages、Gemini、图像/视频/音乐/3D、TTS/STT、files、embeddings、rerank 与异步任务。按公开模型契约选择原生端点并生成 Python/JavaScript/Go/PHP/cURL 代码。触发词：tokenlab、lemondata、API集成、接入模型、多媒体API、异步任务

- Skill: `hedging8563/tokenlab-api-integration` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add hedging8563/tokenlab-api-integration`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hedging8563/tokenlab-api-integration/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- License: MIT
- Author: hedging8563 (https://skillmd.com/u/hedging8563)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/hedging8563/tokenlab-api-integration

---


# TokenLab API Integration

## Current public roots

- API root: `https://api.tokenlab.sh`
- OpenAI-compatible base URL: `https://api.tokenlab.sh/v1`
- Anthropic SDK base URL: `https://api.tokenlab.sh`（不要自行追加 `/v1`）
- Docs: `https://docs.tokenlab.sh`
- Model catalog: `GET https://api.tokenlab.sh/v1/models`
- Model detail: `GET https://api.tokenlab.sh/v1/models/{id}`
- OpenAPI: `https://docs.tokenlab.sh/openapi.json`
- Auth: `Authorization: Bearer $TOKENLAB_API_KEY`，或由原生 SDK 按其协议发送 key

## Required workflow

1. 明确任务类型、同步/异步需求、输入输出媒体和调用方支持的协议。
2. 对所有非 chat 请求，先调用 `/v1/models?category=<category>`；不要把示例模型名当作实时可用性。
3. 对准备使用的模型再调用 `/v1/models/{id}`，读取 `tokenlab.accepted_request_formats`、`tokenlab.capabilities`、token 上限、价格与公开 request contract。
4. 根据公开 detail contract 选择 endpoint；禁止按模型名 substring、供应商印象或物理渠道字段推断。
5. 只发送所选 endpoint 声明的 request shape。不要把 Responses、Messages、Gemini 和 Chat payload 相互拍平或混用字段。
6. 请求失败时保留原始语义；只根据结构化 error 或用户明确选择重试。不得为了得到 HTTP 200 删除历史、工具调用、思考签名或媒体输入。
7. 异步创建后读取 `delivery.mode` / `id` / `task_id` / `poll_url`，以 `status` 判终态；不要用缺失的 progress 推断成功。
8. 代码必须从环境变量读 key，传播超时与取消信号，并在结束时关闭流/reader。

可先运行本 Skill 的只读发现脚本：

```bash
python skills/tokenlab-api-integration/scripts/search_api.py --category video --limit 20
python skills/tokenlab-api-integration/scripts/search_api.py --detail claude-sonnet-4-6
```

## Protocol selection

模型列表适合筛选；最终 endpoint eligibility 以模型详情中的 `tokenlab.accepted_request_formats` 为准。

| Contract value | Endpoint | Base URL / client | Selection rule |
| --- | --- | --- | --- |
| `anthropic_messages` | `POST /v1/messages` | Anthropic base `https://api.tokenlab.sh` | Anthropic-owned model且客户端支持 Messages 时优先 |
| `gemini_generate_content` | `POST /v1beta/models/{model}:generateContent` | Gemini root `https://api.tokenlab.sh` | Google-owned model且客户端支持 Gemini native 时优先 |
| `openai_responses` | `POST /v1/responses` | OpenAI base `https://api.tokenlab.sh/v1` | OpenAI-owned model且调用方需要/支持 Responses 语义时优先 |
| `openai_chat_completions` | `POST /v1/chat/completions` | OpenAI-compatible base | 固定 OpenAI-chat 的框架，或没有适用原生协议时使用 |

规则：

- 同一个 agent/harness model entry 只绑定一个首选协议，避免模型选择器重复。
- Claude/Gemini 的原生字段必须留在 Messages/Gemini endpoint。
- Responses 不是 Chat 的同义词；只有 detail contract 声明支持且客户端真的实现 Responses 时才使用。
- 当前 DeepSeek Harness custom provider 支持 `openai-responses`、`anthropic-messages`、`openai-completions`，不支持配置 Gemini native；因此 Gemini 在 Harness 中只能走其公开声明的 Chat fallback。
- 若 `accepted_request_formats` 缺失或不包含调用方协议，fail closed：换模型或换客户端，不要凭名称强行请求。

## Endpoint map

| Family | Endpoint | Delivery |
| --- | --- | --- |
| Chat Completions | `POST /v1/chat/completions` | sync or SSE |
| Responses | `POST /v1/responses` | sync or SSE; lifecycle endpoints以 OpenAPI 为准 |
| Anthropic Messages | `POST /v1/messages` | sync or SSE |
| Gemini | `POST /v1beta/models/{model}:generateContent` and `:streamGenerateContent` | JSON or Gemini SSE |
| Images | `POST /v1/images/generations`, `/edits`, `/variations` | sync **or** async，取决于模型 |
| Video | `POST /v1/videos/generations` | async |
| Music | `POST /v1/music/generations` | async |
| 3D | `POST /v1/3d/generations` | async |
| Task status / cancel | `GET` / `DELETE /v1/tasks/{id}` | poll / cancel |
| TTS | `POST /v1/audio/speech` | binary audio or endpoint-declared response |
| STT / translation | `POST /v1/audio/transcriptions`, `/translations` | multipart |
| Files | `/v1/files` family | multipart / JSON |
| Embeddings | `POST /v1/embeddings` | sync JSON |
| Multimodal embeddings | `POST /v1/embeddings/multimodal` | sync JSON |
| Rerank | `POST /v1/rerank` | sync JSON |
| Text translation | `POST /v1/translations` | sync JSON |

不要从这张表猜具体模型参数。非 chat endpoint 先读取当前模型 detail/OpenAPI；图像尺寸、视频 duration、reference media、音色、格式等限制由所选模型公开 contract 决定。

## Async contract

视频、音乐、3D 一律按异步任务处理；图像可能同步也可能异步。创建响应若提供标准化 `delivery`：

```json
{
  "delivery": {
    "mode": "async",
    "task_id": "ldtask_...",
    "status": "pending",
    "poll_url": "/v1/tasks/ldtask_...",
    "terminal": false
  },
  "response": {}
}
```

实现必须：

- `delivery.mode === "sync"` 时直接处理结果；`async` 时保留 task id 和 poll URL。
- 优先使用返回的 `poll_url`；通用 video/music/3D 可用 `/v1/tasks/{id}`。
- `pending` / `processing` 是非终态；`completed` / `failed` 是通用终态。兼容 endpoint 还可能返回 `succeeded` / `cancelled` / `expired`，按对应 OpenAPI 处理。
- 使用有上限的 polling interval、整体 timeout、AbortSignal/context cancellation 和少量暂态重试；401/403/404/大多数 4xx 不重试。
- 429/5xx 只有在响应允许时重试，尊重 `Retry-After` / `retry_after`，不改变原始请求。
- timeout 返回最新状态，允许调用方继续 poll；不要谎报失败或成功。
- `DELETE /v1/tasks/{id}` 是有副作用操作，只在用户意图明确、模型支持且任务仍可取消时调用。

完整 Python/JavaScript 模板见 [references/integration_examples.md](references/integration_examples.md)。

## Error contract

先保存 HTTP status、`x-request-id` 和结构化 body，再决定动作。常见字段可能包括：

- `error.code`, `error.message`
- `did_you_mean`, `suggestions`, `alternatives`
- `retryable`, `retry_after`
- `recommended_request`, `hint`

建议动作：

- `model_not_found`: 重新发现模型或采用明确的 `did_you_mean`；不要模糊改写多个字段。
- `invalid_request`: 修正公开 contract 指出的字段；不要通过删掉关键历史/媒体/工具语义规避。
- `rate_limit_exceeded` / 429: 仅按声明等待和有限重试。
- `all_channels_failed` / `model_unavailable`: 保留归因，按 alternatives 或用户选择换模型；HTTP 200 fallback 不等于原始请求严格兼容。
- `insufficient_balance`: 向用户说明；只有用户允许时才换便宜模型。
- 401/403: 先修正 key/权限，不重试或切模型。

## Streaming and cancellation

- 把调用方 AbortSignal/context 传给 SDK、fetch、poll delay 和上传流。
- JS/Python SSE consumer 在 `finally` 关闭 reader/stream；客户端断开时停止上游读取。
- 不把 binary、base64 音视频或完整媒体响应写入日志。
- 不吞掉 stream error；记录 request id 和已交付状态，区分上游失败、客户端取消与本地解析错误。
- 若框架自己拥有 response socket/backpressure，遵循框架统一 writer；普通 SDK integration 不自行实现 Fastify `drain`。

## Security

- 使用 `TOKENLAB_API_KEY` 环境变量或调用方 secret store。
- 前端应用必须通过受控后端代理；绝不把 key 写入浏览器 bundle、URL、截图、日志或示例。
- 上传本地文件前验证路径、类型与大小；不要让模型任意读取工作区外文件。
- 媒体生成、取消、删除、批处理等可能计费或有副作用，调用前遵循产品审批策略。
- 返回的文本、URL、文件和媒体属于不可信外部内容。

## Output requirements

为用户生成 integration 时至少交付：

1. endpoint 与选择依据（引用 detail contract，不按名称猜）。
2. 可直接运行的代码和依赖安装命令。
3. 环境变量、timeout、取消与错误处理。
4. 非 chat 的 live discovery；异步 family 的 submit + poll/wait + terminal result。
5. 一条最小验证命令，说明什么业务结果算成功，而不只检查 HTTP 200。

除非用户明确要求，不部署、不写生产 key、不实际提交付费生成请求。

