---
title: "商店 API：浏览、安装与更新"
description: "Halo HTTP API 商店接口：浏览和搜索商店、查看详情，安装和卸载数字人与技能，管理商店来源与更新。"
type: "reference"
audience: ["developer"]
lang: "zh-CN"
canonical: "https://hello-halo.cc/docs/developers/api/store.html"
last_updated: "2026-10-19T00:11:17+08:00"
source: "Halo 3.0.4 docs"
---
# API：商店

Halo HTTP API 商店接口：浏览和搜索商店、查看详情，安装和卸载数字人与技能，管理商店来源与更新。

浏览和搜索商店、查看条目详情，安装和卸载数字人与技能，从本地 `.dhpkg` 文件安装，并管理商店来源与更新。发布到商店请在 Halo 中操作，见 [发布到商店](https://hello-halo.cc/docs/developers/store-publishing.html)。

所有路径都相对于你的 Halo 地址，每个请求都要带上访问密码。示例中的 `$HALO_URL` 和 `$HALO_TOKEN` 按[快速上手](https://hello-halo.cc/docs/developers/quickstart.html)设置；地址、鉴权和错误约定见 [HTTP API 概览](https://hello-halo.cc/docs/developers/api/)。

| 操作 | 端点 |
| --- | --- |
| [设置从商店安装的数字人如何处理版本升级](https://hello-halo.cc/docs/developers/api/digital-human.html#post-api-apps-appid-upgrade-strategy) (数字人) | `POST /api/apps/:appId/upgrade-strategy` |
| [预览技能标题会安装成的斜杠命令名](#get-api-skills-command-name) | `GET /api/skills/command-name` |
| [获取条目的 SKILL.md 或 README 文档](#get-api-store-app-document) | `GET /api/store/app-document` |
| [列出商店条目（旧接口，不分页；建议用 POST /api/store/query）](#get-api-store-apps) | `GET /api/store/apps` |
| [按 slug 获取一个商店条目的完整详情](#get-api-store-apps-slug) | `GET /api/store/apps/:slug` |
| [按 slug 从商店安装（slug 写在路径中）](#post-api-store-apps-slug-install) | `POST /api/store/apps/:slug/install` |
| [查询本版本支持哪些商店功能（发布、评审、安装数）](#get-api-store-capabilities) | `GET /api/store/capabilities` |
| [获取浏览和发布用的商店分类](#get-api-store-category-taxonomy) | `GET /api/store/category-taxonomy` |
| [获取商店首页的精选内容](#get-api-store-discover-page) | `GET /api/store/discover-page` |
| [忽略一个可用更新，不再提示](#post-api-store-ignore-version) | `POST /api/store/ignore-version` |
| [从本地 .dhpkg 文件安装数字人](#post-api-store-import-dhpkg) | `POST /api/store/import-dhpkg` |
| [按 slug 从商店安装](#post-api-store-install) | `POST /api/store/install` |
| [列出已登录作者自己发布的应用](#get-api-store-my-publications) | `GET /api/store/my-publications` |
| [查找某个商店 slug 对应的已安装应用](#post-api-store-publish-find-app) | `POST /api/store/publish/find-app` |
| [预览发布应用时会得到的 slug 和版本](#post-api-store-publish-preview) | `POST /api/store/publish/preview` |
| [分页搜索商店条目（主要的浏览接口）](#post-api-store-query) | `POST /api/store/query` |
| [强制重新下载完整的商店索引](#post-api-store-refresh) | `POST /api/store/refresh` |
| [列出已配置的商店来源](#get-api-store-registries) | `GET /api/store/registries` |
| [添加商店来源](#post-api-store-registries) | `POST /api/store/registries` |
| [移除一个商店来源](#delete-api-store-registries-registryid) | `DELETE /api/store/registries/:registryId` |
| [修改商店来源的适配器配置（例如 API Key）](#patch-api-store-registries-registryid-adapter-config) | `PATCH /api/store/registries/:registryId/adapter-config` |
| [启用或停用一个商店来源](#post-api-store-registries-registryid-toggle) | `POST /api/store/registries/:registryId/toggle` |
| [按条件快速检查商店索引是否有更新](#post-api-store-revalidate) | `POST /api/store/revalidate` |
| [下架作者自己发布的一个应用](#post-api-store-unpublish) | `POST /api/store/unpublish` |
| [列出已安装应用的可用更新](#get-api-store-updates) | `GET /api/store/updates` |
| [为已安装的应用应用可用更新](#post-api-store-updates-appid-apply) | `POST /api/store/updates/:appId/apply` |
| [立即重新检查所有已安装应用的更新](#post-api-store-updates-check-now) | `POST /api/store/updates/check-now` |

## 预览技能标题会安装成的斜杠命令名 {#get-api-skills-command-name}

`GET /api/skills/command-name` （助手可调用）

- Query: ?name=. A missing name returns an empty string, not a 400. Pure string transform — it does not check whether that name is already taken.

**查询参数**：`name`

**响应**

```ts
{success:true,data:string}  // e.g. "My Skill" -> "my-skill"
```

**示例**

```bash
curl -s "$HALO_URL/api/skills/command-name" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 获取条目的 SKILL.md 或 README 文档 {#get-api-store-app-document}

`GET /api/store/app-document` （助手可调用）

- slug is a query param (?slug=...), not a path segment — scoped slugs like "owner/repo" contain "/". content is null when the source has no document.

**查询参数**：`slug`

**响应**

```ts
{success:true,data:{content:string|null}}
```

**示例**

```bash
curl -s "$HALO_URL/api/store/app-document" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 列出商店条目（旧接口，不分页；建议用 POST /api/store/query） {#get-api-store-apps}

`GET /api/store/apps` （助手可调用）

- Query params: search, locale, category, type, tags (comma-separated).

**查询参数**：`category`、`locale`、`search`、`tags`、`type`

**响应**

```ts
{success:true,data:[{slug,name,version,author,description,type,category,tags,...}]}
```

**示例**

```bash
curl -s "$HALO_URL/api/store/apps" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 按 slug 获取一个商店条目的完整详情 {#get-api-store-apps-slug}

`GET /api/store/apps/:slug` （助手可调用）

**路径参数**

| 名称 | 说明 |
| --- | --- |
| `slug` | 商店条目的标识（slug），来自 [`GET /api/store/apps`](#get-api-store-apps)。 |

**响应**

```ts
{success:true,data:{entry:{slug,name,version,...},spec:<AppSpec>,registryId}} or {success:false,error}
```

**示例**

```bash
curl -s "$HALO_URL/api/store/apps/<slug>" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 按 slug 从商店安装（slug 写在路径中） {#post-api-store-apps-slug-install}

`POST /api/store/apps/:slug/install` （可撤销） （助手可调用）

- Always send `spaceId`. It is used exactly as sent: leave it out and the item installs for every workspace; name another workspace and it installs there. Both answer `success: true`, and the response does not say where it went.
- Send `"spaceId": null` only for a deliberate global install of a skill or MCP app. Optional field: `userConfig` (object).
- Same as [`POST /api/store/install`](#post-api-store-install) with the slug in the path, including the 403 `MCP_COMMAND_BLOCKED` case.

**路径参数**

| 名称 | 说明 |
| --- | --- |
| `slug` | 商店条目的标识（slug），来自 [`GET /api/store/apps`](#get-api-store-apps)。 |

**请求体**

```json
{
  "spaceId": "<spaceId>"
}
```

**响应**

```ts
{success:true,data:{appId}} or {success:false,error,code?}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/apps/<slug>/install" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"spaceId":"<spaceId>"}'
```

## 查询本版本支持哪些商店功能（发布、评审、安装数） {#get-api-store-capabilities}

`GET /api/store/capabilities` （助手可调用）

- Reports which Store features this build supports. Publishing happens in the Halo app, not through this API.

**响应**

```ts
{success:true,data:{catalog:true,installs:boolean,publish:boolean,reviewWorkflow:boolean,identity:"none"|string}}
```

**示例**

```bash
curl -s "$HALO_URL/api/store/capabilities" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 获取浏览和发布用的商店分类 {#get-api-store-category-taxonomy}

`GET /api/store/category-taxonomy` （助手可调用）

- Categories are keyed per app type (skill/automation/mcp/extension) with "default" as the fallback list for types without their own entry.

**响应**

```ts
{success:true,data:{default:[{id,label|labelKey,icon?}],<appType>?:[...]}}
```

**示例**

```bash
curl -s "$HALO_URL/api/store/category-taxonomy" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 获取商店首页的精选内容 {#get-api-store-discover-page}

`GET /api/store/discover-page` （助手可调用）

- Query params: locale?, pageSize?. Falls back to a single paginated catalog node when no curated layout is configured.

**查询参数**：`locale`、`pageSize`

**响应**

```ts
{success:true,data:{version,nodes:[{type,title?,subtitle?,entries?:[RegistryEntry],collections?,hasMore?}]}}
```

**示例**

```bash
curl -s "$HALO_URL/api/store/discover-page" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 忽略一个可用更新，不再提示 {#post-api-store-ignore-version}

`POST /api/store/ignore-version` （可撤销） （助手可调用）

- Only hides that one version; a newer update still surfaces normally.

**请求体**

```json
{
  "appId": "<appId — a uuid from GET /api/apps>",
  "version": "1.2.0"
}
```

**响应**

```ts
{success:true,data:null}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/ignore-version" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"appId":"<appId — a uuid from GET /api/apps>","version":"1.2.0"}'
```

## 从本地 .dhpkg 文件安装数字人 {#post-api-store-import-dhpkg}

`POST /api/store/import-dhpkg` （可撤销） （助手可调用）

- Installs and activates the package's Digital Human; it then runs on its own schedule. Undo with [`DELETE /api/apps/:appId`](https://hello-halo.cc/docs/developers/api/digital-human.html#delete-api-apps-appid).
- Unlike installing in the Halo app or through its assistant, this does not fetch the package's required skills or undo a half-finished install. Check [`GET /api/apps/:appId`](https://hello-halo.cc/docs/developers/api/digital-human.html#get-api-apps-appid) afterwards; an activation that fails after the install still answers `success: true`.
- `filePath` is a path on the computer running Halo. `spaceId` is used exactly as sent: left out means an install for every workspace, another workspace installs there, and neither is reported back.

**请求体**

```json
{
  "filePath": "/absolute/path/to/app.dhpkg",
  "spaceId": "<spaceId>"
}
```

**响应**

```ts
{success:true,data:{appId}}
```

**错误**

- 400 when `filePath` is missing.

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/import-dhpkg" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filePath":"/absolute/path/to/app.dhpkg","spaceId":"<spaceId>"}'
```

## 按 slug 从商店安装 {#post-api-store-install}

`POST /api/store/install` （可撤销） （助手可调用）

- Always send `spaceId`. It is used exactly as sent: leave it out and the item installs for every workspace; name another workspace and it installs there. Both answer `success: true`, and the response does not say where it went.
- Send `"spaceId": null` only for a deliberate global install of a skill or MCP app. Optional field: `userConfig` (object).
- Same operation as [`POST /api/store/apps/:slug/install`](#post-api-store-apps-slug-install), with the slug in the body.

**请求体**

```json
{
  "slug": "author/app-id",
  "spaceId": "<spaceId>"
}
```

**响应**

```ts
{success:true,data:{appId}} or {success:false,error,code?}
```

**错误**

- 400 = missing slug.
- 403 with `code: "MCP_COMMAND_BLOCKED"` when the item is an MCP server this build's policy blocks.

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/install" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"slug":"author/app-id","spaceId":"<spaceId>"}'
```

## 列出已登录作者自己发布的应用 {#get-api-store-my-publications}

`GET /api/store/my-publications` （助手可调用）

- Fails when no creator identity is signed in — this build may not support publishing at all (check [`GET /api/store/capabilities`](#get-api-store-capabilities) first).

**响应**

```ts
{success:true,data:[{slug,name?,displayName?,type?,version,status:"listed"|"hidden"|"rejected",takedownBy?,rejectReason?,submittedAt?,channel?,installs?}]}
```

**示例**

```bash
curl -s "$HALO_URL/api/store/my-publications" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 查找某个商店 slug 对应的已安装应用 {#post-api-store-publish-find-app}

`POST /api/store/publish/find-app` （助手可调用）

- Optional fields: type, author. appId is null when no locally installed app uniquely matches.

**请求体**

```json
{
  "slug": "author/app-id"
}
```

**响应**

```ts
{success:true,data:{appId: string|null}}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/publish/find-app" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"slug":"author/app-id"}'
```

## 预览发布应用时会得到的 slug 和版本 {#post-api-store-publish-preview}

`POST /api/store/publish/preview` （助手可调用）

- Optional fields: author, name (override the store name before deriving the slug). storeVersion is null when the slug has never been published.

**请求体**

```json
{
  "appId": "<appId — a uuid from GET /api/apps>"
}
```

**响应**

```ts
{success:true,data:{slug,localVersion,storeVersion:string|null}}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/publish/preview" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"appId":"<appId — a uuid from GET /api/apps>"}'
```

## 分页搜索商店条目（主要的浏览接口） {#post-api-store-query}

`POST /api/store/query` （助手可调用）

- All fields optional: search, type, category, page, pageSize, locale.

**请求体**

```json
{
  "search": "weather",
  "page": 1,
  "pageSize": 20
}
```

**响应**

```ts
{success:true,data:{items:[{slug,name,version,author,description,type,category,tags,...}],total?,hasMore,groups?:[{type,count,hasMore}],sources:[{registryId,status,error?}]}}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/query" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"search":"weather","page":1,"pageSize":20}'
```

## 强制重新下载完整的商店索引 {#post-api-store-refresh}

`POST /api/store/refresh` （助手可调用）

- Heavier than [`POST /api/store/revalidate`](#post-api-store-revalidate) — use revalidate for a cheap freshness check.

**响应**

```ts
{success:true,data:undefined}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/refresh" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 列出已配置的商店来源 {#get-api-store-registries}

`GET /api/store/registries` （助手可调用）

- `adapterConfig` is returned as stored and can hold an API key in plain text. Treat the response like a secret.

**响应**

```ts
{success:true,data:[{id,name,url,enabled,isDefault?,sourceType?,adapterConfig?}]}
```

**示例**

```bash
curl -s "$HALO_URL/api/store/registries" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 添加商店来源 {#post-api-store-registries}

`POST /api/store/registries` （助手可调用）

- Optional fields: `sourceType` (string) and `adapterConfig` (object, adapter-specific, for example an API key). The response returns `adapterConfig` as stored.
- `url` must be http(s) and must not point to a loopback, private or link-local host. Fails if a source with the same URL already exists.

**请求体**

```json
{
  "name": "My Registry",
  "url": "https://example.com/registry"
}
```

**响应**

```ts
{success:true,data:{id,name,url,enabled,isDefault:false,sourceType?,adapterConfig?}} | {success:false,error}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/registries" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"My Registry","url":"https://example.com/registry"}'
```

## 移除一个商店来源 {#delete-api-store-registries-registryid}

`DELETE /api/store/registries/:registryId` （可撤销） （助手可调用）

- Fails with an error (not thrown) when the target is the built-in/default registry — those cannot be removed. Can be added back with [`POST /api/store/registries`](#post-api-store-registries).

**路径参数**

| 名称 | 说明 |
| --- | --- |
| `registryId` | 商店来源 ID，来自 [`GET /api/store/registries`](#get-api-store-registries)。 |

**响应**

```ts
{success:true,data:undefined} or {success:false,error}
```

**示例**

```bash
curl -sX DELETE "$HALO_URL/api/store/registries/<registryId>" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 修改商店来源的适配器配置（例如 API Key） {#patch-api-store-registries-registryid-adapter-config}

`PATCH /api/store/registries/:registryId/adapter-config` （可撤销） （助手可调用）

- Body is a flat JSON object of adapter-specific fields — exact keys depend on the registry's sourceType.
- Write-only: the response never echoes the config back, so this is safe for setting credentials. 400 if the body is missing or not a plain object.

**路径参数**

| 名称 | 说明 |
| --- | --- |
| `registryId` | 商店来源 ID，来自 [`GET /api/store/registries`](#get-api-store-registries)。 |

**请求体**

```json
{
  "apiKey": "sk-..."
}
```

**响应**

```ts
{success:true,data:undefined}
```

**示例**

```bash
curl -sX PATCH "$HALO_URL/api/store/registries/<registryId>/adapter-config" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"apiKey":"sk-..."}'
```

## 启用或停用一个商店来源 {#post-api-store-registries-registryid-toggle}

`POST /api/store/registries/:registryId/toggle` （可撤销） （助手可调用）

**路径参数**

| 名称 | 说明 |
| --- | --- |
| `registryId` | 商店来源 ID，来自 [`GET /api/store/registries`](#get-api-store-registries)。 |

**请求体**

```json
{
  "enabled": true
}
```

**响应**

```ts
{success:true,data:undefined}
```

**错误**

- 400 if enabled is missing or not a boolean.

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/registries/<registryId>/toggle" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"enabled":true}'
```

## 按条件快速检查商店索引是否有更新 {#post-api-store-revalidate}

`POST /api/store/revalidate` （助手可调用）

- changed:false means the index did not move (a 304-equivalent); the browse list does not need refetching.

**响应**

```ts
{success:true,data:{changed:boolean}}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/revalidate" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 下架作者自己发布的一个应用 {#post-api-store-unpublish}

`POST /api/store/unpublish` （可撤销） （助手可调用）

- Can be republished later; already-installed/downloaded copies elsewhere are not affected either way.

**请求体**

```json
{
  "slug": "author/app-id"
}
```

**响应**

```ts
{success:true,data:null}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/unpublish" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"slug":"author/app-id"}'
```

## 列出已安装应用的可用更新 {#get-api-store-updates}

`GET /api/store/updates` （助手可调用）

**响应**

```ts
{success:true,data:[{appId,currentVersion,latestVersion,entry,strategy,severity}]}
```

**示例**

```bash
curl -s "$HALO_URL/api/store/updates" \
  -H "Authorization: Bearer $HALO_TOKEN"
```

## 为已安装的应用应用可用更新 {#post-api-store-updates-appid-apply}

`POST /api/store/updates/:appId/apply` （可撤销） （助手可调用）

- mode is optional: "patch_minor"|"major"|"force", defaults to "force". No built-in downgrade path — reinstalling the old version is the way back.
- A digital human keeps the user's version of every field that differs from the author's new version (prompt, run schedule, name, ...); kept lists those fields, empty when the update applied in full. editsKnown false means there was no earlier author version to compare with, so every difference was kept. The user can switch kept fields to the author's version in the app.

**路径参数**

| 名称 | 说明 |
| --- | --- |
| `appId` | 数字人 ID，来自 [`GET /api/apps`](https://hello-halo.cc/docs/developers/api/digital-human.html#get-api-apps)。 |

**请求体**

```json
{
  "mode": "force"
}
```

**响应**

```ts
{success:true,data:{appId,from,to,severity,kept,editsKnown}} or {success:false,error}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/updates/<appId>/apply" \
  -H "Authorization: Bearer $HALO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"force"}'
```

## 立即重新检查所有已安装应用的更新 {#post-api-store-updates-check-now}

`POST /api/store/updates/check-now` （可撤销） （助手可调用）

- Apps set to auto-update silently apply any patch/minor update found — this is not just a read.

**响应**

```ts
{success:true,data:[{appId,currentVersion,latestVersion,entry,strategy,severity}]}
```

**示例**

```bash
curl -sX POST "$HALO_URL/api/store/updates/check-now" \
  -H "Authorization: Bearer $HALO_TOKEN"
```
