---
title: 外掛程式 API
url: https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api
description: 盤點並管理您 Claude Enterprise 組織中的外掛程式：上傳外掛程式與版本、選擇提供給成員的版本、控制誰可以使用每個外掛程式、下載外掛程式檔案以供審查，並在連接市集之前先驗證市集。
---

外掛程式 API 可讓您盤點 Claude Enterprise 組織中的每個「plugin」（外掛程式），從您自己的管線發布外掛程式與新版本，選擇要提供給成員的版本，控制誰可以使用每個外掛程式，下載外掛程式檔案以供審查，並在連接 Git「marketplace」（市集）之前先檢查它。

如需外掛程式*使用情況*報告（成員使用哪些外掛程式和技能，以及使用頻率），請參閱 [Analytics API](https://platform.claude.com/docs/zh-TW/manage-claude/analytics-api)。

<Check>
  **需要具有「scope」（範圍）的 Admin API 金鑰**

  這些端點需要具有 `read:plugins` 範圍（適用於 `GET` 端點，包括封存檔下載）或 `write:plugins` 範圍（適用於 `POST` 和 `DELETE` 端點，但市集驗證除外，兩種範圍皆可使用）的 Admin API 金鑰；[範圍](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#scopes)提供詳細資訊，包括另外兩個同樣適用的讀取範圍。請參閱[建立 Admin API 金鑰](https://platform.claude.com/docs/zh-TW/manage-claude/admin-api-keys#create-a-key-for-a-claude-enterprise-organization)，了解您的主要擁有者在何處建立金鑰。請在每個請求的 `x-api-key` 標頭中傳遞金鑰，並搭配 [`anthropic-version`](https://platform.claude.com/docs/zh-TW/api/versioning) 標頭以及下方附註中所示的 beta 標頭。
</Check>

<Note>
  外掛程式 API 目前為 **beta** 版，僅供 Claude Enterprise 組織使用。Claude Platform（Claude Console）組織，或已啟用 HIPAA 就緒的組織，皆無法使用。

  每個請求都必須包含 [beta 標頭](https://platform.claude.com/docs/zh-TW/api/beta-headers) `anthropic-beta: ce-plugins-2026-09-01`（SDK 和 `ant` CLI 會為您傳送）。未包含此標頭的請求會傳回 `404`，就如同該端點不存在一樣。
</Note>

## 端點

此 API 在五種資源中提供 18 個端點：

| 資源                                                               | 端點                                                                                                                                                                                                                                                                                                                        |
| ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **外掛程式**：列出組織中的每個外掛程式、上傳新的外掛程式、查詢單一外掛程式、選擇提供給成員的版本（回復或升級）、刪除外掛程式 | `GET /v1/organizations/plugins`<br />`POST /v1/organizations/plugins`<br />`GET /v1/organizations/plugins/{plugin_id}`<br />`POST /v1/organizations/plugins/{plugin_id}`<br />`DELETE /v1/organizations/plugins/{plugin_id}`                                                                                              |
| **外掛程式版本**：列出外掛程式的版本歷史、上傳新版本、查詢單一版本、下載版本的檔案                      | `GET /v1/organizations/plugins/{plugin_id}/versions`<br />`POST /v1/organizations/plugins/{plugin_id}/versions`<br />`GET /v1/organizations/plugins/{plugin_id}/versions/{version}`<br />`GET /v1/organizations/plugins/{plugin_id}/versions/{version}/content`                                                           |
| **安裝設定**：讀取誰可以使用組織擁有的外掛程式、為整個組織或單一群組設定、移除任一設定                    | `GET /v1/organizations/plugins/{plugin_id}/installation_settings`<br />`POST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}`<br />`DELETE /v1/organizations/plugins/{plugin_id}/installation_settings/{target}`                                                                                     |
| **分享**：讀取成員將自己的外掛程式分享給了誰（唯讀）                                     | `GET /v1/organizations/plugins/{plugin_id}/shares`                                                                                                                                                                                                                                                                        |
| **外掛程式市集**：尋找市集的 ID、查詢單一市集、為其外掛程式設定預設安裝設定、在連接市集之前檢查市集內容          | `GET /v1/organizations/plugin_marketplaces`<br />`GET /v1/organizations/plugin_marketplaces/{marketplace_id}`<br />`POST /v1/organizations/plugin_marketplaces/{marketplace_id}`<br />`POST /v1/organizations/plugin_marketplaces/validate_repository`<br />`POST /v1/organizations/plugin_marketplaces/validate_archive` |

此版本不包含獨立技能（成員在技能編輯器中撰寫，或在 claude.ai 中以單一技能形式上傳的技能）。它們不會出現在清單中，也無法在此建立。Anthropic 發布的外掛程式也不會列入清單；其使用情況由 [Analytics API](https://platform.claude.com/docs/zh-TW/manage-claude/analytics-api) 回報。市集是在 claude.ai 中建立、連接到儲存庫及刪除的，而非透過此 API。

## 先決條件

* 您的組織必須使用 Claude Enterprise 方案。
* 您的主要擁有者在 [claude.ai > Organization settings > API](https://claude.ai/admin-settings/api-access) 中建立具有 `read:plugins` 範圍、`write:plugins` 範圍或兩者兼具的 Admin API 金鑰。請參閱[建立 Admin API 金鑰](https://platform.claude.com/docs/zh-TW/manage-claude/admin-api-keys#create-a-key-for-a-claude-enterprise-organization)。
* 每個請求都帶有三個標頭：`x-api-key`、`anthropic-version: 2023-06-01` 和 `anthropic-beta: ce-plugins-2026-09-01`。

Python、TypeScript、C#、Go、Java、PHP 和 Ruby SDK 在 `client.beta.organization` (csharp, go: `client.Beta.Organization`; java: `client.beta().organization()`; php: `$client->beta->organization`) 下提供這些端點，[`ant` CLI](https://platform.claude.com/docs/zh-TW/cli-sdks-libraries/cli/quickstart) 則在 `ant beta:organization` 下提供；它們會為您傳送 `anthropic-version` 和 `anthropic-beta` 標頭。本頁的範例使用各 SDK 的預設用戶端，與 CLI 一樣，會從 `ANTHROPIC_API_KEY` 環境變數讀取 Admin API 金鑰；curl 範例從同一個變數讀取金鑰，並在 `x-api-key` 標頭中傳遞。當 SDK 或 CLI 為您擷取更多頁面時，`limit` 設定的是每頁大小，而非總數（請參閱[分頁](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#pagination)）。

API 金鑰屬於組織，在建立者離開後仍會繼續運作。請勿分享金鑰，也不要將其簽入原始碼控制系統。

## 快速入門

列出您組織自有市集中的外掛程式，最新的排在最前面：

<CodeGroup>
  ```bash cURL
  curl "https://api.anthropic.com/v1/organizations/plugins?owner_type=organization&limit=20" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugins list --owner-type organization --limit 20
  ```

  ```python Python
  client = anthropic.Anthropic()

  plugins = client.beta.organization.plugins.list(owner_type="organization", limit=20)

  # 視需要自動擷取更多頁面。
  for plugin in plugins:
      print(f"{plugin.id}: {plugin.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const plugins = await client.beta.organization.plugins.list({
    owner_type: "organization",
    limit: 20
  });

  for await (const plugin of plugins) {
    console.log(`${plugin.id}: ${plugin.name}`);
  }
  ```

  ```csharp C#
  using Anthropic.Models.Beta.Organization.Plugins;

  AnthropicClient client = new();

  var page = await client.Beta.Organization.Plugins.List(
      new() { OwnerType = OwnerType.Organization, Limit = 20 }
  );

  await foreach (var plugin in page.Paginate())
  {
      Console.WriteLine($"{plugin.ID}: {plugin.Name}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  plugins := client.Beta.Organization.Plugins.ListAutoPaging(context.Background(), anthropic.BetaOrganizationPluginListParams{
  	OwnerType: anthropic.BetaOrganizationPluginListParamsOwnerTypeOrganization,
  	Limit:     anthropic.Int(20),
  })

  for plugins.Next() {
  	plugin := plugins.Current()
  	fmt.Printf("%s: %s\n", plugin.ID, plugin.Name)
  }
  if err := plugins.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  import com.anthropic.models.beta.organization.plugins.PluginListParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = PluginListParams.builder()
          .ownerType(PluginListParams.OwnerType.ORGANIZATION)
          .limit(20)
          .build();
      var plugins = client.beta().organization().plugins().list(params);

      for (var plugin : plugins.autoPager()) {
          IO.println(plugin.id() + ": " + plugin.name());
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\Organization\Plugins\PluginListParams\OwnerType;
  // ...

  $client = new Client();

  $plugins = $client->beta->organization->plugins->list(
      limit: 20,
      ownerType: OwnerType::ORGANIZATION,
  );

  // 僅限此頁；若要取得下一頁，請以 page: $plugins->nextPage 再次呼叫 list()。
  foreach ($plugins->getItems() as $plugin) {
      echo "{$plugin->id}: {$plugin->name}\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  page = client.beta.organization.plugins.list(owner_type: :organization, limit: 20)

  page.auto_paging_each do |plugin|
    puts "#{plugin.id}: #{plugin.name}"
  end
  ```
</CodeGroup>

```json
{
  "data": [
    {
      "type": "plugin",
      "id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
      "name": "sales-toolkit",
      "display_name": "Sales Toolkit",
      "description": "Account research and call prep for the sales team.",
      "served_version_id": "pluginver_01Km7tL4pR9xF5sU2zV3jP6q",
      "served_version_pinned": true,
      "latest_version_id": "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
      "manifest_version": "1.4.0",
      "owner": { "type": "organization" },
      "marketplace_id": "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
      "created_by": { "type": "api_actor", "api_key_id": "apikey_01Nq9vN6rT2zH7uW4bX5mR8s" },
      "organization_installation_preference": "available",
      "organization_installation_preference_inherited": true,
      "content_scan": { "status": "completed", "assessment": "pass", "reason": null },
      "components": [
        {
          "type": "skill",
          "name": "account-research",
          "description": "Researches a customer account before a call."
        },
        { "type": "mcp_server", "name": "crm", "description": null }
      ],
      "reach": "remote",
      "created_at": "2026-09-01T17:04:11Z",
      "updated_at": "2026-09-15T14:12:30Z"
    }
  ],
  "next_page": "page_xK9f2LqT7vNw3pRzBd8sHy"
}
```

在此範例中，外掛程式被釘選到較早的版本：較新的版本（`latest_version_id`）已儲存，但尚未提供。

## 範圍

| 範圍                         | 授予的權限                                                                                                                                                                                                                                 |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `read:plugins`             | 本頁上的每個 `GET` 端點（包括封存檔下載），以及市集驗證。                                                                                                                                                                                                      |
| `write:plugins`            | 本頁上的每個 `POST` 和 `DELETE` 端點：建立外掛程式、建立版本、變更提供版本、刪除外掛程式、設定和移除安裝設定，以及設定市集的預設值，另外還有市集驗證。它不授予讀取權限。                                                                                                                                         |
| `read:org_audit`           | 供安全稽核整合使用的唯讀範圍：本頁上的每個 `GET` 端點（包括封存檔下載），以及[使用者管理](https://platform.claude.com/docs/zh-TW/manage-claude/user-management)和 [Compliance API](https://platform.claude.com/docs/zh-TW/manage-claude/compliance-api) 的讀取端點。它不授予市集驗證或任何寫入權限。 |
| `read:compliance_org_data` | Compliance API 用於組織中繼資料（名稱、類型、角色和群組）及有效設定的範圍。授予本頁上的每個 `GET` 端點，與 `read:org_audit` 完全相同，因此 Compliance Access Key 無需第二把金鑰即可讀取外掛程式。它不授予市集驗證或任何寫入權限。                                                                                      |

一把金鑰可以帶有多個範圍。上傳外掛程式後再將其讀回的整合，需要同時具備 `read:plugins` 和 `write:plugins`。本頁凡提到端點需要 `read:plugins` 範圍之處，具有 `read:org_audit` 或 `read:compliance_org_data` 的金鑰也同樣適用。

### 存取成員的外掛程式檔案

這些讀取範圍（`read:plugins`、`read:org_audit` 和 `read:compliance_org_data`）中的每一個，都可以下載成員個人市集中外掛程式的檔案，包括 claude.ai 管理設定中未顯示的檔案；而綁定到您上層組織的 `read:org_audit` 或 `read:compliance_org_data` 金鑰，可以透過傳遞 `organization_id`，在其下任何可存取此 API 的組織中執行此操作（請參閱[讀取同一上層組織下的其他組織](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#reading-another-organization-under-the-same-parent)）。每次此類下載都會在 [Compliance API Activity Feed](https://platform.claude.com/docs/zh-TW/manage-claude/compliance-activity-feed) 上記錄一個 `claude_plugin_archive_accessed` 事件，識別金鑰、外掛程式、版本和成員（請參閱 [Activity Feed 事件](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#activity-feed-events)）。組織擁有之外掛程式的下載不會被記錄。

### 讀取同一上層組織下的其他組織

`read:plugins` 和 `write:plugins` 金鑰只能讀寫建立它們的組織。如果您的公司有多個 Claude 組織連結在同一個上層組織下，由上層組織的主要擁有者為所有連結組織建立的 `read:org_audit` 或 `read:compliance_org_data` 金鑰（請參閱[建立 Admin API 金鑰](https://platform.claude.com/docs/zh-TW/manage-claude/admin-api-keys#create-a-key-for-a-claude-enterprise-organization)），也可以讀取其中任何可存取此 API 的組織：在本頁任何 `GET` 端點上，於 `organization_id` 查詢參數中傳遞該組織的 ID。此 ID 是 claude.ai 設定中顯示的組織 UUID（也接受其 `org_` 前綴形式）。若未提供此參數，金鑰會讀取建立它的組織。`404` 表示指定的組織不在金鑰的上層組織之下，或該組織無法使用此 API；不是 UUID 或 `org_` ID 的值會傳回 `400`。任何其他金鑰若指定了非自身所屬的組織，會收到 `404`。寫入操作不接受 `organization_id`。

## 關鍵概念

### 外掛程式與元件

**外掛程式**是為您組織成員擴充 Claude 功能的套件。它包含下列元件的任意組合：

| 元件                  | 說明                                                  |
| ------------------- | --------------------------------------------------- |
| Skill（技能）           | Claude 在任務需要時載入的指示和檔案。                              |
| Command（指令）         | 成員輸入 `/` 後接指令名稱即可執行的已儲存提示。                          |
| Agent（代理）           | 具有自己指示的輔助助理，Claude 可以將部分任務交給它處理。                    |
| Hook（鉤子）            | 在工作階段中發生事件時自動執行的命令，例如在 Claude 使用工具之前。               |
| MCP server（MCP 伺服器） | 從 Claude 連接到另一個系統中工具和資料的連線（Model Context Protocol）。 |
| CLI                 | 外掛程式讓 Claude 執行的命令列程式。                              |

每個外掛程式在 `.claude-plugin/plugin.json` 都有一個「manifest」（資訊清單）。資訊清單的 `name` 會成為外掛程式的 `name`：一個在其市集內唯一的小寫識別碼。

### 市集

**市集**是外掛程式的容器。每個市集都有一個擁有者和一個來源。

* **擁有者。** 組織擁有其市集。每位成員也可以擁有個人市集。
* **來源。** `manual` 表示外掛程式是透過上傳而來，可在 claude.ai 中上傳，或者（對於組織市集）透過此 API 上傳。`github`、`gitlab` 和 `public_git` 表示外掛程式是從擁有者連接的 Git 儲存庫同步而來。同步的市集無法上傳任何內容，此 API 也無法刪除其外掛程式，因為下一次同步會撤銷任一變更。請改為變更儲存庫。

您組織的**程式庫市集**（library marketplace）是組織擁有的 `manual` 市集，當您未指定市集時，上傳內容會進入此市集。它會在第一次有內容上傳到其中時建立。

### 組織擁有與成員擁有的外掛程式

外掛程式的 `owner.type` 說明它位於誰的市集中：

* `organization`：您可以透過此 API 管理它，但位於從 Git 同步之市集中的外掛程式無法在此接收上傳或被刪除。
* `user`：它位於某位成員的個人市集中。您可以讀取其詳細資訊並下載其檔案，若其市集為 `manual`，也可以刪除它。上傳版本和選擇提供版本會傳回 `403`。分享僅由成員在 claude.ai 中管理。

將成員從組織中移除並不會移除其外掛程式。它們會以該成員的 `user_id` 保留在清單中，`owner_user_id` 篩選器仍能找到它們，因此您可以審查並移除已離開成員的內容。當成員的帳戶被刪除時，它們才會從清單中移除。

### 版本與提供版本

每次上傳都會建立一個新的、不可變的**版本**，無論它來自此 API、claude.ai 或 Git 同步。外掛程式有兩個指向其版本的指標：

* `latest_version_id`：最新的版本。
* `served_version_id`：提供給成員的版本。

預設情況下 `served_version_pinned` 為 `false`：提供的版本通常會跟隨最新版本。當內容掃描開啟時，在 claude.ai 中儲存的版本可能會**等待**其內容掃描：它已儲存但不會立即提供。本頁僅將「等待」用於在 claude.ai 中儲存的版本，而非成員或管理員發布至外掛程式的版本。在掃描開啟期間，等待中的版本只有在其掃描以 `pass` 或 `warn` 完成後才會提供。當版本等待時，`served_version_id` 指向的版本會比 `latest_version_id` 更早。請勿輪詢直到兩個 ID 相符：它們可能會一直不同，例如當掃描失敗時。

使用 `POST /v1/organizations/plugins/{plugin_id}` 選擇版本會**釘選**（pin）外掛程式（`served_version_pinned: true`）。管理員在 claude.ai 中選擇版本，或接受成員發布到該外掛程式的請求，也會產生相同效果。從那時起，新的上傳會被儲存並推進 `latest_version_id`，但成員會持續使用釘選的版本，直到您將 `served_version_id` 指向另一個版本。兩個指標不同的外掛程式，表示有一個已儲存但未提供的版本。

這讓發布管線可以上傳每個建置、進行測試，然後再升級它。若要讓您的管線決定每個建置何時提供，請將 `served_version_id` 設為外掛程式目前的版本，以釘選外掛程式一次；從那時起，升級您想要提供的每個建置。啟用內容掃描時，在目前版本的掃描完成之前，第一次釘選會傳回 `409 scan_pending`；若掃描完成的結果為 `fail` 或 `unknown`，或發生錯誤，則傳回 `400 scan_failed`（`warn` 會被接受）。已釘選的外掛程式目前無法取消釘選，無論在此處或在 claude.ai 中皆然。

若要回復，請將 `served_version_id` 設為較早的版本。以相同方式向前推進。

這些規則描述的是組織擁有的外掛程式。成員擁有之外掛程式的提供版本由其擁有者在 claude.ai 中控制。

### 安裝設定

**安裝設定**決定誰可以使用組織擁有的外掛程式。每個設定具有四個值之一，承載於名為 `installation_preference` 的欄位中（在外掛程式和市集物件上，則為 `organization_installation_preference` 和 `default_installation_preference`）：

| 值               | 成員看到的情況       |
| --------------- | ------------- |
| `required`      | 外掛程式已安裝且無法移除。 |
| `auto_install`  | 外掛程式已安裝且可以移除。 |
| `available`     | 外掛程式可依要求安裝。   |
| `not_available` | 外掛程式被隱藏。      |

外掛程式可以擁有一個全組織設定，以及每個群組各一個設定（即在[使用者管理](https://platform.claude.com/docs/zh-TW/manage-claude/user-management#groups)中管理的角色型存取控制群組）。成員依下列規則取得值：

1. 全組織值是外掛程式自身的全組織設定（若有），否則為其市集的預設值，再否則為 `not_available`。外掛程式會在 `organization_installation_preference` 中回報此值，當該值來自市集預設值時，`organization_installation_preference_inherited: true`。
2. 不屬於任何對該外掛程式持有設定之群組的成員，會取得全組織值。
3. 屬於一個或多個持有設定之群組的成員，則改為取得這些群組設定中最寬鬆的一個，寬鬆程度依序為 `required`、`auto_install`、`available`、`not_available`。

群組的設定會為其成員取代全組織值，而非疊加於其上。例如，若全組織值為 `required`，而 Pilot 群組持有 `available`，則 Pilot 成員取得 `available`。當您將外掛程式從試行群組推廣至整個組織時，請設定全組織值，然後移除該群組的設定。設定全組織值會使外掛程式不再繼承其市集預設值；[移除全組織設定](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#remove-an-installation-setting)會讓外掛程式回到該預設值。

透過此 API 建立的外掛程式一開始沒有自己的設定，因此會繼承其市集的預設值：除非有人設定了預設值，否則為 `not_available`。刪除群組會從每個外掛程式中移除該群組的設定。

### 分享

**分享**決定誰可以使用成員擁有的外掛程式。擁有者在 claude.ai 中將其分享給所有成員、某個群組或指定的成員。此 API 會列出分享，但無法變更它們。

如果您的組織已在其 claude.ai 設定中關閉某種分享，該類型的分享仍會出現在列表中，但在該設定關閉期間不會授予任何人存取權；列表本身不會顯示該設定是否已關閉。

### 內容掃描

內容掃描是 claude.ai 中的組織設定。啟用時，新儲存的版本會被掃描（claude.ai 會豁免少數版本），結果會回報在 `content_scan` 中；未經掃描的版本（例如在啟用掃描之前儲存的版本）的值為 `content_scan: null`。使用客戶管理加密金鑰或零資料保留的組織不提供掃描功能。

啟用掃描期間，只有當外掛程式提供版本的掃描為 `completed` 且結果為 `pass` 或 `warn` 時，才會提供給成員。在掃描執行期間，或在掃描失敗、發生錯誤或未得出判定之後，外掛程式會對成員隱藏，且不會改為提供較早的版本。從未掃描過的版本（`content_scan: null`）會正常提供。

您透過此 API 上傳的版本永遠不會等待其內容掃描。當它成為提供的版本時，成員會失去該外掛程式，直到其掃描通過；若掃描失敗，則持續無法使用。如果成員應在新版本掃描期間保留目前版本，請先釘選外掛程式（請參閱[版本與提供版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#versions-and-the-served-version)）。

當在 claude.ai 中儲存的版本等待其掃描時，提供的版本不會改變。當您透過 API 上傳的版本成為提供的版本時，任何等待都會結束：等待中的版本只有在有人選擇它時才會提供。若要查看等待中版本的掃描，請讀取該版本（請參閱[列出外掛程式的版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#list-a-plugins-versions)）。

上傳後，`content_scan.status` 為 `processing`，判定結果會以非同步方式送達。請讀取版本以查看結果；外掛程式物件只會顯示其提供版本的掃描。將提供版本變更為掃描仍在執行中的版本會傳回 `409 scan_pending`；變更為掃描失敗的版本則傳回 `400 scan_failed`。

### 觸及範圍

`reach`（觸及範圍）以單一值概括版本在成員電腦上及其他地方的觸及程度：

| 值            | 意義                                                                                                                                                                                        |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `remote`     | 宣告了 MCP 伺服器或 CLI，無論它還宣告了什麼。                                                                                                                                                               |
| `privileged` | 未宣告 MCP 伺服器或 CLI，但宣告了 hook、monitor（在工作階段期間持續執行的背景指令）、LSP（Language Server Protocol）伺服器，或外掛程式套用至成員應用程式的設定，或包含 frontmatter 預先核准工具（`allowed-tools`）的技能、指令或任何其他 Markdown 檔案。這些會在成員自己的電腦上執行或生效。 |
| `contained`  | 未宣告 MCP 伺服器、CLI、hook、monitor、LSP 伺服器或應用程式設定，且其 Markdown 檔案均未預先核准工具（例如，僅包含技能、指令和代理，且皆無 `allowed-tools` 的外掛程式）。                                                                             |

`reach` 會計入版本宣告的所有內容，包括 `components` 未列出的 monitor、LSP 伺服器和應用程式設定，因此 `components` 清單為空的版本仍可能是 `privileged`。對於在開始記錄元件之前儲存的版本，以及因其某個技能的 `SKILL.md` 或某個指令檔案無法讀取而無法判定觸及範圍的版本，其值為 `null`；請將 `null` 視為未分類。

### 上傳要求

上傳遵循與 claude.ai 中外掛程式上傳相同的規則，因此兩處接受相同的封存檔。

* 上傳內容可以是一個 `.zip` 或 `.plugin` 封存檔，或一組個別檔案。封存檔可以將所有內容包在一個頂層資料夾中。
* 它必須恰好包含一個資訊清單，位於 `.claude-plugin/plugin.json`，且必須宣告 `name`。沒有資訊清單的單獨 `SKILL.md` 會被拒絕。
* 若頂層 `SKILL.md` 的 frontmatter 宣告了外掛程式元件，會被合併到資訊清單中；兩者都設定某個值時，以 `plugin.json` 為準。
* `name` 可包含小寫字母（任何字母系統）、數字和連字號，最多 64 個字元。大寫字母、空格、底線和其他標點符號會被拒絕。
* `displayName` 最多 64 個字元，`description` 最多 500 個字元。
* 每個 `SKILL.md` 都需要有效的 YAML frontmatter，包含 `name` 和 `description`，且兩者都不得包含 XML 標籤（例如 `<example>`）。兩個技能或兩個指令不能共用同一名稱。
* 任何檔案都不得位於頂層 `bin/` 目錄下。
* 不得有巢狀 `.zip` 檔案。允許封裝的 MCP 伺服器（`.mcpb`、`.dxt`）。
* 檔案路徑必須是相對路徑、不得包含 `..`，且只能使用字母、數字、空格和 `_ . - / ( ) ,`。
* 請求主體和解壓縮後的封存檔各自最多 200 MB；超過限制的請求主體會傳回 `413`（`request_too_large`），而非 `400`。一次上傳最多 5,000 個檔案、路徑深度 12 層、路徑長度 472 個字元，檔案或資料夾名稱 255 個字元。
* ZIP 封存檔必須使用 DEFLATE 或 STORE 壓縮，且不得加密或包含符號連結。
* 一個市集最多容納 500 個項目，計入其外掛程式以及成員保存在其中的任何獨立技能。此限制和 5,000 個檔案的限制為目前的值，未來可能會提高。

## 範例工作流程

### 從發布管線發布每個建置

從 CI 上傳每個已標記的建置，並讓管線決定建置何時提供。

1. 使用 `GET /v1/organizations/plugin_marketplaces?owner_type=organization` 找到要上傳的市集，或省略 `marketplace_id` 以使用程式庫市集。
2. 首次發布時，使用 `POST /v1/organizations/plugins` [建立外掛程式](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#create-a-plugin)。之後每次發布時，記錄外掛程式的 `latest_version_id`，然後使用 `POST /v1/organizations/plugins/{plugin_id}/versions` [上傳版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#create-a-version)。如果上傳的回應遺失，請讀取外掛程式，並僅在 `latest_version_id` 未變更時重試（請參閱[重試上傳](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#retrying-uploads)）。
3. 若要在檢查每個新建置期間讓成員保持使用目前版本，請將 `served_version_id` 設為外掛程式目前的版本，以釘選外掛程式一次。從那時起，每次上傳都會被儲存但不會提供，且釘選無法撤銷：您想要提供的每個建置都需要執行步驟 5。
4. 啟用內容掃描時，輪詢 `GET /v1/organizations/plugins/{plugin_id}/versions/{version}` 直到 `content_scan.status` 不再是 `processing`，並僅在其為 `completed` 且結果為 `pass` 或 `warn` 時才升級。
5. 使用 `POST /v1/organizations/plugins/{plugin_id}` 和 `{"served_version_id": "<the new version's ID>"}` [升級建置](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#change-the-served-version)。若要回復，請以相同方式傳送前一個版本的 ID。

### 將外掛程式推出給試行群組，再推出給所有人

1. 使用 `GET /v1/organizations/rbac_groups` 查詢試行群組的 ID。該呼叫需要 `read:rbac_groups` 範圍，而此範圍需要為所有連結組織建立的金鑰（請參閱[使用者管理](https://platform.claude.com/docs/zh-TW/manage-claude/user-management#groups)）。接下來的步驟需要 `write:plugins`，它只作用於建立其金鑰的組織，因此在具有多個連結組織的企業中，請在持有該外掛程式的組織中建立此金鑰並賦予兩個範圍，或在該組織中另外建立第二把金鑰用於這些步驟。

2. 使用 `POST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}` [為群組設定其專屬設定](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#set-an-installation-setting)，例如 `auto_install`，其中 `{target}` 是群組的 `rbac_group_` ID，同時全組織值保持為 `not_available`。只有該群組的成員會取得外掛程式。

3. 試行結束時，使用下列呼叫設定全組織值，然後移除群組的設定，讓群組再次跟隨組織。設定全組織值會使外掛程式不再繼承其市集預設值；之後[移除全組織設定](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#remove-an-installation-setting)會讓外掛程式回到該預設值。

   <CodeGroup>
     ```bash cURL
     curl -X POST "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL/installation_settings/organization" \
       -H "content-type: application/json" \
       -H "x-api-key: $ANTHROPIC_API_KEY" \
       -H "anthropic-version: 2023-06-01" \
       -H "anthropic-beta: ce-plugins-2026-09-01" \
       -d '{"installation_preference": "required"}'
     ```

     ```bash CLI
     ant beta:organization:plugins:installation-settings set \
       --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL \
       --target organization \
       --installation-preference required
     ```

     ```python Python
     client = anthropic.Anthropic()

     setting = client.beta.organization.plugins.installation_settings.set(
         "organization",
         plugin_id="plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
         installation_preference="required",
     )

     print(f"plugin_id: {setting.plugin_id}")
     print(f"installation_preference: {setting.installation_preference}")
     ```

     ```typescript TypeScript
     const client = new Anthropic();

     const setting = await client.beta.organization.plugins.installationSettings.set(
       "organization",
       {
         plugin_id: "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
         installation_preference: "required"
       }
     );

     console.log(`plugin_id: ${setting.plugin_id}`);
     console.log(`installation_preference: ${setting.installation_preference}`);
     ```

     ```csharp C#
     using Anthropic.Models.Beta.Organization.Plugins.InstallationSettings;

     AnthropicClient client = new();

     var setting = await client.Beta.Organization.Plugins.InstallationSettings.Set(
         "organization",
         new()
         {
             PluginID = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
             InstallationPreference = InstallationPreference.Required,
         }
     );

     Console.WriteLine($"plugin_id: {setting.PluginID}");
     Console.WriteLine($"installation_preference: {setting.InstallationPreference.Raw()}");
     ```

     ```go Go
     client := anthropic.NewClient()

     setting, err := client.Beta.Organization.Plugins.InstallationSettings.Set(
     	context.Background(),
     	"organization",
     	anthropic.BetaOrganizationPluginInstallationSettingSetParams{
     		PluginID:               "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
     		InstallationPreference: anthropic.BetaOrganizationPluginInstallationSettingSetParamsInstallationPreferenceRequired,
     	},
     )
     if err != nil {
     	log.Fatal(err)
     }

     fmt.Printf("plugin_id: %s\n", setting.PluginID)
     fmt.Printf("installation_preference: %s\n", setting.InstallationPreference)
     ```

     ```java Java
     import com.anthropic.models.beta.organization.plugins.installationsettings.InstallationSettingSetParams;

     void main() {
         AnthropicClient client = AnthropicOkHttpClient.fromEnv();

         var params = InstallationSettingSetParams.builder()
             .pluginId("plugin_01Hq3vX8kZcN2mB7pR4tY9wL")
             .installationPreference(InstallationSettingSetParams.InstallationPreference.REQUIRED)
             .build();
         var setting = client.beta().organization().plugins().installationSettings()
             .set("organization", params);

         IO.println("plugin_id: " + setting.pluginId());
         IO.println("installation_preference: " + setting.installationPreference().asString());
     }
     ```

     ```php PHP
     use Anthropic\Beta\Organization\Plugins\InstallationSettings\InstallationSettingSetParams\InstallationPreference;
     // ...

     $client = new Client();

     $setting = $client->beta->organization->plugins->installationSettings->set(
         target: 'organization',
         pluginID: 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL',
         installationPreference: InstallationPreference::REQUIRED,
     );

     echo "plugin_id: {$setting->pluginID}\n";
     echo "installation_preference: {$setting->installationPreference}\n";
     ```

     ```ruby Ruby
     client = Anthropic::Client.new

     plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
     setting = client.beta.organization.plugins.installation_settings.set(
       "organization",
       plugin_id: plugin_id,
       installation_preference: :required
     )

     puts "plugin_id: #{setting.plugin_id}"
     puts "installation_preference: #{setting.installation_preference}"
     ```
   </CodeGroup>

   接著使用 `DELETE /v1/organizations/plugins/{plugin_id}/installation_settings/{target}` 移除群組的設定，其中 `{target}` 是群組的 ID。群組的設定會為其成員取代全組織值，而非附加於其上，因此殘留的 `available` 群組設定會讓這些成員維持在 `available`。

### 保持安全清單同步

執行每晚作業，標記觸及範圍超出成員工作階段，或內容掃描未通過的外掛程式。

1. 逐頁瀏覽 [`GET /v1/organizations/plugins?limit=100`](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#list-plugins)，直到 `next_page` 為 `null`（請參閱[分頁](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#pagination)）。每次執行時都從該清單讀取每個外掛程式的 `reach` 和 `content_scan`：稍後送達的掃描判定不會變動 `updated_at`。`updated_at` 通常會告訴您自上次執行以來哪些外掛程式有新內容或新的提供版本（值得重新下載封存檔）。等待中的版本（請參閱[版本與提供版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#versions-and-the-served-version)）會在成為提供的版本時變動 `updated_at`，而不一定是在儲存時。若要察覺此類版本，請將 `latest_version_id` 與上次執行的值進行比較。完整重新列出也是偵測移除的方式，因為被 Git 同步或帳戶刪除移除的外掛程式會在沒有事件的情況下消失。
2. 標記 `reach` 為 `remote`（宣告了 MCP 伺服器或 CLI），或 `content_scan.assessment` 為 `fail` 或 `unknown` 的每個外掛程式。這些欄位描述的是提供的版本。若也要檢查未提供的較新版本，請在 `latest_version_id` 與 `served_version_id` 不同時列出外掛程式的版本（請參閱[列出外掛程式的版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#list-a-plugins-versions)）。
3. 對於每個被標記的外掛程式，使用 `GET /v1/organizations/plugins/{plugin_id}/versions/{served_version_id}/content` 下載提供版本的封存檔以供審查（請參閱[下載版本的檔案](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#download-a-versions-files)）。也請依 ID 下載任何符合步驟 2 檢驗條件的未提供版本。
4. 若要在審查期間讓成員無法使用外掛程式，請參閱[刪除外掛程式](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#delete-a-plugin)，了解可逆（組織擁有）和永久的選項。

## 外掛程式

外掛程式物件描述位於您組織某個市集或成員個人市集中的外掛程式（[快速入門](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#quick-start)的回應顯示了一個完整的物件）。其 `display_name`、`description`、`manifest_version`、`content_scan`、`components` 和 `reach` 描述的是其**提供**版本，因此一次列表呼叫即可顯示成員正在使用的內容。

| 欄位                                                                                      | 說明                                                                                                                                                                                                                                                                                                      |
| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                                                                                    | 前綴為 `plugin_`。                                                                                                                                                                                                                                                                                          |
| `name`                                                                                  | 來自資訊清單。在其市集內唯一，而非在整個組織內唯一。組織擁有的外掛程式此值固定；若成員在 claude.ai 中重新命名自己的外掛程式，此值會變更。                                                                                                                                                                                                                              |
| `display_name`、`description`、`manifest_version`                                         | 提供版本資訊清單中的 `displayName`、`description` 和 `version`；資訊清單未宣告時各為 `null`。`manifest_version` 會為顯示而正規化：會移除一個開頭的 `v` 或 `V`，因此資訊清單 `version` 為 `"v1.4.0"` 時會傳回 `"1.4.0"`。對於看起來不像版本號的值（例如 `"latest"`），以及在 claude.ai 於 2026 年 8 月開始記錄此欄位之前建立的外掛程式版本，其值也為 `null`。上傳絕不會因其 `version` 而被拒絕，且 `manifest_version` 並非唯一。 |
| `served_version_id`、`latest_version_id`                                                 | 前綴為 `pluginver_`：提供給成員的版本，以及最新版本。請參閱[版本與提供版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#versions-and-the-served-version)。                                                                                                                                                        |
| `served_version_pinned`                                                                 | 在外掛程式被釘選之前為 `false`（請參閱[版本與提供版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#versions-and-the-served-version)）；之後為 `true`。                                                                                                                                                         |
| `owner`                                                                                 | `{"type": "organization"}`，或成員個人市集的 `{"type": "user", "user_id": "user_..."}`。                                                                                                                                                                                                                          |
| `marketplace_id`                                                                        | 前綴為 `marketplace_`。                                                                                                                                                                                                                                                                                     |
| `created_by`                                                                            | 建立外掛程式的人：claude.ai 中的人員為 `{"type": "user_actor", "user_id": "user_...", "email_address": "..."}`（`email_address` 可能為 `null`），API 金鑰則為 `{"type": "api_actor", "api_key_id": "apikey_..."}`。可能會出現其他行為者類型。未記錄建立者時為 `null`，例如從 Git 同步的外掛程式。                                                                 |
| `organization_installation_preference`、`organization_installation_preference_inherited` | 組織擁有：全組織值，以及該值是否來自市集的預設值（請參閱[安裝設定](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#installation-settings)）。成員擁有：兩者皆為 `null`。                                                                                                                                                           |
| `content_scan`                                                                          | 提供版本的掃描結果，為包含 `status`、`assessment` 和 `reason` 的物件（於此表格之後說明）。從未掃描時為 `null`。                                                                                                                                                                                                                             |
| `components`                                                                            | 提供版本的元件，每個為 `{"type", "name", "description"}`，其中 `type` 為 `skill`、`mcp_server`、`command`、`agent`、`hook` 或 `cli` 之一，依該類型順序再依名稱排列。對於 MCP 伺服器，`name` 是其在資訊清單中的鍵；對於 hook，是其執行時所對應的事件；對於 CLI，是可執行檔的名稱。MCP 伺服器、hook 和 CLI 的 `description` 一律為 `null`。未記錄時為 `null`。                                            |
| `reach`                                                                                 | `contained`、`privileged` 或 `remote`。請參閱[觸及範圍](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#reach)。                                                                                                                                                                                  |
| `updated_at`                                                                            | 在提供的版本變更時、外掛程式被釘選時，以及通常在儲存新版本時改變。等待中的版本（請參閱[版本與提供版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#versions-and-the-served-version)）會在成為提供的版本時改變此值，而不一定是在儲存時。安裝設定、分享或新的掃描結果不會改變此值。                                                                                                   |

`content_scan` 物件：

| 欄位           | 說明                                                                                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`     | 掃描執行中為 `processing`，完成時為 `completed`，無法完成時為 `errored`（或偶爾在此回應中無法讀取其結果時也是如此，此時稍後的讀取可能會回報結果）。掃描為 `processing` 或 `errored` 的版本不會提供給成員；將內容重新上傳為新版本即可取得新的掃描。 |
| `assessment` | 當 `status` 為 `completed` 時設定：`pass`（未發現任何問題）、`warn`（發現不會阻擋使用的問題）、`fail`（發現會阻擋使用的問題）或 `unknown`（無判定）。否則為 `null`。                                         |
| `reason`     | 對於 `warn` 和 `fail`，為主要疑慮，取自下列清單。否則為 `null`；在開始記錄原因之前的較舊掃描上也為 `null`。                                                                                    |

<Accordion title="內容掃描 reason 值">
  | `reason`                          | 意義                                                   |
  | --------------------------------- | ---------------------------------------------------- |
  | `covert-usage-telemetry`          | 指示 Claude 在未告知成員的情況下，將有關成員或其使用情況的資訊傳送到外部位址。          |
  | `undisclosed-data-destination`    | 將檔案、電子郵件、文件或其他內容傳送到成員看不到且無法控制的固定外部目的地。               |
  | `remote-code-instruction-loader`  | 指示 Claude 下載並執行外部內容，或遵循來自外部內容的指示，而這些內容在外掛程式安裝後可能會變更。 |
  | `credential-exposure`             | 包含有效的憑證，或從成員的環境中收集憑證或權杖。                             |
  | `guardrail-tampering`             | 削弱成員的防護措施，例如預先核准每個權限提示。                              |
  | `system-prompt-spoofing`          | 模仿或試圖取代 Claude 的系統指示。                                |
  | `covert-record-tampering`         | 暗中變更、隱藏或刪除成員原本會看到的資訊。                                |
  | `covert-behavior-override`        | 變更 Claude 的行為，超出外掛程式的用途，並對成員隱藏此變更。                   |
  | `hidden-code-execution`           | 執行隨附的程式碼，同時指示 Claude 不要透露其作用。                        |
  | `undisclosed-promotion-injection` | 在 Claude 的輸出中插入未揭露的推廣內容。                             |
  | `hidden-identity-gate`            | 根據執行它的帳戶變更或停止其行為，且未說明原因。                             |
  | `destructive-persistence`         | 可能刪除或損毀成員的檔案，或安裝在外掛程式移除後仍會保留的程式。                     |
  | `unanalyzable-binary`             | 包含已編譯或無法讀取的程式，因此掃描無法驗證其作用。                           |
  | `other`                           | 任何其他疑慮，包括比此清單更新的疑慮。                                  |
</Accordion>

缺少 `plugin_` 前綴的 `plugin_id` 會傳回 `400`。帶有前綴但無法解析、屬於其他組織或指向獨立技能的 `plugin_id` 會傳回 `404`。

### 列出外掛程式

`GET /v1/organizations/plugins` 會列出您組織中的每個外掛程式，包括組織市集和成員個人市集中的外掛程式，依 `created_at` 遞減排序。可依 `owner_type`（`organization` 或 `user`）、`owner_user_id`（前綴為 `user_`；某位成員的外掛程式，包括該成員離開組織之後）、`marketplace_id`，以及 `created_at[gte]`、`created_at[gt]`、`created_at[lte]`、`created_at[lt]`（RFC 3339 時間戳記）進行篩選。篩選條件以 AND 組合。在您組織中沒有任何相符項目的 `marketplace_id` 或 `owner_user_id` 會傳回空白頁面，而非錯誤。回應的結構如[快速入門](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#quick-start)所示。需要 `read:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl "https://api.anthropic.com/v1/organizations/plugins?owner_type=organization&limit=20" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugins list --owner-type organization --limit 20
  ```

  ```python Python
  client = anthropic.Anthropic()

  plugins = client.beta.organization.plugins.list(owner_type="organization", limit=20)

  # 視需要自動擷取更多頁面。
  for plugin in plugins:
      print(f"{plugin.id}: {plugin.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const plugins = await client.beta.organization.plugins.list({
    owner_type: "organization",
    limit: 20
  });

  for await (const plugin of plugins) {
    console.log(`${plugin.id}: ${plugin.name}`);
  }
  ```

  ```csharp C#
  using Anthropic.Models.Beta.Organization.Plugins;

  AnthropicClient client = new();

  var page = await client.Beta.Organization.Plugins.List(
      new() { OwnerType = OwnerType.Organization, Limit = 20 }
  );

  await foreach (var plugin in page.Paginate())
  {
      Console.WriteLine($"{plugin.ID}: {plugin.Name}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  plugins := client.Beta.Organization.Plugins.ListAutoPaging(context.Background(), anthropic.BetaOrganizationPluginListParams{
  	OwnerType: anthropic.BetaOrganizationPluginListParamsOwnerTypeOrganization,
  	Limit:     anthropic.Int(20),
  })

  for plugins.Next() {
  	plugin := plugins.Current()
  	fmt.Printf("%s: %s\n", plugin.ID, plugin.Name)
  }
  if err := plugins.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  import com.anthropic.models.beta.organization.plugins.PluginListParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = PluginListParams.builder()
          .ownerType(PluginListParams.OwnerType.ORGANIZATION)
          .limit(20)
          .build();
      var plugins = client.beta().organization().plugins().list(params);

      for (var plugin : plugins.autoPager()) {
          IO.println(plugin.id() + ": " + plugin.name());
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\Organization\Plugins\PluginListParams\OwnerType;
  // ...

  $client = new Client();

  $plugins = $client->beta->organization->plugins->list(
      limit: 20,
      ownerType: OwnerType::ORGANIZATION,
  );

  // 僅限此頁；若要取得下一頁，請以 page: $plugins->nextPage 再次呼叫 list()。
  foreach ($plugins->getItems() as $plugin) {
      echo "{$plugin->id}: {$plugin->name}\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  page = client.beta.organization.plugins.list(owner_type: :organization, limit: 20)

  page.auto_paging_each do |plugin|
    puts "#{plugin.id}: #{plugin.name}"
  end
  ```
</CodeGroup>

### 建立外掛程式

`POST /v1/organizations/plugins` 會在一次呼叫中建立一個組織擁有的「plugin」（外掛程式）及其第一個版本；該版本會成為「served version」（提供版本）。請求主體為 `multipart/form-data`：`files[]` 可以是單一 `.zip` 或 `.plugin` 封存檔，也可以是每個檔案各一個部分，其中每個部分的檔名是該檔案在外掛程式中的路徑（例如 `.claude-plugin/plugin.json`）。選用欄位為 `marketplace_id`（組織擁有的 `manual`「marketplace」（市集）；預設為您的程式庫市集，該市集會在首次使用時建立）和 `release_notes`（最多 5,000 個字元，會顯示在 claude.ai 的版本歷史記錄中，並隨版本一併傳回）。外掛程式的 `name`、`display_name`、`description` 和 `manifest_version` 來自上傳的 manifest，且上傳內容必須符合[上傳要求](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#upload-requirements)。啟用「content scanning」（內容掃描）時，回應的 `content_scan.status` 為 `processing`，判定結果會以非同步方式送達。傳回外掛程式。需要 `write:plugins` 範圍。

上傳封存檔：

<CodeGroup>
  ```bash cURL
  curl -X POST "https://api.anthropic.com/v1/organizations/plugins" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01" \
    -F "files[]=@dist/sales-toolkit.zip" \
    -F "release_notes=First release"
  ```

  ```bash CLI
  ant beta:organization:plugins create \
    --file dist/sales-toolkit.zip \
    --release-notes "First release"
  ```

  ```python Python
  client = anthropic.Anthropic()

  with open("dist/sales-toolkit.zip", "rb") as archive:
      plugin = client.beta.organization.plugins.create(
          files=[archive],
          release_notes="First release",
      )

  print(f"id: {plugin.id}")
  print(f"served_version_id: {plugin.served_version_id}")
  ```

  ```typescript TypeScript
  import fs from "node:fs";

  const client = new Anthropic();

  const plugin = await client.beta.organization.plugins.create({
    files: [fs.createReadStream("dist/sales-toolkit.zip")],
    release_notes: "First release"
  });

  console.log(`id: ${plugin.id}`);
  console.log(`served_version_id: ${plugin.served_version_id}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var plugin = await client.Beta.Organization.Plugins.Create(
      new()
      {
          Files = [File.OpenRead("dist/sales-toolkit.zip")],
          ReleaseNotes = "First release",
      }
  );

  Console.WriteLine($"id: {plugin.ID}");
  Console.WriteLine($"served_version_id: {plugin.ServedVersionID}");
  ```

  ```go Go
  client := anthropic.NewClient()

  archive, err := os.Open("dist/sales-toolkit.zip")
  if err != nil {
  	log.Fatal(err)
  }
  defer archive.Close()

  plugin, err := client.Beta.Organization.Plugins.New(context.Background(), anthropic.BetaOrganizationPluginNewParams{
  	Files:        []io.Reader{archive},
  	ReleaseNotes: anthropic.String("First release"),
  })
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", plugin.ID)
  fmt.Printf("served_version_id: %s\n", plugin.ServedVersionID)
  ```

  ```java Java
  import com.anthropic.core.MultipartField;
  import com.anthropic.models.beta.organization.plugins.PluginCreateParams;

  void main() throws Exception {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      // 手動建構 `files[]` 部分，讓封存檔連同其檔名一併送出，
      // 這是上傳所必需的。
      var archive = MultipartField.<List<InputStream>>builder()
          .value(List.of(Files.newInputStream(Path.of("dist/sales-toolkit.zip"))))
          .filename("sales-toolkit.zip")
          .contentType("application/octet-stream")
          .build();
      var params = PluginCreateParams.builder()
          .files(archive)
          .releaseNotes("First release")
          .build();
      var plugin = client.beta().organization().plugins().create(params);

      IO.println("id: " + plugin.id());
      IO.println("served_version_id: " + plugin.servedVersionId());
  }
  ```

  ```php PHP
  use Anthropic\Core\FileParam;

  $client = new Client();

  $plugin = $client->beta->organization->plugins->create(
      files: [
          FileParam::fromResource(fopen('dist/sales-toolkit.zip', 'r')),
      ],
      releaseNotes: 'First release',
  );

  echo "id: {$plugin->id}\n";
  echo "served_version_id: {$plugin->servedVersionID}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin = client.beta.organization.plugins.create(
    files: [Pathname("dist/sales-toolkit.zip")],
    release_notes: "First release"
  )

  puts "id: #{plugin.id}"
  puts "served_version_id: #{plugin.served_version_id}"
  ```
</CodeGroup>

```json
{
  "type": "plugin",
  "id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  "name": "sales-toolkit",
  "display_name": "Sales Toolkit",
  "description": "Account research and call prep for the sales team.",
  "served_version_id": "pluginver_01Km7tL4pR9xF5sU2zV3jP6q",
  "served_version_pinned": false,
  "latest_version_id": "pluginver_01Km7tL4pR9xF5sU2zV3jP6q",
  "manifest_version": "1.4.0",
  "owner": { "type": "organization" },
  "marketplace_id": "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
  "created_by": { "type": "api_actor", "api_key_id": "apikey_01Nq9vN6rT2zH7uW4bX5mR8s" },
  "organization_installation_preference": "available",
  "organization_installation_preference_inherited": true,
  "content_scan": { "status": "processing", "assessment": null, "reason": null },
  "components": [
    {
      "type": "skill",
      "name": "account-research",
      "description": "Researches a customer account before a call."
    },
    { "type": "mcp_server", "name": "crm", "description": null }
  ],
  "reach": "remote",
  "created_at": "2026-09-01T17:04:11Z",
  "updated_at": "2026-09-01T17:04:11Z"
}
```

將個別檔案上傳到指定的市集。請以每個檔案在外掛程式中的路徑附加該檔案（cURL 範例中的 `;filename=` 後綴，SDK 範例中的檔名引數）；若檔案僅以其基本名稱傳送，將會找不到 manifest。TypeScript 和 Java SDK 以及 `ant` CLI 目前還無法以路徑附加檔案，因此這些範例改為將外掛程式以單一封存檔上傳到該市集：

<CodeGroup>
  ```bash cURL
  curl -X POST "https://api.anthropic.com/v1/organizations/plugins" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01" \
    -F "files[]=@.claude-plugin/plugin.json;filename=.claude-plugin/plugin.json" \
    -F "files[]=@skills/account-research/SKILL.md;filename=skills/account-research/SKILL.md" \
    -F "marketplace_id=marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"
  ```

  ```bash CLI
  # CLI 上傳每個檔案時只會使用其基本名稱，
  # 因此請改將外掛程式打包成單一封存檔上傳。
  ant beta:organization:plugins create \
    --file dist/sales-toolkit.zip \
    --marketplace-id marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r
  ```

  ```python Python
  client = anthropic.Anthropic()

  # 使用 (filename, file) tuple 可保留每個檔案在外掛中的路徑；
  # 若只傳入檔案物件，則只會以其基本名稱傳送。
  with (
      open(".claude-plugin/plugin.json", "rb") as manifest,
      open("skills/account-research/SKILL.md", "rb") as skill_md,
  ):
      plugin = client.beta.organization.plugins.create(
          files=[
              (".claude-plugin/plugin.json", manifest),
              ("skills/account-research/SKILL.md", skill_md),
          ],
          marketplace_id="marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
      )

  print(f"id: {plugin.id}")
  print(f"served_version_id: {plugin.served_version_id}")
  ```

  ```typescript TypeScript
  import fs from "node:fs";

  const client = new Anthropic();

  // TypeScript SDK 會以各檔案的基本名稱（base name）傳送，
  // 因此請將外掛程式打包成單一封存檔上傳。
  const plugin = await client.beta.organization.plugins.create({
    files: [fs.createReadStream("dist/sales-toolkit.zip")],
    marketplace_id: "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"
  });

  console.log(`id: ${plugin.id}`);
  console.log(`served_version_id: ${plugin.served_version_id}`);
  ```

  ```csharp C#
  using Anthropic.Core;

  AnthropicClient client = new();

  // FileName 會保留每個檔案在外掛程式內的路徑；若未設定，FileStream
  // 只會以其基本檔名（base name）傳送。
  var plugin = await client.Beta.Organization.Plugins.Create(
      new()
      {
          Files =
          [
              new BinaryContent
              {
                  Stream = File.OpenRead(".claude-plugin/plugin.json"),
                  FileName = ".claude-plugin/plugin.json",
              },
              new BinaryContent
              {
                  Stream = File.OpenRead("skills/account-research/SKILL.md"),
                  FileName = "skills/account-research/SKILL.md",
              },
          ],
          MarketplaceID = "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
      }
  );

  Console.WriteLine($"id: {plugin.ID}");
  Console.WriteLine($"served_version_id: {plugin.ServedVersionID}");
  ```

  ```go Go
  client := anthropic.NewClient()

  manifest, err := os.Open(".claude-plugin/plugin.json")
  if err != nil {
  	log.Fatal(err)
  }
  defer manifest.Close()

  skillMd, err := os.Open("skills/account-research/SKILL.md")
  if err != nil {
  	log.Fatal(err)
  }
  defer skillMd.Close()

  // anthropic.File 會將每個檔案在外掛中的路徑保留為該 part 的檔名；
  // 若直接使用 *os.File，則會以其基本名稱傳送，導致找不到 manifest。
  plugin, err := client.Beta.Organization.Plugins.New(context.Background(), anthropic.BetaOrganizationPluginNewParams{
  	Files: []io.Reader{
  		anthropic.File(manifest, ".claude-plugin/plugin.json", "application/json"),
  		anthropic.File(skillMd, "skills/account-research/SKILL.md", "text/markdown"),
  	},
  	MarketplaceID: anthropic.String("marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"),
  })
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", plugin.ID)
  fmt.Printf("served_version_id: %s\n", plugin.ServedVersionID)
  ```

  ```java Java
  import com.anthropic.core.MultipartField;
  import com.anthropic.models.beta.organization.plugins.PluginCreateParams;

  void main() throws Exception {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      // PluginCreateParams 上的 `files` setter 只接受一個檔名來代表整個
      // 清單，因此請改將外掛程式上傳為單一封存檔：一個手動建構的
      // part，並帶有該封存檔的檔名，這是上傳所必需的。
      var archive = MultipartField.<List<InputStream>>builder()
          .value(List.of(Files.newInputStream(Path.of("dist/sales-toolkit.zip"))))
          .filename("sales-toolkit.zip")
          .contentType("application/octet-stream")
          .build();
      var params = PluginCreateParams.builder()
          .files(archive)
          .marketplaceId("marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r")
          .build();
      var plugin = client.beta().organization().plugins().create(params);

      IO.println("id: " + plugin.id());
      IO.println("served_version_id: " + plugin.servedVersionId());
  }
  ```

  ```php PHP
  use Anthropic\Core\FileParam;

  $client = new Client();

  $plugin = $client->beta->organization->plugins->create(
      files: [
          FileParam::fromResource(
              fopen('.claude-plugin/plugin.json', 'r'),
              filename: '.claude-plugin/plugin.json',
          ),
          FileParam::fromResource(
              fopen('skills/account-research/SKILL.md', 'r'),
              filename: 'skills/account-research/SKILL.md',
          ),
      ],
      marketplaceID: 'marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r',
  );

  echo "id: {$plugin->id}\n";
  echo "served_version_id: {$plugin->servedVersionID}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  # 帶有 filename: 的 FilePart 會保留每個檔案在外掛中的路徑；
  # 若只傳入 Pathname，則僅會以其基本檔名傳送。
  plugin = client.beta.organization.plugins.create(
    files: [
      Anthropic::FilePart.new(
        Pathname(".claude-plugin/plugin.json"),
        filename: ".claude-plugin/plugin.json"
      ),
      Anthropic::FilePart.new(
        Pathname("skills/account-research/SKILL.md"),
        filename: "skills/account-research/SKILL.md"
      )
    ],
    marketplace_id: "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"
  )

  puts "id: #{plugin.id}"
  puts "served_version_id: #{plugin.served_version_id}"
  ```
</CodeGroup>

除了上傳違反[上傳要求](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#upload-requirements)時的 `400`（請求主體超過 200 MB 時為 `413`）以及共用回應（當 `marketplace_id` 是成員的個人市集時為 `403`；請參閱[錯誤回應](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#error-responses)）之外，建立作業還可能因以下原因失敗：

| 狀態                         | 原因                               | 處理方式                                                                                                                                    |
| -------------------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| 404                        | `marketplace_id` 不是您組織的市集。       | 從[列出市集](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#list-marketplaces)取得 ID。                                       |
| 400                        | 該市集是從 Git 同步的，或已包含 500 個外掛程式和技能。 | 上傳到 `manual` 市集，或改為變更儲存庫。                                                                                                               |
| 409 `plugin_name_taken`    | 該名稱在該市集中已被使用。                    | 繼續使用 `details.plugin_id`（向其上傳版本），或變更 manifest 的 `name`。                                                                                 |
| 409 `skill_name_taken`     | 外掛程式將進入程式庫市集，且其中一個技能與某個組織技能同名。   | 重新命名該技能，或在 claude.ai 中移除該組織技能。                                                                                                          |
| 409（無 `error_code`）        | 另一個以相同名稱上傳到相同市集的作業仍在進行中。         | 稍後重試。                                                                                                                                   |
| 503 `registration_pending` | 外掛程式已建立，但其註冊未完成。                 | 請勿重新傳送；將相同檔案作為 `details.plugin_id` 的版本上傳（請參閱[重試上傳](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#retrying-uploads)）。 |

### 取得外掛程式

`GET /v1/organizations/plugins/{plugin_id}` 傳回一個外掛程式。需要 `read:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugins retrieve \
    --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL
  ```

  ```python Python
  client = anthropic.Anthropic()

  plugin = client.beta.organization.plugins.retrieve("plugin_01Hq3vX8kZcN2mB7pR4tY9wL")

  print(f"id: {plugin.id}")
  print(f"name: {plugin.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const plugin = await client.beta.organization.plugins.retrieve(
    "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  );

  console.log(`id: ${plugin.id}`);
  console.log(`name: ${plugin.name}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var plugin = await client.Beta.Organization.Plugins.Retrieve("plugin_01Hq3vX8kZcN2mB7pR4tY9wL");

  Console.WriteLine($"id: {plugin.ID}");
  Console.WriteLine($"name: {plugin.Name}");
  ```

  ```go Go
  client := anthropic.NewClient()

  plugin, err := client.Beta.Organization.Plugins.Get(
  	context.Background(),
  	"plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  	anthropic.BetaOrganizationPluginGetParams{},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", plugin.ID)
  fmt.Printf("name: %s\n", plugin.Name)
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  var plugin = client.beta().organization().plugins()
      .retrieve("plugin_01Hq3vX8kZcN2mB7pR4tY9wL");

  IO.println("id: " + plugin.id());
  IO.println("name: " + plugin.name());
  ```

  ```php PHP
  $client = new Client();

  $plugin = $client->beta->organization->plugins->retrieve(
      pluginID: 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL',
  );

  echo "id: {$plugin->id}\n";
  echo "name: {$plugin->name}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  plugin = client.beta.organization.plugins.retrieve(plugin_id)

  puts "id: #{plugin.id}"
  puts "name: #{plugin.name}"
  ```
</CodeGroup>

### 變更提供版本

`POST /v1/organizations/plugins/{plugin_id}` 會變更組織擁有的外掛程式要提供給成員的版本。傳入較早的版本即可回復，或傳入較新的版本以推出已儲存但尚未提供的建置。這會釘選該外掛程式，而已釘選的外掛程式目前無法取消釘選，無論在此處或在 claude.ai 中皆然（請參閱[版本與提供版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#versions-and-the-served-version)）。唯一可更新的欄位是 `served_version_id`，且為必填。此變更會在回應傳回之前送達成員，且不會建立版本。啟用內容掃描時，該版本必須是可提供給成員的版本（請參閱[內容掃描](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#content-scanning)）。對已釘選的外掛程式傳入目前已提供的版本不會有任何變更；對未釘選的外掛程式傳入該版本則會將其釘選在該版本，因此之後的上傳將不再自動提供。釘選也會結束任何等待：正在等待內容掃描的版本會保持儲存狀態，只有在有人選擇它時才會提供。傳回該外掛程式。需要 `write:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl -X POST "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL" \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01" \
    -d '{"served_version_id": "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p"}'
  ```

  ```bash CLI
  ant beta:organization:plugins update \
    --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL \
    --served-version-id pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p
  ```

  ```python Python
  client = anthropic.Anthropic()

  plugin = client.beta.organization.plugins.update(
      "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
      served_version_id="pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
  )

  print(f"id: {plugin.id}")
  print(f"served_version_id: {plugin.served_version_id}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const plugin = await client.beta.organization.plugins.update(
    "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
    { served_version_id: "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p" }
  );

  console.log(`id: ${plugin.id}`);
  console.log(`served_version_id: ${plugin.served_version_id}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var plugin = await client.Beta.Organization.Plugins.Update(
      "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
      new() { ServedVersionID = "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p" }
  );

  Console.WriteLine($"id: {plugin.ID}");
  Console.WriteLine($"served_version_id: {plugin.ServedVersionID}");
  ```

  ```go Go
  client := anthropic.NewClient()

  plugin, err := client.Beta.Organization.Plugins.Update(
  	context.Background(),
  	"plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  	anthropic.BetaOrganizationPluginUpdateParams{
  		ServedVersionID: "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", plugin.ID)
  fmt.Printf("served_version_id: %s\n", plugin.ServedVersionID)
  ```

  ```java Java
  import com.anthropic.models.beta.organization.plugins.PluginUpdateParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = PluginUpdateParams.builder()
          .servedVersionId("pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p")
          .build();
      var plugin = client.beta().organization().plugins()
          .update("plugin_01Hq3vX8kZcN2mB7pR4tY9wL", params);

      IO.println("id: " + plugin.id());
      IO.println("served_version_id: " + plugin.servedVersionId());
  }
  ```

  ```php PHP
  $client = new Client();

  $plugin = $client->beta->organization->plugins->update(
      pluginID: 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL',
      servedVersionID: 'pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p',
  );

  echo "id: {$plugin->id}\n";
  echo "served_version_id: {$plugin->servedVersionID}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  plugin = client.beta.organization.plugins.update(
    plugin_id,
    served_version_id: "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p"
  )

  puts "id: #{plugin.id}"
  puts "served_version_id: #{plugin.served_version_id}"
  ```
</CodeGroup>

```json
{
  "type": "plugin",
  "id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  "name": "sales-toolkit",
  "display_name": "Sales Toolkit",
  "description": "Account research and call prep for the sales team.",
  "served_version_id": "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
  "served_version_pinned": true,
  "latest_version_id": "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
  "manifest_version": "1.5.0",
  "owner": { "type": "organization" },
  "marketplace_id": "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
  "created_by": { "type": "api_actor", "api_key_id": "apikey_01Nq9vN6rT2zH7uW4bX5mR8s" },
  "organization_installation_preference": "available",
  "organization_installation_preference_inherited": true,
  "content_scan": { "status": "completed", "assessment": "pass", "reason": null },
  "components": [
    {
      "type": "skill",
      "name": "account-research",
      "description": "Researches a customer account before a call."
    },
    { "type": "mcp_server", "name": "crm", "description": null },
    {
      "type": "command",
      "name": "call-prep",
      "description": "Builds a one-page brief for an upcoming call."
    }
  ],
  "reach": "remote",
  "created_at": "2026-09-01T17:04:11Z",
  "updated_at": "2026-09-16T10:02:45Z"
}
```

除了共用回應（成員擁有的外掛程式為 `403`，成員無法取得的版本為 `409 scan_pending` 或 `400 scan_failed`；請參閱[錯誤回應](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#error-responses)）之外，請求還可能因以下原因失敗：

| 狀態                     | 原因                                                                                | 處理方式                                                                                                         |
| ---------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| 400                    | 主體省略了 `served_version_id`、將其設為 `null`，或包含任何其他欄位；或該值缺少 `pluginver_` 前綴或為 `latest`。 | 僅傳送 `{"served_version_id": "pluginver_…"}`。                                                                  |
| 404                    | `served_version_id` 不是此外掛程式的版本。                                                   | 從[列出外掛程式的版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#list-a-plugins-versions)取得 ID。 |
| 409（無 `error_code`）    | 對此外掛程式的上傳或另一個提供版本變更仍在進行中。                                                         | 稍後重試。                                                                                                        |
| 409 `skill_name_taken` | 外掛程式位於程式庫市集中，且該版本有一個技能的名稱目前已被某個組織技能使用。                                            | 選擇其他版本，或重新命名其中一個技能。                                                                                          |

### 刪除外掛程式

`DELETE /v1/organizations/plugins/{plugin_id}` 會永久刪除外掛程式及其包含的每個版本，就如同管理員在 claude.ai 中執行刪除一樣。它適用於 `manual` 市集中的任何外掛程式，包括成員的外掛程式，即使該成員已離開組織。刪除傳回後，該外掛程式、其版本及其檔案將從所有讀取中消失，成員也不再獲得提供。組織擁有的外掛程式的「installation setting」（安裝設定）會隨之移除；成員擁有的外掛程式的分享會被撤回，且對其擁有者而言也會消失。位於從 Git 同步之市集中的外掛程式會傳回 `400`：請從儲存庫中移除它，或在 claude.ai 中移除該市集。需要 `write:plugins` 範圍。

刪除無法復原，且沒有針對個別版本的刪除。若要以可復原的方式停止提供組織擁有的外掛程式，請將其組織層級安裝設定設為 `not_available`（原本繼承其市集預設值的外掛程式會取得自己的設定，之後[移除該組織層級設定](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#remove-an-installation-setting)即可讓外掛程式回到預設值），並移除（或設為 `not_available`）`GET /v1/organizations/plugins/{plugin_id}/installation_settings` 列出的每個群組設定，因為群組的設定會覆寫其成員的組織層級值。請依序傳送這些寫入，而非平行傳送（請參閱[設定安裝設定](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#set-an-installation-setting)）。成員擁有的外掛程式無法透過此 API 停止提供，只能將其刪除，且僅限其市集為 `manual` 時。

<CodeGroup>
  ```bash cURL
  curl -X DELETE "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugins delete --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL
  ```

  ```python Python
  client = anthropic.Anthropic()

  deleted_plugin = client.beta.organization.plugins.delete(
      "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  )

  print(f"id: {deleted_plugin.id}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const deletedPlugin = await client.beta.organization.plugins.delete(
    "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  );

  console.log(`id: ${deletedPlugin.id}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var deletedPlugin = await client.Beta.Organization.Plugins.Delete(
      "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  );

  Console.WriteLine($"id: {deletedPlugin.ID}");
  ```

  ```go Go
  client := anthropic.NewClient()

  deletedPlugin, err := client.Beta.Organization.Plugins.Delete(
  	context.Background(),
  	"plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  	anthropic.BetaOrganizationPluginDeleteParams{},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", deletedPlugin.ID)
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  var deletedPlugin = client.beta().organization().plugins()
      .delete("plugin_01Hq3vX8kZcN2mB7pR4tY9wL");

  IO.println("id: " + deletedPlugin.id());
  ```

  ```php PHP
  $client = new Client();

  $deletedPlugin = $client->beta->organization->plugins->delete(
      pluginID: 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL',
  );

  echo "id: {$deletedPlugin->id}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  deleted_plugin = client.beta.organization.plugins.delete(plugin_id)

  puts "id: #{deleted_plugin.id}"
  ```
</CodeGroup>

```json
{ "type": "plugin_deleted", "id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL" }
```

## 外掛程式版本

外掛程式版本是某次上傳中外掛程式檔案的不可變快照（[建立版本](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#create-a-version)的回應顯示了完整物件）。其欄位對應此版本的外掛程式提供版本欄位（`display_name`、`description`、`manifest_version`、`content_scan`、`components`、`reach`），另外還有 `release_notes`（與上傳一併提供的內容；顯示在 claude.ai 的版本歷史記錄中）和 `created_by`（上傳者）。

缺少 `pluginver_` 前綴的 `{version}` 會傳回 `400`（註明之處的字面值 `latest` 除外）。帶有前綴但無法識別該外掛程式版本的值會傳回 `404`。

### 列出外掛程式的版本

`GET /v1/organizations/plugins/{plugin_id}/versions` 列出外掛程式的版本，依 `created_at` 遞減排序；第一個項目是 `latest_version_id` 所識別的版本。`limit` 為 1 到 1,000。需要 `read:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL/versions?limit=50" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugins:versions list \
    --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL \
    --limit 50
  ```

  ```python Python
  client = anthropic.Anthropic()

  versions = client.beta.organization.plugins.versions.list(
      "plugin_01Hq3vX8kZcN2mB7pR4tY9wL", limit=50
  )

  # 視需要自動擷取更多頁面。
  for version in versions:
      print(f"{version.id}: {version.manifest_version}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const versions = await client.beta.organization.plugins.versions.list(
    "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
    { limit: 50 }
  );

  for await (const version of versions) {
    console.log(`${version.id}: ${version.manifest_version}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  var page = await client.Beta.Organization.Plugins.Versions.List(
      "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
      new() { Limit = 50 }
  );

  await foreach (var version in page.Paginate())
  {
      Console.WriteLine($"{version.ID}: {version.ManifestVersion}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  versions := client.Beta.Organization.Plugins.Versions.ListAutoPaging(
  	context.Background(),
  	"plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  	anthropic.BetaOrganizationPluginVersionListParams{
  		Limit: anthropic.Int(50),
  	},
  )

  for versions.Next() {
  	version := versions.Current()
  	fmt.Printf("%s: %s\n", version.ID, version.ManifestVersion)
  }
  if err := versions.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  import com.anthropic.models.beta.organization.plugins.versions.VersionListParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = VersionListParams.builder()
          .limit(50)
          .build();
      var versions = client.beta().organization().plugins().versions()
          .list("plugin_01Hq3vX8kZcN2mB7pR4tY9wL", params);

      for (var version : versions.autoPager()) {
          IO.println(version.id() + ": " + version.manifestVersion().orElse(null));
      }
  }
  ```

  ```php PHP
  $client = new Client();

  $versions = $client->beta->organization->plugins->versions->list(
      pluginID: 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL',
      limit: 50,
  );

  // 僅限此頁；若要取得下一頁，請以 page: $versions->nextPage 再次呼叫 list()。
  foreach ($versions->getItems() as $version) {
      echo "{$version->id}: {$version->manifestVersion}\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  page = client.beta.organization.plugins.versions.list(plugin_id, limit: 50)

  page.auto_paging_each do |version|
    puts "#{version.id}: #{version.manifest_version}"
  end
  ```
</CodeGroup>

### 建立版本

`POST /v1/organizations/plugins/{plugin_id}/versions` 會為 `manual` 市集中組織擁有的外掛程式新增一個版本。請求主體為 `multipart/form-data`，具有與[建立外掛程式](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#create-a-plugin)相同的 `files[]` 和 `release_notes` 欄位、[上傳要求](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#upload-requirements)，以及檔案、資訊清單、封存檔和大小錯誤。上傳的名稱（資訊清單的 `name`）必須與外掛程式的 `name` 相同。若外掛程式未釘選，新版本通常會在儲存後立即提供；若已釘選，該版本會被儲存，但在您將提供的版本變更為它之前不會提供。若要確認，請比較回應的 `id` 與外掛程式的 `served_version_id`。傳回該版本。需要 `write:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl -X POST "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL/versions" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01" \
    -F "files[]=@dist/sales-toolkit.zip" \
    -F "release_notes=Adds the call-prep command."
  ```

  ```bash CLI
  ant beta:organization:plugins:versions create \
    --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL \
    --file dist/sales-toolkit.zip \
    --release-notes "Adds the call-prep command."
  ```

  ```python Python
  client = anthropic.Anthropic()

  with open("dist/sales-toolkit.zip", "rb") as archive:
      version = client.beta.organization.plugins.versions.create(
          "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
          files=[archive],
          release_notes="Adds the call-prep command.",
      )

  print(f"id: {version.id}")
  print(f"manifest_version: {version.manifest_version}")
  ```

  ```typescript TypeScript
  import fs from "node:fs";

  const client = new Anthropic();

  const version = await client.beta.organization.plugins.versions.create(
    "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
    {
      files: [fs.createReadStream("dist/sales-toolkit.zip")],
      release_notes: "Adds the call-prep command."
    }
  );

  console.log(`id: ${version.id}`);
  console.log(`manifest_version: ${version.manifest_version}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var version = await client.Beta.Organization.Plugins.Versions.Create(
      "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
      new()
      {
          Files = [File.OpenRead("dist/sales-toolkit.zip")],
          ReleaseNotes = "Adds the call-prep command.",
      }
  );

  Console.WriteLine($"id: {version.ID}");
  Console.WriteLine($"manifest_version: {version.ManifestVersion}");
  ```

  ```go Go
  client := anthropic.NewClient()

  archive, err := os.Open("dist/sales-toolkit.zip")
  if err != nil {
  	log.Fatal(err)
  }
  defer archive.Close()

  version, err := client.Beta.Organization.Plugins.Versions.New(
  	context.Background(),
  	"plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  	anthropic.BetaOrganizationPluginVersionNewParams{
  		Files:        []io.Reader{archive},
  		ReleaseNotes: anthropic.String("Adds the call-prep command."),
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", version.ID)
  fmt.Printf("manifest_version: %s\n", version.ManifestVersion)
  ```

  ```java Java
  import com.anthropic.core.MultipartField;
  import com.anthropic.models.beta.organization.plugins.versions.VersionCreateParams;

  void main() throws Exception {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      // 手動建構 `files[]` 部分，讓封存檔連同其檔名一併傳送，
      // 這是上傳所必需的。
      var archive = MultipartField.<List<InputStream>>builder()
          .value(List.of(Files.newInputStream(Path.of("dist/sales-toolkit.zip"))))
          .filename("sales-toolkit.zip")
          .contentType("application/octet-stream")
          .build();
      var params = VersionCreateParams.builder()
          .files(archive)
          .releaseNotes("Adds the call-prep command.")
          .build();
      var version = client.beta().organization().plugins().versions()
          .create("plugin_01Hq3vX8kZcN2mB7pR4tY9wL", params);

      IO.println("id: " + version.id());
      IO.println("manifest_version: " + version.manifestVersion().orElse(null));
  }
  ```

  ```php PHP
  use Anthropic\Core\FileParam;

  $client = new Client();

  $version = $client->beta->organization->plugins->versions->create(
      pluginID: 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL',
      files: [
          FileParam::fromResource(fopen('dist/sales-toolkit.zip', 'r')),
      ],
      releaseNotes: 'Adds the call-prep command.',
  );

  echo "id: {$version->id}\n";
  echo "manifest_version: {$version->manifestVersion}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  version = client.beta.organization.plugins.versions.create(
    plugin_id,
    files: [Pathname("dist/sales-toolkit.zip")],
    release_notes: "Adds the call-prep command."
  )

  puts "id: #{version.id}"
  puts "manifest_version: #{version.manifest_version}"
  ```
</CodeGroup>

```json
{
  "type": "plugin_version",
  "id": "pluginver_01Jd5sK2nQ8wE4rT6yU1iO3p",
  "plugin_id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  "display_name": "Sales Toolkit",
  "description": "Account research and call prep for the sales team.",
  "manifest_version": "1.5.0",
  "release_notes": "Adds the call-prep command.",
  "created_by": { "type": "api_actor", "api_key_id": "apikey_01Nq9vN6rT2zH7uW4bX5mR8s" },
  "content_scan": { "status": "processing", "assessment": null, "reason": null },
  "components": [
    {
      "type": "skill",
      "name": "account-research",
      "description": "Researches a customer account before a call."
    },
    { "type": "mcp_server", "name": "crm", "description": null },
    {
      "type": "command",
      "name": "call-prep",
      "description": "Builds a one-page brief for an upcoming call."
    }
  ],
  "reach": "remote",
  "created_at": "2026-09-15T14:12:30Z"
}
```

除了上傳違反[上傳要求](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#upload-requirements)時的 `400`（請求主體超過 200 MB 時為 `413`）以及共用回應（成員擁有的外掛程式為 `403`；請參閱[錯誤回應](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#error-responses)）之外，請求還可能因以下原因失敗：

| 狀態                         | 原因                                   | 處理方式                                                                                                                                    |
| -------------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| 400                        | 外掛程式位於從 Git 同步的市集中，或上傳的名稱與外掛程式的名稱不同。 | 改為變更儲存庫，或修正 manifest 的 `name`。                                                                                                          |
| 409（無 `error_code`）        | 對此外掛程式的另一個上傳或提供版本變更仍在進行中。            | 稍後重試。                                                                                                                                   |
| 409 `skill_name_taken`     | 外掛程式位於程式庫市集中，且該版本新增了一個與組織技能同名的技能。    | 重新命名該技能，或在 claude.ai 中移除該組織技能。                                                                                                          |
| 503 `registration_pending` | 版本已儲存，但其註冊未完成。                       | 當回應帶有 `x-should-retry: true` 時，重新傳送相同的請求（請參閱[重試上傳](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#retrying-uploads)）。 |

### 取得版本

`GET /v1/organizations/plugins/{plugin_id}/versions/{version}` 傳回一個版本。`{version}` 是版本 ID，或是 `latest`，代表請求當下 `latest_version_id` 所識別的版本。需要 `read:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL/versions/latest" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugins:versions retrieve \
    --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL \
    --version latest
  ```

  ```python Python
  client = anthropic.Anthropic()

  version = client.beta.organization.plugins.versions.retrieve(
      "latest",
      plugin_id="plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  )

  print(f"id: {version.id}")
  print(f"manifest_version: {version.manifest_version}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const version = await client.beta.organization.plugins.versions.retrieve("latest", {
    plugin_id: "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  });

  console.log(`id: ${version.id}`);
  console.log(`manifest_version: ${version.manifest_version}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var version = await client.Beta.Organization.Plugins.Versions.Retrieve(
      "latest",
      new() { PluginID = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL" }
  );

  Console.WriteLine($"id: {version.ID}");
  Console.WriteLine($"manifest_version: {version.ManifestVersion}");
  ```

  ```go Go
  client := anthropic.NewClient()

  version, err := client.Beta.Organization.Plugins.Versions.Get(
  	context.Background(),
  	"latest",
  	anthropic.BetaOrganizationPluginVersionGetParams{
  		PluginID: "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", version.ID)
  fmt.Printf("manifest_version: %s\n", version.ManifestVersion)
  ```

  ```java Java
  import com.anthropic.models.beta.organization.plugins.versions.VersionRetrieveParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = VersionRetrieveParams.builder()
          .pluginId("plugin_01Hq3vX8kZcN2mB7pR4tY9wL")
          .build();
      var version = client.beta().organization().plugins().versions()
          .retrieve("latest", params);

      IO.println("id: " + version.id());
      IO.println("manifest_version: " + version.manifestVersion().orElse(null));
  }
  ```

  ```php PHP
  $client = new Client();

  $version = $client->beta->organization->plugins->versions->retrieve(
      version: 'latest',
      pluginID: 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL',
  );

  echo "id: {$version->id}\n";
  echo "manifest_version: {$version->manifestVersion}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  version = client.beta.organization.plugins.versions.retrieve("latest", plugin_id: plugin_id)

  puts "id: #{version.id}"
  puts "manifest_version: #{version.manifest_version}"
  ```
</CodeGroup>

### 下載版本的檔案

`GET /v1/organizations/plugins/{plugin_id}/versions/{version}/content` 會以儲存的 `.zip` 封存檔（`Content-Type: application/zip`）下載版本的檔案。無論內容掃描結果為何，都會傳回封存檔，因此您可以檢查對成員停止提供的版本。它會完全依照儲存時的樣子提供，因此對於 `manual` 市集中組織擁有的外掛程式，您可以將其原封不動地重新上傳為新版本，前提是它符合目前的上傳要求。`{version}` 必須是版本 ID，而非 `latest`：請先讀取外掛程式的 `served_version_id` 或 `latest_version_id`，或使用 `GET /v1/organizations/plugins/{plugin_id}/versions/latest` 解析 `latest`。`Content-Disposition` 檔名衍生自外掛程式的名稱，且不唯一；請依外掛程式和版本 ID 為儲存的檔案命名。需要 `read:plugins` 範圍。

下載**成員擁有的**外掛程式封存檔會在 Compliance API 的 Activity Feed（活動摘要）上記錄一個 `claude_plugin_archive_accessed` 事件，以 ID 識別金鑰（作為 `api_actor`）、外掛程式及其市集、版本以及擁有該外掛程式的成員；其中不包含任何名稱。下載組織擁有的外掛程式封存檔則不會記錄任何內容。

<CodeGroup>
  ```bash cURL
  curl "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL/versions/pluginver_01Km7tL4pR9xF5sU2zV3jP6q/content" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01" \
    -o plugin_01Hq3vX8kZcN2mB7pR4tY9wL_pluginver_01Km7tL4pR9xF5sU2zV3jP6q.zip
  ```

  ```bash CLI
  ant beta:organization:plugins:versions download \
    --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL \
    --version pluginver_01Km7tL4pR9xF5sU2zV3jP6q \
    --output plugin_01Hq3vX8kZcN2mB7pR4tY9wL_pluginver_01Km7tL4pR9xF5sU2zV3jP6q.zip
  ```

  ```python Python
  client = anthropic.Anthropic()

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  version_id = "pluginver_01Km7tL4pR9xF5sU2zV3jP6q"

  with client.beta.organization.plugins.versions.with_streaming_response.download(
      version_id,
      plugin_id=plugin_id,
  ) as response:
      response.stream_to_file(f"{plugin_id}_{version_id}.zip")
  ```

  ```typescript TypeScript
  import { writeFile } from "node:fs/promises";

  const client = new Anthropic();

  const pluginId = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL";
  const versionId = "pluginver_01Km7tL4pR9xF5sU2zV3jP6q";

  const response = await client.beta.organization.plugins.versions.download(versionId, {
    plugin_id: pluginId
  });
  if (!response.body) {
    throw new Error("The download returned no body");
  }

  await writeFile(`${pluginId}_${versionId}.zip`, response.body);
  ```

  ```csharp C#
  AnthropicClient client = new();

  using var response = await client.Beta.Organization.Plugins.Versions.Download(
      "pluginver_01Km7tL4pR9xF5sU2zV3jP6q",
      new() { PluginID = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL" }
  );

  using var content = await response.ReadAsStream();
  using var file = File.Create(
      "plugin_01Hq3vX8kZcN2mB7pR4tY9wL_pluginver_01Km7tL4pR9xF5sU2zV3jP6q.zip"
  );
  await content.CopyToAsync(file);
  ```

  ```go Go
  client := anthropic.NewClient()

  response, err := client.Beta.Organization.Plugins.Versions.Download(
  	context.Background(),
  	"pluginver_01Km7tL4pR9xF5sU2zV3jP6q",
  	anthropic.BetaOrganizationPluginVersionDownloadParams{
  		PluginID: "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }
  defer response.Body.Close()

  out, err := os.Create("plugin_01Hq3vX8kZcN2mB7pR4tY9wL_pluginver_01Km7tL4pR9xF5sU2zV3jP6q.zip")
  if err != nil {
  	log.Fatal(err)
  }
  defer out.Close()

  if _, err := io.Copy(out, response.Body); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  import com.anthropic.core.http.HttpResponse;
  import com.anthropic.models.beta.organization.plugins.versions.VersionDownloadParams;

  void main() throws Exception {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = VersionDownloadParams.builder()
          .pluginId("plugin_01Hq3vX8kZcN2mB7pR4tY9wL")
          .build();
      try (HttpResponse response = client.beta().organization().plugins().versions()
              .download("pluginver_01Km7tL4pR9xF5sU2zV3jP6q", params)) {
          Files.copy(
              response.body(),
              Path.of("plugin_01Hq3vX8kZcN2mB7pR4tY9wL_pluginver_01Km7tL4pR9xF5sU2zV3jP6q.zip"),
              StandardCopyOption.REPLACE_EXISTING);
      }
  }
  ```

  ```php PHP
  $client = new Client();

  // download() 會將整個封存檔以單一字串傳回，因此改為取得原始
  // 回應，並將其本文分塊複製到磁碟。
  $response = $client->beta->organization->plugins->versions->raw->download(
      version: 'pluginver_01Km7tL4pR9xF5sU2zV3jP6q',
      params: ['pluginID' => 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL'],
  );

  $archive = $response->getBody();
  $file = fopen('plugin_01Hq3vX8kZcN2mB7pR4tY9wL_pluginver_01Km7tL4pR9xF5sU2zV3jP6q.zip', 'wb');
  while (!$archive->eof()) {
      fwrite($file, $archive->read(1024 * 1024));
  }
  fclose($file);
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  version_id = "pluginver_01Km7tL4pR9xF5sU2zV3jP6q"
  archive = client.beta.organization.plugins.versions.download(version_id, plugin_id: plugin_id)

  # SDK 會以 StringIO 形式傳回已讀入記憶體的封存檔。
  File.binwrite("#{plugin_id}_#{version_id}.zip", archive.string)
  ```
</CodeGroup>

## 外掛程式安裝設定

這些端點適用於組織擁有的外掛程式。對於成員擁有的外掛程式，它們會傳回 `404`，這類外掛程式改用[分享](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#plugin-shares)。`{target}` 為字面值 `organization` 時代表外掛程式的組織層級設定，為群組的 `rbac_group_` ID 時代表該群組的設定；任何其他值都會傳回 `400`。群組 ID 來自 `GET /v1/organizations/rbac_groups`（範圍 `read:rbac_groups`；請參閱[使用者管理](https://platform.claude.com/docs/zh-TW/manage-claude/user-management#groups)）。設定本身沒有 `id`：它以 `(plugin_id, target)` 定址，且不會記錄執行者（執行者記錄在其 `plugin_installation_preference_updated` 活動事件上）。

### 列出外掛程式的安裝設定

`GET /v1/organizations/plugins/{plugin_id}/installation_settings` 列出組織擁有的外掛程式所持有的設定，依 `created_at` 遞減排序：其自身的組織層級設定（在繼承其市集預設值期間不存在）以及每個群組的設定。可依 `target_type`（`organization` 或 `rbac_group`）篩選。需要 `read:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL/installation_settings" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugins:installation-settings list \
    --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL
  ```

  ```python Python
  client = anthropic.Anthropic()

  settings = client.beta.organization.plugins.installation_settings.list(
      "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  )

  # 視需要自動擷取更多頁面。
  for setting in settings:
      print(f"{setting.plugin_id}: {setting.installation_preference}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const settings = await client.beta.organization.plugins.installationSettings.list(
    "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  );

  for await (const setting of settings) {
    console.log(`${setting.plugin_id}: ${setting.installation_preference}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  var page = await client.Beta.Organization.Plugins.InstallationSettings.List(
      "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  );

  await foreach (var setting in page.Paginate())
  {
      Console.WriteLine($"{setting.PluginID}: {setting.InstallationPreference.Raw()}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  settings := client.Beta.Organization.Plugins.InstallationSettings.ListAutoPaging(
  	context.Background(),
  	"plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  	anthropic.BetaOrganizationPluginInstallationSettingListParams{},
  )

  for settings.Next() {
  	setting := settings.Current()
  	fmt.Printf("%s: %s\n", setting.PluginID, setting.InstallationPreference)
  }
  if err := settings.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  var settings = client.beta().organization().plugins().installationSettings()
      .list("plugin_01Hq3vX8kZcN2mB7pR4tY9wL");

  for (var setting : settings.autoPager()) {
      IO.println(setting.pluginId() + ": " + setting.installationPreference().asString());
  }
  ```

  ```php PHP
  $client = new Client();

  $settings = $client->beta->organization->plugins->installationSettings->list(
      pluginID: 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL',
  );

  // 僅限此頁；若要取得下一頁，請以 page: $settings->nextPage 再次呼叫 list()。
  foreach ($settings->getItems() as $setting) {
      echo "{$setting->pluginID}: {$setting->installationPreference}\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  page = client.beta.organization.plugins.installation_settings.list(plugin_id)

  page.auto_paging_each do |setting|
    puts "#{setting.plugin_id}: #{setting.installation_preference}"
  end
  ```
</CodeGroup>

### 設定安裝設定

`POST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}` 會為組織擁有的外掛程式設定某個目標的安裝設定，建立該設定或變更其現有的值。請求主體唯一的欄位是 `installation_preference`（`required`、`auto_install`、`available` 或 `not_available`），且為必填。設定目標已持有的值不會有任何變更。設定 `organization` 目標會使外掛程式停止繼承其市集的預設值（`organization_installation_preference_inherited` 變為 `false`），即使該值與預設值相同亦然，因此外掛程式將不再跟隨市集預設值之後的變更。若要讓外掛程式回到其市集的預設值，請[移除組織層級設定](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#remove-an-installation-setting)；群組設定不受影響。群組目標必須是您的組織可在 `GET /v1/organizations/rbac_groups` 中看到的群組，否則請求會傳回 `404`。此變更不會改變外掛程式的 `updated_at`；它會記錄在 Activity Feed 上。傳回該設定。需要 `write:plugins` 範圍。

請一次只傳送一個外掛程式的安裝設定寫入。如果同一個外掛程式的多個寫入同時抵達，伺服器會依序處理，並可能以 `503` 回應其中部分寫入，而不套用它們。該 `503` 帶有 `x-should-retry: true`，且該寫入可以安全地重複：等待一兩秒，然後再次傳送。

<CodeGroup>
  ```bash cURL
  curl -X POST "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL/installation_settings/rbac_group_01F3xQqQzXyWvUtSrQpOnMlK" \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01" \
    -d '{"installation_preference": "available"}'
  ```

  ```bash CLI
  ant beta:organization:plugins:installation-settings set \
    --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL \
    --target rbac_group_01F3xQqQzXyWvUtSrQpOnMlK \
    --installation-preference available
  ```

  ```python Python
  client = anthropic.Anthropic()

  setting = client.beta.organization.plugins.installation_settings.set(
      "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK",
      plugin_id="plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
      installation_preference="available",
  )

  print(f"plugin_id: {setting.plugin_id}")
  print(f"installation_preference: {setting.installation_preference}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const setting = await client.beta.organization.plugins.installationSettings.set(
    "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK",
    {
      plugin_id: "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
      installation_preference: "available"
    }
  );

  console.log(`plugin_id: ${setting.plugin_id}`);
  console.log(`installation_preference: ${setting.installation_preference}`);
  ```

  ```csharp C#
  using Anthropic.Models.Beta.Organization.Plugins.InstallationSettings;

  AnthropicClient client = new();

  var setting = await client.Beta.Organization.Plugins.InstallationSettings.Set(
      "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK",
      new()
      {
          PluginID = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
          InstallationPreference = InstallationPreference.Available,
      }
  );

  Console.WriteLine($"plugin_id: {setting.PluginID}");
  Console.WriteLine($"installation_preference: {setting.InstallationPreference.Raw()}");
  ```

  ```go Go
  client := anthropic.NewClient()

  setting, err := client.Beta.Organization.Plugins.InstallationSettings.Set(
  	context.Background(),
  	"rbac_group_01F3xQqQzXyWvUtSrQpOnMlK",
  	anthropic.BetaOrganizationPluginInstallationSettingSetParams{
  		PluginID:               "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  		InstallationPreference: anthropic.BetaOrganizationPluginInstallationSettingSetParamsInstallationPreferenceAvailable,
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("plugin_id: %s\n", setting.PluginID)
  fmt.Printf("installation_preference: %s\n", setting.InstallationPreference)
  ```

  ```java Java
  import com.anthropic.models.beta.organization.plugins.installationsettings.InstallationSettingSetParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = InstallationSettingSetParams.builder()
          .pluginId("plugin_01Hq3vX8kZcN2mB7pR4tY9wL")
          .installationPreference(InstallationSettingSetParams.InstallationPreference.AVAILABLE)
          .build();
      var setting = client.beta().organization().plugins().installationSettings()
          .set("rbac_group_01F3xQqQzXyWvUtSrQpOnMlK", params);

      IO.println("plugin_id: " + setting.pluginId());
      IO.println("installation_preference: " + setting.installationPreference().asString());
  }
  ```

  ```php PHP
  use Anthropic\Beta\Organization\Plugins\InstallationSettings\InstallationSettingSetParams\InstallationPreference;
  // ...

  $client = new Client();

  $setting = $client->beta->organization->plugins->installationSettings->set(
      target: 'rbac_group_01F3xQqQzXyWvUtSrQpOnMlK',
      pluginID: 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL',
      installationPreference: InstallationPreference::AVAILABLE,
  );

  echo "plugin_id: {$setting->pluginID}\n";
  echo "installation_preference: {$setting->installationPreference}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  group_id = "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK"
  setting = client.beta.organization.plugins.installation_settings.set(
    group_id,
    plugin_id: plugin_id,
    installation_preference: :available
  )

  puts "plugin_id: #{setting.plugin_id}"
  puts "installation_preference: #{setting.installation_preference}"
  ```
</CodeGroup>

```json
{
  "type": "plugin_installation_setting",
  "plugin_id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  "target": { "type": "rbac_group", "rbac_group_id": "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK" },
  "installation_preference": "available",
  "created_at": "2026-09-02T10:00:00Z",
  "updated_at": "2026-09-02T10:00:00Z"
}
```

### 移除安裝設定

`DELETE /v1/organizations/plugins/{plugin_id}/installation_settings/{target}` 會移除組織擁有的外掛程式某個目標的安裝設定。當 `{target}` 為 `organization` 時，會移除外掛程式自身的組織層級設定。外掛程式隨後會再次繼承其市集的預設值（`organization_installation_preference_inherited` 變為 `true`），並跟隨該預設值之後的變更；群組設定不受影響。當使用群組的 `rbac_group_` ID 時，會移除該群組的設定：該群組的成員會改用組織層級值，或其所屬其他群組的設定。沒有自身設定的目標會傳回 `404`；這包括已繼承其市集預設值之外掛程式的 `organization` 目標。此變更不會改變外掛程式的 `updated_at`；它會記錄在 Activity Feed 上。回應以複合鍵取代 `id`；對於 `organization` 目標，其 `target` 為 `{"type": "organization"}`。需要 `write:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl -X DELETE "https://api.anthropic.com/v1/organizations/plugins/plugin_01Hq3vX8kZcN2mB7pR4tY9wL/installation_settings/rbac_group_01F3xQqQzXyWvUtSrQpOnMlK" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugins:installation-settings remove \
    --plugin-id plugin_01Hq3vX8kZcN2mB7pR4tY9wL \
    --target rbac_group_01F3xQqQzXyWvUtSrQpOnMlK
  ```

  ```python Python
  client = anthropic.Anthropic()

  removed_setting = client.beta.organization.plugins.installation_settings.remove(
      "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK",
      plugin_id="plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  )

  print(f"plugin_id: {removed_setting.plugin_id}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const removedSetting = await client.beta.organization.plugins.installationSettings.remove(
    "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK",
    { plugin_id: "plugin_01Hq3vX8kZcN2mB7pR4tY9wL" }
  );

  console.log(`plugin_id: ${removedSetting.plugin_id}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var removedSetting = await client.Beta.Organization.Plugins.InstallationSettings.Remove(
      "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK",
      new() { PluginID = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL" }
  );

  Console.WriteLine($"plugin_id: {removedSetting.PluginID}");
  ```

  ```go Go
  client := anthropic.NewClient()

  removedSetting, err := client.Beta.Organization.Plugins.InstallationSettings.Remove(
  	context.Background(),
  	"rbac_group_01F3xQqQzXyWvUtSrQpOnMlK",
  	anthropic.BetaOrganizationPluginInstallationSettingRemoveParams{
  		PluginID: "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("plugin_id: %s\n", removedSetting.PluginID)
  ```

  ```java Java
  import com.anthropic.models.beta.organization.plugins.installationsettings.InstallationSettingRemoveParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = InstallationSettingRemoveParams.builder()
          .pluginId("plugin_01Hq3vX8kZcN2mB7pR4tY9wL")
          .build();
      var removedSetting = client.beta().organization().plugins().installationSettings()
          .remove("rbac_group_01F3xQqQzXyWvUtSrQpOnMlK", params);

      IO.println("plugin_id: " + removedSetting.pluginId());
  }
  ```

  ```php PHP
  $client = new Client();

  $removedSetting = $client->beta->organization->plugins->installationSettings->remove(
      target: 'rbac_group_01F3xQqQzXyWvUtSrQpOnMlK',
      pluginID: 'plugin_01Hq3vX8kZcN2mB7pR4tY9wL',
  );

  echo "plugin_id: {$removedSetting->pluginID}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
  group_id = "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK"
  removed_setting = client.beta.organization.plugins.installation_settings.remove(
    group_id,
    plugin_id: plugin_id
  )

  puts "plugin_id: #{removed_setting.plugin_id}"
  ```
</CodeGroup>

```json
{
  "type": "plugin_installation_setting_deleted",
  "plugin_id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL",
  "target": { "type": "rbac_group", "rbac_group_id": "rbac_group_01F3xQqQzXyWvUtSrQpOnMlK" }
}
```

## 外掛程式分享

「Share」（分享）僅存在於成員擁有的外掛程式上，且在此 API 中為唯讀（請參閱[分享](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#shares)）。

### 列出外掛程式的分享

`GET /v1/organizations/plugins/{plugin_id}/shares` 列出成員擁有的外掛程式的擁有者已將其分享給誰，依 `granted_at` 遞減排序：所有成員（`organization`）、某個群組（`rbac_group`）或指定的成員（`organization_member`）。可依 `target_type` 篩選。擁有者未分享的外掛程式會傳回空清單；組織擁有的外掛程式會傳回 `404`。分享在此 API 上為唯讀，且列出的分享僅在您的組織於 claude.ai 中開啟該類型的分享時才會授予存取權（請參閱[分享](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#shares)）。`granted_at` 是給予分享的時間；如果擁有者之後在 claude.ai 中變更了分享，則為該變更的時間。需要 `read:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl "https://api.anthropic.com/v1/organizations/plugins/plugin_01Mr2wP7sU3aJ8vX5cY6nS9t/shares" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugins:shares list \
    --plugin-id plugin_01Mr2wP7sU3aJ8vX5cY6nS9t
  ```

  ```python Python
  client = anthropic.Anthropic()

  shares = client.beta.organization.plugins.shares.list("plugin_01Mr2wP7sU3aJ8vX5cY6nS9t")

  # 視需要自動擷取更多頁面。
  for share in shares:
      print(f"plugin_id: {share.plugin_id}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const shares = await client.beta.organization.plugins.shares.list(
    "plugin_01Mr2wP7sU3aJ8vX5cY6nS9t"
  );

  for await (const share of shares) {
    console.log(`plugin_id: ${share.plugin_id}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  var page = await client.Beta.Organization.Plugins.Shares.List("plugin_01Mr2wP7sU3aJ8vX5cY6nS9t");

  await foreach (var share in page.Paginate())
  {
      Console.WriteLine($"plugin_id: {share.PluginID}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  shares := client.Beta.Organization.Plugins.Shares.ListAutoPaging(
  	context.Background(),
  	"plugin_01Mr2wP7sU3aJ8vX5cY6nS9t",
  	anthropic.BetaOrganizationPluginShareListParams{},
  )

  for shares.Next() {
  	share := shares.Current()
  	fmt.Printf("plugin_id: %s\n", share.PluginID)
  }
  if err := shares.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  var shares = client.beta().organization().plugins().shares()
      .list("plugin_01Mr2wP7sU3aJ8vX5cY6nS9t");

  for (var share : shares.autoPager()) {
      IO.println("plugin_id: " + share.pluginId());
  }
  ```

  ```php PHP
  $client = new Client();

  $shares = $client->beta->organization->plugins->shares->list(
      pluginID: 'plugin_01Mr2wP7sU3aJ8vX5cY6nS9t',
  );

  // 僅限此頁；若要取得下一頁，請以 page: $shares->nextPage 再次呼叫 list()。
  foreach ($shares->getItems() as $share) {
      echo "plugin_id: {$share->pluginID}\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  plugin_id = "plugin_01Mr2wP7sU3aJ8vX5cY6nS9t"
  page = client.beta.organization.plugins.shares.list(plugin_id)

  page.auto_paging_each do |share|
    puts "plugin_id: #{share.plugin_id}"
  end
  ```
</CodeGroup>

```json
{
  "data": [
    {
      "type": "plugin_share",
      "plugin_id": "plugin_01Mr2wP7sU3aJ8vX5cY6nS9t",
      "target": { "type": "organization_member", "user_id": "user_01WCz9BvGLdMYRUMmcAxMWvW" },
      "granted_at": "2026-08-20T15:12:00Z"
    }
  ],
  "next_page": null
}
```

## 外掛程式市集

此 API 會讀取[市集](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#marketplaces)並設定組織市集的預設安裝設定；市集本身是在 claude.ai 中建立、連接到儲存庫及刪除的。

```json
{
  "type": "plugin_marketplace",
  "id": "marketplace_01VbNcMxZaSdFgHjKlQwErTy",
  "name": "engineering-tools",
  "owner": { "type": "organization" },
  "source": "github",
  "sync_status": "success",
  "last_sync_ended_at": "2026-09-10T22:15:03Z",
  "last_sync_read_sha": "9fceb02d0ae598e95dc970b74767f19372d61af8",
  "default_installation_preference": "available",
  "created_at": "2026-06-12T08:45:00Z"
}
```

| 欄位                                | 說明                                                                                                                                                 |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                            | 市集的名稱。在其存續期間固定不變。                                                                                                                                  |
| `owner`                           | 結構與外掛程式上的相同。                                                                                                                                       |
| `source`                          | `manual`、`github`、`gitlab` 或 `public_git`。請參閱[市集](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#marketplaces)。                  |
| `sync_status`                     | 最近一次同步的結果：`success`、`in_progress`、`failed_content`、`failed_transient`、`failed_auth` 或 `failed_limits`。在首次嘗試同步之前為 `null`，而來源為 `manual` 的市集永遠不會進行同步。 |
| `last_sync_ended_at`              | 最近一次同步嘗試完成的時間，無論其結果為何；對於尚未同步的已連接儲存庫，則為市集建立的時間。未同步的市集為 `null`。                                                                                      |
| `last_sync_read_sha`              | 上次同步從儲存庫讀取的 commit。不一定是提供版本所來自的 commit。未同步的市集為 `null`。                                                                                             |
| `default_installation_preference` | 組織市集：其中每個沒有自身設定的外掛程式的組織層級值（若從未設定則為 `not_available`）。個人市集：`null`。                                                                                   |

缺少 `marketplace_` 前綴的 `marketplace_id` 會傳回 `400`。帶有前綴但無法解析或屬於其他組織的值會傳回 `404`。

### 列出市集

`GET /v1/organizations/plugin_marketplaces` 列出您組織的市集以及成員的個人市集，依 `created_at` 遞減排序。您可以使用它來找出市集的 ID，以便在市集包含任何外掛程式之前，依其篩選外掛程式清單或上傳到其中。程式庫市集會在首次於其中建立內容後出現，無論是在 claude.ai 中或透過此 API 建立。可依 `owner_type`（`organization` 或 `user`）和 `source` 篩選。`limit` 為 1 到 1,000。需要 `read:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl "https://api.anthropic.com/v1/organizations/plugin_marketplaces?owner_type=organization" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugin-marketplaces list --owner-type organization
  ```

  ```python Python
  client = anthropic.Anthropic()

  marketplaces = client.beta.organization.plugin_marketplaces.list(
      owner_type="organization"
  )

  # 視需要自動擷取更多頁面。
  for marketplace in marketplaces:
      print(f"{marketplace.id}: {marketplace.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const marketplaces = await client.beta.organization.pluginMarketplaces.list({
    owner_type: "organization"
  });

  for await (const marketplace of marketplaces) {
    console.log(`${marketplace.id}: ${marketplace.name}`);
  }
  ```

  ```csharp C#
  using Anthropic.Models.Beta.Organization.PluginMarketplaces;

  AnthropicClient client = new();

  var page = await client.Beta.Organization.PluginMarketplaces.List(
      new() { OwnerType = OwnerType.Organization }
  );

  await foreach (var marketplace in page.Paginate())
  {
      Console.WriteLine($"{marketplace.ID}: {marketplace.Name}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  marketplaces := client.Beta.Organization.PluginMarketplaces.ListAutoPaging(
  	context.Background(),
  	anthropic.BetaOrganizationPluginMarketplaceListParams{
  		OwnerType: anthropic.BetaOrganizationPluginMarketplaceListParamsOwnerTypeOrganization,
  	},
  )

  for marketplaces.Next() {
  	marketplace := marketplaces.Current()
  	fmt.Printf("%s: %s\n", marketplace.ID, marketplace.Name)
  }
  if err := marketplaces.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  import com.anthropic.models.beta.organization.pluginmarketplaces.PluginMarketplaceListParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = PluginMarketplaceListParams.builder()
          .ownerType(PluginMarketplaceListParams.OwnerType.ORGANIZATION)
          .build();
      var marketplaces = client.beta().organization().pluginMarketplaces().list(params);

      for (var marketplace : marketplaces.autoPager()) {
          IO.println(marketplace.id() + ": " + marketplace.name());
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\Organization\PluginMarketplaces\PluginMarketplaceListParams\OwnerType;
  // ...

  $client = new Client();

  $marketplaces = $client->beta->organization->pluginMarketplaces->list(
      ownerType: OwnerType::ORGANIZATION,
  );

  // 僅限此頁；若要取得下一頁，請以 page: $marketplaces->nextPage 再次呼叫 list()。
  foreach ($marketplaces->getItems() as $marketplace) {
      echo "{$marketplace->id}: {$marketplace->name}\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  page = client.beta.organization.plugin_marketplaces.list(owner_type: :organization)

  page.auto_paging_each do |marketplace|
    puts "#{marketplace.id}: #{marketplace.name}"
  end
  ```
</CodeGroup>

### 取得市集

`GET /v1/organizations/plugin_marketplaces/{marketplace_id}` 傳回一個市集。需要 `read:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl "https://api.anthropic.com/v1/organizations/plugin_marketplaces/marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01"
  ```

  ```bash CLI
  ant beta:organization:plugin-marketplaces retrieve \
    --marketplace-id marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r
  ```

  ```python Python
  client = anthropic.Anthropic()

  marketplace = client.beta.organization.plugin_marketplaces.retrieve(
      "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"
  )

  print(f"id: {marketplace.id}")
  print(f"name: {marketplace.name}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const marketplace = await client.beta.organization.pluginMarketplaces.retrieve(
    "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"
  );

  console.log(`id: ${marketplace.id}`);
  console.log(`name: ${marketplace.name}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var marketplace = await client.Beta.Organization.PluginMarketplaces.Retrieve(
      "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"
  );

  Console.WriteLine($"id: {marketplace.ID}");
  Console.WriteLine($"name: {marketplace.Name}");
  ```

  ```go Go
  client := anthropic.NewClient()

  marketplace, err := client.Beta.Organization.PluginMarketplaces.Get(
  	context.Background(),
  	"marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
  	anthropic.BetaOrganizationPluginMarketplaceGetParams{},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", marketplace.ID)
  fmt.Printf("name: %s\n", marketplace.Name)
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  var marketplace = client.beta().organization().pluginMarketplaces()
      .retrieve("marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r");

  IO.println("id: " + marketplace.id());
  IO.println("name: " + marketplace.name());
  ```

  ```php PHP
  $client = new Client();

  $marketplace = $client->beta->organization->pluginMarketplaces->retrieve(
      marketplaceID: 'marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r',
  );

  echo "id: {$marketplace->id}\n";
  echo "name: {$marketplace->name}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  marketplace_id = "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"
  marketplace = client.beta.organization.plugin_marketplaces.retrieve(marketplace_id)

  puts "id: #{marketplace.id}"
  puts "name: #{marketplace.name}"
  ```
</CodeGroup>

### 設定市集的預設安裝設定

`POST /v1/organizations/plugin_marketplaces/{marketplace_id}` 設定組織擁有的市集的預設安裝設定。市集中每個沒有自身組織層級設定的外掛程式都會將此預設值回報為其 `organization_installation_preference`，包括之後新增的外掛程式。它適用於 `manual` 和同步的市集；成員的個人市集會傳回 `403`。唯一可更新的欄位是 `default_installation_preference`，且為必填。它無法設回 `null`：市集一旦有了預設值，就會一直保有，與 claude.ai 中相同。變更會記錄為一個 `marketplace_updated` 事件，不會有個別外掛程式的事件，且不會改變任何外掛程式的 `updated_at`。設定為已設定的值不會有任何變更，但有一個例外：從未設定預設值的市集會回報 `not_available`，但並未持有設定，因此其第一次寫入（即使是 `not_available`）也算作變更。傳回市集。需要 `write:plugins` 範圍。

<CodeGroup>
  ```bash cURL
  curl -X POST "https://api.anthropic.com/v1/organizations/plugin_marketplaces/marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r" \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01" \
    -d '{"default_installation_preference": "available"}'
  ```

  ```bash CLI
  ant beta:organization:plugin-marketplaces update \
    --marketplace-id marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r \
    --default-installation-preference available
  ```

  ```python Python
  client = anthropic.Anthropic()

  marketplace = client.beta.organization.plugin_marketplaces.update(
      "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
      default_installation_preference="available",
  )

  print(f"id: {marketplace.id}")
  print(f"default_installation_preference: {marketplace.default_installation_preference}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const marketplace = await client.beta.organization.pluginMarketplaces.update(
    "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
    { default_installation_preference: "available" }
  );

  console.log(`id: ${marketplace.id}`);
  console.log(`default_installation_preference: ${marketplace.default_installation_preference}`);
  ```

  ```csharp C#
  using Anthropic.Models.Beta.Organization.PluginMarketplaces;

  AnthropicClient client = new();

  var marketplace = await client.Beta.Organization.PluginMarketplaces.Update(
      "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
      new() { DefaultInstallationPreference = DefaultInstallationPreference.Available }
  );

  Console.WriteLine($"id: {marketplace.ID}");
  Console.WriteLine(
      $"default_installation_preference: {marketplace.DefaultInstallationPreference?.Raw()}"
  );
  ```

  ```go Go
  client := anthropic.NewClient()

  marketplace, err := client.Beta.Organization.PluginMarketplaces.Update(
  	context.Background(),
  	"marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r",
  	anthropic.BetaOrganizationPluginMarketplaceUpdateParams{
  		DefaultInstallationPreference: anthropic.BetaOrganizationPluginMarketplaceUpdateParamsDefaultInstallationPreferenceAvailable,
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("id: %s\n", marketplace.ID)
  fmt.Printf("default_installation_preference: %s\n", marketplace.DefaultInstallationPreference)
  ```

  ```java Java
  import com.anthropic.models.beta.organization.pluginmarketplaces.PluginMarketplaceUpdateParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = PluginMarketplaceUpdateParams.builder()
          .defaultInstallationPreference(PluginMarketplaceUpdateParams.DefaultInstallationPreference.AVAILABLE)
          .build();
      var marketplace = client.beta().organization().pluginMarketplaces()
          .update("marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r", params);

      IO.println("id: " + marketplace.id());
      IO.println("default_installation_preference: "
          + marketplace.defaultInstallationPreference().map(preference -> preference.asString()).orElse(null));
  }
  ```

  ```php PHP
  use Anthropic\Beta\Organization\PluginMarketplaces\PluginMarketplaceUpdateParams\DefaultInstallationPreference;
  // ...

  $client = new Client();

  $marketplace = $client->beta->organization->pluginMarketplaces->update(
      marketplaceID: 'marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r',
      defaultInstallationPreference: DefaultInstallationPreference::AVAILABLE,
  );

  echo "id: {$marketplace->id}\n";
  echo "default_installation_preference: {$marketplace->defaultInstallationPreference}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  marketplace_id = "marketplace_01Lp8uM5qS1yG6tV3aW4kQ7r"
  marketplace = client.beta.organization.plugin_marketplaces.update(
    marketplace_id,
    default_installation_preference: :available
  )

  puts "id: #{marketplace.id}"
  puts "default_installation_preference: #{marketplace.default_installation_preference}"
  ```
</CodeGroup>

### 驗證市集內容

有兩個端點會回報對給定市集內容進行同步時會發生什麼，而不會連接或儲存任何內容：`POST /v1/organizations/plugin_marketplaces/validate_repository` 讀取公開的 GitHub 儲存庫，`POST /v1/organizations/plugin_marketplaces/validate_archive` 讀取您上傳的市集目錄 `.zip`。兩者傳回相同的報告：`marketplace.json` 格式是否正確、哪些外掛程式會被略過及其原因，以及哪些外掛程式在同步時會遺漏部分內容。這些檢查與實際同步時執行的檢查相同。內容的問題會在報告中傳回，而非作為 HTTP 錯誤：請求會以 `valid: false` 成功，即使完全無法讀取儲存庫或封存檔也是如此。驗證算作一次讀取，且這兩個端點合計另外限制為每個組織每分鐘 10 次驗證（請參閱[速率限制](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#rate-limiting)）；它們不會在 Activity Feed 上記錄任何內容。驗證最多可能需要 120 秒才會傳回，因此請將用戶端的逾時設定為高於此值。兩個端點都需要 `read:plugins` 或 `write:plugins` 範圍（`read:org_audit` 和 `read:compliance_org_data` 不會授予這些範圍）。

儲存庫以及其在 GitHub 上位於儲存庫外部的任何外掛程式來源都會以匿名方式讀取，因此私人儲存庫或私人外掛程式來源會被回報為找不到。不會擷取 GitHub 以外主機上的外掛程式來源；這類外掛程式通常會收到 `marketplace_validate_source_not_checked` 警告，並在市集實際同步時進行檢查。如果儲存庫是（或封存檔指名的是）Anthropic 同步到每個組織的市集，則適用更嚴格的規則：市集外部的每個外掛程式來源都必須釘選到完整的 commit SHA，未釘選或位於不支援主機的來源會被回報為外掛程式錯誤，且讀取的分支預設為該市集同步來源的分支。

`validate_repository` 接受具有兩個欄位的 JSON 主體：`repository_url`，即 github.com 上公開儲存庫的 `https://` URL（必填），以及 `ref`，即分支名稱或完整的 40 字元 commit SHA（選用；省略或為 `null` 時，使用同步會讀取的分支，通常是儲存庫的預設分支）。`validate_archive` 接受恰好只有一個部分 `archive` 的 `multipart/form-data`，該部分須以帶有檔名的檔案部分傳送：市集目錄的 `.zip`，最大 32 MB，其內容位於根目錄或包在一個資料夾中（如 Git 主機下載所產生的），僅限 DEFLATE 或 STORE 壓縮。不接受其他表單欄位。

驗證位於某分支的公開儲存庫：

<CodeGroup>
  ```bash cURL
  curl -X POST "https://api.anthropic.com/v1/organizations/plugin_marketplaces/validate_repository" \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01" \
    -d '{"repository_url": "https://github.com/example-org/claude-plugins", "ref": "release-candidate"}'
  ```

  ```bash CLI
  ant beta:organization:plugin-marketplaces validate-repository \
    --repository-url https://github.com/example-org/claude-plugins \
    --ref release-candidate
  ```

  ```python Python
  client = anthropic.Anthropic()

  report = client.beta.organization.plugin_marketplaces.validate_repository(
      repository_url="https://github.com/example-org/claude-plugins",
      ref="release-candidate",
  )

  print(f"valid: {str(report.valid).lower()}")
  print(f"total_plugin_count: {report.total_plugin_count}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const report = await client.beta.organization.pluginMarketplaces.validateRepository({
    repository_url: "https://github.com/example-org/claude-plugins",
    ref: "release-candidate"
  });

  console.log(`valid: ${report.valid}`);
  console.log(`total_plugin_count: ${report.total_plugin_count}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var report = await client.Beta.Organization.PluginMarketplaces.ValidateRepository(
      new()
      {
          RepositoryUrl = "https://github.com/example-org/claude-plugins",
          Ref = "release-candidate",
      }
  );

  Console.WriteLine($"valid: {report.Valid.ToString().ToLowerInvariant()}");
  Console.WriteLine($"total_plugin_count: {report.TotalPluginCount}");
  ```

  ```go Go
  client := anthropic.NewClient()

  report, err := client.Beta.Organization.PluginMarketplaces.ValidateRepository(
  	context.Background(),
  	anthropic.BetaOrganizationPluginMarketplaceValidateRepositoryParams{
  		RepositoryURL: "https://github.com/example-org/claude-plugins",
  		Ref:           anthropic.String("release-candidate"),
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("valid: %t\n", report.Valid)
  fmt.Printf("total_plugin_count: %d\n", report.TotalPluginCount)
  ```

  ```java Java
  import com.anthropic.models.beta.organization.pluginmarketplaces.PluginMarketplaceValidateRepositoryParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var params = PluginMarketplaceValidateRepositoryParams.builder()
          .repositoryUrl("https://github.com/example-org/claude-plugins")
          .ref("release-candidate")
          .build();
      var report = client.beta().organization().pluginMarketplaces().validateRepository(params);

      IO.println("valid: " + report.valid());
      IO.println("total_plugin_count: " + report.totalPluginCount());
  }
  ```

  ```php PHP
  $client = new Client();

  $report = $client->beta->organization->pluginMarketplaces->validateRepository(
      repositoryURL: 'https://github.com/example-org/claude-plugins',
      ref: 'release-candidate',
  );

  echo 'valid: ' . ($report->valid ? 'true' : 'false') . "\n";
  echo "total_plugin_count: {$report->totalPluginCount}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  report = client.beta.organization.plugin_marketplaces.validate_repository(
    repository_url: "https://github.com/example-org/claude-plugins",
    ref: "release-candidate"
  )

  puts "valid: #{report.valid}"
  puts "total_plugin_count: #{report.total_plugin_count}"
  ```
</CodeGroup>

```json
{
  "type": "plugin_marketplace_validation_report",
  "valid": false,
  "ref": "release-candidate",
  "commit_sha": "9fceb02d0ae598e95dc970b74767f19372d61af8",
  "total_plugin_count": 3,
  "manifest_error": null,
  "manifest_error_code": null,
  "plugin_errors": [
    {
      "name": "deploy-helper",
      "error": "The plugin has a top-level bin/ directory.",
      "error_code": "marketplace_sync_bin_directory_not_allowed"
    }
  ],
  "plugin_warnings": [
    {
      "name": "release-notes",
      "warnings": [
        {
          "message": "plugin.json has unrecognized top-level keys: owners",
          "error_code": "marketplace_sync_plugin_unrecognized_keys"
        }
      ]
    }
  ]
}
```

| 欄位                                     | 說明                                                                                                                                       |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `valid`                                | 當 `marketplace.json` 格式正確且沒有外掛程式會被略過時為 `true`。警告不會使其變為 `false`。                                                                          |
| `ref`                                  | 以名稱表示所讀取的分支；未指定分支而讀取預設分支時、指定 commit SHA 時或驗證封存檔時為 `null`。                                                                                |
| `commit_sha`                           | 已驗證的 commit。對於從 Git 主機下載的封存檔，則為主機記錄在 ZIP 檔案註解欄位中的 commit（如果有的話；未經驗證）。                                                                    |
| `total_plugin_count`                   | `marketplace.json` 宣告的外掛程式數量；無法讀取時為 `0`。                                                                                                 |
| `manifest_error`、`manifest_error_code` | 在無法驗證任何內容時設定：無法讀取來源，或 `marketplace.json` 遺失、格式錯誤或超過限制。未在 120 秒內完成的驗證會回報 `manifest_error_code: "marketplace_validate_deadline_exceeded"`。 |
| `plugin_errors`                        | 同步會略過的每個外掛程式各一個 `{name, error, error_code}`。                                                                                             |
| `plugin_warnings`                      | 同步時會遺漏部分內容的每個外掛程式各一個 `{name, warnings: [{message, error_code}]}`。                                                                        |

改為以 `.zip` 驗證市集目錄的本機副本；回應是相同的報告：

<CodeGroup>
  ```bash cURL
  curl -X POST "https://api.anthropic.com/v1/organizations/plugin_marketplaces/validate_archive" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: ce-plugins-2026-09-01" \
    -F "archive=@marketplace.zip"
  ```

  ```bash CLI
  ant beta:organization:plugin-marketplaces validate-archive \
    --archive marketplace.zip
  ```

  ```python Python
  client = anthropic.Anthropic()

  with open("marketplace.zip", "rb") as archive:
      report = client.beta.organization.plugin_marketplaces.validate_archive(
          archive=archive
      )

  print(f"valid: {str(report.valid).lower()}")
  print(f"total_plugin_count: {report.total_plugin_count}")
  ```

  ```typescript TypeScript
  import fs from "node:fs";

  const client = new Anthropic();

  const report = await client.beta.organization.pluginMarketplaces.validateArchive({
    archive: fs.createReadStream("marketplace.zip")
  });

  console.log(`valid: ${report.valid}`);
  console.log(`total_plugin_count: ${report.total_plugin_count}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var report = await client.Beta.Organization.PluginMarketplaces.ValidateArchive(
      new() { Archive = File.OpenRead("marketplace.zip") }
  );

  Console.WriteLine($"valid: {report.Valid.ToString().ToLowerInvariant()}");
  Console.WriteLine($"total_plugin_count: {report.TotalPluginCount}");
  ```

  ```go Go
  client := anthropic.NewClient()

  archive, err := os.Open("marketplace.zip")
  if err != nil {
  	log.Fatal(err)
  }
  defer archive.Close()

  report, err := client.Beta.Organization.PluginMarketplaces.ValidateArchive(
  	context.Background(),
  	anthropic.BetaOrganizationPluginMarketplaceValidateArchiveParams{
  		Archive: archive,
  	},
  )
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Printf("valid: %t\n", report.Valid)
  fmt.Printf("total_plugin_count: %d\n", report.TotalPluginCount)
  ```

  ```java Java
  import com.anthropic.models.beta.organization.pluginmarketplaces.PluginMarketplaceValidateArchiveParams;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      // 傳入 Path，讓 `archive` 部分附帶檔名送出，此端點要求必須提供檔名。
      var params = PluginMarketplaceValidateArchiveParams.builder()
          .archive(Path.of("marketplace.zip"))
          .build();
      var report = client.beta().organization().pluginMarketplaces().validateArchive(params);

      IO.println("valid: " + report.valid());
      IO.println("total_plugin_count: " + report.totalPluginCount());
  }
  ```

  ```php PHP
  use Anthropic\Core\FileParam;

  $client = new Client();

  $report = $client->beta->organization->pluginMarketplaces->validateArchive(
      archive: FileParam::fromResource(fopen('marketplace.zip', 'r')),
  );

  echo 'valid: ' . ($report->valid ? 'true' : 'false') . "\n";
  echo "total_plugin_count: {$report->totalPluginCount}\n";
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  report = client.beta.organization.plugin_marketplaces.validate_archive(
    archive: Pathname("marketplace.zip")
  )

  puts "valid: #{report.valid}"
  puts "total_plugin_count: #{report.total_plugin_count}"
  ```
</CodeGroup>

內容的問題永遠不會使請求失敗。除了每個端點共用的回應（僅具有 `read:org_audit` 或 `read:compliance_org_data` 的金鑰為 `403`；請參閱[錯誤回應](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#error-responses)和[速率限制](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#rate-limiting)）之外，請求本身還可能因以下原因失敗：

| 狀態  | 原因                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | 處理方式                  |
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- |
| 400 | 在 `validate_repository` 上：主體不是 JSON 物件；`repository_url` 遺失、長度超過 2,048 個字元、帶有憑證，或不是 `https://github.com/{owner}/{repo}` 的形式（接受 `.git` 後綴；不接受其他主機、較長的路徑（例如分支頁面的 `/tree/main`），或 443 或 80 以外的連接埠）；`ref` 為空、長度超過 255 個字元、包含 `..`，或包含 ASCII 字母、數字、`.`、`_`、`-`、`+` 和 `/` 以外的字元；或存在其他欄位。通過這些檢查但指名儲存庫中不存在之分支的 `ref` 不會被拒絕：請求會以 `valid: false` 成功，且 `manifest_error` 會指出找不到該分支。在 `validate_archive` 上：主體不是 `multipart/form-data`，`archive` 部分遺失、重複或未以帶有檔名的檔案部分傳送，或存在其他表單欄位。 | 修正請求並重新傳送。            |
| 413 | 在 `validate_archive` 上：`archive` 部分或請求宣告的主體長度超過 32 MB。                                                                                                                                                                                                                                                                                                                                                                                                             | 改為依 URL 驗證儲存庫，或縮減封存檔。 |

#### 報告代碼

報告中的每個發現都有一個穩定的代碼：無法驗證任何內容時為 `manifest_error_code`，每個 `plugin_errors` 項目上為 `error_code`，每個警告上也為 `error_code`。當外掛程式有多個問題時，`error_code` 是第一個問題的代碼，而 `error` 會合併它們的訊息。未來可能會新增代碼；無法識別的 `manifest_error_code` 仍表示無法驗證內容，`plugin_errors` 項目上無法識別的代碼仍表示該外掛程式會被略過，警告上無法識別的代碼仍表示該外掛程式會同步。以下代碼表示暫時性狀況，因此相同的請求之後可能會成功：`marketplace_host_rate_limited`、`marketplace_host_server_error`、`marketplace_host_timeout`、`marketplace_host_unreachable`、`marketplace_repo_access_denied`、`marketplace_sync_transient_fetch_budget_exhausted`、`marketplace_validate_network_error`，以及通常也包括 `marketplace_validate_deadline_exceeded`。

## 無法識別的值

此頁面上的每個字串值（元件類型、`reach`、掃描欄位、市集 `source`、錯誤代碼）隨時可能新增值。請將無法識別的值視為任何未知字串來處理，而不是讓程式失敗。

## 速率限制

讀取請求（此頁面上的每個 `GET` 端點）共用每個組織**每分鐘 300 個請求**的「rate limit」（速率限制），寫入請求（建立外掛程式或版本、變更提供版本、刪除、設定或移除安裝設定，以及更新市集）共用每個組織**每分鐘 60 個請求**的限制。市集驗證（任一端點）算作讀取，且驗證另外限制為每個組織在兩個端點合計每分鐘 10 次；兩項限制都會在讀取請求主體之前檢查。這些限制是跨您組織的所有金鑰計算的，並與您組織的其他 Admin API 限制分開。超過限制的請求會傳回 **429 Too Many Requests** 並帶有 `retry-after` 標頭。回應包含適用限制的 `anthropic-ratelimit-requests-*` 標頭（在市集驗證上為其每分鐘 10 次的限制；在 `429` 上為拒絕該請求的限制）。

當服務暫時沒有容量處理另一個上傳、提供版本變更或驗證時，這些作業也可能傳回帶有 `retry-after` 的 `429`，而當您的組織超過其內容掃描速率時，上傳會傳回 `429`。請以相同方式處理所有這些情況：等待 `retry-after` 指定的時間，然後重試。除了這些限制之外，請一次只傳送一個同一外掛程式的安裝設定寫入：當多個寫入同時抵達時，部分寫入可能會以 `503` 和 `x-should-retry: true` 回應，這些寫入在一兩秒後可以安全地再次傳送（請參閱[設定安裝設定](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#set-an-installation-setting)）。

## 分頁

列表端點使用「**opaque cursor**」（不透明游標）。第一個請求最多傳回 `limit` 列以及一個 `next_page` 游標；在下一個請求中將該游標原封不動地作為 `page` 參數傳遞，並重複此操作直到 `next_page` 為 `null`。請將游標字串視為不透明的：不要自行解析、修改或建構它。[列出外掛程式](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#list-plugins)可能會傳回少於 `limit` 個外掛程式或沒有任何外掛程式的頁面，而 `next_page` 仍然有設定，因此請持續請求頁面直到 `next_page` 為 `null`。Python、TypeScript、C#、Go、Java 和 Ruby SDK 的列表迭代器以及 CLI（使用 `--format raw` 時除外）會為您處理這件事。它們會在 `next_page` 有設定時請求下一頁，因此較短或空白的頁面不會使其結束。在 PHP 和 curl 中，請自行請求每一頁，並將其 `next_page` 作為 `page` 傳遞。

`limit` 預設為 20，最小值為 1。外掛程式、安裝設定和分享的最大值為 100，版本和市集的最大值為 1,000。每個清單都依最新優先排序。

## 錯誤回應

錯誤回應遵循 [錯誤](https://platform.claude.com/docs/zh-TW/api/errors) 中記載的標準格式。聯絡支援團隊時，請提供回應主體中的 `request_id`。

| 狀態  | 意義                                                                                                                                                                      |
| --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400 | 輸入無效，或該操作不適用於此「plugin」（外掛程式）或「marketplace」（市集）（請參閱各端點的章節）。端點無法辨識查詢參數時，或組織不是 Claude Enterprise 組織時（`this endpoint is not supported for this organization type`），也會傳回此狀態。 |
| 401 | 缺少 `x-api-key` 標頭，或無法辨識該金鑰。                                                                                                                                             |
| 403 | 金鑰缺少必要的「scope」（範圍）。請求嘗試上傳至成員的外掛程式或個人市集、變更其提供的版本，或為其設定預設值時，也會傳回此狀態。（允許刪除成員的外掛程式。）                                                                                        |
| 404 | 找不到資源。請求省略 `anthropic-beta` 值，或您的組織未啟用此 API 時，也會傳回此狀態，因此這些端點看起來就像不存在。                                                                                                   |
| 409 | 名稱已被使用、內容掃描仍在執行中，或有衝突的上傳正在進行。                                                                                                                                           |
| 413 | 請求主體超過大小限制：上傳為 200 MB，市集驗證為 32 MB。                                                                                                                                      |
| 429 | 超過「rate limit」（速率限制）。請參閱[速率限制](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#rate-limiting)。                                                         |
| 500 | 內部錯誤。                                                                                                                                                                   |
| 503 | 暫時性錯誤。同一外掛程式的多個安裝設定寫入同時抵達時，也會傳回此狀態；請逐一傳送這些請求。請以「backoff」（退避）方式重試，但 `registration_pending` 除外（請參閱下表）。                                                                    |

當同一狀態有多種需要您以不同方式處理的原因時，錯誤也會包含 `error.details.error_code`。若原因涉及特定外掛程式或版本，錯誤還會包含 `error.details.plugin_id` 或 `error.details.plugin_version_id`：

```json
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "...",
    "details": {
      "error_code": "plugin_name_taken",
      "plugin_id": "plugin_01Hq3vX8kZcN2mB7pR4tY9wL"
    }
  },
  "request_id": "req_018EeWyXxfu5pfWkrYcMdjWG"
}
```

| `error_code`                                    | 狀態  | 意義與處理方式                                                                                                                              |
| ----------------------------------------------- | --- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `plugin_name_taken`                             | 409 | 市集中已存在同名的外掛程式，`details.plugin_id` 即為該外掛程式。如果您正在重試一個遺失回應的建立請求，請繼續使用該外掛程式。若沒有 `plugin_id`，表示該名稱已被獨立技能佔用：請改用其他名稱上傳，或在 claude.ai 中刪除該技能。 |
| `skill_name_taken`                              | 409 | 該外掛程式位於程式庫市集中，且其中一個技能與某個組織技能（管理員在 claude.ai 中為整個組織上傳的技能）同名。`details.skill_name` 會指出該名稱。請重新命名或移除其中一個。                                 |
| `registration_pending`                          | 503 | 檔案已儲存，但外掛程式的技能尚無法提供給成員使用。請參閱[重試上傳](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#retrying-uploads)。               |
| `scan_pending`                                  | 409 | 該版本的內容掃描仍在執行中。請在掃描完成後重試。                                                                                                             |
| `scan_failed`                                   | 400 | 該版本的內容掃描失敗、發生錯誤或未得出結論，因此無法提供該版本。請選擇其他版本。                                                                                             |
| `cmek_key_disabled`, `cmek_key_network_blocked` | 400 | 您組織的客戶管理加密金鑰無法使用。請參閱[客戶管理加密金鑰](https://platform.claude.com/docs/zh-TW/manage-claude/plugins-api#customer-managed-encryption-keys)。   |

日後可能會新增代碼。遇到無法辨識的代碼時，請依其狀態碼的方式處理。

### 重試上傳

沒有任何端點接受 `Idempotency-Key`。變更提供的版本、設定安裝設定以及設定市集預設值都可以安全地重複執行。重複的刪除或重複移除安裝設定會傳回 `404`。

傳回錯誤的上傳不會儲存任何內容，唯一的例外是帶有 `error_code: "registration_pending"` 的 `503`。伺服器儲存上傳的檔案後，會向 claude.ai 註冊新版本的技能，成員才能使用這些技能。`registration_pending` 表示檔案已儲存，但最後這個步驟未完成。再次上傳相同的檔案即可完成此步驟（同時會再儲存一個相同的版本）：

* 在 `POST /v1/organizations/plugins` 上，外掛程式*已經*建立，且回應帶有 `x-should-retry: false`：請勿重新傳送建立請求（重新傳送會傳回 `409 plugin_name_taken`），而應將相同的檔案上傳為 `details.plugin_id` 的一個版本。
* 在 `POST /v1/organizations/plugins/{plugin_id}/versions` 上，版本*已經*儲存（`details.plugin_version_id`）。回應帶有 `x-should-retry: true` 時，請重新傳送相同的請求；帶有 `false` 時則不要重新傳送。

如果建立請求的回應遺失，請重試：重試會傳回 `409 plugin_name_taken`，並在 `details.plugin_id` 中提供該外掛程式的 ID，您可以繼續使用該外掛程式。重試一個遺失回應的版本建立請求，會儲存第二個相同的版本。為避免這種情況，請在每次上傳前記錄外掛程式的 `latest_version_id`；如果回應遺失，請讀取該外掛程式，並僅在 `latest_version_id` 未變更時才重試。

## Activity Feed 事件

透過此 API 進行的每次寫入，都會記錄在您組織的 [Compliance API Activity Feed](https://platform.claude.com/docs/zh-TW/manage-claude/compliance-activity-feed) 上，並歸屬於該 API 金鑰，以帶有其 `apikey_` ID 的 `api_actor` 表示。該金鑰所建立的外掛程式和版本，其 `created_by` 中也會出現相同的執行者。

| 事件                                       | 發出時機                                                                                           |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `claude_plugin_created`                  | 透過上傳（在此處或在 claude.ai 中）或透過已接受的發布請求建立外掛程式時。由 Git 同步建立的外掛程式只會發出 `claude_plugin_version_created`。 |
| `claude_plugin_version_created`          | 儲存版本時。由 Git 同步儲存的版本會歸屬於 `system_actor`。                                                        |
| `claude_plugin_updated`                  | 將新版本上傳至現有外掛程式時。                                                                                |
| `claude_plugin_served_version_updated`   | 提供的版本變更時。                                                                                      |
| `claude_plugin_deleted`                  | 單獨刪除外掛程式時（在此處或在 claude.ai 中）。                                                                  |
| `plugin_installation_preference_updated` | 設定或移除安裝設定時。                                                                                    |
| `marketplace_created`                    | 首次上傳建立程式庫市集時。                                                                                  |
| `marketplace_updated`                    | 市集的預設安裝設定變更時，或管理員或擁有者在 claude.ai 中啟動同步時。                                                       |
| `marketplace_deleted`                    | 在 claude.ai 中連同其外掛程式一併刪除市集時（不會發出個別外掛程式的事件）。                                                    |
| `claude_plugin_archive_accessed`         | 下載成員擁有的外掛程式封存檔時。                                                                               |
| `claude_plugin_security_scan_completed`  | 內容掃描完成時。                                                                                       |

這些事件中的外掛程式、版本和市集 ID，與此 API 傳回的 ID 相同。`plugin_installation_preference_updated` 以外掛程式的 `name` 和 `marketplace_id` 來識別外掛程式，而非其 `id`。

變更市集的預設值只會記錄一個 `marketplace_updated` 事件，不會記錄個別外掛程式的事件，即使此變更會改變所有繼承該預設值的外掛程式的值。讀取操作不會被記錄，但下載成員擁有的外掛程式封存檔除外。未造成任何變更的寫入不會被記錄。

在 claude.ai 中授予或撤回的共用，會以 `role_assignment_granted` 和 `role_assignment_revoked` 事件出現在動態中。此 API 不會回報刪除：已刪除的外掛程式只會從下一次的清單中消失。透過 Git 同步移除的外掛程式、因刪除其市集而移除的外掛程式（只有一個 `marketplace_deleted` 事件），或因刪除成員帳戶或組織而移除的外掛程式，都不會發出個別外掛程式的事件，因此請定期重新列出完整清單，以掌握移除情況。

## 客戶管理加密金鑰

如果您的組織使用「[customer-managed encryption key](https://platform.claude.com/docs/zh-TW/manage-claude/cmek)」（客戶管理加密金鑰），版本的 `description`、`release_notes`、`components` 和檔案都會以該金鑰加密。當金鑰無法使用時：

* 讀取和列出仍會成功，但 `description`、`release_notes` 和 `components` 會以 `null` 傳回。
* 下載封存檔、建立、建立版本以及變更提供的版本，會傳回帶有 `cmek_key_disabled` 或 `cmek_key_network_blocked` 的 `400`。
* 刪除程式庫市集中的外掛程式會傳回 `400 cmek_key_disabled`，且不會刪除任何內容，因為必須先從 claude.ai 撤回其技能，而這需要該金鑰。其他刪除、安裝設定和市集預設值則可正常運作。

恢復金鑰後，上述所有限制都會解除。

## 另請參閱

<CardGroup cols={2}>
  <Card title="建立 Admin API 金鑰" href="https://platform.claude.com/docs/zh-TW/manage-claude/admin-api-keys">
    您的主要擁有者在此建立具範圍限制的金鑰。
  </Card>

  <Card title="使用者管理" href="https://platform.claude.com/docs/zh-TW/manage-claude/user-management">
    提供安裝設定中所用 `rbac_group_` ID 的群組端點。
  </Card>

  <Card title="Compliance API Activity Feed" href="https://platform.claude.com/docs/zh-TW/manage-claude/compliance-activity-feed">
    記錄外掛程式寫入和成員封存檔下載的位置。
  </Card>

  <Card title="Analytics API" href="https://platform.claude.com/docs/zh-TW/manage-claude/analytics-api">
    Claude Enterprise 的外掛程式與技能使用情況報告。
  </Card>
</CardGroup>
