# SkillPKG Skill/Solution API

Canonical API base: https://skillpkg.com/api/v1

对外 API 用于按分类、类型、推荐状态和名称查询 Skill/Solution，读取详情并获取 ZIP 的临时下载地址。以下接口全部需要 API Key。它们当前只返回已发布、已上架且发布版本审核通过的 `skill` 和 `solution`，不包含 `claw`、提示词、文章或助手会话。

## 鉴权与标识

在 [账户](https://skillpkg.com/account) 的“API Key 管理”创建密钥，然后在请求头中传递：

```http
Authorization: Bearer YOUR_SKILLPKG_API_KEY
```

Key 属于用户凭证。不要放入 URL 查询参数、公开代码或分享内容；网站登录会话不会替代 API Key。

- `publicId`：对外稳定标识，列表返回后用于详情和下载请求。
- `slug`：用于网页跳转，例如 `/packages/{slug}`。
- `categoryPublicId`：分类公开标识，来自分类接口，不是分类 slug 或内部数据库 id。

## 四个接口

| 方法 | 路径 | 返回内容 |
| --- | --- | --- |
| GET | `/api/v1/skills/categories` | `data.docs` 中的全部技能包分类，不分页 |
| GET | `/api/v1/skills` | `data.docs` 中的 Skill/Solution 列表及 `data.meta` 分页信息 |
| GET | `/api/v1/skills/{publicId}` | `data` 中的单个包详情 |
| GET | `/api/v1/skills/{publicId}/download` | `data.url` 中的临时 ZIP 下载链接，不直接返回 ZIP 字节 |

### 列表参数

| 参数 | 默认值 | 说明 |
| --- | --- | --- |
| `type` | Skill 和 Solution | 仅接受 `skill`、`solution`；可重复参数或用逗号分隔 |
| `categoryPublicId` | 所有分类 | 分类接口返回的 publicId；可重复参数或用逗号分隔 |
| `isFeatured` | 不筛选推荐状态 | 仅接受 `true` 或 `false`；false 表示仅非推荐项 |
| `q` | 不按名称筛选 | 名称模糊匹配，与网页搜索的范围不同 |
| `page` | `1` | 正整数 |
| `pageSize` | `20` | `1`–`100` 的整数 |

例如：

```text
/api/v1/skills?type=skill&isFeatured=true&page=1&pageSize=20
/api/v1/skills?type=skill&type=solution
/api/v1/skills?categoryPublicId=FIRST_CATEGORY_PUBLIC_ID,SECOND_CATEGORY_PUBLIC_ID
```

分类标识示例是占位符，须替换为分类接口实际返回的值。列表当前按创建时间倒序返回；没有匹配结果时 `data.docs` 为空，分页信息仍应读取响应。

## 推荐调用顺序

1. 获取分类列表，保存需要的分类 publicId。
2. 查询列表，根据 `data.meta.totalPages` 翻页，不要把第一页当作完整目录。
3. 使用候选项的 publicId 请求详情，读取说明、目录、版本、来源和风险等级。
4. 用户需要下载时，请求该 publicId 的 download 接口，再使用返回的 `data.url` 获取 ZIP。

curl 示例（由调用环境提供 `SKILLPKG_API_KEY`，不要把真实密钥写进文档）：

```sh
curl --fail-with-body 'https://skillpkg.com/api/v1/skills?type=skill&page=1&pageSize=20' \
  -H "Authorization: Bearer ${SKILLPKG_API_KEY}"

curl --fail-with-body 'https://skillpkg.com/api/v1/skills/ACTUAL_PUBLIC_ID' \
  -H "Authorization: Bearer ${SKILLPKG_API_KEY}"

curl --fail-with-body 'https://skillpkg.com/api/v1/skills/ACTUAL_PUBLIC_ID/download' \
  -H "Authorization: Bearer ${SKILLPKG_API_KEY}"
```

将 `ACTUAL_PUBLIC_ID` 替换为列表返回的标识。下载 URL 有时效，应在获取后尽快使用；失效时重新请求，不应当作永久资源链接。访问对象存储下载链接时不需要继续发送 SkillPKG 的 Authorization 请求头。

## 返回数据

成功响应的公共外层为：

```json
{
  "message": "successful",
  "code": 200,
  "data": {}
}
```

列表的 `data` 包含 `docs` 和 `meta`，meta 的字段为 `totalDocs`、`totalPages`、`page`、`limit`。

列表项包含 `publicId`、`slug`、`type`、`name`、`description`、`category`、`author`、`publisher`、`homepage`、`riskLevel`、`isFeatured`。其中部分说明、关联对象和风险信息可以为空。

详情还包含 `skillMd`、`fileStructure`、`version`、`downloadCount`、`createdAt`、`updatedAt`：

- `skillMd` 是发布版本所选展示入口文件的正文，字段名称不保证正文一定来自 SKILL.md；可能来自 README.md。
- `fileStructure` 是文件/目录节点数组，节点包括 `name`、`path`、`type`，可包含 `bytes` 和 `children`；解析失败可返回空数组。
- `riskLevel` 可为 `benign`、`suspicious`、`malicious` 或空值。未知风险不能解释为已通过审查。
- `author` 优先反映提交用户的信息，`publisher` 为另一个作者/发布者信息对象；需要署名或核对来源时应结合二者及原始链接。

下载成功时 `data` 为 `{ "url": "临时下载地址" }`。它没有独立版本选择参数，获取的是该记录当前发布文件的下载链接。

## 错误处理和时效

错误响应包含 `error` 字符串，按 HTTP 状态处理：

| 状态 | 下一步 |
| --- | --- |
| `400` | 修正页码、pageSize、类型或 isFeatured 参数 |
| `401` | 检查是否提供有效 API Key；不要改用网页登录凭证尝试绕过 |
| `404` | 详情不存在、未公开或下载文件不可用，重新确认实际 publicId 与当前列表 |
| `500` | 服务端错误，保留错误信息并稍后重试 |

分类和查询结果使用服务端缓存，因此不能作为实时变更通知。下载链接与发布状态应在需要下载时重新获取。这里描述的接口不支持投稿、内容修改、助手运行或本地安装。

Related: [技能包](https://skillpkg.com/packages.md)、[分类](https://skillpkg.com/categories.md)、[账户](https://skillpkg.com/account.md)、[搜索](https://skillpkg.com/search.md)。
