Follow Discord
Sweep 01 Oct 2026 · 17:27Z Build v2.1.287 508 read Stable v2.1.285 Latest v2.1.287 Next v2.1.287 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · api

plugins-api changedmanage-claude/plugins-api

Nearest release: v2.1.287, published under an hour after this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Recorded here
Lines+3,251added
Lines−0removed
From line — no hunk to open at
First seen 1 Oct 2026 this site's first read of the page
Recorded edits1to this page, all time

## Endpoints ## Prerequisites ## Quick start ## Scopes ### Access to members' plugin files ### Reading another organization under the same parent ## Key concepts ### Plugins and components ### Marketplaces ### Organization-owned and member-owned plugins ### Versions and the served version ### Installation settings ### Shares ### Content scanning ### Reach ### Upload requirements ## Example workflows ### Publish each build from a release pipeline ### Roll a plugin out to a pilot group, then to everyone ### Keep a security inventory in sync ## Plugins ### List plugins ### Create a plugin ### Get a plugin ### Change the served version ### Delete a plugin ## Plugin versions ### List a plugin's versions ### Create a version ### Get a version ### Download a version's files ## Plugin installation settings ### List a plugin's installation settings ### Set an installation setting ### Remove an installation setting ## Plugin shares ### List a plugin's shares ## Plugin marketplaces ### List marketplaces ### Get a marketplace ### Set a marketplace's default installation setting ### Validate marketplace content #### Report codes ## Unrecognized values ## Rate limiting ## Pagination ## Error responses ### Retrying uploads ## Activity Feed events ## Customer-managed encryption keys ## See also

The whole hunk

3251 lines, new page
/
lines

A whole new page. There's nothing to diff it against, so here is what it says.

---
title: Plugins API
url: https://platform.claude.com/docs/en/manage-claude/plugins-api
description: "Inventory and manage the plugins in your Claude Enterprise organization: upload plugins and versions, choose the version members are served, control who can use each plugin, download plugin files for review, and validate a marketplace before you connect it."
---

The Plugins API lets you inventory every plugin in your Claude Enterprise organization, publish plugins and new versions from your own pipelines, choose which version members are served, control who can use each plugin, download plugin files for review, and check a Git marketplace before you connect it.

For plugin *usage* reporting (which plugins and skills members use, and how often), see [Analytics APIs](https://platform.claude.com/docs/en/manage-claude/analytics-api).

<Check>
  **Scoped Admin API key required**

  These endpoints require an Admin API key with the `read:plugins` scope (for `GET` endpoints, including archive downloads) or the `write:plugins` scope (for `POST` and `DELETE` endpoints, except marketplace validation, which either scope allows); [Scopes](https://platform.claude.com/docs/en/manage-claude/plugins-api#scopes) has the details, including two other read scopes that also work. See [Create an Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys#create-a-key-for-a-claude-enterprise-organization) for where your primary owner creates one. Pass the key in the `x-api-key` header on every request, together with the [`anthropic-version`](https://platform.claude.com/docs/en/api/versioning) header and the beta header shown in the following note.
</Check>

<Note>
  The Plugins API is in **beta** and is available to Claude Enterprise organizations only. It is not available to Claude Platform (Claude Console) organizations, or to organizations with HIPAA readiness enabled.

  Every request must include the [beta header](https://platform.claude.com/docs/en/api/beta-headers) `anthropic-beta: ce-plugins-2026-09-01` (the SDKs and the `ant` CLI send it for you). A request without it returns `404`, exactly as if the endpoint did not exist.
</Note>

## Endpoints

The API exposes 18 endpoints across five resources:

| Resource                                                                                                                                                            | Endpoints                                                                                                                                                                                                                                                                                             |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Plugins**: list every plugin in the organization, upload a new one, look one up, choose the version members are served (roll back or promote), delete one         | `GET /v1/organizations/plugins` `POST /v1/organizations/plugins` `GET /v1/organizations/plugins/{plugin_id}` `POST /v1/organizations/plugins/{plugin_id}` `DELETE /v1/organizations/plugins/{plugin_id}`                                                                                              |
| **Plugin versions**: list a plugin's version history, upload a new version, look one up, download a version's files                                                 | `GET /v1/organizations/plugins/{plugin_id}/versions` `POST /v1/organizations/plugins/{plugin_id}/versions` `GET /v1/organizations/plugins/{plugin_id}/versions/{version}` `GET /v1/organizations/plugins/{plugin_id}/versions/{version}/content`                                                      |
| **Installation settings**: read who can use an organization-owned plugin, set it for the whole organization or for one group, remove either setting                 | `GET /v1/organizations/plugins/{plugin_id}/installation_settings` `POST /v1/organizations/plugins/{plugin_id}/installation_settings/{target}` `DELETE /v1/organizations/plugins/{plugin_id}/installation_settings/{target}`                                                                           |
| **Shares**: read who a member has shared their own plugin with (read-only)                                                                                          | `GET /v1/organizations/plugins/{plugin_id}/shares`                                                                                                                                                                                                                                                    |
| **Plugin marketplaces**: find a marketplace's ID, look one up, set the default installation setting for its plugins, check marketplace content before connecting it | `GET /v1/organizations/plugin_marketplaces` `GET /v1/organizations/plugin_marketplaces/{marketplace_id}` `POST /v1/organizations/plugin_marketplaces/{marketplace_id}` `POST /v1/organizations/plugin_marketplaces/validate_repository` `POST /v1/organizations/plugin_marketplaces/validate_archive` |

This release does not include standalone skills (skills a member writes in the skills editor or uploads as a single skill in claude.ai). They do not appear in the inventory and cannot be created here. Plugins that Anthropic publishes are not inventoried either; their usage is reported by the [Analytics APIs](https://platform.claude.com/docs/en/manage-claude/analytics-api). Marketplaces are created, connected to repositories, and deleted in claude.ai, not through this API.

## Prerequisites

* Your organization must be on a Claude Enterprise plan.
* Your primary owner creates an Admin API key with the `read:plugins` scope, the `write:plugins` scope, or both in [claude.ai > Organization settings > API](https://claude.ai/admin-settings/api-access). See [Create an Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys#create-a-key-for-a-claude-enterprise-organization).
* Every request carries three headers: `x-api-key`, `anthropic-version: 2023-06-01`, and `anthropic-beta: ce-plugins-2026-09-01`.

The Python, TypeScript, C#, Go, Java, PHP, and Ruby SDKs expose these endpoints under `client.beta.organization` (csharp, go: `client.Beta.Organization`; java: `client.beta().organization()`; php: `$client->beta->organization`), and the [`ant` CLI](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/quickstart) under `ant beta:organization`; they send the `anthropic-version` and `anthropic-beta` headers for you. The examples on this page use each SDK's default client, which, like the CLI, reads the Admin API key from the `ANTHROPIC_API_KEY` environment variable; the curl examples read the key from the same variable and pass it in the `x-api-key` header. In the Python, TypeScript, C#, Go, Java, and Ruby list examples and in the CLI, the SDK fetches more pages as you iterate, so `limit` sets the page size, not the total; the PHP and curl examples return one page (see [Pagination](https://platform.claude.com/docs/en/manage-claude/plugins-api#pagination)).

API keys belong to the organization and keep working after the person who created them leaves. Do not share them or check them into source control.

## Quick start

List the plugins in your organization's own marketplaces, newest first:

<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)

  # Automatically fetches more pages as needed.
  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,
  );

  // Only this page; for the next, call list() again with page: $plugins->nextPage.
  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"
}
```

In this example the plugin is pinned to an earlier version: a newer version (`latest_version_id`) is stored but not yet served.

## Scopes

| Scope                      | Grants                                                                                                                                                                                                                                                                                                                                                                         |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `read:plugins`             | Every `GET` endpoint on this page, including archive downloads, plus marketplace validation.                                                                                                                                                                                                                                                                                   |
| `write:plugins`            | Every `POST` and `DELETE` endpoint on this page: create a plugin, create a version, change the served version, delete a plugin, set and remove installation settings, and set a marketplace's default, plus marketplace validation. It does not grant reads.                                                                                                                   |
| `read:org_audit`           | A read-only scope for security-audit integrations: every `GET` endpoint on this page, including archive downloads, plus the [user management](https://platform.claude.com/docs/en/manage-claude/user-management) and [Compliance API](https://platform.claude.com/docs/en/manage-claude/compliance-api) read endpoints. It does not grant marketplace validation or any write. |
| `read:compliance_org_data` | The Compliance API's scope for organization metadata (names, types, roles, and groups) and effective settings. Grants every `GET` endpoint on this page, exactly as `read:org_audit` does, so a Compliance Access Key can read plugins without a second key. It does not grant marketplace validation or any write.                                                            |

A key can carry several scopes. An integration that uploads a plugin and then reads it back needs both `read:plugins` and `write:plugins`. Wherever this page says an endpoint requires the `read:plugins` scope, a key with `read:org_audit` or `read:compliance_org_data` works too.

### Access to members' plugin files

Each of these read scopes (`read:plugins`, `read:org_audit`, and `read:compliance_org_data`) can download the files of plugins in members' personal marketplaces, including files that claude.ai's admin settings do not show, and a `read:org_audit` or `read:compliance_org_data` key bound to your parent organization can do this in any organization under it that has access to this API, by passing `organization_id` (see [Reading another organization under the same parent](https://platform.claude.com/docs/en/manage-claude/plugins-api#reading-another-organization-under-the-same-parent)). Each such download records a `claude_plugin_archive_accessed` event on the [Compliance API Activity Feed](https://platform.claude.com/docs/en/manage-claude/compliance-activity-feed), identifying the key, the plugin, the version, and the member (see [Activity Feed events](https://platform.claude.com/docs/en/manage-claude/plugins-api#activity-feed-events)). Downloads of organization-owned plugins are not recorded.

### Reading another organization under the same parent

`read:plugins` and `write:plugins` keys read and write only the organization they were created in. If your company has several Claude organizations linked under one parent organization, a `read:org_audit` or `read:compliance_org_data` key that the parent's primary owner created for all linked organizations (see [Create an Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys#create-a-key-for-a-claude-enterprise-organization)) can also read any of them that has access to this API: pass that organization's ID in the `organization_id` query parameter on any `GET` endpoint on this page. The ID is the organization UUID shown in claude.ai's settings (its `org_`-prefixed form is accepted too). Without the parameter, the key reads the organization it was created in. A `404` means the named organization is not under the key's parent or the API is not available to it; a value that is not a UUID or `org_` ID returns `400`. Any other key that names an organization other than its own gets `404`. Writes do not accept `organization_id`.

## Key concepts

### Plugins and components

A **plugin** is a package that extends Claude for your organization's members. It contains any combination of these components:

| Component  | What it is                                                                                               |
| ---------- | -------------------------------------------------------------------------------------------------------- |
| Skill      | Instructions and files that Claude loads when a task calls for it.                                       |
| Command    | A saved prompt a member runs by typing `/` followed by the command's name.                               |
| Agent      | A helper assistant with its own instructions, to which Claude can hand part of a task.                   |
| Hook       | A command that runs automatically when an event happens in a session, such as before Claude uses a tool. |
| MCP server | A connection from Claude to tools and data in another system (Model Context Protocol).                   |
| CLI        | A command-line program that the plugin lets Claude run.                                                  |

Every plugin has a manifest at `.claude-plugin/plugin.json`. The manifest's `name` becomes the plugin's `name`: a lowercase identifier that is unique within its marketplace.

### Marketplaces

A **marketplace** is a container of plugins. Each marketplace has an owner and a source.

* **Owner.** The organization owns its marketplaces. Each member can also have personal marketplaces.
* **Source.** `manual` means plugins are uploaded, in claude.ai or, for an organization marketplace, through this API. `github`, `gitlab`, and `public_git` mean plugins are synchronized from a Git repository the owner connected. Nothing can be uploaded to a synchronized marketplace, and this API cannot delete its plugins, because the next synchronization would undo either change. Change the repository instead.

Your organization's **library marketplace** is the organization-owned `manual` marketplace that uploads go to when you do not name a marketplace. It is created the first time something is uploaded to it.

### Organization-owned and member-owned plugins

A plugin's `owner.type` says whose marketplace it lives in:

* `organization`: you can manage it through this API, except that a plugin in a marketplace synchronized from Git cannot receive uploads or be deleted here.
* `user`: it lives in one member's personal marketplace. You can read its details and download its files, and delete it if its marketplace is `manual`. Uploading versions and choosing the served version return `403`. Sharing is managed only by the member, in claude.ai.

Removing a member from the organization does not remove their plugins. They stay in the inventory under the member's `user_id`, and the `owner_user_id` filter still finds them, so you can review and remove a departed member's content. They are deleted when the member's account is deleted.

### Versions and the served version

Every upload creates a new, immutable **version**, whether it comes from this API, from claude.ai, or from a Git synchronization. A plugin has two pointers to its versions:

* `latest_version_id`: the newest version.
* `served_version_id`: the version members are served.

By default `served_version_pinned` is `false`: the served version follows the newest one, and each new version is served as soon as it is stored.

Choosing a version with `POST /v1/organizations/plugins/{plugin_id}` **pins** the plugin (`served_version_pinned: true`). So does an administrator choosing a version in claude.ai, or accepting a member's request to publish into the plugin. From then on, new uploads are stored and advance `latest_version_id`, but members keep the pinned version until you point `served_version_id` at another one. A plugin whose two pointers differ has a stored version that is not being served.

This lets a release pipeline upload each build, test it, and then promote it. To have your pipeline decide when each build is served, pin the plugin once by setting `served_version_id` to its current version; from then on, promote each build you want served. With content scanning on, that first pin returns `409 scan_pending` until the current version's scan completes, and `400 scan_failed` if the scan completed with `fail` or `unknown`, or errored (`warn` is accepted). A pinned plugin cannot currently be unpinned, here or in claude.ai.

To roll back, set `served_version_id` to an earlier version. Roll forward the same way.

These rules describe organization-owned plugins. A member-owned plugin's served version is controlled by its owner in claude.ai.

### Installation settings

**Installation settings** decide who can use an organization-owned plugin. Each setting has one of four values, carried in the fields named `installation_preference` (and, on the plugin and marketplace objects, `organization_installation_preference` and `default_installation_preference`):

| Value           | Members see                                    |
| --------------- | ---------------------------------------------- |
| `required`      | The plugin is installed and cannot be removed. |
| `auto_install`  | The plugin is installed and can be removed.    |
| `available`     | The plugin can be installed on request.        |
| `not_available` | The plugin is hidden.                          |

A plugin can hold an organization-wide setting and one setting per group (the role-based access control groups managed in [User management](https://platform.claude.com/docs/en/manage-claude/user-management#groups)). A member gets a value by these rules:

1. The organization-wide value is the plugin's own organization-wide setting if it has one, otherwise its marketplace's default, otherwise `not_available`. The plugin reports this value in `organization_installation_preference`, with `organization_installation_preference_inherited: true` while it comes from the marketplace default.
2. A member who belongs to no group holding a setting for the plugin gets the organization-wide value.
3. A member who belongs to one or more groups holding a setting gets the most permissive of those groups' settings instead, ranked `required`, `auto_install`, `available`, `not_available`.

A group's setting replaces the organization-wide value for its members; it does not add to it. For example, if the organization-wide value is `required` and the Pilot group holds `available`, Pilot members get `available`. When you move a plugin from a pilot group to the whole organization, set the organization-wide value and then remove the group's setting. Setting the organization-wide value stops the plugin from inheriting its marketplace default; [removing the organization-wide setting](https://platform.claude.com/docs/en/manage-claude/plugins-api#remove-an-installation-setting) returns the plugin to that default.

A plugin created through this API starts with no settings of its own, so it inherits its marketplace's default: `not_available` unless someone has set a default. Deleting a group removes its settings from every plugin.

### Shares

**Shares** decide who can use a member-owned plugin. The owner shares it in claude.ai with every member, with a group, or with named members. This API lists shares but cannot change them.

If your organization has turned off a kind of sharing in its claude.ai settings, shares of that kind still appear in the list but give no one access while that setting is off; the list itself does not show whether it is.

### Content scanning

Cut at 300 lines. The page has the rest.

Feedback