# API 参考

Developer 与模型 API 的完整清单。机器可读版本：[`/developer/openapi.json`](https://www.ai-dc.ai/developer/openapi.json)（由服务端的契约注册表生成，与代码同步）。

## 约定

- 根地址 `https://www.ai-dc.ai`；路径都在 `/api/v1/**` 下，`v1` 内不做破坏性变更。
- 成功：`{ "ok": true, "data": …, "meta": { "requestId", "generatedAt", "version": "v1" } }`；失败：`{ "ok": false, "error": { "code", "message", "details" }, "meta": … }`。例外：OpenAI 兼容端点（`/chat/completions`、`/audio/transcriptions`、`/models`）成功时返回 OpenAI 的形状，失败仍是信封。
- 传 `x-request-id` 可以贯穿日志；响应头回同一个值。
- 写操作支持 `x-aidc-dry-run: true`（返回 202 + 计划，不落库）。

## 鉴权

| 凭证 | 形如 | 谁用 | 能做什么 |
| --- | --- | --- | --- |
| 开发者 Key | `aidc-dk-…` | CLI、服务端、智能体 | 发布应用、调模型与数据集（记 Key 所属公司） |
| 应用票据 | `aidc-at-…` | Nexus 应用里的浏览器 SDK（平台自动注入） | 只能调清单里声明的模型与数据集，按应用额度计量 |
| Agent Key | `aidc-sk-…` | 调智能体（Agent API） | 与某个智能体对话 |

`Authorization: Bearer <凭证>`。

## 端点

### 登录（设备授权，RFC 8628 语义）

| 方法 | 路径 | 说明 |
| --- | --- | --- |
| `POST` | `/api/v1/developer/device-codes` | 开始登录：返回 `deviceCode`、`userCode`、`verificationUriComplete`、`interval` |
| `POST` | `/api/v1/developer/device-codes/decision` | （浏览器，已登录）批准 / 拒绝 |
| `POST` | `/api/v1/developer/device-tokens` | 轮询换 Key：`authorization_pending` → 成功返回 `apiKey`（仅此一次） |
| `GET` | `/api/v1/developer/me` | 当前身份 |
| `GET` | `/api/v1/developer/keys` | 本人的开发者 Key（只含前缀） |
| `DELETE` | `/api/v1/developer/keys/{keyId}` | 吊销（幂等） |

### 应用（发布 SDK）

| 方法 | 路径 | 说明 |
| --- | --- | --- |
| `GET` | `/api/v1/developer/apps` | 列表 |
| `GET` | `/api/v1/developer/apps/{namespace}/{slug}` | 通道、版本、地址 |
| `POST` | `/api/v1/developer/apps/{namespace}/{slug}/versions` | 上传版本包（201 新建 / 200 已存在） |
| `POST` | `/api/v1/developer/apps/{namespace}/{slug}/channels/{channel}` | 晋升到 `test` / `production` |
| `POST` | `/api/v1/developer/apps/{namespace}/{slug}/tickets?channel=` | 应用票据续期 |

### 模型

| 方法 | 路径 | 说明 |
| --- | --- | --- |
| `GET` | `/api/v1/models` | 目录（公开） |
| `GET` | `/api/v1/models/models` | OpenAI 形状的模型列表 |
| `POST` | `/api/v1/models/chat/completions` | OpenAI 兼容对话（文本 / 图片 / 流式 / 结构化） |
| `POST` | `/api/v1/models/audio/transcriptions` | OpenAI 兼容文件转写（multipart，≤ 4 MB） |
| `POST` | `/api/v1/models/realtime/transcription-sessions` | 实时转写票据（WebRTC 直连） |
| `POST` | `/api/v1/models/jev/decisions` | Jev 决策 |

### 数据集（连接 SDK）

| 方法 | 路径 | 说明 |
| --- | --- | --- |
| `GET` | `/api/v1/developer/datasets` | 可读的数据集 |
| `GET` | `/api/v1/developer/datasets/{datasetId}/reports/{reportId}` | 固定报告（只含聚合） |

## 错误码（节选）

| 码 | HTTP | 含义 |
| --- | --- | --- |
| `unauthorized` | 401 | 没带凭证或凭证无效 / 已吊销 / 已过期 |
| `forbidden` | 403 | 没有权限（例如清单没声明这个模型） |
| `rate_limited` | 429 | 太频繁，`details.retryAfterSeconds` |
| `quota_exhausted` | 429 | 应用当日额度用完 |
| `invalid_payload` / `bundle_invalid` | 400 | 请求或版本包不合法，`details.issues` |
| `app_not_found` / `app_version_not_found` | 404 | 应用 / 版本不存在 |
| `version_not_tested` | 409 | 发布没进过 test 的版本 |
| `authorization_pending` / `device_code_expired` / `access_denied` | 400 / 403 | 设备授权的轮询状态 |
| `model_not_found` / `model_upstream_failed` | 404 / 502 | 模型不在目录 / 上游故障 |
